home *** CD-ROM | disk | FTP | other *** search
/ Mega Top 1 / os2_top1.zip / os2_top1 / APPS / TEKST / TXI2IPF1 / SOURCE.ZIP / gen / String_XClass_VHMap.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1993-02-04  |  5.9 KB  |  226 lines

  1. ///////////////////////////////////////////////////////////////////////////////
  2. // $Id: String_XClass_VHMap.cc,v 1.1.1.1 1993/02/04 15:18:32 ak Exp $
  3. ///////////////////////////////////////////////////////////////////////////////
  4. // $Log: String_XClass_VHMap.cc,v $
  5. // Revision 1.1.1.1  1993/02/04  15:18:32  ak
  6. // Please Edit this file to contain the RCS log information
  7. // to be associated with this file (please remove these lines)
  8. //
  9. // Revision 1.1  1993/02/04  15:18:29  ak
  10. // Initial revision
  11. //
  12. ///////////////////////////////////////////////////////////////////////////////
  13.  
  14. static char *rcsid = "$Id: String_XClass_VHMap.cc,v 1.1.1.1 1993/02/04 15:18:32 ak Exp $";
  15.  
  16. // This may look like C code, but it is really -*- C++ -*-
  17. /*
  18. Copyright (C) 1988 Free Software Foundation
  19.     written by Doug Lea (dl@rocky.oswego.edu)
  20.  
  21. This file is part of the GNU C++ Library.  This library is free
  22. software; you can redistribute it and/or modify it under the terms of
  23. the GNU Library General Public License as published by the Free
  24. Software Foundation; either version 2 of the License, or (at your
  25. option) any later version.  This library is distributed in the hope
  26. that it will be useful, but WITHOUT ANY WARRANTY; without even the
  27. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  28. PURPOSE.  See the GNU Library General Public License for more details.
  29. You should have received a copy of the GNU Library General Public
  30. License along with this library; if not, write to the Free Software
  31. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  32. */
  33.  
  34. #ifdef __GNUG__
  35. #pragma implementation
  36. #endif
  37. #include "info.h"
  38.  
  39. /* codes for status fields */
  40.  
  41. #define EMPTYCELL   0
  42. #define VALIDCELL   1
  43. #define DELETEDCELL 2
  44.  
  45.  
  46. StringXClassVHMap::StringXClassVHMap(XClass& dflt, unsigned int sz)
  47.      :StringXClassMap(dflt)
  48. {
  49.   tab = new String[size = sz];
  50.   cont = new XClass[size];
  51.   status = new char[size];
  52.   for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL;
  53. }
  54.  
  55. StringXClassVHMap::StringXClassVHMap(StringXClassVHMap& a) : StringXClassMap(a.def)
  56. {
  57.   tab = new String[size = a.size];
  58.   cont = new XClass[size];
  59.   status = new char[size];
  60.   for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL;
  61.   count = 0;
  62.   for (Pix p = a.first(); p; a.next(p)) (*this)[a.key(p)] = a.contents(p);
  63. }
  64.  
  65.  
  66. /*
  67.  * hashing method: double hash based on high bits of hash fct,
  68.  * followed by linear probe. Can't do too much better if table
  69.  * sizes not constrained to be prime.
  70. */
  71.  
  72.  
  73. static inline unsigned int doublehashinc(unsigned int h, unsigned int s)
  74. {
  75.   unsigned int dh =  ((h / s) % s);
  76.   return (dh > 1)? dh : 1;
  77. }
  78.  
  79. Pix StringXClassVHMap::seek(String& key)
  80. {
  81.   unsigned int hashval = StringHASH(key);
  82.   unsigned int h = hashval % size;
  83.   for (unsigned int i = 0; i <= size; ++i)
  84.   {
  85.     if (status[h] == EMPTYCELL)
  86.       return 0;
  87.     else if (status[h] == VALIDCELL && StringEQ(key, tab[h]))
  88.       return Pix(&tab[h]);
  89.     if (i == 0)
  90.       h = (h + doublehashinc(hashval, size)) % size;
  91.     else if (++h >= size)
  92.       h -= size;
  93.   }
  94.   return 0;
  95. }
  96.  
  97.  
  98. XClass& StringXClassVHMap::operator [](String& item)
  99. {
  100.   if (size <= count + 1)
  101.     resize();
  102.  
  103.   unsigned int bestspot = size;
  104.   unsigned int hashval = StringHASH(item);
  105.   unsigned int h = hashval % size;
  106.   for (unsigned int i = 0; i <= size; ++i)
  107.   {
  108.     if (status[h] == EMPTYCELL)
  109.     {
  110.       ++count;
  111.       if (bestspot >= size) bestspot = h;
  112.       tab[bestspot] = item;
  113.       status[bestspot] = VALIDCELL;
  114.       cont[bestspot] = def;
  115.       return cont[bestspot];
  116.     }
  117.     else if (status[h] == DELETEDCELL)
  118.     {
  119.       if (bestspot >= size) bestspot = h;
  120.     }
  121.     else if (StringEQ(tab[h],item))
  122.       return cont[h];
  123.  
  124.     if (i == 0)
  125.       h = (h + doublehashinc(hashval, size)) % size;
  126.     else if (++h >= size)
  127.       h -= size;
  128.   }
  129.  
  130.   ++count;
  131.   status[bestspot] = VALIDCELL;
  132.   tab[bestspot] = item;
  133.   cont[bestspot] = def;
  134.   return cont[bestspot];
  135. }
  136.  
  137.  
  138. void StringXClassVHMap::del(String& key)
  139. {
  140.   unsigned int hashval = StringHASH(key);
  141.   unsigned int h = hashval % size;
  142.   for (unsigned int i = 0; i <= size; ++i)
  143.   {
  144.     if (status[h] == EMPTYCELL)
  145.       return;
  146.     else if (status[h] == VALIDCELL && StringEQ(key, tab[h]))
  147.     {
  148.       status[h] = DELETEDCELL;
  149.       --count;
  150.       return;
  151.     }
  152.     if (i == 0)
  153.       h = (h + doublehashinc(hashval, size)) % size;
  154.     else if (++h >= size)
  155.       h -= size;
  156.   }
  157. }
  158.  
  159.  
  160. void StringXClassVHMap::clear()
  161. {
  162.   for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL;
  163.   count = 0;
  164. }
  165.  
  166. void StringXClassVHMap::resize(unsigned int newsize)
  167. {
  168.   if (newsize <= count)
  169.   {
  170.     newsize = DEFAULT_INITIAL_CAPACITY;
  171.     while (newsize <= count) newsize <<= 1;
  172.   }
  173.   String* oldtab = tab;
  174.   XClass* oldcont = cont;
  175.   char* oldstatus = status;
  176.   unsigned int oldsize = size;
  177.   tab = new String[size = newsize];
  178.   cont = new XClass[size];
  179.   status = new char[size];
  180.   for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL;
  181.   count = 0;
  182.   for (i = 0; i < oldsize; ++i)
  183.     if (oldstatus[i] == VALIDCELL)
  184.       (*this)[oldtab[i]] = oldcont[i];
  185.   delete [] oldtab;
  186.   delete [] oldcont;
  187.   delete oldstatus;
  188. }
  189.  
  190. Pix StringXClassVHMap::first()
  191. {
  192.   for (unsigned int pos = 0; pos < size; ++pos)
  193.     if (status[pos] == VALIDCELL) return Pix(&tab[pos]);
  194.   return 0;
  195. }
  196.  
  197. void StringXClassVHMap::next(Pix& i)
  198. {
  199.   if (i == 0) return;
  200.   unsigned int pos = ((unsigned)i - (unsigned)tab) / sizeof(String) + 1;
  201.   for (; pos < size; ++pos)
  202.     if (status[pos] == VALIDCELL)
  203.     {
  204.       i = Pix(&tab[pos]);
  205.       return;
  206.     }
  207.   i = 0;
  208. }
  209.  
  210.  
  211. int StringXClassVHMap::OK()
  212. {
  213.   int v = tab != 0;
  214.   v &= status != 0;
  215.   int n = 0;
  216.   for (unsigned int i = 0; i < size; ++i)
  217.   {
  218.     if (status[i] == VALIDCELL) ++n;
  219.     else if (status[i] != DELETEDCELL && status[i] != EMPTYCELL)
  220.       v = 0;
  221.   }
  222.   v &= n == count;
  223.   if (!v) error("invariant failure");
  224.   return v;
  225. }
  226.