#include "topology.hpp" #include 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(); 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(); 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> Topology::getAssocs(const std::map& boards) { std::unordered_map> 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; } } }