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] */