Belle II Software  release-08-01-10
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 
18 namespace 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 
75  bool addInnerToLastOuterNode(NodeID innerNodeID)
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 
98  bool addOuterToLastInnerNode(NodeID outerNodeID)
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.
std::vector< Node * > & getNodes()
Returns all nodes of the network.
std::int64_t NodeID
NodeID should be some unique integer.
DirectedNode< EntryType, MetaInfoType > Node
Defining abbreviation for the used directed node type pack.
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 *************************
bool addInnerToLastOuterNode(NodeID innerNodeID)
to the last outerNode added, another innerNode will be attached
void finalize()
Finalizing the NodeNetwork.
std::vector< Node * >::iterator end()
Returns iterator for container: end.
Node * getNode(NodeID toBeFound)
Returns pointer to the node carrying the entry which is equal to given parameter.
static bool createLink(Node &outerNode, Node &innerNode)
************************* INTERNAL MEMBER FUNCTIONS *************************
std::vector< Node * > getOuterEnds()
getters:
~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::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
std::vector< Node * > getInnerEnds()
returns all nodes which have no inner nodes (but outer ones) and therefore are inner ends of the netw...
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 * >::iterator begin()
Returns iterator for container: begin.
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 > * > & getOuterNodes()
Returns links to all outer nodes attached to this one.
Definition: DirectedNode.h:89
std::vector< DirectedNode< EntryType, MetaInfoType > * > & getInnerNodes()
************************* PUBLIC MEMBER FUNCTIONS *************************
Definition: DirectedNode.h:86
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.