IntHash.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "IntHash.h"
00019 #include "Error.h"
00020
00021 #include <stdio.h>
00022
00023 IntHash::IntHash(int startsize)
00024 {
00025 count = 0;
00026 size = startsize;
00027 mask = startsize - 1;
00028
00029
00030 if (startsize & mask)
00031 error("IntHash: Hash table size must be a power of two.\n");
00032
00033 objects = new bool [size];
00034 keys = new unsigned int [size];
00035
00036 for (unsigned int i = 0; i < size; i++)
00037 {
00038 objects[i] = false;
00039 }
00040 };
00041
00042 IntHash::~IntHash()
00043 {
00044 delete [] objects;
00045 delete [] keys;
00046 }
00047
00048 void IntHash::Clear()
00049 {
00050
00051
00052 count = 0;
00053
00054 if (size > 16)
00055 SetSize(16);
00056
00057 for (unsigned int i = 0; i < size; i++)
00058 objects[i] = false;
00059 }
00060
00061 void IntHash::SetSize(int newsize)
00062 {
00063 int newmask = newsize - 1;
00064
00065 bool * newobjects = new bool [newsize];
00066 unsigned int * newkeys = new unsigned int [newsize];
00067
00068 for (int i = 0; i < newsize; i++)
00069 {
00070 newobjects[i] = false;
00071 }
00072
00073 if (count)
00074 for (unsigned int i = 0; i < size; i++)
00075 if (objects[i] != false)
00076 {
00077 unsigned int key = keys[i];
00078 unsigned int h = key & newmask;
00079
00080 while (newobjects[h] != false && newkeys[h] != h)
00081 h = (h + 1) & newmask;
00082
00083 newkeys[h] = key;
00084 newobjects[h] = objects[i];
00085 }
00086
00087 delete [] objects;
00088 delete [] keys;
00089
00090 objects = newobjects;
00091 keys = newkeys;
00092 size = newsize;
00093 mask = newmask;
00094 }
00095
00096 int IntHash::Add(int key, bool object)
00097 {
00098 if (count * 2 > size)
00099 Grow();
00100
00101 unsigned int h = Iterate(key);
00102
00103 while ((objects[h] != false) && (objects[h] != object))
00104 h = ReIterate(key, h);
00105
00106 if (objects[h] == false)
00107 {
00108
00109 keys[h] = key;
00110 count++;
00111 }
00112
00113 objects[h] = object;
00114
00115 return h;
00116 }
00117
00118 int IntHash::Find(int key)
00119 {
00120 int h = Iterate(key);
00121
00122 return objects[h] == false ? -1 : h;
00123 }
00124
00125 int IntHash::Rehash(int key, int h)
00126 {
00127 h = ReIterate(key, h);
00128
00129 return objects[h] == false ? -1 : h;
00130 }
00131
00132 void IntHash::Delete(unsigned int index)
00133 {
00134 if (index >= size || objects[index] == false)
00135 return;
00136
00137 objects[index] = false;
00138 count--;
00139
00140 if (count * 8 < size && size > 32)
00141 Shrink();
00142 else
00143 {
00144
00145 index = (index + 1) & mask;
00146
00147 while (objects[index] != false)
00148 {
00149 if ((keys[index] & mask) != index)
00150 {
00151 unsigned int h = Iterate(keys[index]);
00152
00153 while ((objects[h] != false) && (objects[h] != objects[index]))
00154 h = ReIterate(keys[index], h);
00155
00156 if (h != (unsigned int) index)
00157 {
00158 keys[h] = keys[index];
00159 objects[h] = objects[index];
00160 objects[index] = false;
00161 }
00162 }
00163
00164 index = (index + 1) & mask;
00165 }
00166 }
00167 }
00168