Virtlab:Řídící server/Mapping.php.inc
Z VirtlabWiki
(Rozdíly mezi verzemi)
| Verze z 11:28, 22. 2. 2007 Vav166 (Diskuse | příspěvky) (→Popis funkcí) ← Předchozí porovnání |
Verze z 13:07, 5. 3. 2007 Vav166 (Diskuse | příspěvky) Následující porovnání → |
||
| Řádka 1: | Řádka 1: | ||
| - | 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. | + | Tato třída implementuje vlastní namapování fyzický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ézt je proveden jen vypis oznamení.''' | + | '''Zatím není plně dokončeno - pokud mapovaní nelze provést je proveden jen vypis oznamení.''' |
| - | == Popis funkcí == | + | == Konstanty == |
| + | ; equipment : odkaz na objekt <tt>virtlabParserEquipment</tt>, který poskytuje data o fyzických zařízení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í]] | ; 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í hodnotu zadaného zařízení. Podle nastavení třídy [[Virtlab:Values.php.inc|virtlabValues]]. | + | ; public function Evaluate($device) : vrátí vypočtenou hodnotu (tu ovlivnňuje typ zařízení, počet rozhrani, ...) zadaného zařízení. Nastavení konstant třídy [[Virtlab:Values.php.inc|virtlabValues]] ovlivní výslednou hodnotu. |
| - | ; public function DevicesValue() : vrátí pole všech zařízení s vypočtenou hodnotou | + | ; public function DevicesValue() : vrátí pole všech zařízení s jejich 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ě [[Virtlab:Values.php.inc|virtlabValues]]. | + | ; public function Availability($device, $vertex) : zjistí, zda-li může být zadané fyzické zařízení, 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 znovu použita na mapovaní LINKA-ROZHRANÍ.'' Podrobnější informace k algoritmu rekuzivní funkce jsou [[Virtlab:Mapovací algoritmus|zde]]. | ; 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 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í]]. | ; public function Map() : funkce obstarávající [[Virtlab:Mapovací algoritmus|celý algoritmus mapování]]. | ||
Verze z 13:07, 5. 3. 2007
Tato třída implementuje vlastní namapování fyzický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í.
Obsah |
Konstanty
- equipment
- odkaz na objekt virtlabParserEquipment, který poskytuje data o fyzických zařízeních
- topology
- odkaz na objekt virtlabParserTopology, 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 - virtuální topologie a vybavení
- public function Evaluate($device)
- vrátí vypočtenou hodnotu (tu ovlivnňuje typ zařízení, počet rozhrani, ...) zadaného zařízení. Nastavení konstant třídy virtlabValues ovlivní výslednou hodnotu.
- public function DevicesValue()
- vrátí pole všech zařízení s jejich vypočtenou hodnotou
- public function Availability($device, $vertex)
- zjistí, zda-li může být zadané fyzické zařízení, 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ě 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
