Virtlab:Řídící server/Mapping.php.inc

Z VirtlabWiki

< Virtlab:Řídící server(Rozdíly mezi verzemi)
Přejít na: navigace, hledání
Verze z 10:16, 22. 10. 2007
Vav166 (Diskuse | příspěvky)

← Předchozí porovnání
Aktuální verze
Vav166 (Diskuse | příspěvky)

Řádka 1: Řádka 1:
-Tato třída implementuje vlastní namapování laboratorních prvků na prvky v logické topologii, tak aby byly splněny všechny podmínky.+Tato třída (virtlabMapping) implementuje vlastní namapování laboratorních prvků na prvky v logické topologii, tak aby byly splněny všechny podmínky.
-'''Zatím není plně dokončeno - pokud mapovaní nelze provést je proveden jen vypis oznamení.'''+'''Poznámka: podrobné výpisy z průběhu algoritmu, jsou [[Virtlab:Řídící server/Mapovací algoritmus|zde]].'''
- +
-== Proměnné == +
-; equipment : odkaz na objekt <tt>virtlabParserEquipment</tt>, který poskytuje data o laboratorních prvcích+
-; topology : odkaz na objekt <tt>virtlabParserTopology</tt>, který poskytuje data o logické topologii+
- +
-== Metody ==+
-; function __construct(virtlabParserEquipment $equip, virtlabParserTopology $topol) : konstruktor třídy v PHP5. Jako parametry očekává objekty jednotlivých parseru - [[Virtlab:ParserTopology.php.inc|virtuální topologie]] a [[Virtlab:ParserEquipment.php.inc|vybavení]]+
-; public function Evaluate($device) : vrátí vypočtenou hodnotu (tu ovlivnňuje typ laboratorního prvku, počet rozhrani, ...) zadaného lab. prvku. Nastavení konstant třídy [[Virtlab:Values.php.inc|virtlabValues]] ovlivní výslednou hodnotu.+
-; public function DevicesValue() : vrátí pole všech laboratorních prvků s jejich vypočtenou hodnotou+
-; public function Availability($device, $vertex) : zjistí, zda-li může být zadaný laboratorní prvek, zařízením v logické topologii. Pokud '''ano''', vrátí pole s určením, která rozhraní mohou být použita, na kterých linkách logické topologie. Pokud '''ne''', vrátí číslo chyby - definováno ve třídě [[Virtlab:Values.php.inc|virtlabValues]].+
-; private function Mapping($map2, &$vysledek) : '''rekurzivní''' funkce, která se snaží mapovat. Ve dvojrozměrné poli <tt>$map2</tt> je uloženo, který ''vertex'' může být realizován jakými ''device''. Případný vysledek mapovaní je uložen do proměnné <tt>$vysledek</tt>. (viz příklady) ''Pozn.: tato funkce je psána obecně, takže je ve druhém kroku je znovu použita na mapovaní LINKA-ROZHRANÍ.'' Podrobnější informace k algoritmu rekuzivní funkce jsou [[Virtlab:Mapovací algoritmus|zde]].+
-; public function Map() : funkce obstarávající [[Virtlab:Mapovací algoritmus|celý algoritmus mapování]].+
- +
-== Příklady ==+
-Výsledný výstup:+
- '''$mapper->Map();'''+
- r21:s0/0 r11:s0/0 +
- r21:s0/1 r10:s0/0 +
- r42:gi7 r21:fa3 +
- r41:gi7 r21:fa2 +
- r41:gi6 r11:gi1 +
- r42:gi6 r10:gi1 +
- r42:gi5 r11:gi0 +
- r41:gi5 r10:gi0 +
- +
-'''Poznámka: podrobné výpisy z průběhu algoritmu, jsou [[Virtlab:Mapovací algoritmus|zde]].'''+
== Zdrojový kód == == Zdrojový kód ==
-<pre>+Aktuální verze se nachází [https://vl-test.cs.vsb.cz/websvn/filedetails.php?repname=virtlab&path=%2FDISTR%2Fweb%2Fclass%2FvirtlabMapping.php.inc&rev=0&sc=0 zde]
-<?php+
- +
-class virtlabMapping {+
- private $equipment = NULL;+
- private $topology = NULL;+
- +
- function __construct(virtlabParserEquipment $equip, virtlabParserTopology $topol) {+
- $this->equipment = $equip;+
- $this->topology = $topol;+
- }//konstruktor+
- +
- public function Evaluate($device) {+
- $hodnota = 0;+
- $eq = $this->equipment; //pointer to equipment+
- +
- $temp = $eq->getDeviceFeatures($device);+
- $hodnota += count($temp) * virtlabValues::DeviceFeature;+
- +
- $temp = $eq->getDeviceInterfacesFeatures($device);+
- $hodnota += count($temp) * virtlabValues::InterfaceFeature;+
- +
- for($i = $eq->getDeviceInterfacesCount($device) - 1; $i >= 0; $i--) {+
- $technology = $eq->getDeviceInterfaceTechnology($device, $i);+
- +
- if($technology == "ethernet") {+
- $inf = virtlabValues::InterfaceTechnologyEthernet;+
- $ether_type = $eq->getDeviceInterfaceEthertype($device, $i);+
- if($ether_type == "legacy") +
- $inf *= virtlabValues::EthertypeMultiplerLegacy;+
- else if($ether_type == "fast")+
- $inf *= virtlabValues::EthertypeMultiplerFast;+
- else if($ether_type == "gigabit")+
- $inf *= virtlabValues::EthertypeMultiplerGigabit;+
- else $inf *= 0; //error+
- +
- $hodnota += $inf;+
- }//if:ethernet+
- else if($technology == "serial") {+
- $inf = virtlabValues::InterfaceTechnologySerial;+
- $bps = $eq->getDeviceInterfaceMaxbps($device, $i);+
- +
- if(is_null($bps)) $bps = virtlabValues::defaultMaxbps; //error+
- +
- if((int)$bps < virtlabValues::bpsDefault)+
- $inf = (int)((double)$inf * virtlabValues::bpsLower);+
- else if((int)$bps > virtlabValues::bpsDefault)+
- $inf = (int)((double)$inf * virtlabValues::bpsBigger);+
- +
- $hodnota += $inf;+
- }//else-if:serial+
- }//for-interfaces+
- return $hodnota;+
- }//function-Evaluate+
- +
- +
- public function DevicesValue() {+
- $tmp = array();+
- $devices = $this->equipment->getDevicesList();+
- foreach($devices as $device) {+
- $tmp[$device] = $this->Evaluate($device);+
- }//foreach+
- return $tmp;+
- }//function-DevicesValue+
- +
- +
- public function Availability($device, $vertex) {+
- $device_idx = NULL;+
- $eq = $this->equipment; //pointer to equipment+
- $to = $this->topology; //pointer to topology+
- +
- $eq->getDeviceByName($device, &$device_idx);+
- +
- +
- //type+
- $tmp_e = $eq->getDeviceType($device_idx);+
- $tmp_t = $to->getVertexType($vertex);+
- if($tmp_e != $tmp_t) return virtlabValues::badType;+
- //print("Same type\n");+
- +
- +
- //platform+
- $tmp_e = $eq->getDevicePlatform($device_idx);+
- $tmp_t = $to->getVertexPlatforms($vertex, 1);+
- $tmp_platf = 0;+
- if(!is_null($tmp_t)) {+
- foreach($tmp_t as $hodnota) {+
- $pattern = "/" . $hodnota . "/";+
- if(preg_match($pattern, $tmp_e)) {+
- $tmp_platf = 1;+
- break;+
- }//if-preg_match+
- }//foreach+
- if(!$tmp_platf) return virtlabValues::badPlatform;+
- }//if-compare+
- unset($tmp_platf);+
- //print("Good platform\n");+
- +
- +
- //OS+
- $tmp_e = $eq->getDeviceOS($device, 1);+
- $tmp_t = $to->getVertexOS($vertex, 1); +
- $pattern = "/" . $tmp_t . "/";+
- if(!preg_match($pattern, $tmp_e)) return virtlabValues::badOS;+
- unset($pattern);+
- //print("Good OS\n");+
- +
- +
- //device features+
- $tmp_e = $eq->getDeviceFeatures($device);+
- $tmp_t = $to->getVertexFeatures($vertex);+
- if(count(array_diff((array)$tmp_t,(array)$tmp_e)) > 0) return virtlabValues::noDeviceFeature;+
- //print("Device features-OK\n");+
- +
- +
- //enough interfaces+
- $tmp_t_if = array();+
- $tmp_e_if = array();+
- $tmp_t = $to->getEdgesByVertex($vertex);+
- foreach($tmp_t as $edge_idx => $edge) {+
- $tmp_tech = $to->getEdgeTechnology($edge_idx);+
- array_push($tmp_t_if, $tmp_tech);+
- }//foreach+
- for($i = $eq->getDeviceInterfacesCount($device) - 1; $i>=0; $i--) {+
- $tmp_tech = $eq->getDeviceInterfaceTechnology($device, $i);+
- array_push($tmp_e_if, $tmp_tech);+
- }//for+
- $tmp_res = array_porovnej($tmp_t_if, $tmp_e_if); //intersect of multisets+
- if(count($tmp_res) != 0) return virtlabValues::notEnoughInterfaces;+
- unset($tmp_t_if, $tmp_e_if, $tmp_res);+
- +
- +
- //interfaces+
- $tmp_t = $to->getEdgesByVertex($vertex);+
- $result = array();+
- foreach($tmp_t as $idx => $edge) {+
- $result[$edge] = array();+
- +
- for($i = $eq->getDeviceInterfacesCount($device) - 1; $i >= 0; $i--) {+
- +
- $tmp_e_fea = $eq->getDeviceInterfaceFeatures($device, $i);+
- if(is_null($tmp_e_fea)) $tmp_e_fea = array();+
- $tmp_t_fea = $to->getEdgeFeatures($idx);+
- if(is_null($tmp_t_fea)) $tmp_t_fea = array();+
- if(array_diff($tmp_t_fea, $tmp_e_fea)) continue; //uncompatible interface features -> next interface+
- +
- if($eq->getDeviceInterfaceTechnology($device, $i) == $to->getEdgeTechnology($idx)) {+
- if($to->getEdgeTechnology($idx) == "serial") {+
- if(is_null($to->getEdgeMinbps($idx))) {+
- $result[$edge][$i] = $eq->getDeviceInterfaceName($device, $i);+
- continue; +
- }//if-minbps=NULL+
- +
- if(is_null($eq->getDeviceInterfaceMaxbps($device, $i)))+
- $tmp_maxbps = virtlabValues::defaultMaxbps; //error avoidance+
- else $tmp_maxbps = $eq->getDeviceInterfaceMaxbps($device, $i);+
- if($to->getEdgeMinbps($idx) > $tmp_maxbps) continue; //slow serial interface -> next inteface+
- +
- $result[$edge][$i] = $eq->getDeviceInterfaceName($device, $i);+
- +
- }//if-technology=serial+
- else if($to->getEdgeTechnology($idx) == "ethernet") {+
- if(is_null($to->getEdgeEthertype($idx))) {+
- $result[$edge][$i] = $eq->getDeviceInterfaceName($device, $i);+
- continue;+
- }//if-ethertype-topology=NULL+
- +
- if(is_null($eq->getDeviceInterfaceEthertype($device, $i)))+
- $tmp_e_ethertype = virtlabValues::defaultEthertype; //error avoidance+
- else $tmp_e_ethertype = $eq->getDeviceInterfaceEthertype($device, $i);+
- +
- $tmp_t_ethertype = $to->getEdgeEthertype($idx);+
- +
- //if slower ethernet -> next interface+
- if($tmp_t_ethertype == "fast" && $tmp_e_ethertype == "legacy") continue;+
- else if($tmp_t_ethertype == "gigabit" && $tmp_e_ethertype == "legacy") continue;+
- else if($tmp_t_ethertype == "gigabit" && $tmp_e_ethertype == "fast") continue;+
- +
- $result[$edge][$i] = $eq->getDeviceInterfaceName($device, $i);+
- }//if-technology=ethernet+
- }//if-same technology+
- }//for - interfaces+
- }//foreach+
- +
- foreach($result as $hodnota) {+
- if(!$hodnota) return virtlabValues::VertexDeviceMismatch; //some edge has no compatible interface+
- }//foreach+
- +
- return $result;+
- }//function+
- +
- private function Mapping($map2, &$vysledek) {//recursive+
- foreach($map2 as $vertex => $devices) {+
- if(count($devices) == 0) return 0; //some vertex cannot be mapped+
- }//foreach+
- +
- if(count($map2) == 1) {+
- foreach($map2 as $vertex => $devices) {+
- if(count($devices) == 0) return 0; //cannot be mapped +
- foreach($devices as $device => $cena) {+
- $tmp["vertex"] = $vertex;+
- $tmp["device"] = $device;+
- array_push($vysledek, $tmp);+
- return 1;+
- }//foreach+
- }//foreach+
- }//if - count=1+
- else {+
- foreach($map2 as $vertex => $devices) { //exist vertex with one possibly device+
- if(count($devices) == 1) {+
- foreach($devices as $device => $cena) {+
- MatrixClear($map2, $vertex, $device);+
- if($this->Mapping($map2, $vysledek)) { //if mapping $vertex to $device is good+
- $tmp["vertex"] = $vertex;+
- $tmp["device"] = $device;+
- array_push($vysledek, $tmp);+
- return 1;+
- }//if+
- else return 0; //bad choice+
- }//foreach+
- }//if+
- }//foreach-vertex with one poss device+
- +
- foreach($map2 as $vertex => $devices) { +
- foreach($devices as $device => $cena) {+
- MatrixClear($map2,$vertex,$device);+
- if($this->Mapping($map2, $vysledek)) {+
- $tmp["vertex"] = $vertex;+
- $tmp["device"] = $device;+
- array_push($vysledek, $tmp);+
- return 1;+
- }//if+
- }//foreach+
- return 0; //no mapping is possible+
- }//general+
- }//else+
- }//function+
- +
- +
- public function Map() {+
- $devices = $this->equipment->getDevicesList();+
- $vertexes = $this->topology->getVertexesList();+
- +
- $map = array();+
- foreach($vertexes as $vertex) {+
- foreach($devices as $device) {+
- $vysledek = $this->Availability($device,$vertex);+
- +
- if(is_array($vysledek)) $map[$vertex][$device] = $vysledek;+
- else $map[$vertex][$device] = 0;+
- }//foreach+
- }//foreach+
- +
- //print("&lt;pre&gt; "); print_r($map); print(" &lt;/pre&gt;");+
- +
- $map2 = array();+
- foreach($map as $vertex => $devices) {+
- foreach($devices as $device => $infs) {+
- if(is_array($infs))+
- $map2[$vertex][$device] = $this->Evaluate($device);+
- }//foreach+
- }//foreach+
- +
- foreach($map2 as $idx => $devices) {+
- asort($devices,SORT_NUMERIC);+
- reset($devices);+
- $map2[$idx] = $devices;+
- }//foreach - sort+
- +
- //print("&lt;pre&gt; "); print_r($map2); print(" &lt;/pre&gt;");+
- +
- +
- $ahoj = array();+
- if($this->Mapping($map2,$ahoj)) {+
- //print("&lt;pre&gt; "); print_r($ahoj); print(" &lt;/pre&gt;");+
- }+
- else print("Smula");+
- +
- +
- $hotovo = array();+
- foreach($ahoj as $spojeni) {+
- $ahoj2 = array();+
- if($this->Mapping($map[$spojeni["vertex"]][$spojeni["device"]],$ahoj2)) {//map interfaces+
- $hotovo[$spojeni["vertex"]]["device"] = $spojeni["device"];+
- foreach($ahoj2 as $linka) {+
- $hotovo[$spojeni["vertex"]]["links"][$linka["vertex"]] = $this->equipment->getDeviceInterfaceName($spojeni["device"], $linka["device"]);+
- }//foreach+
- }//if+
- else print("Smula");+
- }//foreach+
- +
- //print("&lt;pre&gt; "); print_r($hotovo); print(" &lt;/pre&gt;");+
- +
- +
- print("&lt;pre&gt;");+
- $tmp = $this->topology->getEdgesList();+
- foreach($tmp as $edge_idx => $edge) {+
- $vertexes = $this->topology->getEdgeVertexes($edge_idx);+
- foreach($vertexes as $vertex) {+
- print($hotovo[$vertex]["device"] . ":" . $hotovo[$vertex]["links"][$edge] . " ");+
- }+
- print("\n");+
- }+
- print("&lt;/pre&gt;");+
- }//function+
-}//class+
-?>+
- +
-</pre>+
 +[[Kategorie:Komponenty virtlabu]]
 +[[Kategorie:Server]]
 +[[Kategorie:Řídící server]]
[[Kategorie:PHP]] [[Kategorie:PHP]]
[[Kategorie:Třída]] [[Kategorie:Třída]]

Aktuální verze

Tato třída (virtlabMapping) implementuje vlastní namapování laboratorních prvků na prvky v logické topologii, tak aby byly splněny všechny podmínky.

Poznámka: podrobné výpisy z průběhu algoritmu, jsou zde.

Zdrojový kód

Aktuální verze se nachází zde

Osobní nástroje