Belle II Software development
DirectedNodeNetwork.h
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8#pragma once
9
10#include <framework/logging/Logger.h>
11
12#include <tracking/trackFindingVXD/segmentNetwork/DirectedNode.h>
13
14#include <cstdint>
15#include <unordered_map>
16#include <vector>
17
18namespace Belle2 {
27 template<typename EntryType, typename MetaInfoType>
29 protected:
33 using NodeID = std::int64_t;
34
35 public:
41 m_isFinalized(false)
42 {
43 m_nodeMap.reserve(40000);
44 m_nodes.reserve(40000);
45 }
46
47
51 {
52 for (auto nodePointer : m_nodeMap) {
53 delete nodePointer.second;
54 }
55 m_nodeMap.clear();
56 }
57
58
62 bool addNode(NodeID nodeID, EntryType& newEntry)
63 {
64 if (m_nodeMap.count(nodeID) == 0) {
65 // cppcheck-suppress stlFindInsert
66 m_nodeMap.emplace(nodeID, new Node(newEntry));
67 m_isFinalized = false;
68 return true;
69 }
70 return false;
71 }
72
73
76 {
77 // check if entry does not exist, constructed with ID=-1
78 if (m_lastOuterNodeID < 0) {
79 B2WARNING("Last OuterNode is not yet in this network! CurrentNetworkSize is: " << size());
80 return false;
81 }
82 // check if entries are identical (catch loops):
83 if (m_lastOuterNodeID == innerNodeID) {
84 B2WARNING("LastOuterNode and innerEntry are identical! Skipping linking-process");
85 return false;
86 }
87
88 if (linkNodes(m_lastOuterNodeID, innerNodeID)) {
89 return true;
90 }
91 B2WARNING("Last OuterNode and innerEntry were already in the network and were already connected."
92 "This is a sign for unintended behavior!");
93 return false;
94 }
95
96
99 {
100 // check if entry does not exist, constructed with ID=-1
101 if (m_lastInnerNodeID < 0) {
102 B2WARNING("Last InnerNode is not yet in this network! CurrentNetworkSize is: " << size());
103 return false;
104 }
105 // check if entries are identical (catch loops):
106 if (outerNodeID == m_lastInnerNodeID) {
107 B2WARNING("OuterEntry and lastInnerNode are identical! Skipping linking-process");
108 return false;
109 }
110
111 if (linkNodes(outerNodeID, m_lastInnerNodeID)) {
112 return true;
113 }
114
115 B2WARNING("Last InnerNode and outerEntry were already in the network and were already connected."
116 "This is a sign for unintended behavior!");
117 return false;
118 }
119
120
122 bool linkNodes(NodeID outerNodeID, NodeID innerNodeID)
123 {
124 m_isFinalized = false;
125 // check if entries are identical (catch loops):
126 if (outerNodeID == innerNodeID) {
127 B2WARNING("OuterNodeID and innerNodeID are identical! Skipping linking-process");
128 return false;
129 }
130 if (m_nodeMap.count(innerNodeID) == 0 or m_nodeMap.count(outerNodeID) == 0) {
131 B2WARNING("Trying to link Nodes that are not present yet");
132 return false;
133 }
134
135 m_lastOuterNodeID = outerNodeID;
136 m_lastInnerNodeID = innerNodeID;
137
138 return createLink(*(m_nodeMap[outerNodeID]), *(m_nodeMap[innerNodeID]));
139 }
140
141
143 inline bool isNodeInNetwork(const NodeID nodeID) const
144 {
145 return m_nodeMap.count(nodeID);
146 }
147
148
153 void clear()
154 {
155 m_nodes.clear();
156 // Clearing the unordered_map is important as the following modules will process the event
157 // if it still contains entries.
158 for (auto nodePointer : m_nodeMap) {
159 delete nodePointer.second;
160 }
161 m_nodeMap.clear();
162 }
163
164
166
167 std::vector<Node*> getOuterEnds()
168 {
169 if (!m_isFinalized) finalize();
170 return m_outerEnds;
171 }
172
173
175 std::vector<Node*> getInnerEnds()
176 {
177 if (!m_isFinalized) finalize();
178 return m_innerEnds;
179 }
180
181
184 Node* getNode(NodeID toBeFound)
185 {
186 if (m_nodeMap.count(toBeFound)) return m_nodeMap.at(toBeFound);
187 else return nullptr;
188 }
189
191 std::vector<Node* >& getNodes()
192 {
193 if (!m_isFinalized) finalize();
194 return m_nodes;
195 }
196
197
199 typename std::vector<Node* >::iterator begin()
200 {
201 if (!m_isFinalized) finalize();
202 return m_nodes.begin();
203 }
204
205
207 typename std::vector<Node* >::iterator end()
208 {
209 if (!m_isFinalized) finalize();
210 return m_nodes.end();
211 }
212
213
215 inline unsigned int size() const { return m_nodeMap.size(); }
216
217
218 protected:
221 static bool createLink(Node& outerNode, Node& innerNode)
222 {
223 // not successful if one of them was already added to the other one:
224 if (std::find(outerNode.getInnerNodes().begin(), outerNode.getInnerNodes().end(), &innerNode) != outerNode.getInnerNodes().end()) {
225 return false;
226 }
227 if (std::find(innerNode.getOuterNodes().begin(), innerNode.getOuterNodes().end(), &outerNode) != innerNode.getOuterNodes().end()) {
228 return false;
229 }
230
231 outerNode.addInnerNode(innerNode);
232 innerNode.addOuterNode(outerNode);
233 return true;
234 }
235
237 void finalize()
238 {
239 if (m_isFinalized) return;
240 m_nodes.clear();
241 m_nodes.reserve(m_nodeMap.size());
242 m_innerEnds.clear();
243 m_outerEnds.clear();
244 for (const auto& item : m_nodeMap) {
245 m_nodes.push_back(item.second);
246 if (item.second->getInnerNodes().empty()) m_innerEnds.push_back(item.second);
247 if (item.second->getOuterNodes().empty()) m_outerEnds.push_back(item.second);
248 }
249 m_isFinalized = true;
250 }
251
254 std::unordered_map<NodeID, Node*> m_nodeMap;
255
258
261
264
268 std::vector<Node*> m_nodes;
269
272 std::vector<Node*> m_outerEnds;
273
276 std::vector<Node*> m_innerEnds;
277 };
279}
Network of directed nodes of the type EntryType.
Node * getNode(NodeID toBeFound)
Returns pointer to the node carrying the entry which is equal to given parameter.
std::int64_t NodeID
NodeID should be some unique integer.
DirectedNode< EntryType, MetaInfoType > Node
Defining abbreviation for the used directed node type pack.
std::vector< Node * > getInnerEnds()
returns all nodes which have no inner nodes (but outer ones) and therefore are inner ends of the netw...
std::vector< Node * >::iterator begin()
Returns iterator for container: begin.
bool m_isFinalized
keeps track of the state of the network to fill the vectors m_nodes, m_outerEnds, m_innerEnds only if...
DirectedNodeNetwork()
************************* CONSTRUCTOR/DESTRUCTOR *************************
std::vector< Node * > & getNodes()
Returns all nodes of the network.
bool addInnerToLastOuterNode(NodeID innerNodeID)
to the last outerNode added, another innerNode will be attached
std::vector< Node * >::iterator end()
Returns iterator for container: end.
void finalize()
Finalizing the NodeNetwork.
static bool createLink(Node &outerNode, Node &innerNode)
************************* INTERNAL MEMBER FUNCTIONS *************************
~DirectedNodeNetwork()
destructor taking care of cleaning up the pointer-mess WARNING only needed when using classic pointer...
unsigned int size() const
Returns number of nodes to be found in the network.
std::vector< Node * > getOuterEnds()
getters:
std::unordered_map< NodeID, Node * > m_nodeMap
************************* DATA MEMBERS *************************
std::vector< Node * > m_innerEnds
keeps track of current innerEnds (nodes which have no innerNodes) entries are the NodeIds of the node...
bool linkNodes(NodeID outerNodeID, NodeID innerNodeID)
takes two entry IDs and weaves them into the network
bool isNodeInNetwork(const NodeID nodeID) const
Check if a given entry is already in the network.
NodeID m_lastInnerNodeID
temporal storage for last inner node added, used for speed-up
bool addNode(NodeID nodeID, EntryType &newEntry)
************************* PUBLIC MEMBER FUNCTIONS *************************
std::vector< Node * > m_outerEnds
keeps track of current outerEnds (nodes which have no outerNodes) entries are the NodeIDs of the node...
bool addOuterToLastInnerNode(NodeID outerNodeID)
to the last innerNode added, another outerNode will be attached
void clear()
Clear directed node network Called to clear the directed node network if its size grows to large.
NodeID m_lastOuterNodeID
temporal storage for last outer node added, used for speed-up
std::vector< Node * > m_nodes
After the network is finalized this vector will also carry all nodes to be able to keep the old inter...
The Node-Class.
Definition: DirectedNode.h:31
std::vector< DirectedNode< EntryType, MetaInfoType > * > & getInnerNodes()
************************* PUBLIC MEMBER FUNCTIONS *************************
Definition: DirectedNode.h:86
std::vector< DirectedNode< EntryType, MetaInfoType > * > & getOuterNodes()
Returns links to all outer nodes attached to this one.
Definition: DirectedNode.h:89
void addInnerNode(DirectedNode< EntryType, MetaInfoType > &newNode)
************************* INTERNAL MEMBER FUNCTIONS *************************
Definition: DirectedNode.h:55
void addOuterNode(DirectedNode< EntryType, MetaInfoType > &newNode)
Adds new links to the outward direction.
Definition: DirectedNode.h:62
Abstract base class for different kinds of events.