Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
pq_node.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file pq_node.cpp
1 /* This software is distributed under the GNU Lesser General Public License */
2 //==========================================================================
3 //
4 // pq_node.cpp
5 //
6 //==========================================================================
7 // $Id: pq_node.cpp,v 1.12 2002/10/04 08:07:36 chris Exp $
8 
9 #include <GTL/pq_node.h>
10 
11 #ifdef __GTL_MSVCC
12 # ifdef _DEBUG
13 # ifndef SEARCH_MEMORY_LEAKS_ENABLED
14 # error SEARCH NOT ENABLED
15 # endif
16 # define new DEBUG_NEW
17 # undef THIS_FILE
18  static char THIS_FILE[] = __FILE__;
19 # endif // _DEBUG
20 #endif // __GTL_MSVCC
21 
23 
25 {
26  while (!sons.empty()) {
27  pq_node* tmp = sons.front();
28  sons.erase (sons.begin());
29  delete tmp;
30  }
31 }
32 
33 
34 //--------------------------------------------------------------------------
35 // P-NODE
36 //--------------------------------------------------------------------------
37 
38 p_node::p_node (node n_, int id_) : pq_node (n_, id_), partial_count (0), full_count (0)
39 {
40 }
41 
43  pq_node (n_, id_), child_count (0), partial_count (0), full_count (0)
44 {
45  sons.splice (sons.end(), s.begin(), s.end());
46 
47  iterator it = sons.begin();
48  iterator end = sons.end();
49 
50  for (; it != end; ++it) {
51  ++child_count;
52  (*it)->is_endmost = true;
53  (*it)->father = this;
54  }
55 }
56 
57 void p_node::clear ()
58 {
59  pq_node::clear();
61  if (!full_sons.empty())
63 
64  if (!partial_sons.empty())
66 }
67 
68 inline void p_node::partial (iterator it)
69 {
70  ++partial_count;
71  pert_leaves += (*it)->pert_leaves;
73 }
74 
75 inline void p_node::full (iterator it)
76 {
77  ++full_count;
78  pert_leaves += (*it)->pert_leaves;
80 }
81 
82 
83 inline void p_node::write (ostream& os, int _id)
84 {
85  os << "node [\n" << "id " << _id << endl;
86  os << "label \"" << id << "\nP" << "\"\n";
87  os << "graphics [\n" << "x 100\n" << "y 100\n";
88  if (mark == UNBLOCKED) {
89  os << "outline \"#0000ff\"\n";
90  } else if (mark == BLOCKED) {
91  os << "outline \"#ff0000\"\n";
92  }
93  os << "type \"oval\"\n" << "]" << endl;
94  os << "LabelGraphics [\n";
95  os << "type \"text\"\n]\n]" << endl;
96 }
97 
98 //--------------------------------------------------------------------------
99 // Q-NODE
100 //--------------------------------------------------------------------------
101 
102 q_node::q_node (node n_, int id_) : pq_node (n_, id_), partial_count (0), full_count (0)
103 {
104 }
105 
107 {
108  if (partial_count < 3) {
110  }
111 
112  pert_leaves += (*it)->pert_leaves;
113  ++partial_count;
114 
115  if (pert_begin == iterator()) {
116  pertinent (it);
117  }
118 }
119 
120 
121 inline void q_node::full (iterator it)
122 {
123  ++full_count;
124  pert_leaves += (*it)->pert_leaves;
125 
126 
127  if (pert_begin == iterator()) {
128  pertinent (it);
129  }
130 }
131 
132 
134 {
135  iterator end = sons.end();
136  iterator tmp = it;
137  pq_node* first;
138  pq_node* last;
139  pert_end = it;
140  ++tmp;
141  int pert_block_count = 1;
142 
143  while (tmp != end) {
144  if ((*tmp)->mark != UNBLOCKED) {
145  break;
146  }
147 
148  if ((*tmp)->kind () != DIR) {
149  ++pert_block_count;
150  pert_end = tmp;
151  }
152 
153  ++tmp;
154  }
155 
156  last = *pert_end;
157 
158  pert_begin = tmp = it;
159  --tmp;
160 
161  while (tmp != end) {
162  if ((*tmp)->mark != UNBLOCKED) {
163  break;
164  }
165 
166  if ((*tmp)->kind () != DIR) {
167  ++pert_block_count;
168  pert_begin = tmp;
169  }
170 
171  --tmp;
172  }
173 
174  first = *pert_begin;
175  pert_cons = (pert_block_count == pert_children);
176 
177  //
178  // it must be true, that either first or last is in
179  // {sons.front(), sons.back()} (or both). Thus we are able to achive
180  // the following normalization: pert_end is *always* sons.last() and
181  // pert_begin is some other child, such that ++pert_begin leads towards
182  // pert_end.
183  //
184 
185  if (pert_cons) {
186  if (last == sons.front()) {
187  turn();
188  } else if (last != sons.back()) {
189  tmp = pert_begin;
191  pert_end = tmp;
192  pert_end.reverse();
193  pert_begin.reverse();
194 
195  if (first == sons.front()) {
196  turn();
197  } else if (first != sons.back()) {
198 
199  //
200  // This should not happen. In this case the pertinent children are
201  // BLOCKED and thus this method wouldīt be called.
202  //
203  // 17.3. Now this can happen.
204  //
205 
206  // pert_cons = false;
207 
208  // assert (false);
209  }
210  }
211 
212  } else {
213 
214  //
215  // In case that there are more than one block of pertinent children although
216  // bubble up didnīt fail (e.g. pp...pe...ep...pp or ee...ep...pe...ep...pp)
217  // we need some element of the second block in order to find K5 or K33. So we
218  // leave pert_begin as it is, but assign pert_end to something in the second
219  // block
220  //
221 
222  tmp = pert_begin;
223  --tmp;
224 
225  while (tmp != sons.end()) {
226  if ((*tmp)->mark == UNBLOCKED && (*tmp)->kind () != DIR) {
227  break;
228  }
229 
230  --tmp;
231  }
232 
233 
234  //
235  // We need an empty child. So we always keep the invariant that --pert_end
236  // leads to an empty child. Please note that --pert_end might be a DI.
237  //
238 
239  tmp.reverse();
240 
241  if (tmp == sons.end()) {
242  tmp = pert_end;
243  ++tmp;
244 
245  while (tmp != sons.end()) {
246  if ((*tmp)->mark == UNBLOCKED && (*tmp)->kind () != DIR) {
247  break;
248  }
249 
250  ++tmp;
251  }
252 
253  assert (tmp != sons.end());
254  }
255 
256  pert_end = tmp;
257  }
258 
259  //
260  // In the case that there is in fact only one pertinent child we so far
261  // only assured that it is the last child, but it is still possible
262  // that pert_begin (and pert_end, too) is headed the wrong way.
263  //
264 
265  if (pert_begin == pert_end && pert_cons && pert_end == --(sons.end())) {
266  pert_begin = pert_end = --(sons.end());
267  }
268 }
269 
270 inline void q_node::clear ()
271 {
272  pq_node::clear();
276 }
277 
278 inline void q_node::write (ostream& os, int _id)
279 {
280  os << "node [\n" << "id " << _id << endl;
281  os << "label \"" << id << "\n" << "Q" << "\"\n";
282  os << "graphics [\n" << "x 100\n" << "y 100 \n";
283  if (mark == UNBLOCKED) {
284  os << "outline \"#0000ff\"\n";
285  } else if (mark == BLOCKED) {
286  os << "outline \"#ff0000\"\n";
287  }
288  os << "]\n";
289  os << "LabelGraphics [\n";
290  os << "type \"text\"\n]\n]" << endl;
291 }
292 
294 {
295  assert ((*it)->kind() == pq_node::Q_NODE);
296  q_node* part = (q_node*) *it;
297 
298  if (part == sons.front()) {
299  part->sons.front()->father = this;
300  part->sons.back()->is_endmost = false;
301  } else if (part == sons.back()){
302  part->sons.back()->father = this;
303  part->sons.front()->is_endmost = false;
304  } else {
305  part->sons.front()->is_endmost = false;
306  part->sons.back()->is_endmost = false;
307  }
308 
309  sons.splice (it, part->sons.begin(), part->sons.end());
310  sons.erase (it);
311 
312  return part;
313 }
314 
315 
316 void q_node::turn ()
317 {
318  sons.reverse();
319 }
320 
321 
322 //--------------------------------------------------------------------------
323 // LEAF
324 //--------------------------------------------------------------------------
325 
326 
327 pq_leaf::pq_leaf (int id_, int other_, edge e_, node n_) : pq_node (n_, id_)
328 {
329  up_id = other_;
330  up = n_.opposite (e_);
331  other_id = other_;
332  e = e_;
333 }
334 
335 inline void pq_leaf::write (ostream& os, int _id)
336 {
337  os << "node [\n" << "id " << _id << endl;
338  os << "label \"" << other_id << "\n" << id << "\"\n";
339  os << "graphics [\n" << "x 100\n" << "y 100 \n";
340  if (mark == UNBLOCKED) {
341  os << "outline \"#0000ff\"\n";
342  } else if (mark == BLOCKED) {
343  os << "outline \"#ff0000\"\n";
344  }
345  os << "]\n";
346  os << "LabelGraphics [\n";
347  os << "type \"text\"\n]\n]" << endl;
348 }
349 
350 
351 void direction_indicator::write (ostream& os, int _id)
352 {
353  os << "node [\n" << "id " << _id << endl;
354  os << "label \"DIR\n" << id << "\"\n";
355  os << "graphics [\n" << "x 100\n" << "y 100 \n";
356  if (mark == UNBLOCKED) {
357  os << "outline \"#0000ff\"\n";
358  } else if (mark == BLOCKED) {
359  os << "outline \"#ff0000\"\n";
360  }
361  os << "]\n";
362  os << "LabelGraphics [\n";
363  os << "type \"text\"\n]\n]" << endl;
364 }
365 
367 
368 //--------------------------------------------------------------------------
369 // end of file
370 //--------------------------------------------------------------------------