fpmas 1.6
graph.h
Go to the documentation of this file.
1#ifndef FPMAS_GRAPH_H
2#define FPMAS_GRAPH_H
3
9
10#include "fpmas/graph/node.h"
11#include "fpmas/graph/edge.h"
12
13namespace fpmas { namespace graph {
14
18 template<
19 typename NodeType,
20 typename EdgeType
21 > class Graph : public virtual api::graph::Graph<NodeType, EdgeType> {
22 public:
25
28
31
32 private:
33 std::vector<api::utils::Callback<NodeType*>*> insert_node_callbacks;
34 std::vector<api::utils::Callback<NodeType*>*> erase_node_callbacks;
35 std::vector<api::utils::Callback<EdgeType*>*> insert_edge_callbacks;
36 std::vector<api::utils::Callback<EdgeType*>*> erase_edge_callbacks;
37
38 NodeMap nodes;
39 EdgeMap edges;
40
41 public:
45 Graph() {}
46 Graph(const Graph<NodeType, EdgeType>&) = delete;
47 Graph<NodeType, EdgeType>& operator=(const Graph<NodeType, EdgeType>&) = delete;
48
57
58 void insert(NodeType*) override;
59 void insert(EdgeType*) override;
60
61 void erase(NodeType*) override;
62 void erase(EdgeType*) override;
63
65 insert_node_callbacks.push_back(callback);
66 }
67
68 std::vector<api::utils::Callback<NodeType*>*> onInsertNodeCallbacks() const override {
69 return insert_node_callbacks;
70 }
71
73 erase_node_callbacks.push_back(callback);
74 }
75
76 std::vector<api::utils::Callback<NodeType*>*> onEraseNodeCallbacks() const override {
77 return erase_node_callbacks;
78 }
79
81 insert_edge_callbacks.push_back(callback);
82 }
83
84 std::vector<api::utils::Callback<EdgeType*>*> onInsertEdgeCallbacks() const override {
85 return insert_edge_callbacks;
86 }
87
89 erase_edge_callbacks.push_back(callback);
90 }
91
92 std::vector<api::utils::Callback<EdgeType*>*> onEraseEdgeCallbacks() const override {
93 return erase_edge_callbacks;
94 }
95
96 // Node getters
97 NodeType* getNode(NodeIdType) override;
98 const NodeType* getNode(NodeIdType) const override;
99 const NodeMap& getNodes() const override;
100
101 // Edge getters
102 EdgeType* getEdge(EdgeIdType) override;
103 const EdgeType* getEdge(EdgeIdType) const override;
104 const EdgeMap& getEdges() const override;
105
106 void clear() override;
107
108 virtual ~Graph();
109 };
110
111 template<typename NodeType, typename EdgeType>
113 this->nodes = std::move(graph.nodes);
114 this->edges = std::move(graph.edges);
115 this->insert_node_callbacks = std::move(graph.insert_node_callbacks);
116 this->insert_edge_callbacks = std::move(graph.insert_edge_callbacks);
117 this->erase_node_callbacks = std::move(graph.erase_node_callbacks);
118 this->erase_edge_callbacks = std::move(graph.erase_edge_callbacks);
119 }
120
121 template<typename NodeType, typename EdgeType>
123 this->clear();
124 for(auto callback : insert_node_callbacks)
125 delete callback;
126 for(auto callback : erase_node_callbacks)
127 delete callback;
128 for(auto callback : insert_edge_callbacks)
129 delete callback;
130 for(auto callback : erase_edge_callbacks)
131 delete callback;
132
133 this->nodes = std::move(graph.nodes);
134 this->edges = std::move(graph.edges);
135 this->insert_node_callbacks = std::move(graph.insert_node_callbacks);
136 this->insert_edge_callbacks = std::move(graph.insert_edge_callbacks);
137 this->erase_node_callbacks = std::move(graph.erase_node_callbacks);
138 this->erase_edge_callbacks = std::move(graph.erase_edge_callbacks);
139
140 return *this;
141 }
142
143
144 template<typename NodeType, typename EdgeType>
146 FPMAS_LOGD(-1, "GRAPH", "Insert node %s", FPMAS_C_STR(node->getId()));
147 this->nodes.insert({node->getId(), node});
148 for(auto callback : insert_node_callbacks)
149 callback->call(node);
150 }
151
152 template<typename NodeType, typename EdgeType>
154 FPMAS_LOGD(
155 -1, "GRAPH", "Insert edge %s-{%i} (%p) (from %s to %s)",
156 FPMAS_C_STR(edge->getId()), edge->getLayer(), edge,
157 FPMAS_C_STR(edge->getSourceNode()->getId()),
158 FPMAS_C_STR(edge->getTargetNode()->getId())
159 );
160 this->edges.insert({edge->getId(), edge});
161 for(auto callback : insert_edge_callbacks)
162 callback->call(edge);
163 }
164
165 template<typename NodeType, typename EdgeType>
166 void Graph<NodeType, EdgeType>::erase(NodeType* node) {
167 FPMAS_LOGD(-1, "GRAPH", "Erase node %s", FPMAS_C_STR(node->getId()));
168 // Deletes incoming edges
169 for(auto* edge : node->getIncomingEdges()) {
170 FPMAS_LOGV(
171 -1,
172 "GRAPH",
173 "Unlink incoming edge %s",
174 FPMAS_C_STR(edge->getId())
175 );
176 this->erase(edge);
177 }
178 // Deletes outgoing edges
179 for(auto* edge : node->getOutgoingEdges()) {
180 FPMAS_LOGV(
181 -1,
182 "GRAPH",
183 "Unlink incoming edge %s",
184 FPMAS_C_STR(edge->getId())
185 );
186 this->erase(edge);
187 }
188
189 auto id = node->getId();
190 // Removes the node from the global nodes index
191 nodes.erase(id);
192 // Triggers callbacks
193 for(auto callback : erase_node_callbacks)
194 callback->call(node);
195
196 // Deletes the node
197 delete node;
198 FPMAS_LOGD(-1, "GRAPH", "Node %s removed.", FPMAS_C_STR(id));
199 }
200
201 template<typename NodeType, typename EdgeType>
202 void Graph<NodeType, EdgeType>::erase(EdgeType* edge) {
203 auto id = edge->getId();
204 FPMAS_LOGD(
205 -1, "GRAPH", "Erase edge %s-{%i} (%p) (from %s to %s)",
206 FPMAS_C_STR(id), edge->getLayer(), edge,
207 FPMAS_C_STR(edge->getSourceNode()->getId()),
208 FPMAS_C_STR(edge->getTargetNode()->getId())
209 );
210 // Removes the incoming edges from the incoming/outgoing
211 // edge lists of target/source nodes.
212 edge->getSourceNode()->unlinkOut(edge);
213 edge->getTargetNode()->unlinkIn(edge);
214
215 // Erases edge from the graph
216 this->edges.erase(id);
217 // Triggers callbacks
218 for(auto callback : erase_edge_callbacks)
219 callback->call(edge);
220
221 // Deletes edge
222 delete edge;
223 FPMAS_LOGD(-1, "GRAPH", "Edge %s removed.", FPMAS_C_STR(id));
224 }
225
226 template<typename NodeType, typename EdgeType>
227 NodeType*
229 return this->nodes.find(id)->second;
230 }
231
232 template<typename NodeType, typename EdgeType>
233 const NodeType*
235 return this->nodes.find(id)->second;
236 }
237
238 template<typename NodeType, typename EdgeType>
241 return this->nodes;
242 }
243
244 template<typename NodeType, typename EdgeType>
245 EdgeType*
247 return this->edges.find(id)->second;
248 }
249
250 template<typename NodeType, typename EdgeType>
251 const EdgeType*
253 return this->edges.find(id)->second;
254 }
255
256 template<typename NodeType, typename EdgeType>
259 return this->edges;
260 }
261
262 template<typename NodeType, typename EdgeType>
264 // This is VERY hacky.
265 std::vector<EdgeType*> _edges;
266 for(auto edge : this->edges)
267 _edges.push_back(edge.second);
268
269 for(auto edge : _edges) {
270 erase(edge);
271 }
272
273 std::vector<NodeType*> _nodes;
274 for(auto node : this->nodes)
275 _nodes.push_back(node.second);
276
277 for(auto node : _nodes) {
278 erase(node);
279 }
280 }
281
282 template<typename NodeType, typename EdgeType>
284 clear();
285 for(auto callback : insert_node_callbacks)
286 delete callback;
287 for(auto callback : erase_node_callbacks)
288 delete callback;
289 for(auto callback : insert_edge_callbacks)
290 delete callback;
291 for(auto callback : erase_edge_callbacks)
292 delete callback;
293 }
294
295}}
296#endif
Definition: graph.h:21
std::unordered_map< EdgeIdType, EdgeType *, EdgeIdHash > EdgeMap
Definition: graph.h:56
std::unordered_map< NodeIdType, NodeType *, NodeIdHash > NodeMap
Definition: graph.h:50
EdgeType::IdType EdgeIdType
Definition: graph.h:34
NodeType::IdType NodeIdType
Definition: graph.h:23
Definition: graph.h:21
Graph()
Definition: graph.h:45
void addCallOnEraseEdge(api::utils::Callback< EdgeType * > *callback) override
Definition: graph.h:88
const EdgeMap & getEdges() const override
Definition: graph.h:258
const NodeMap & getNodes() const override
Definition: graph.h:240
void addCallOnEraseNode(api::utils::Callback< NodeType * > *callback) override
Definition: graph.h:72
std::vector< api::utils::Callback< NodeType * > * > onEraseNodeCallbacks() const override
Definition: graph.h:76
EdgeType * getEdge(EdgeIdType) override
Definition: graph.h:246
std::vector< api::utils::Callback< NodeType * > * > onInsertNodeCallbacks() const override
Definition: graph.h:68
void addCallOnInsertNode(api::utils::Callback< NodeType * > *callback) override
Definition: graph.h:64
NodeType * getNode(NodeIdType) override
Definition: graph.h:228
void insert(NodeType *) override
Definition: graph.h:145
void clear() override
Definition: graph.h:263
void erase(NodeType *) override
Definition: graph.h:166
std::vector< api::utils::Callback< EdgeType * > * > onEraseEdgeCallbacks() const override
Definition: graph.h:92
std::vector< api::utils::Callback< EdgeType * > * > onInsertEdgeCallbacks() const override
Definition: graph.h:84
void addCallOnInsertEdge(api::utils::Callback< EdgeType * > *callback) override
Definition: graph.h:80
#define FPMAS_C_STR(arg)
Definition: macros.h:24
Definition: fpmas.cpp:3
Definition: id.h:58