| #include "topology.hpp" |
| |
| #include <iostream> |
| |
| void Topology::addBoard(const std::string& path, const std::string& boardType, |
| const std::string& boardName, |
| const nlohmann::json& exposesItem) |
| { |
| auto findType = exposesItem.find("Type"); |
| if (findType == exposesItem.end()) |
| { |
| return; |
| } |
| |
| boardNames.try_emplace(boardName, path); |
| |
| PortType exposesType = findType->get<std::string>(); |
| |
| if (exposesType == "DownstreamPort") |
| { |
| auto findConnectsTo = exposesItem.find("ConnectsToType"); |
| if (findConnectsTo == exposesItem.end()) |
| { |
| std::cerr << "Board at path " << path |
| << " is missing ConnectsToType" << std::endl; |
| return; |
| } |
| PortType connectsTo = findConnectsTo->get<std::string>(); |
| |
| downstreamPorts[connectsTo].emplace_back(path); |
| boardTypes[path] = boardType; |
| auto findPoweredBy = exposesItem.find("PowerPort"); |
| if (findPoweredBy != exposesItem.end()) |
| { |
| powerPaths.insert(path); |
| } |
| } |
| else if (exposesType.ends_with("Port")) |
| { |
| upstreamPorts[exposesType].emplace_back(path); |
| boardTypes[path] = boardType; |
| } |
| } |
| |
| std::unordered_map<std::string, std::vector<Association>> |
| Topology::getAssocs(const std::map<Path, BoardName>& boards) |
| { |
| std::unordered_map<std::string, std::vector<Association>> result; |
| |
| // look at each upstream port type |
| for (const auto& upstreamPortPair : upstreamPorts) |
| { |
| auto downstreamMatch = downstreamPorts.find(upstreamPortPair.first); |
| |
| if (downstreamMatch == downstreamPorts.end()) |
| { |
| // no match |
| continue; |
| } |
| |
| for (const Path& upstream : upstreamPortPair.second) |
| { |
| if (boardTypes[upstream] == "Chassis" || |
| boardTypes[upstream] == "Board") |
| { |
| for (const Path& downstream : downstreamMatch->second) |
| { |
| // The downstream path must be one we care about. |
| if (boards.find(downstream) != boards.end()) |
| { |
| result[downstream].emplace_back("contained_by", |
| "containing", upstream); |
| if (powerPaths.find(downstream) != powerPaths.end()) |
| { |
| result[upstream].emplace_back( |
| "powered_by", "powering", downstream); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| return result; |
| } |
| |
| void Topology::remove(const std::string& boardName) |
| { |
| // Remove the board from boardNames, and then using the path |
| // found in boardNames remove it from upstreamPorts and |
| // downstreamPorts. |
| auto boardFind = boardNames.find(boardName); |
| if (boardFind == boardNames.end()) |
| { |
| return; |
| } |
| |
| std::string boardPath = boardFind->second; |
| |
| boardNames.erase(boardFind); |
| |
| for (auto it = upstreamPorts.begin(); it != upstreamPorts.end();) |
| { |
| auto pathIt = |
| std::find(it->second.begin(), it->second.end(), boardPath); |
| if (pathIt != it->second.end()) |
| { |
| it->second.erase(pathIt); |
| } |
| |
| if (it->second.empty()) |
| { |
| it = upstreamPorts.erase(it); |
| } |
| else |
| { |
| ++it; |
| } |
| } |
| |
| for (auto it = downstreamPorts.begin(); it != downstreamPorts.end();) |
| { |
| auto pathIt = |
| std::find(it->second.begin(), it->second.end(), boardPath); |
| if (pathIt != it->second.end()) |
| { |
| it->second.erase(pathIt); |
| } |
| |
| if (it->second.empty()) |
| { |
| it = downstreamPorts.erase(it); |
| } |
| else |
| { |
| ++it; |
| } |
| } |
| } |