ATLAS Offline Software
Loading...
Searching...
No Matches
CBTree.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
5/*****************************************************************************
6 *
7 * CBTree.cxx
8 * IOVSvc
9 *
10 * Author: Charles Leggett
11 *
12 * Callback function trigger tree
13 *
14 *****************************************************************************/
15
16#include "CBTree.h"
17
18#include "SGTools/DataProxy.h"
19
20#include <iostream>
21
22using namespace std;
23
24//
26//
27
29 m_root = new CBNode("root",0);
30 m_allNodes.insert( m_root );
31}
32
33/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
34
36 for(std::set<CBNode*>::iterator itr=m_allNodes.begin();
37 itr != m_allNodes.end(); ++itr) {
38 delete *itr;
39 }
40}
41
42/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
43
44CBNode* CBTree::addNode(const SG::DataProxy* proxy, const std::string& name) {
45
46 CBNode* n = new CBNode(proxy, name, m_root);
47
48 m_allNodes.insert( n );
49
50 return n;
51}
52
53/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
54
56 assert (0 != pOld);
57 assert (0 != pNew);
58 CBNode* n(findNode(pOld));
59 if (0 != n) n->setProxy(pNew);
60 return n;
61}
62
63/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
64
65CBNode* CBTree::addNode(const std::string& name, CBNode* parent) {
66 if (parent == 0) {
67 parent = m_root;
68 }
69 CBNode* n = new CBNode(name, parent);
70
71 m_allNodes.insert( n );
72
73 return n;
74}
75/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
76
78 const SG::DataProxy* proxy) {
79
80 CBNode* parent = findNode(proxy);
81
82 if (parent == 0) {
83 cout << "ERROR: no parent proxy found in tree for " << proxy->name()
84 << endl;
85 return 0;
86 }
87
88 CBNode* n = new CBNode(fcn, cb, parent);
89
90 m_allNodes.insert( n );
91
92 return n;
93}
94/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
95
96CBNode* CBTree::addNode(BFCN* fcn, const CallBackID& cb, BFCN* parent_fcn) {
97
98 CBNode* parent = findNode(parent_fcn);
99
100 if (parent == 0) {
101 cout << "ERROR: no parent function found in tree for " << parent_fcn
102 << endl;
103 return 0;
104 }
105
106 CBNode* n = new CBNode(fcn, cb, parent);
107
108 m_allNodes.insert( n );
109
110 return n;
111}
112/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
113
115 CBNode *n = findNode(prx);
116 if (n == 0) {
117 cout << "ERROR: no node with DataProxy " << prx->name() << " found in tree"
118 << endl;
119 return false;
120 }
121
122 bool b(true);
123 for ( auto p : n->parents() ) {
124 if (!p->delChild( n )) {
125 cout << "ERROR: CBTree::delNode : unable to delete child "
126 << n->name() << " from parent " << p->name() << endl;
127 b = false;
128 }
129 }
130
131 for (auto c : n->children()) {
132 if (!c->delParent( n )) {
133 cout << "ERROR: CBTree::delNode : unable to delete parent "
134 << n->name() << " from child " << c->name() << endl;
135 b = false;
136 }
137 }
138
139 return b;
140}
141
142/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
143
145
146 // check to see if we're creating a loop
147 cascadeFlag(true, node);
148 if (parent->flag()) {
149 cout << "ERROR: cannot connect " << node->name() << " to "
150 << parent->name() << " as a loop would be formed"
151 << endl;
152 return;
153 }
154 clearFlag();
155
156 node->addParent( parent );
157 parent->addChild( node );
158 if (node->level() < (parent->level() + 1)) {
159 // we need to erase it first and then reinsert it as the ordering
160 // critereon has changed. Do this for all children too.
161 m_allNodes.erase( m_allNodes.find( node ) );
162 node->setLevel( parent->level() + 1);
163 m_allNodes.insert( node );
164
166
167 }
168}
169
170/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
171
172void CBTree::connectNode(const std::string& name, CBNode* parent) {
173 CBNode* n = findNode(name);
174 if (n == 0) {
175 addNode(name,parent);
176 } else {
177 connectNode(n, parent);
178 }
179}
180
181/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
182
184
185 return findNode(proxy, m_root);
186
187}
188
189/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
190
192
193 if ( start->proxy() == proxy ) {
194 return start;
195 } else {
196
197 for ( auto c : start->children() ) {
198 c = findNode(proxy, c);
199 if (c != 0) {
200 return c;
201 }
202 }
203 }
204
205 return 0;
206
207}
208
209/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
210
212 return findNode(fcn, m_root);
213}
214
215/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
216
218
219 if (start->fcn() == fcn) {
220 return start;
221 } else {
222
223 CBNode *c;
224 std::set<CBNode*>::const_iterator citr = start->children().begin();
225 for (; citr != start->children().end(); ++citr) {
226 c = findNode(fcn,*citr);
227 if (c != 0) {
228 return c;
229 }
230 }
231 }
232
233 return 0;
234}
235
236/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
237
238CBNode* CBTree::findNode(const std::string& name) {
239 return findNode(name, m_root);
240}
241
242/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
243
244CBNode* CBTree::findNode(const std::string& name, CBNode* start) {
245
246 if (start->name() == name) {
247 return start;
248 } else {
249
250 CBNode *c;
251 std::set<CBNode*>::const_iterator citr = start->children().begin();
252 for (; citr != start->children().end(); ++citr) {
253 c = findNode(name,*citr);
254 if (c != 0) {
255 return c;
256 }
257 }
258 }
259
260 return 0;
261}
262
263/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
264
265void CBTree::printTree() const {
266 cout << "total entries: " << m_allNodes.size() << " max levels: "
267 << maxLevel() << endl;
269}
270
271/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
272
273void CBTree::printTree( const CBNode* start ) const {
274
275 for (int i=0; i<start->level(); ++i) {
276 cout << " ";
277 }
278
279 if (start->trigger()) {
280 cout << "␛[93;1m";
281 }
282 cout << start->name();
283 if (start->trigger()) {
284 cout << "␛[m";
285 }
286 cout << endl;
287
288 for (const CBNode* child : start->children()) {
289 printTree( child );
290 }
291
292}
293
294void CBTree::_printTree( const CBNode* current, const CBNode* parent ) {
295 std::string np;
296 int lp;
297 if (parent == 0) {
298 np = "";
299 lp = 0;
300 } else {
301 np = parent->name();
302 lp = parent->level();
303 }
304
305 for (int i=0; i<lp; ++i) {
306 cout << " ";
307 }
308
309 for (int i=0; i<(current->level()-lp); ++i) {
310 if ( i == 0 ) {
311 // cout << "␕␒";
312 cout << "+-";
313 } else {
314 // cout << "␒␒";
315 cout << "--";
316 }
317 }
318
319 if (current->trigger()) {
320 cout << "␛[93;1m" << current->name() << "␛[m";
321 } else {
322 cout << current->name();
323 }
324 cout << endl;
325
326}
327/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
328
329int CBTree::maxLevel() const {
330 nodeSet::const_iterator itr = m_allNodes.end();
331 --itr;
332 return (*itr)->level();
333}
334
335/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
336
337void CBTree::listNodes() const {
338 nodeSet::const_iterator citr = m_allNodes.begin();
339 for (; citr != m_allNodes.end(); ++citr) {
340 cout << (*citr)->name() << " " << *citr << " " << (*citr)->level()
341 << " " << (*citr)->trigger() << endl;
342 }
343}
344
345/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
346
347void CBTree::listNodes(const int& level,
348 nodeSet::const_iterator& start,
349 nodeSet::const_iterator& end) const {
350
351 bool s = false;
352
353 start = m_allNodes.end();
354 end = m_allNodes.end();
355
356 nodeSet::const_iterator citr = m_allNodes.begin();
357 for (; citr != m_allNodes.end(); ++citr) {
358 if (!s && (*citr)->level() == level) {
359 s = true;
360 start = citr;
361 }
362
363 if (s && (*citr)->level() != level) {
364 end = citr;
365 break;
366 }
367 }
368
369 return;
370}
371
372/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
373
374void CBTree::cascadeTrigger(const bool b, CBNode* start) {
375 if (start == 0) {
376 start = m_root;
377 }
378
379 start->setTrigger(b);
380
381 std::set<CBNode*>::iterator citr = start->children().begin();
382 for (;citr!=start->children().end(); ++citr) {
383 cascadeTrigger(b, *citr);
384 }
385}
386
387/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
388
389void CBTree::cascadeTrigger(const bool b, BFCN* fcn) {
390
391 CBNode* start = findNode(fcn);
392 if (start == 0) {
393 cout << "ERROR cascading trigger from fcn: " << fcn << endl;
394 return;
395 }
396
397 cascadeTrigger(b, start);
398
399}
400
401/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
402
403void CBTree::cascadeTrigger(const bool b, const SG::DataProxy* proxy) {
404
405 CBNode* start = findNode(proxy);
406 if (start == 0) {
407 cout << "ERROR cascading trigger from proxy: " << proxy->name() << endl;
408 return;
409 }
410
411 cascadeTrigger(b, start);
412
413}
414
415/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
416
418
419 nodeSet::const_iterator itr;
420 for (itr=m_allNodes.begin(); itr != m_allNodes.end(); ++itr) {
421 (*itr)->setTrigger(false);
422 }
423
424}
425
426/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
427
428void CBTree::cascadeFlag(const bool b, CBNode* start) const {
429 if (start == 0) {
430 start = m_root;
431 }
432
433 start->setFlag(b);
434
435 for (CBNode* child : start->children()) {
436 cascadeFlag(b, child);
437 }
438}
439
440/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
441
442void CBTree::clearFlag() const {
443 nodeSet::const_iterator itr;
444 for (itr=m_allNodes.begin(); itr != m_allNodes.end(); ++itr) {
445 (*itr)->setFlag(false);
446 }
447}
448
449/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
450
451// adjust levels of all children to this node
453
454 int level = start->level();
455
456 std::set<CBNode*>::iterator citr = start->children().begin();
457 for (;citr != start->children().end(); ++citr) {
458 m_allNodes.erase( m_allNodes.find( *citr ) );
459 (*citr)->setLevel( level+1 );
460 m_allNodes.insert( *citr );
461 adjustLevels( *citr );
462 }
463}
464
465/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
466
467// Traverse full tree, applying function void fnc(current) to each node
468
469void CBTree::traverse(void(*pf) (const CBNode*)) const {
470
471 const CBNode* current = m_root;
472
473 traverse(current, pf);
474
475}
476
477void CBTree::traverse(const CBNode* current, void(*pf) (const CBNode*)) const {
478
479 if (current == 0) { return; }
480
481 (*pf)(current);
482
483 for (const CBNode* child : current->children()) {
484 traverse( child, pf);
485 }
486
487}
488
489void CBTree::traverseR(const CBNode* current, void(*pf) (const CBNode*)) const {
490 // traverse tree in reverse
491
492 if (current == 0) { return; }
493
494 (*pf)(current);
495
496 for (const CBNode* parent : current->parents()) {
497 traverseR( parent, pf);
498 }
499
500}
501
502
503/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
504
505// Traverse tree, applying function void fnc(current, parent) to each node.
506
507void CBTree::traverse(void(*pf) (const CBNode*,const CBNode*)) const {
508
509 const CBNode* current = m_root;
510
511 traverse(current,0, pf);
512
513}
514
515void CBTree::traverse(const CBNode* current, const CBNode* parent,
516 void(*pf) (const CBNode*, const CBNode*)) const {
517
518 if (current == 0) { return; }
519
520 (*pf)(current,parent);
521
522 for (const CBNode* child : current->children()) {
523 traverse( child, current, pf);
524 }
525
526}
527
528void CBTree::traverseR(const CBNode* current, const CBNode* child,
529 void(*pf) (const CBNode*, const CBNode*)) const {
530
531 if (current == 0) { return; }
532
533 (*pf)(current,child);
534
535 for (const CBNode* parent : current->parents()) {
536 traverseR( parent, current, pf);
537 }
538
539}
540
541/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
542
543// Traverse tree, stopping when function CBNode* fnc( current ) returns
544// a non-null. Good for searches.
545
546const CBNode* CBTree::traverse(const CBNode* (*pf) (const CBNode*)) const {
547
548 return traverse(m_root, pf);
549
550}
551
552const CBNode* CBTree::traverse(const CBNode* current, const CBNode* (*pf) (const CBNode*)) const {
553
554 const CBNode *n = (*pf)(current);
555
556 if ( n != 0 ) {
557 return n;
558 } else {
559
560 for (const CBNode* child : current->children()) {
561 const CBNode* c = traverse(child, pf );
562 if (c != 0) {
563 return c;
564 }
565 }
566 }
567
568 return 0;
569
570}
571
572const CBNode* CBTree::traverseR(const CBNode* current, const CBNode* (*pf) (const CBNode*)) const {
573
574 const CBNode *n = (*pf)(current);
575
576 if ( n != 0 ) {
577 return n;
578 } else {
579
580 for (const CBNode* parent : current->parents()) {
581 const CBNode* c = traverseR(parent, pf );
582 if (c != 0) {
583 return c;
584 }
585 }
586 }
587
588 return 0;
589
590}
591
592/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
593/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
CBNode * addNode(const std::string &name, CBNode *parent)
Definition CBTree.cxx:65
CBNode * replaceProxy(const SG::DataProxy *pOld, const SG::DataProxy *pNew)
Definition CBTree.cxx:55
void cascadeTrigger(const bool b, CBNode *start)
Definition CBTree.cxx:374
void connectNode(CBNode *node, CBNode *parent)
Definition CBTree.cxx:144
void adjustLevels(CBNode *start)
Definition CBTree.cxx:452
IOVSvcCallBackFcn BFCN
Definition CBTree.h:34
void traverseR(const CBNode *, void(*pF)(const CBNode *)) const
Definition CBTree.cxx:489
void clearTrigger() const
Definition CBTree.cxx:417
~CBTree()
Definition CBTree.cxx:35
nodeSet m_allNodes
Definition CBTree.h:101
int maxLevel() const
Definition CBTree.cxx:329
void listNodes() const
Definition CBTree.cxx:337
void cascadeFlag(const bool b, CBNode *node) const
Definition CBTree.cxx:428
void traverse(void(*pF)(const CBNode *)) const
Definition CBTree.cxx:469
void clearFlag() const
Definition CBTree.cxx:442
static void _printTree(const CBNode *, const CBNode *)
Definition CBTree.cxx:294
void printTree() const
Definition CBTree.cxx:265
CBTree()
Definition CBTree.cxx:28
CBNode * m_root
Definition CBTree.h:100
CBNode * findNode(const std::string &name)
Definition CBTree.cxx:238
bool delNode(const SG::DataProxy *prx)
Definition CBTree.cxx:114
virtual const name_type & name() const override final
Retrieve data object key == string.
Definition node.h:24
void name(const std::string &n)
Definition node.h:40
STL namespace.