00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #include "Hash_i_dh.h"
00044 #include "Parser_dh.h"
00045 #include "Mem_dh.h"
00046
00047 #define DEFAULT_TABLE_SIZE 16
00048
00049 static void rehash_private (Hash_i_dh h);
00050
00051
00052
00053
00054
00055 #define HASH_1(k,size,idxOut) \
00056 { *idxOut = k % size; }
00057
00058 #define HASH_2(k,size,idxOut) \
00059 { \
00060 int r = k % (size-13); \
00061 r = (r % 2) ? r : r+1; \
00062 *idxOut = r; \
00063 }
00064
00065
00066
00067
00068
00069 typedef struct _hash_i_node_private Hash_i_Record;
00070
00071 struct _hash_i_node_private
00072 {
00073 int key;
00074 int mark;
00075 int data;
00076 };
00077
00078
00079 struct _hash_i_dh
00080 {
00081 int size;
00082 int count;
00083 int curMark;
00084 Hash_i_Record *data;
00085 };
00086
00087
00088
00089
00090
00091
00092 #undef __FUNC__
00093 #define __FUNC__ "Hash_i_dhCreate"
00094 void
00095 Hash_i_dhCreate (Hash_i_dh * h, int sizeIN)
00096 {
00097 START_FUNC_DH int i, size;
00098 Hash_i_Record *tmp2;
00099 struct _hash_i_dh *tmp;
00100
00101 size = DEFAULT_TABLE_SIZE;
00102 if (sizeIN == -1)
00103 {
00104 sizeIN = size = DEFAULT_TABLE_SIZE;
00105 }
00106 tmp = (struct _hash_i_dh *) MALLOC_DH (sizeof (struct _hash_i_dh));
00107 CHECK_V_ERROR;
00108 *h = tmp;
00109 tmp->size = 0;
00110 tmp->count = 0;
00111 tmp->curMark = 0;
00112 tmp->data = NULL;
00113
00114
00115
00116
00117
00118
00119 while (size < sizeIN)
00120 size *= 2;
00121
00122 if ((size - sizeIN) < (.1 * size))
00123 {
00124 size *= 2.0;
00125 }
00126 tmp->size = size;
00127
00128
00129
00130 tmp2 = tmp->data =
00131 (Hash_i_Record *) MALLOC_DH (size * sizeof (Hash_i_Record));
00132 CHECK_V_ERROR;
00133 for (i = 0; i < size; ++i)
00134 {
00135 tmp2[i].key = -1;
00136 tmp2[i].mark = -1;
00137
00138 }
00139
00140 END_FUNC_DH}
00141
00142
00143 #undef __FUNC__
00144 #define __FUNC__ "Hash_i_dhDestroy"
00145 void
00146 Hash_i_dhDestroy (Hash_i_dh h)
00147 {
00148 START_FUNC_DH if (h->data != NULL)
00149 {
00150 FREE_DH (h->data);
00151 CHECK_V_ERROR;
00152 }
00153 FREE_DH (h);
00154 CHECK_V_ERROR;
00155 END_FUNC_DH}
00156
00157 #undef __FUNC__
00158 #define __FUNC__ "Hash_i_dhReset"
00159 void
00160 Hash_i_dhReset (Hash_i_dh h)
00161 {
00162 START_FUNC_DH h->count = 0;
00163 h->curMark += 1;
00164 END_FUNC_DH}
00165
00166
00167 #undef __FUNC__
00168 #define __FUNC__ "Hash_i_dhLookup"
00169 int
00170 Hash_i_dhLookup (Hash_i_dh h, int key)
00171 {
00172 START_FUNC_DH int idx, inc, i, start;
00173 int curMark = h->curMark;
00174 int size = h->size;
00175 int retval = -1;
00176 Hash_i_Record *data = h->data;
00177
00178 HASH_1 (key, size, &start) HASH_2 (key, size, &inc)
00179
00180
00181 for (i = 0; i < size; ++i)
00182 {
00183 idx = (start + i * inc) % size;
00184
00185
00186
00187 if (data[idx].mark != curMark)
00188 {
00189 break;
00190 }
00191 else
00192 {
00193 if (data[idx].key == key)
00194 {
00195 retval = data[idx].data;
00196 break;
00197 }
00198 }
00199 }
00200 END_FUNC_VAL (retval)}
00201
00202
00203 #undef __FUNC__
00204 #define __FUNC__ "Hash_i_dhInsert"
00205 void
00206 Hash_i_dhInsert (Hash_i_dh h, int key, int dataIN)
00207 {
00208 START_FUNC_DH int i, idx, inc, start, size;
00209 int curMark = h->curMark;
00210 Hash_i_Record *data;
00211 bool success = false;
00212
00213 if (dataIN < 0)
00214 {
00215 sprintf (msgBuf_dh, "data = %i must be >= 0", dataIN);
00216 SET_V_ERROR (msgBuf_dh);
00217 }
00218
00219
00220 if (h->count >= 0.9 * h->size)
00221 {
00222 rehash_private (h);
00223 CHECK_V_ERROR;
00224 }
00225
00226 size = h->size;
00227 data = h->data;
00228 h->count += 1;
00229
00230 HASH_1 (key, size, &start) HASH_2 (key, size, &inc)
00231
00232
00233 for (i = 0; i < size; ++i)
00234 {
00235 idx = (start + i * inc) % size;
00236
00237
00238
00239
00240
00241 if (data[idx].mark == curMark && data[idx].key == key)
00242 {
00243 sprintf (msgBuf_dh, "key,data= <%i, %i> already inserted", key,
00244 dataIN);
00245 SET_V_ERROR (msgBuf_dh);
00246 }
00247
00248 if (data[idx].mark < curMark)
00249 {
00250 data[idx].key = key;
00251 data[idx].mark = curMark;
00252 data[idx].data = dataIN;
00253 success = true;
00254 break;
00255 }
00256 }
00257
00258 if (!success)
00259 {
00260 sprintf (msgBuf_dh, "Failed to insert key= %i, data= %i", key, dataIN);
00261 }
00262 END_FUNC_DH}
00263
00264
00265 #undef __FUNC__
00266 #define __FUNC__ "rehash_private"
00267 void
00268 rehash_private (Hash_i_dh h)
00269 {
00270 START_FUNC_DH
00271 int i,
00272 old_size = h->size, new_size = old_size * 2, oldCurMark = h->curMark;
00273 Hash_i_Record *oldData = h->data, *newData;
00274
00275 sprintf (msgBuf_dh, "rehashing; old_size= %i, new_size= %i", old_size,
00276 new_size);
00277 SET_INFO (msgBuf_dh);
00278
00279
00280
00281
00282 newData = (Hash_i_Record *) MALLOC_DH (new_size * sizeof (Hash_i_Record));
00283 CHECK_V_ERROR;
00284 for (i = 0; i < new_size; ++i)
00285 {
00286 newData[i].key = -1;
00287 newData[i].mark = -1;
00288 }
00289 h->size = new_size;
00290 h->data = newData;
00291 h->count = 0;
00292 h->curMark = 0;
00293
00294 for (i = h->count; i < new_size; ++i)
00295 {
00296 newData[i].key = -1;
00297 newData[i].mark = -1;
00298 }
00299
00300
00301
00302
00303
00304 for (i = 0; i < old_size; ++i)
00305 {
00306 if (oldData[i].mark == oldCurMark)
00307 {
00308 Hash_i_dhInsert (h, oldData[i].key, oldData[i].data);
00309 CHECK_V_ERROR;
00310 }
00311 }
00312
00313 FREE_DH (oldData);
00314 CHECK_V_ERROR;
00315 END_FUNC_DH}