## modules/up/src/gnug++/SymbolConjunctPtr.SplayBag.cc

/* [<][>][^][v][top][bottom][index][help] */

## FUNCTIONS

This source file includes following functions.

1. leftmost
2. rightmost
3. succ
4. pred
5. seek
6. nof
7. add
8. _del
9. remove
10. _kill
11. _copy
12. 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

/* [<][>][^][v][top][bottom][index][help] */