1 #include "topology.hpp" 2 3 #include <iostream> 4 5 void Topology::addBoard(const std::string& path, const std::string& boardType, 6 const std::string& boardName, 7 const nlohmann::json& exposesItem) 8 { 9 auto findType = exposesItem.find("Type"); 10 if (findType == exposesItem.end()) 11 { 12 return; 13 } 14 15 boardNames.try_emplace(boardName, path); 16 17 PortType exposesType = findType->get<std::string>(); 18 19 if (exposesType == "DownstreamPort") 20 { 21 auto findConnectsTo = exposesItem.find("ConnectsToType"); 22 if (findConnectsTo == exposesItem.end()) 23 { 24 std::cerr << "Board at path " << path 25 << " is missing ConnectsToType" << std::endl; 26 return; 27 } 28 PortType connectsTo = findConnectsTo->get<std::string>(); 29 30 downstreamPorts[connectsTo].emplace_back(path); 31 boardTypes[path] = boardType; 32 } 33 else if (exposesType.ends_with("Port")) 34 { 35 upstreamPorts[exposesType].emplace_back(path); 36 boardTypes[path] = boardType; 37 } 38 } 39 40 std::unordered_map<std::string, std::vector<Association>> 41 Topology::getAssocs(const std::map<Path, BoardName>& boards) 42 { 43 std::unordered_map<std::string, std::vector<Association>> result; 44 45 // look at each upstream port type 46 for (const auto& upstreamPortPair : upstreamPorts) 47 { 48 auto downstreamMatch = downstreamPorts.find(upstreamPortPair.first); 49 50 if (downstreamMatch == downstreamPorts.end()) 51 { 52 // no match 53 continue; 54 } 55 56 for (const Path& upstream : upstreamPortPair.second) 57 { 58 if (boardTypes[upstream] == "Chassis" || 59 boardTypes[upstream] == "Board") 60 { 61 for (const Path& downstream : downstreamMatch->second) 62 { 63 // The downstream path must be one we care about. 64 if (boards.find(downstream) != boards.end()) 65 { 66 result[downstream].emplace_back("contained_by", 67 "containing", upstream); 68 } 69 } 70 } 71 } 72 } 73 74 return result; 75 } 76 77 void Topology::remove(const std::string& boardName) 78 { 79 // Remove the board from boardNames, and then using the path 80 // found in boardNames remove it from upstreamPorts and 81 // downstreamPorts. 82 auto boardFind = boardNames.find(boardName); 83 if (boardFind == boardNames.end()) 84 { 85 return; 86 } 87 88 std::string boardPath = boardFind->second; 89 90 boardNames.erase(boardFind); 91 92 for (auto it = upstreamPorts.begin(); it != upstreamPorts.end();) 93 { 94 auto pathIt = std::find(it->second.begin(), it->second.end(), 95 boardPath); 96 if (pathIt != it->second.end()) 97 { 98 it->second.erase(pathIt); 99 } 100 101 if (it->second.empty()) 102 { 103 it = upstreamPorts.erase(it); 104 } 105 else 106 { 107 ++it; 108 } 109 } 110 111 for (auto it = downstreamPorts.begin(); it != downstreamPorts.end();) 112 { 113 auto pathIt = std::find(it->second.begin(), it->second.end(), 114 boardPath); 115 if (pathIt != it->second.end()) 116 { 117 it->second.erase(pathIt); 118 } 119 120 if (it->second.empty()) 121 { 122 it = downstreamPorts.erase(it); 123 } 124 else 125 { 126 ++it; 127 } 128 } 129 } 130