Virtlab:Řídící server/Mapping.php.inc
Z VirtlabWiki
< Virtlab:Řídící serverVerze z 11:26, 22. 2. 2007; zobrazit aktuální verzi
← Starší verze | Novější verze →
← Starší verze | Novější verze →
Tato třída implementuje vlastní namapování fyzických prvků na prvky ve virtuální topologii, tak aby byly splněny všechny podmínky.
Zatím není plně dokončeno - pokud mapovaní nelze provézt je proveden jen vypis oznamení.
Popis funkcí
- function __construct(virtlabParserEquipment $equip, virtlabParserTopology $topol)
- konstruktor třídy v PHP5. Jako parametry očekává objekty jednotlivých parseru - virtuální topologie a vybavení
- public function Evaluate($device)
- vrátí hodnotu zadaného zařízení. Podle nastavení třídy virtlabValues.
- public function DevicesValue()
- vrátí pole všech zařízení s vypočtenou hodnotou
- public function Availability($device, $vertex)
- zjistí zda-li může být zadané fyzické zařízením zařízením ve virtuální topologii. Pokud ano, vrátí pole s určením, které rozhraní mohou být použity, na kterých linkách virtuální topologie. Pokud ne vrátí číslo chyby - definováno ve třídě virtlabValues.
- private function Mapping($map2, &$vysledek)
- rekurzivní funkce, která se snaží mapovat. Ve dvojrozměrné poli $map2 je uloženo, který vertex může být realizován jakými device. Případný vysledek mapovaní je uložen do proměnné $vysledek. (viz příklady) Pozn.: tato funkce je psána obecně, takže je ve druhém kroku znovu použita na mapovaní LINKA-ROZHRANÍ. Podrobnější informace k algoritmu rekuzivní funkce jsou zde.
- public function Map()
- funkce obstarávající 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 zde.
Zdrojový kód
<?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("<pre> "); print_r($map); print(" </pre>"); $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("<pre> "); print_r($map2); print(" </pre>"); $ahoj = array(); if($this->Mapping($map2,$ahoj)) { //print("<pre> "); print_r($ahoj); print(" </pre>"); } 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("<pre> "); print_r($hotovo); print(" </pre>"); print("<pre>"); $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("</pre>"); }//function }//class ?>
Kategorie: PHP | Třída | Diplomová práce | Jan Vavříček