HPCToolkit
NonUniformDegreeTree.cpp
Go to the documentation of this file.
1 // -*-Mode: C++;-*-
2 
3 // * BeginRiceCopyright *****************************************************
4 //
5 // $HeadURL$
6 // $Id$
7 //
8 // --------------------------------------------------------------------------
9 // Part of HPCToolkit (hpctoolkit.org)
10 //
11 // Information about sources of support for research and development of
12 // HPCToolkit is at 'hpctoolkit.org' and in 'README.Acknowledgments'.
13 // --------------------------------------------------------------------------
14 //
15 // Copyright ((c)) 2002-2019, Rice University
16 // All rights reserved.
17 //
18 // Redistribution and use in source and binary forms, with or without
19 // modification, are permitted provided that the following conditions are
20 // met:
21 //
22 // * Redistributions of source code must retain the above copyright
23 // notice, this list of conditions and the following disclaimer.
24 //
25 // * Redistributions in binary form must reproduce the above copyright
26 // notice, this list of conditions and the following disclaimer in the
27 // documentation and/or other materials provided with the distribution.
28 //
29 // * Neither the name of Rice University (RICE) nor the names of its
30 // contributors may be used to endorse or promote products derived from
31 // this software without specific prior written permission.
32 //
33 // This software is provided by RICE and contributors "as is" and any
34 // express or implied warranties, including, but not limited to, the
35 // implied warranties of merchantability and fitness for a particular
36 // purpose are disclaimed. In no event shall RICE or contributors be
37 // liable for any direct, indirect, incidental, special, exemplary, or
38 // consequential damages (including, but not limited to, procurement of
39 // substitute goods or services; loss of use, data, or profits; or
40 // business interruption) however caused and on any theory of liability,
41 // whether in contract, strict liability, or tort (including negligence
42 // or otherwise) arising in any way out of the use of this software, even
43 // if advised of the possibility of such damage.
44 //
45 // ******************************************************* EndRiceCopyright *
46 
47 //***************************************************************************
48 //
49 // NonUniformDegreeTree.C
50 //
51 // a general purpose abstraction for non-uniform degree trees.
52 // children of a node are represented by a circularly linked-list
53 // of siblings.
54 //
55 // two iterators are included here. one for enumerating the children
56 // of a node, and a second for enumerating a tree rooted at a node.
57 //
58 // these abstractions are useless in their own right since the tree
59 // contains only structural information. to make use of the abstraction,
60 // derive a tree node class that contains some useful data. all of the
61 // structural manipulation can be performed using the functions provided
62 // in the base classes defined here.
63 //
64 // Author: John Mellor-Crummey
65 //
66 // Creation Date: September 1991
67 //
68 // Modification History:
69 // see NonUniformDegreeTree.h
70 //
71 //***************************************************************************
72 
73 //************************* System Include Files ****************************
74 
75 //*************************** User Include Files ****************************
76 
77 #include <include/gcc-attr.h>
78 
79 #include "NonUniformDegreeTree.hpp"
80 #include "StrUtil.hpp"
81 #include "diagnostics.h"
82 
83 //*************************** Forward Declarations **************************
84 
85 using std::endl;
86 
87 //***************************************************************************
88 // class NonUniformDegreeTreeNode interface operations
89 //***************************************************************************
90 
91 
92 //-----------------------------------------------
93 // links a node to a parent and at the end of the
94 // circular doubly-linked list of its siblings
95 // (if any)
96 //-----------------------------------------------
98 {
99  DIAG_Assert(this->m_parent == 0, ""); // can only have one parent
100  if (newParent != 0) {
101  // children maintained as a doubly linked ring.
102  // a new node is linked at the end of the ring (as a predecessor
103  // of "m_parent->children") which points to first child in the ring
104 
105  NonUniformDegreeTreeNode *first_sibling = newParent->m_children;
106  if (first_sibling) linkAfter(first_sibling->m_prev_sibling);
107  else {
108  newParent->m_children = this; // solitary child
109  newParent->m_child_count++;
110  m_parent = newParent;
111  }
112  }
113 }
114 
115 
116 //-----------------------------------------------
118 {
119  DIAG_Assert(sibling != NULL, "");
120  DIAG_Assert(this->m_parent == NULL, ""); // can only have one parent
121 
122  this->m_parent = sibling->m_parent;
124 
125  // children maintained as a doubly linked ring.
126 
127  // link forward chain
128  m_next_sibling = sibling->m_next_sibling;
129  sibling->m_next_sibling = this;
130 
131  // link backward chain
132  m_prev_sibling = sibling;
134 }
135 
136 
137 //-----------------------------------------------
139 {
140  DIAG_Assert(sibling != NULL, "");
141  linkAfter(sibling->m_prev_sibling);
142  if (m_parent && sibling == m_parent->m_children) {
143  m_parent->m_children = this;
144  }
145 }
146 
147 
148 //-----------------------------------------------
149 // unlinks a node from a parent and siblings
150 //-----------------------------------------------
151 
153 {
154  if (m_parent != 0) {
155  // children maintained as a doubly linked ring.
156  // excise this node from from the ring
157  if (--(m_parent->m_child_count) == 0) {
158  // current node is removed as only child of parent
159  // leaving it linked in a circularly linked list with
160  // itself
161  m_parent->m_children = 0;
162  } else {
163  // fix link from parent to the ring if necessary
164  if (m_parent->m_children == this)
166 
167  // relink predecessor's forward link
169 
170  // relink successor's backward link
172 
173  // relink own pointers into self-circular configuration
174  m_prev_sibling = this;
175  m_next_sibling = this;
176  }
177  }
178  this->m_parent = 0;
179 }
180 
181 
182 uint
184 {
185  unsigned int ancestorCount = 0;
186  for (NonUniformDegreeTreeNode* ancestor = m_parent;
187  ancestor;
188  ancestor = ancestor->m_parent) {
189  ancestorCount++;
190  }
191  return ancestorCount;
192 }
193 
194 
195 uint
197 {
198  uint depth = parentDepth + 1;
199 
200  if (isLeaf()) {
201  return depth;
202  }
203  else {
204  uint max_depth = 0;
206  for (NonUniformDegreeTreeNode* x = NULL; (x = it.Current()); ++it) {
207  uint x_depth = x->maxDepth(depth);
208  max_depth = std::max(max_depth, x_depth);
209  }
210  return max_depth;
211  }
212 }
213 
214 
215 std::string
217  const char* GCC_ATTR_UNUSED pfx) const
218 {
219  return "NonUniformDegreeTreeNode: " + StrUtil::toStr((void*)this);
220 }
221 
222 
223 //****************************************************************************
224 // class NonUniformDegreeTreeNodeChildIterator interface operations
225 //****************************************************************************
226 
227 
228 
229 //****************************************************************************
230 // class NonUniformDegreeTreeIterator interface operations
231 //****************************************************************************
232 
233 
235  const NonUniformDegreeTreeNode* root,
236  TraversalOrder torder,
241 {
242  StackableIterator* top = 0;
244  {// make an iterator for the next (non-root) level
245  top = IteratorToPushIfAny((void*) root);
246  }
247  else
248  {// make a singleton iterator for the root
249  top = new SingletonIterator(root,
250  (torder == PostOrder) ? PostVisit : PreVisit);
251  }
252  if (top)
253  {// there is something to push on the stack
254  Push(top);
255  }
256 }
257 
258 
261 {
263 
265  StackableIterator *top = dynamic_cast<StackableIterator*>(Top());
266  SingletonIterator *stop = dynamic_cast<SingletonIterator*>(top);
267  if (stop == 0) { // not a SingletonIterator
268  Push(new SingletonIterator(node, PostVisit));
269  } else {
270  if (stop->VisitType() == PreVisit) {
271  Push(new SingletonIterator(node, PostVisit));
272  } else return 0;
273  }
274  }
275 
276  return (node->childCount() > 0)
278  : 0;
279 }
280 
281 
282 
283 /**********************************************************************/
284 /* debugging support */
285 /**********************************************************************/
286 void
288 {
289  os << "NonUniformDegreeTreeIterator: " << endl;
290  while (Current()) {
291  os << Current()->toString() << endl;
292  (*this)++;
293  }
294  Reset();
295 }
296 
297 
298 void
300 {
301  os << "NonUniformDegreeTreeNodeChildIterator: " << endl;
302  while (Current()) {
303  os << Current()->toString() << endl;
304  (*this)++;
305  }
306  Reset();
307 }
StackableIterator * IteratorToPushIfAny(void *current)
StackableIterator * Top(void) const
virtual bool IterationIsForward() const
virtual NonUniformDegreeTreeNode * Current() const
string toStr(const int x, int base)
Definition: StrUtil.cpp:243
virtual void DumpAndReset(std::ostream &os=std::cerr)
virtual NonUniformDegreeTreeNode * Current() const
void linkBefore(NonUniformDegreeTreeNode *sibling)
NonUniformDegreeTreeNode * m_prev_sibling
cct_node_t * node
Definition: cct.c:128
TraversalVisitType VisitType() const
NonUniformDegreeTreeNode * m_children
unsigned int uint
Definition: uint.h:124
TraversalOrder GetTraversalOrder() const
NonUniformDegreeTreeNode * m_next_sibling
void link(NonUniformDegreeTreeNode *parent)
void linkAfter(NonUniformDegreeTreeNode *sibling)
virtual std::string toString(uint oFlags=0, const char *pfx="") const
NonUniformDegreeTreeEnumType
NonUniformDegreeTreeIterator(const NonUniformDegreeTreeNode *root, TraversalOrder torder=PreOrder, NonUniformDegreeTreeEnumType how=NON_UNIFORM_DEGREE_TREE_ENUM_ALL_NODES)
#define NULL
Definition: ElfHelper.cpp:85
void Push(StackableIterator *)
#define GCC_ATTR_UNUSED
Definition: gcc-attr.h:80
virtual void DumpAndReset(std::ostream &os=std::cerr)
NonUniformDegreeTreeNode * m_parent