## modules/up/src/rpsl/gnu/SymID.VHSet.cc

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

## FUNCTIONS

This source file includes following functions.

1. SymIDVHSet
2. SymIDVHSet
3. doublehashinc
4. seek
5. add
6. del
7. clear
8. resize
9. first
10. next
11. 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
      17 */
      18
      19 #ifdef __GNUG__
      20 #pragma implementation
      21 #endif
      22 #include "config.h"
      23 #include "SymID.VHSet.h"
      24
      25 /* codes for status fields */
      26
      27 #define EMPTYCELL   0
      28 #define VALIDCELL   1
      29 #define DELETEDCELL 2
      30
      31
      32 SymIDVHSet::SymIDVHSet(unsigned int sz)
         /* [<][>][^][v][top][bottom][index][help] */
      33 {
      34   tab = new SymID[size = sz];
      35   status = new char[size];
      36   for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL;
      37   count = 0;
      38 }
      39
      40 SymIDVHSet::SymIDVHSet(const SymIDVHSet& a)
         /* [<][>][^][v][top][bottom][index][help] */
      41 {
      42   tab = new SymID[size = a.size];
      43   status = new char[size];
      44   for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL;
      45   count = 0;
      46   for (Pix p = a.first(); p; a.next(p)) add(a(p));
      47 }
      48
      49
      50 /*
      51  * hashing method: double hash based on high bits of hash fct,
      52  * followed by linear probe. Can't do too much better if table
      53  * sizes not constrained to be prime.
      54 */
      55
      56
      57 static inline unsigned int doublehashinc(unsigned int h, unsigned int s)
         /* [<][>][^][v][top][bottom][index][help] */
      58 {
      59   unsigned int dh =  ((h / s) % s);
      60   return (dh > 1)? dh : 1;
      61 }
      62
      63 Pix SymIDVHSet::seek(SymID  key) const
         /* [<][>][^][v][top][bottom][index][help] */
      64 {
      65   unsigned int hashval = SymIDHASH(key);
      66   unsigned int h = hashval % size;
      67   for (unsigned int i = 0; i <= size; ++i)
      68   {
      69     if (status[h] == EMPTYCELL)
      70       return 0;
      71     else if (status[h] == VALIDCELL && SymIDEQ(key, tab[h]))
      72       return Pix(&tab[h]);
      73     if (i == 0)
      74       h = (h + doublehashinc(hashval, size)) % size;
      75     else if (++h >= size)
      76       h -= size;
      77   }
      78   return 0;
      79 }
      80
      81
      82 Pix SymIDVHSet::add(SymID  item)
         /* [<][>][^][v][top][bottom][index][help] */
      83 {
      84   if (HASHTABLE_TOO_CROWDED(count, size))
      85     resize();
      86
      87   unsigned int bestspot = size;
      88   unsigned int hashval = SymIDHASH(item);
      89   unsigned int h = hashval % size;
      90   for (unsigned int i = 0; i <= size; ++i)
      91   {
      92     if (status[h] == EMPTYCELL)
      93     {
      94       if (bestspot >= size) bestspot = h;
      95       tab[bestspot] = item;
      96       status[bestspot] = VALIDCELL;
      97       ++count;
      98       return Pix(&tab[bestspot]);
      99     }
     100     else if (status[h] == DELETEDCELL)
     101     {
     102       if (bestspot >= size) bestspot = h;
     103     }
     104     else if (SymIDEQ(tab[h],item))
     105       return Pix(&tab[h]);
     106
     107     if (i == 0)
     108       h = (h + doublehashinc(hashval, size)) % size;
     109     else if (++h >= size)
     110       h -= size;
     111   }
     112   tab[bestspot] = item;
     113   status[bestspot] = VALIDCELL;
     114   ++count;
     115   return Pix(&tab[bestspot]);
     116
     117 }
     118
     119
     120 void SymIDVHSet::del(SymID  key)
         /* [<][>][^][v][top][bottom][index][help] */
     121 {
     122   unsigned int hashval = SymIDHASH(key);
     123   unsigned int h = hashval % size;
     124   for (unsigned int i = 0; i <= size; ++i)
     125   {
     126     if (status[h] == EMPTYCELL)
     127       return;
     128     else if (status[h] == VALIDCELL && SymIDEQ(key, tab[h]))
     129     {
     130       status[h] = DELETEDCELL;
     131       --count;
     132       return;
     133     }
     134     if (i == 0)
     135       h = (h + doublehashinc(hashval, size)) % size;
     136     else if (++h >= size)
     137       h -= size;
     138   }
     139 }
     140
     141
     142 void SymIDVHSet::clear()
         /* [<][>][^][v][top][bottom][index][help] */
     143 {
     144   for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL;
     145   count = 0;
     146 }
     147
     148 void SymIDVHSet::resize(unsigned int newsize)
         /* [<][>][^][v][top][bottom][index][help] */
     149 {
     150   if (newsize <= count)
     151   {
     152     newsize = DEFAULT_INITIAL_CAPACITY;
     153     while (HASHTABLE_TOO_CROWDED(count, newsize))  newsize <<= 1;
     154   }
     155   SymID* oldtab = tab;
     156   char* oldstatus = status;
     157   unsigned int oldsize = size;
     158   tab = new SymID[size = newsize];
     159   status = new char[size];
     160   for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL;
     161   count = 0;
     162   for (unsigned int i = 0; i < oldsize; ++i) if (oldstatus[i] == VALIDCELL) add(oldtab[i]);
     163   delete [] oldtab;
     164   delete oldstatus;
     165 }
     166
     167 Pix SymIDVHSet::first() const
         /* [<][>][^][v][top][bottom][index][help] */
     168 {
     169   for (unsigned int pos = 0; pos < size; ++pos)
     170     if (status[pos] == VALIDCELL) return Pix(&tab[pos]);
     171   return 0;
     172 }
     173
     174 void SymIDVHSet::next(Pix& i) const
         /* [<][>][^][v][top][bottom][index][help] */
     175 {
     176   if (i == 0) return;
     177   unsigned int pos = ((unsigned)i - (unsigned)tab) / sizeof(SymID) + 1;
     178   for (; pos < size; ++pos)
     179     if (status[pos] == VALIDCELL)
     180     {
     181       i = Pix(&tab[pos]);
     182       return;
     183     }
     184   i = 0;
     185 }
     186
     187 int SymIDVHSet:: operator == (const SymIDVHSet& b) const
     188 {
     189   if (count != b.count)
     190     return 0;
     191   else
     192   {
     193     for (unsigned int i = 0; i < size; ++i)
     194       if (status[i] == VALIDCELL && b.seek(tab[i]) == 0)
     195           return 0;
     196     for (unsigned int i = 0; i < b.size; ++i)
     197       if (b.status[i] == VALIDCELL && seek(b.tab[i]) == 0)
     198           return 0;
     199     return 1;
     200   }
     201 }
     202
     203 int SymIDVHSet::operator <= (const SymIDVHSet& b) const
     204 {
     205   if (count > b.count)
     206     return 0;
     207   else
     208   {
     209     for (unsigned int i = 0; i < size; ++i)
     210       if (status[i] == VALIDCELL && b.seek(tab[i]) == 0)
     211           return 0;
     212     return 1;
     213   }
     214 }
     215
     216 void SymIDVHSet::operator |= (SymIDVHSet& b)
     217 {
     218   if (&b == this || b.count == 0)
     219     return;
     220   for (unsigned int i = 0; i < b.size; ++i)
     221     if (b.status[i] == VALIDCELL) add(b.tab[i]);
     222 }
     223
     224 void SymIDVHSet::operator &= (SymIDVHSet& b)
     225 {
     226   if (&b == this || count == 0)
     227     return;
     228   for (unsigned int i = 0; i < size; ++i)
     229   {
     230     if (status[i] == VALIDCELL && b.seek(tab[i]) == 0)
     231     {
     232       status[i] = DELETEDCELL;
     233       --count;
     234     }
     235   }
     236 }
     237
     238 void SymIDVHSet::operator -= (SymIDVHSet& b)
     239 {
     240   for (unsigned int i = 0; i < size; ++i)
     241   {
     242     if (status[i] == VALIDCELL && b.seek(tab[i]) != 0)
     243     {
     244       status[i] = DELETEDCELL;
     245       --count;
     246     }
     247   }
     248 }
     249
     250 int SymIDVHSet::OK()
         /* [<][>][^][v][top][bottom][index][help] */
     251 {
     252   int v = tab != 0;
     253   v &= status != 0;
     254   int n = 0;
     255   for (unsigned int i = 0; i < size; ++i)
     256   {
     257     if (status[i] == VALIDCELL) ++n;
     258     else if (status[i] != DELETEDCELL && status[i] != EMPTYCELL)
     259       v = 0;
     260   }
     261   v &= n == count;
     262   if (!v) error("invariant failure");
     263   return v;
     264 }

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