blob: f2ee22b756e0c023eb519b3f3686d2fc9ba30a00 [file] [log] [blame]
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +00001#include "topology.hpp"
2
3#include <iostream>
4
5void Topology::addBoard(const std::string& path, const std::string& boardType,
Matt Spinler6eb60972023-08-14 16:36:20 -05006 const std::string& boardName,
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +00007 const nlohmann::json& exposesItem)
8{
9 auto findType = exposesItem.find("Type");
10 if (findType == exposesItem.end())
11 {
12 return;
13 }
Matt Spinler6eb60972023-08-14 16:36:20 -050014
15 boardNames.try_emplace(boardName, path);
16
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +000017 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
Matt Spinler6eb60972023-08-14 16:36:20 -050040std::unordered_map<std::string, std::vector<Association>>
41 Topology::getAssocs(const std::map<Path, BoardName>& boards)
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +000042{
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 {
Matt Spinler6eb60972023-08-14 16:36:20 -050063 // 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 }
Benjamin Fairf2f5b7a2022-09-09 19:45:02 +000069 }
70 }
71 }
72 }
73
74 return result;
75}
Matt Spinler6eb60972023-08-14 16:36:20 -050076
77void 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}