modules/up/src/gnug++/SymbolConjunctPtr.SplayBag.cc
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- leftmost
- rightmost
- succ
- pred
- seek
- nof
- add
- _del
- remove
- _kill
- _copy
- OK
1 // This may look like C code, but it is really -*- C++ -*-
2 /*
3 Copyright (C) 1988 Free Software Foundation
4 written by Doug Lea (dl@rocky.oswego.edu)
5
6 This file is part of the GNU C++ Library. This library is free
7 software; you can redistribute it and/or modify it under the terms of
8 the GNU Library General Public License as published by the Free
9 Software Foundation; either version 2 of the License, or (at your
10 option) any later version. This library is distributed in the hope
11 that it will be useful, but WITHOUT ANY WARRANTY; without even the
12 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
13 PURPOSE. See the GNU Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19 #ifdef __GNUG__
20 #pragma implementation
21 #endif
22
23 #include "config.h"
24
25 #include "SymbolConjunctPtr.SplayBag.h"
26
27
28 /*
29
30 struct to simulate the special `null' node in the Sleater & Tarjan JACM 1985
31 splay tree algorithms
32
33 All routines use a version of their `simple top-down' splay alg. (p 669)
34
35 */
36
37 struct _dummySplayNode
38 {
39 SymbolConjunctPtrSplayNode* lt;
40 SymbolConjunctPtrSplayNode* rt;
41 SymbolConjunctPtrSplayNode* par;
42 } _dummy_null;
43
44
45 /*
46 traversal primitives
47 */
48
49
50 SymbolConjunctPtrSplayNode* SymbolConjunctPtrSplayBag::leftmost()
/* [<][>][^][v][top][bottom][index][help] */
51 {
52 SymbolConjunctPtrSplayNode* t = root;
53 if (t != 0) while (t->lt != 0) t = t->lt;
54 return t;
55 }
56
57 SymbolConjunctPtrSplayNode* SymbolConjunctPtrSplayBag::rightmost()
/* [<][>][^][v][top][bottom][index][help] */
58 {
59 SymbolConjunctPtrSplayNode* t = root;
60 if (t != 0) while (t->rt != 0) t = t->rt;
61 return t;
62 }
63
64 SymbolConjunctPtrSplayNode* SymbolConjunctPtrSplayBag::succ(SymbolConjunctPtrSplayNode* t)
/* [<][>][^][v][top][bottom][index][help] */
65 {
66 if (t == 0)
67 return 0;
68 if (t->rt != 0)
69 {
70 t = t->rt;
71 while (t->lt != 0) t = t->lt;
72 return t;
73 }
74 else
75 {
76 for (;;)
77 {
78 if (t->par == 0 || t == t->par->lt)
79 return t->par;
80 else
81 t = t->par;
82 }
83 }
84 }
85
86 SymbolConjunctPtrSplayNode* SymbolConjunctPtrSplayBag::pred(SymbolConjunctPtrSplayNode* t)
/* [<][>][^][v][top][bottom][index][help] */
87 {
88 if (t == 0)
89 return 0;
90 else if (t->lt != 0)
91 {
92 t = t->lt;
93 while (t->rt != 0) t = t->rt;
94 return t;
95 }
96 else
97 {
98 for (;;)
99 {
100 if (t->par == 0 || t == t->par->rt)
101 return t->par;
102 else
103 t = t->par;
104 }
105 }
106 }
107
108
109
110 Pix SymbolConjunctPtrSplayBag::seek(SymbolConjunctPtr key, Pix i)
/* [<][>][^][v][top][bottom][index][help] */
111 {
112 if (root == 0) return 0;
113
114 SymbolConjunctPtrSplayNode* t = (SymbolConjunctPtrSplayNode*) i;
115 if (t != 0)
116 {
117 int cmp = SymbolConjunctPtrCMP(key, t->item);
118 if (cmp == 0)
119 {
120 t = succ(t);
121 if (t != 0 && SymbolConjunctPtrEQ(key, t->item))
122 return Pix(t);
123 else
124 return 0;
125 }
126 else if (cmp < 0)
127 return 0;
128 }
129
130 t = root;
131 int comp = SymbolConjunctPtrCMP(key, t->item);
132 if (comp == 0)
133 return Pix(t);
134
135 SymbolConjunctPtrSplayNode* dummy = (SymbolConjunctPtrSplayNode*)(&_dummy_null);
136 SymbolConjunctPtrSplayNode* l = dummy;
137 SymbolConjunctPtrSplayNode* r = dummy;
138 dummy->rt = dummy->lt = dummy->par = 0;
139
140 while (comp != 0)
141 {
142 if (comp > 0)
143 {
144 SymbolConjunctPtrSplayNode* tr = t->rt;
145 if (tr == 0)
146 break;
147 else
148 {
149 comp = SymbolConjunctPtrCMP(key, tr->item);
150 if (comp <= 0 || tr->rt == 0)
151 {
152 l->rt = t; t->par = l;
153 l = t;
154 t = tr;
155 if (comp >= 0)
156 break;
157 }
158 else
159 {
160 if ((t->rt = tr->lt) != 0) t->rt->par = t;
161 tr->lt = t; t->par = tr;
162 l->rt = tr; tr->par = l;
163 l = tr;
164 t = tr->rt;
165 comp = SymbolConjunctPtrCMP(key, t->item);
166 }
167 }
168 }
169 else
170 {
171 SymbolConjunctPtrSplayNode* tl = t->lt;
172 if (tl == 0)
173 break;
174 else
175 {
176 comp = SymbolConjunctPtrCMP(key, tl->item);
177 if (comp >= 0 || tl->lt == 0)
178 {
179 r->lt = t; t->par = r;
180 r = t;
181 t = tl;
182 if (comp <= 0)
183 break;
184 }
185 else
186 {
187 if ((t->lt = tl->rt) != 0) t->lt->par = t;
188 tl->rt = t; t->par = tl;
189 r->lt = tl; tl->par = r;
190 r = tl;
191 t = tl->lt;
192 comp = SymbolConjunctPtrCMP(key, t->item);
193 }
194 }
195 }
196 }
197 if ((r->lt = t->rt) != 0) r->lt->par = r;
198 if ((l->rt = t->lt) != 0) l->rt->par = l;
199 if ((t->lt = dummy->rt) != 0) t->lt->par = t;
200 if ((t->rt = dummy->lt) != 0) t->rt->par = t;
201 t->par = 0;
202 root = t;
203 if (comp != 0)
204 return 0;
205 else
206 {
207 l = pred(t);
208 while (l != 0 && SymbolConjunctPtrEQ(l->item, key)) { t = l; l = pred(l); }
209 return Pix(t);
210 }
211 }
212
213 int SymbolConjunctPtrSplayBag::nof(SymbolConjunctPtr item)
/* [<][>][^][v][top][bottom][index][help] */
214 {
215 int n = 0;
216 SymbolConjunctPtrSplayNode* t = (SymbolConjunctPtrSplayNode*)(seek(item));
217 if (t != 0)
218 {
219 do
220 {
221 ++n;
222 t = succ(t);
223 } while (t != 0 && SymbolConjunctPtrEQ(item, t->item));
224 }
225 return n;
226 }
227
228 Pix SymbolConjunctPtrSplayBag::add(SymbolConjunctPtr item)
/* [<][>][^][v][top][bottom][index][help] */
229 {
230 ++count;
231 SymbolConjunctPtrSplayNode* newnode = new SymbolConjunctPtrSplayNode(item);
232 SymbolConjunctPtrSplayNode* t = root;
233 if (t == 0)
234 {
235 root = newnode;
236 return Pix(root);
237 }
238
239 int comp = SymbolConjunctPtrCMP(item, t->item);
240
241 SymbolConjunctPtrSplayNode* dummy = (SymbolConjunctPtrSplayNode*)(&_dummy_null);
242 SymbolConjunctPtrSplayNode* l = dummy;
243 SymbolConjunctPtrSplayNode* r = dummy;
244 dummy->rt = dummy->lt = dummy->par = 0;
245
246 int done = 0;
247 while (!done)
248 {
249 if (comp >= 0)
250 {
251 SymbolConjunctPtrSplayNode* tr = t->rt;
252 if (tr == 0)
253 {
254 tr = newnode;
255 comp = 0; done = 1;
256 }
257 else
258 comp = SymbolConjunctPtrCMP(item, tr->item);
259
260 if (comp <= 0)
261 {
262 l->rt = t; t->par = l;
263 l = t;
264 t = tr;
265 }
266 else
267 {
268 SymbolConjunctPtrSplayNode* trr = tr->rt;
269 if (trr == 0)
270 {
271 trr = newnode;
272 comp = 0; done = 1;
273 }
274 else
275 comp = SymbolConjunctPtrCMP(item, trr->item);
276
277 if ((t->rt = tr->lt) != 0) t->rt->par = t;
278 tr->lt = t; t->par = tr;
279 l->rt = tr; tr->par = l;
280 l = tr;
281 t = trr;
282 }
283 }
284 else
285 {
286 SymbolConjunctPtrSplayNode* tl = t->lt;
287 if (tl == 0)
288 {
289 tl = newnode;
290 comp = 0; done = 1;
291 }
292 else
293 comp = SymbolConjunctPtrCMP(item, tl->item);
294
295 if (comp >= 0)
296 {
297 r->lt = t; t->par = r;
298 r = t;
299 t = tl;
300 }
301 else
302 {
303 SymbolConjunctPtrSplayNode* tll = tl->lt;
304 if (tll == 0)
305 {
306 tll = newnode;
307 comp = 0; done = 1;
308 }
309 else
310 comp = SymbolConjunctPtrCMP(item, tll->item);
311
312 if ((t->lt = tl->rt) != 0) t->lt->par = t;
313 tl->rt = t; t->par = tl;
314 r->lt = tl; tl->par = r;
315 r = tl;
316 t = tll;
317 }
318 }
319 }
320 if ((r->lt = t->rt) != 0) r->lt->par = r;
321 if ((l->rt = t->lt) != 0) l->rt->par = l;
322 if ((t->lt = dummy->rt) != 0) t->lt->par = t;
323 if ((t->rt = dummy->lt) != 0) t->rt->par = t;
324 t->par = 0;
325 root = t;
326 return Pix(root);
327 }
328
329 void SymbolConjunctPtrSplayBag::_del(SymbolConjunctPtrSplayNode* t)
/* [<][>][^][v][top][bottom][index][help] */
330 {
331 if (t == 0) return;
332
333 SymbolConjunctPtrSplayNode* p = t->par;
334
335 --count;
336 if (t->rt == 0)
337 {
338 if (t == root)
339 {
340 if ((root = t->lt) != 0) root->par = 0;
341 }
342 else if (t == p->lt)
343 {
344 if ((p->lt = t->lt) != 0) p->lt->par = p;
345 }
346 else
347 if ((p->rt = t->lt) != 0) p->rt->par = p;
348 }
349 else
350 {
351 SymbolConjunctPtrSplayNode* r = t->rt;
352 SymbolConjunctPtrSplayNode* l = r->lt;
353 for(;;)
354 {
355 if (l == 0)
356 {
357 if (t == root)
358 {
359 root = r;
360 r->par = 0;
361 }
362 else if (t == p->lt)
363 {
364 p->lt = r;
365 r->par = p;
366 }
367 else
368 {
369 p->rt = r;
370 r->par = p;
371 }
372 if ((r->lt = t->lt) != 0) r->lt->par = r;
373 break;
374 }
375 else
376 {
377 if ((r->lt = l->rt) != 0) r->lt->par = r;
378 l->rt = r; r->par = l;
379 r = l;
380 l = l->lt;
381 }
382 }
383 }
384 delete t;
385 }
386
387
388 void SymbolConjunctPtrSplayBag::remove(SymbolConjunctPtr key)
/* [<][>][^][v][top][bottom][index][help] */
389 {
390 SymbolConjunctPtrSplayNode* t = (SymbolConjunctPtrSplayNode*)(seek(key));
391 while (t != 0)
392 {
393 _del(t);
394 t = (SymbolConjunctPtrSplayNode*)(seek(key));
395 }
396 }
397
398
399 void SymbolConjunctPtrSplayBag::_kill(SymbolConjunctPtrSplayNode* t)
/* [<][>][^][v][top][bottom][index][help] */
400 {
401 if (t != 0)
402 {
403 _kill(t->lt);
404 _kill(t->rt);
405 delete t;
406 }
407 }
408
409
410 SymbolConjunctPtrSplayNode* SymbolConjunctPtrSplayBag::_copy(SymbolConjunctPtrSplayNode* t)
/* [<][>][^][v][top][bottom][index][help] */
411 {
412 if (t != 0)
413 {
414 SymbolConjunctPtrSplayNode* l = _copy(t->lt);
415 SymbolConjunctPtrSplayNode* r = _copy(t->rt);
416 SymbolConjunctPtrSplayNode* x = new SymbolConjunctPtrSplayNode(t->item, l, r);
417 if (l != 0) l->par = x;
418 if (r != 0) r->par = x;
419 return x;
420 }
421 else
422 return 0;
423 }
424
425 int SymbolConjunctPtrSplayBag::OK()
/* [<][>][^][v][top][bottom][index][help] */
426 {
427 int v = 1;
428 if (root == 0)
429 v = count == 0;
430 else
431 {
432 int n = 1;
433 SymbolConjunctPtrSplayNode* trail = leftmost();
434 SymbolConjunctPtrSplayNode* t = succ(trail);
435 while (t != 0)
436 {
437 ++n;
438 v &= SymbolConjunctPtrCMP(trail->item, t->item) <= 0;
439 trail = t;
440 t = succ(t);
441 }
442 v &= n == count;
443 }
444 if (!v) error("invariant failure");
445 return v;
446 }
447