Mercurial > hg > xemacs-beta
comparison src/hash.c @ 380:8626e4521993 r21-2-5
Import from CVS: tag r21-2-5
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:07:10 +0200 |
parents | c5d627a313b1 |
children | 7d59cb494b73 |
comparison
equal
deleted
inserted
replaced
379:76b7d63099ad | 380:8626e4521993 |
---|---|
31 #define NULL_ENTRY ((void *) 1) | 31 #define NULL_ENTRY ((void *) 1) |
32 | 32 |
33 #endif /* !emacs */ | 33 #endif /* !emacs */ |
34 | 34 |
35 #include "hash.h" | 35 #include "hash.h" |
36 #include "elhash.h" | 36 |
37 | 37 #define COMFORTABLE_SIZE(size) (21 * (size) / 16) |
38 static CONST unsigned int | 38 |
39 primes []={ | 39 /* Knuth volume 3, hash functions */ |
40 #define WORD_HASH_4(word) (0x9c406b55 * (word)) | |
41 #define WORD_HASH_8(word) (0x9c406b549c406b55 * (word)) | |
42 | |
43 static CONST hash_size_t | |
44 primes [] = | |
45 { | |
40 13, | 46 13, |
41 29, 37, 47, 59, 71, 89, 107, 131, 163, 197, 239, 293, 353, 431, 521, 631, | 47 29, 37, 47, 59, 71, 89, 107, 131, 163, 197, 239, 293, 353, 431, 521, 631, |
42 761, 919, 1103, 1327, 1597, 1931, 2333, 2801, 3371, 4049, 4861, 5839, 7013, | 48 761, 919, 1103, 1327, 1597, 1931, 2333, 2801, 3371, 4049, 4861, 5839, 7013, |
43 8419, 10103, 12143, 14591, 17519, 21023, 25229, 30293, 36353, 43627, 52361, | 49 8419, 10103, 12143, 14591, 17519, 21023, 25229, 30293, 36353, 43627, 52361, |
44 62851, 75431, 90523, 108631, 130363, 156437, 187751, 225307, 270371, 324449, | 50 62851, 75431, 90523, 108631, 130363, 156437, 187751, 225307, 270371, 324449, |
45 389357, 467237, 560689, 672827, 807403, 968897, 1162687, 1395263, 1674319, | 51 389357, 467237, 560689, 672827, 807403, 968897, 1162687, 1395263, 1674319, |
46 2009191, 2411033, 2893249 | 52 2009191, 2411033, 2893249 |
47 }; | 53 }; |
48 | 54 |
49 /* strings code */ | 55 #if 0 |
50 | 56 static CONST hash_size_t |
51 /* from base/generic-hash.cc, and hence from Dragon book, p436 */ | 57 primes [] = |
58 { | |
59 29, 41, 59, 79, 107, 149, 197, 263, 347, 457, 599, 787, 1031, 1361, | |
60 1777, 2333, 3037, 3967, 5167, 6719, 8737, 11369, 14783, 19219, 24989, | |
61 32491, 42257, 54941, 71429, 92861, 120721, 156941, 204047, 265271, | |
62 344857, 448321, 582821, 757693, 985003, 1280519, 1664681, 2164111, | |
63 2813353, 3657361, 4754591, 6180989, 8035301, 10445899, 13579681, | |
64 17653589, 22949669, 29834603, 38784989, 50420551, 65546729, 85210757, | |
65 110774011, 144006217, 187208107, 243370577, 316381771, 411296309, | |
66 534685237, 695090819, 903618083, 1174703521, 1527114613, 1985248999, | |
67 2580823717, 3355070839, 4361592119 | |
68 }; | |
69 #endif | |
70 | |
52 unsigned long | 71 unsigned long |
53 string_hash (CONST void *xv) | 72 memory_hash (CONST void *xv, size_t size) |
54 { | 73 { |
55 unsigned int h = 0; | 74 unsigned int h = 0; |
56 unsigned CONST char *x = (unsigned CONST char *) xv; | 75 unsigned CONST char *x = (unsigned CONST char *) xv; |
57 | 76 |
58 if (!x) return 0; | 77 if (!x) return 0; |
59 | 78 |
60 while (*x != 0) | 79 while (size--) |
61 { | 80 { |
62 unsigned int g; | 81 unsigned int g; |
63 h = (h << 4) + *x++; | 82 h = (h << 4) + *x++; |
64 if ((g = h & 0xf0000000) != 0) | 83 if ((g = h & 0xf0000000) != 0) |
65 h = (h ^ (g >> 24)) ^ g; | 84 h = (h ^ (g >> 24)) ^ g; |
66 } | 85 } |
67 | 86 |
68 return h; | 87 return h; |
69 } | 88 } |
70 | 89 |
90 /* We've heard of binary search. */ | |
91 static hash_size_t | |
92 prime_size (hash_size_t size) | |
93 { | |
94 int low, high; | |
95 for (low = 0, high = countof (primes) - 1; high - low > 1;) | |
96 { | |
97 /* Loop Invariant: size < primes [high] */ | |
98 int mid = (low + high) / 2; | |
99 if (primes [mid] < size) | |
100 low = mid; | |
101 else | |
102 high = mid; | |
103 } | |
104 return primes [high]; | |
105 } | |
106 | |
107 static void rehash (hentry *harray, struct hash_table *ht, hash_size_t size); | |
108 | |
109 #define KEYS_DIFFER_P(old, new, testfun) \ | |
110 (((old) != (new)) && (!(testfun) || !(testfun) ((old),(new)))) | |
111 | |
112 CONST void * | |
113 gethash (CONST void *key, struct hash_table *hash_table, CONST void **ret_value) | |
114 { | |
115 hentry *harray = hash_table->harray; | |
116 hash_table_test_function test_function = hash_table->test_function; | |
117 hash_size_t size = hash_table->size; | |
118 unsigned int hcode_initial = | |
119 hash_table->hash_function ? | |
120 hash_table->hash_function (key) : | |
121 (unsigned long) key; | |
122 unsigned int hcode = hcode_initial % size; | |
123 hentry *e = &harray [hcode]; | |
124 CONST void *e_key = e->key; | |
125 | |
126 if (!key) | |
127 { | |
128 *ret_value = hash_table->zero_entry; | |
129 return (void *) hash_table->zero_set; | |
130 } | |
131 | |
132 if (e_key ? | |
133 KEYS_DIFFER_P (e_key, key, test_function) : | |
134 e->contents == NULL_ENTRY) | |
135 { | |
136 size_t h2 = size - 2; | |
137 unsigned int incr = 1 + (hcode_initial % h2); | |
138 do | |
139 { | |
140 hcode += incr; if (hcode >= size) hcode -= size; | |
141 e = &harray [hcode]; | |
142 e_key = e->key; | |
143 } | |
144 while (e_key ? | |
145 KEYS_DIFFER_P (e_key, key, test_function) : | |
146 e->contents == NULL_ENTRY); | |
147 } | |
148 | |
149 *ret_value = e->contents; | |
150 return e->key; | |
151 } | |
152 | |
153 void | |
154 clrhash (struct hash_table *hash_table) | |
155 { | |
156 memset (hash_table->harray, 0, sizeof (hentry) * hash_table->size); | |
157 hash_table->zero_entry = 0; | |
158 hash_table->zero_set = 0; | |
159 hash_table->fullness = 0; | |
160 } | |
161 | |
162 void | |
163 free_hash_table (struct hash_table *hash_table) | |
164 { | |
165 xfree (hash_table->harray); | |
166 xfree (hash_table); | |
167 } | |
168 | |
169 struct hash_table* | |
170 make_hash_table (hash_size_t size) | |
171 { | |
172 struct hash_table *hash_table = xnew_and_zero (struct hash_table); | |
173 hash_table->size = prime_size (COMFORTABLE_SIZE (size)); | |
174 hash_table->harray = xnew_array (hentry, hash_table->size); | |
175 clrhash (hash_table); | |
176 return hash_table; | |
177 } | |
178 | |
179 struct hash_table * | |
180 make_general_hash_table (hash_size_t size, | |
181 hash_table_hash_function hash_function, | |
182 hash_table_test_function test_function) | |
183 { | |
184 struct hash_table* hash_table = make_hash_table (size); | |
185 hash_table->hash_function = hash_function; | |
186 hash_table->test_function = test_function; | |
187 return hash_table; | |
188 } | |
189 | |
190 #if 0 /* unused strings code */ | |
191 struct hash_table * | |
192 make_strings_hash_table (hash_size_t size) | |
193 { | |
194 return make_general_hash_table (size, string_hash, string_eq); | |
195 } | |
196 | |
197 /* from base/generic-hash.cc, and hence from Dragon book, p436 */ | |
71 unsigned long | 198 unsigned long |
72 memory_hash (CONST void *xv, size_t size) | 199 string_hash (CONST void *xv) |
73 { | 200 { |
74 unsigned int h = 0; | 201 unsigned int h = 0; |
75 unsigned CONST char *x = (unsigned CONST char *) xv; | 202 unsigned CONST char *x = (unsigned CONST char *) xv; |
76 | 203 |
77 if (!x) return 0; | 204 if (!x) return 0; |
78 | 205 |
79 while (size > 0) | 206 while (*x != 0) |
80 { | 207 { |
81 unsigned int g; | 208 unsigned int g; |
82 h = (h << 4) + *x++; | 209 h = (h << 4) + *x++; |
83 if ((g = h & 0xf0000000) != 0) | 210 if ((g = h & 0xf0000000) != 0) |
84 h = (h ^ (g >> 24)) ^ g; | 211 h = (h ^ (g >> 24)) ^ g; |
85 size--; | |
86 } | 212 } |
87 | 213 |
88 return h; | 214 return h; |
89 } | 215 } |
90 | 216 |
91 static int | 217 static int |
92 string_eq (CONST void *st1, CONST void *st2) | 218 string_eq (CONST void *s1, CONST void *s2) |
93 { | 219 { |
94 if (!st1) | 220 return s1 && s2 ? !strcmp ((CONST char *) s1, (CONST char *) s2) : s1 == s2; |
95 return st2 ? 0 : 1; | 221 } |
96 else if (!st2) | 222 #endif /* unused strings code */ |
97 return 0; | 223 |
98 else | 224 void |
99 return !strcmp ( (CONST char *) st1, (CONST char *) st2); | 225 copy_hash (struct hash_table *dest, struct hash_table *src) |
100 } | 226 { |
101 | |
102 | |
103 /* ### Ever heard of binary search? */ | |
104 static unsigned int | |
105 prime_size (unsigned int size) | |
106 { | |
107 int i; | |
108 for (i = 0; i < countof (primes); i++) | |
109 if (size <= primes [i]) | |
110 return primes [i]; | |
111 return primes [countof (primes) - 1]; | |
112 } | |
113 | |
114 static void rehash (hentry *harray, c_hashtable ht, unsigned int size); | |
115 | |
116 #define KEYS_DIFFER_P(old, new, testfun) \ | |
117 ((testfun)?(((old) == (new))?0:(!(testfun ((old), new)))):((old) != (new))) | |
118 | |
119 CONST void * | |
120 gethash (CONST void *key, c_hashtable hash, CONST void **ret_value) | |
121 { | |
122 hentry *harray = hash->harray; | |
123 int (*test_function) (CONST void *, CONST void *) = hash->test_function; | |
124 unsigned int hsize = hash->size; | |
125 unsigned int hcode_initial = | |
126 (hash->hash_function)?(hash->hash_function(key)):((unsigned long) key); | |
127 unsigned int hcode = hcode_initial % hsize; | |
128 hentry *e = &harray [hcode]; | |
129 CONST void *e_key = e->key; | |
130 | |
131 if (!key) | |
132 { | |
133 *ret_value = hash->zero_entry; | |
134 return (void *) hash->zero_set; | |
135 } | |
136 | |
137 if ((e_key)? | |
138 (KEYS_DIFFER_P (e_key, key, test_function)): | |
139 (e->contents == NULL_ENTRY)) | |
140 { | |
141 unsigned int h2 = hsize - 2; | |
142 unsigned int incr = 1 + (hcode_initial % h2); | |
143 do | |
144 { | |
145 hcode = hcode + incr; | |
146 if (hcode >= hsize) hcode = hcode - hsize; | |
147 e = &harray [hcode]; | |
148 e_key = e->key; | |
149 } | |
150 while ((e_key)? | |
151 (KEYS_DIFFER_P (e_key, key, test_function)): | |
152 (e->contents == NULL_ENTRY)); | |
153 } | |
154 | |
155 *ret_value = e->contents; | |
156 return e->key; | |
157 } | |
158 | |
159 void | |
160 clrhash (c_hashtable hash) | |
161 { | |
162 memset (hash->harray, 0, sizeof (hentry) * hash->size); | |
163 hash->zero_entry = 0; | |
164 hash->zero_set = 0; | |
165 hash->fullness = 0; | |
166 } | |
167 | |
168 void | |
169 free_hashtable (c_hashtable hash) | |
170 { | |
171 #ifdef emacs | |
172 if (!NILP (hash->elisp_table)) | |
173 return; | |
174 #endif | |
175 xfree (hash->harray); | |
176 xfree (hash); | |
177 } | |
178 | |
179 c_hashtable | |
180 make_hashtable (unsigned int hsize) | |
181 { | |
182 c_hashtable res = xnew_and_zero (struct _C_hashtable); | |
183 res->size = prime_size ((13 * hsize) / 10); | |
184 res->harray = xnew_array (hentry, res->size); | |
185 #ifdef emacs | |
186 res->elisp_table = Qnil; | |
187 #endif | |
188 clrhash (res); | |
189 return res; | |
190 } | |
191 | |
192 c_hashtable | |
193 make_general_hashtable (unsigned int hsize, | |
194 unsigned long (*hash_function) (CONST void *), | |
195 int (*test_function) (CONST void *, CONST void *)) | |
196 { | |
197 c_hashtable res = xnew_and_zero (struct _C_hashtable); | |
198 res->size = prime_size ((13 * hsize) / 10); | |
199 res->harray = xnew_array (hentry, res->size); | |
200 res->hash_function = hash_function; | |
201 res->test_function = test_function; | |
202 #ifdef emacs | |
203 res->elisp_table = Qnil; | |
204 #endif | |
205 clrhash (res); | |
206 return res; | |
207 } | |
208 | |
209 c_hashtable | |
210 make_strings_hashtable (unsigned int hsize) | |
211 { | |
212 return make_general_hashtable (hsize, string_hash, string_eq); | |
213 } | |
214 | |
215 #ifdef emacs | |
216 unsigned int | |
217 compute_harray_size (unsigned int hsize) | |
218 { | |
219 return prime_size ((13 * hsize) / 10); | |
220 } | |
221 #endif | |
222 | |
223 void | |
224 copy_hash (c_hashtable dest, c_hashtable src) | |
225 { | |
226 #ifdef emacs | |
227 /* if these are not the same, then we are losing here */ | |
228 if ((NILP (dest->elisp_table)) != (NILP (src->elisp_table))) | |
229 { | |
230 error ("Incompatible hashtable types to copy_hash."); | |
231 return; | |
232 } | |
233 #endif | |
234 | |
235 if (dest->size != src->size) | 227 if (dest->size != src->size) |
236 { | 228 { |
237 #ifdef emacs | 229 xfree (dest->harray); |
238 if (!NILP (dest->elisp_table)) | |
239 elisp_hvector_free (dest->harray, dest->elisp_table); | |
240 else | |
241 #endif | |
242 xfree (dest->harray); | |
243 | 230 |
244 dest->size = src->size; | 231 dest->size = src->size; |
245 #ifdef emacs | 232 dest->harray = xnew_array (hentry, dest->size); |
246 if (!NILP (dest->elisp_table)) | 233 } |
247 dest->harray = (hentry *) | 234 dest->fullness = src->fullness; |
248 elisp_hvector_malloc (sizeof (hentry) * dest->size, | 235 dest->zero_entry = src->zero_entry; |
249 dest->elisp_table); | 236 dest->zero_set = src->zero_set; |
250 else | |
251 #endif | |
252 dest->harray = xnew_array (hentry, dest->size); | |
253 } | |
254 dest->fullness = src->fullness; | |
255 dest->zero_entry = src->zero_entry; | |
256 dest->zero_set = src->zero_set; | |
257 dest->hash_function = src->hash_function; | 237 dest->hash_function = src->hash_function; |
258 dest->test_function = src->test_function; | 238 dest->test_function = src->test_function; |
259 memcpy (dest->harray, src->harray, sizeof (hentry) * dest->size); | 239 memcpy (dest->harray, src->harray, sizeof (hentry) * dest->size); |
260 } | 240 } |
261 | 241 |
262 static void | 242 static void |
263 grow_hashtable (c_hashtable hash, unsigned int new_size) | 243 grow_hash_table (struct hash_table *hash_table, hash_size_t new_size) |
264 { | 244 { |
265 unsigned int old_hsize = hash->size; | 245 hash_size_t old_size = hash_table->size; |
266 hentry *old_harray = hash->harray; | 246 hentry *old_harray = hash_table->harray; |
267 unsigned int new_hsize = prime_size (new_size); | 247 hentry *new_harray; |
268 hentry *new_harray; | 248 |
269 | 249 new_size = prime_size (new_size); |
270 #ifdef emacs | 250 |
271 /* We test for Qzero to facilitate free-hook.c. That module creates | 251 new_harray = xnew_array (hentry, new_size); |
272 a hashtable very very early, at which point Qnil has not yet | 252 |
273 been set and is thus all zeroes. Qzero is "automatically" | 253 hash_table->size = new_size; |
274 initialized at startup because its correct value is also all | 254 hash_table->harray = new_harray; |
275 zeroes. */ | |
276 if (!EQ (hash->elisp_table, Qnull_pointer) && | |
277 !NILP (hash->elisp_table) && | |
278 !ZEROP (hash->elisp_table)) | |
279 new_harray = (hentry *) elisp_hvector_malloc (sizeof (hentry) * new_hsize, | |
280 hash->elisp_table); | |
281 else | |
282 #endif | |
283 new_harray = (hentry *) xmalloc (sizeof (hentry) * new_hsize); | |
284 | |
285 hash->size = new_hsize; | |
286 hash->harray = new_harray; | |
287 | 255 |
288 /* do the rehash on the "grown" table */ | 256 /* do the rehash on the "grown" table */ |
289 { | 257 { |
290 long old_zero_set = hash->zero_set; | 258 long old_zero_set = hash_table->zero_set; |
291 void *old_zero_entry = hash->zero_entry; | 259 void *old_zero_entry = hash_table->zero_entry; |
292 clrhash (hash); | 260 clrhash (hash_table); |
293 hash->zero_set = old_zero_set; | 261 hash_table->zero_set = old_zero_set; |
294 hash->zero_entry = old_zero_entry; | 262 hash_table->zero_entry = old_zero_entry; |
295 rehash (old_harray, hash, old_hsize); | 263 rehash (old_harray, hash_table, old_size); |
296 } | 264 } |
297 | 265 |
298 #ifdef emacs | 266 xfree (old_harray); |
299 if (!EQ (hash->elisp_table, Qnull_pointer) && | 267 } |
300 !NILP (hash->elisp_table) && | 268 |
301 !ZEROP (hash->elisp_table)) | 269 void |
302 elisp_hvector_free (old_harray, hash->elisp_table); | 270 expand_hash_table (struct hash_table *hash_table, hash_size_t needed_size) |
303 else | 271 { |
304 #endif | 272 hash_size_t size = hash_table->size; |
305 xfree (old_harray); | 273 hash_size_t comfortable_size = COMFORTABLE_SIZE (needed_size); |
306 } | 274 if (size < comfortable_size) |
307 | 275 grow_hash_table (hash_table, comfortable_size + 1); |
308 void | 276 } |
309 expand_hashtable (c_hashtable hash, unsigned int needed_size) | 277 |
310 { | 278 void |
311 size_t hsize = hash->size; | 279 puthash (CONST void *key, void *contents, struct hash_table *hash_table) |
312 size_t comfortable_size = (13 * needed_size) / 10; | 280 { |
313 if (hsize < comfortable_size) | 281 hash_table_test_function test_function = hash_table->test_function; |
314 grow_hashtable (hash, comfortable_size + 1); | 282 hash_size_t size = hash_table->size; |
315 } | 283 hash_size_t fullness = hash_table->fullness; |
316 | |
317 void | |
318 puthash (CONST void *key, void *cont, c_hashtable hash) | |
319 { | |
320 unsigned int hsize = hash->size; | |
321 int (*test_function) (CONST void *, CONST void *) = hash->test_function; | |
322 unsigned int fullness = hash->fullness; | |
323 hentry *harray; | 284 hentry *harray; |
324 CONST void *e_key; | 285 CONST void *e_key; |
325 hentry *e; | 286 hentry *e; |
326 unsigned int hcode_initial = | 287 unsigned int hcode_initial = |
327 (hash->hash_function)?(hash->hash_function(key)):((unsigned long) key); | 288 hash_table->hash_function ? |
289 hash_table->hash_function (key) : | |
290 (unsigned long) key; | |
328 unsigned int hcode; | 291 unsigned int hcode; |
329 unsigned int incr = 0; | 292 unsigned int incr = 0; |
330 unsigned int h2; | 293 size_t h2; |
331 CONST void *oldcontents; | 294 CONST void *oldcontents; |
332 | 295 |
333 if (!key) | 296 if (!key) |
334 { | 297 { |
335 hash->zero_entry = cont; | 298 hash_table->zero_entry = contents; |
336 hash->zero_set = 1; | 299 hash_table->zero_set = 1; |
337 return; | 300 return; |
338 } | 301 } |
339 | 302 |
340 if (hsize < (1 + ((13 * fullness) / 10))) | 303 if (size < (1 + COMFORTABLE_SIZE (fullness))) |
341 { | 304 { |
342 grow_hashtable (hash, hsize + 1); | 305 grow_hash_table (hash_table, size + 1); |
343 hsize = hash->size; | 306 size = hash_table->size; |
344 fullness = hash->fullness; | 307 fullness = hash_table->fullness; |
345 } | 308 } |
346 | 309 |
347 harray= hash->harray; | 310 harray= hash_table->harray; |
348 h2 = hsize - 2; | 311 h2 = size - 2; |
349 | 312 |
350 hcode = hcode_initial % hsize; | 313 hcode = hcode_initial % size; |
351 | 314 |
352 e_key = harray [hcode].key; | 315 e_key = harray [hcode].key; |
353 if (e_key && (KEYS_DIFFER_P (e_key, key, test_function))) | 316 if (e_key && KEYS_DIFFER_P (e_key, key, test_function)) |
354 { | 317 { |
355 h2 = hsize - 2; | 318 h2 = size - 2; |
356 incr = 1 + (hcode_initial % h2); | 319 incr = 1 + (hcode_initial % h2); |
357 do | 320 do |
358 { | 321 { |
359 hcode = hcode + incr; | 322 hcode += incr; |
360 if (hcode >= hsize) hcode = hcode - hsize; | 323 if (hcode >= size) hcode -= size; |
361 e_key = harray [hcode].key; | 324 e_key = harray [hcode].key; |
362 } | 325 } |
363 while (e_key && (KEYS_DIFFER_P (e_key, key, test_function))); | 326 while (e_key && KEYS_DIFFER_P (e_key, key, test_function)); |
364 } | 327 } |
365 oldcontents = harray [hcode].contents; | 328 oldcontents = harray [hcode].contents; |
366 harray [hcode].key = key; | 329 harray [hcode].key = key; |
367 harray [hcode].contents = cont; | 330 harray [hcode].contents = contents; |
368 /* if the entry that we used was a deleted entry, | 331 /* If the entry that we used was a deleted entry, |
369 check for a non deleted entry of the same key, | 332 check for a non deleted entry of the same key, |
370 then delete it */ | 333 then delete it. */ |
371 if (!e_key && (oldcontents == NULL_ENTRY)) | 334 if (!e_key && oldcontents == NULL_ENTRY) |
372 { | 335 { |
373 if (!incr) incr = 1 + ((unsigned long) key % h2); | 336 if (!incr) incr = 1 + ((unsigned long) key % h2); |
374 | 337 |
375 do | 338 do |
376 { | 339 { |
377 hcode = hcode + incr; | 340 hcode += incr; if (hcode >= size) hcode -= size; |
378 if (hcode >= hsize) hcode = hcode - hsize; | |
379 e = &harray [hcode]; | 341 e = &harray [hcode]; |
380 e_key = e->key; | 342 e_key = e->key; |
381 } | 343 } |
382 while ((e_key)? | 344 while (e_key ? |
383 (KEYS_DIFFER_P (e_key, key, test_function)): | 345 KEYS_DIFFER_P (e_key, key, test_function): |
384 (e->contents == NULL_ENTRY)); | 346 e->contents == NULL_ENTRY); |
385 | 347 |
386 if (e_key) | 348 if (e_key) |
387 { | 349 { |
388 e->key = 0; | 350 e->key = 0; |
389 e->contents = NULL_ENTRY; | 351 e->contents = NULL_ENTRY; |
390 } | 352 } |
391 } | 353 } |
392 | 354 |
393 /* only increment the fullness when we used up a new hentry */ | 355 /* only increment the fullness when we used up a new hentry */ |
394 if (!e_key || (KEYS_DIFFER_P (e_key, key, test_function))) | 356 if (!e_key || KEYS_DIFFER_P (e_key, key, test_function)) |
395 hash->fullness++; | 357 hash_table->fullness++; |
396 } | 358 } |
397 | 359 |
398 static void | 360 static void |
399 rehash (hentry *harray, c_hashtable hash, unsigned int size) | 361 rehash (hentry *harray, struct hash_table *hash_table, hash_size_t size) |
400 { | 362 { |
401 hentry *limit = harray + size; | 363 hentry *limit = harray + size; |
402 hentry *e; | 364 hentry *e; |
403 for (e = harray; e < limit; e++) | 365 for (e = harray; e < limit; e++) |
404 { | 366 { |
405 if (e->key) | 367 if (e->key) |
406 puthash (e->key, e->contents, hash); | 368 puthash (e->key, e->contents, hash_table); |
407 } | 369 } |
408 } | 370 } |
409 | 371 |
410 void | 372 void |
411 remhash (CONST void *key, c_hashtable hash) | 373 remhash (CONST void *key, struct hash_table *hash_table) |
412 { | 374 { |
413 hentry *harray = hash->harray; | 375 hentry *harray = hash_table->harray; |
414 int (*test_function) (CONST void*, CONST void*) = hash->test_function; | 376 hash_table_test_function test_function = hash_table->test_function; |
415 unsigned int hsize = hash->size; | 377 hash_size_t size = hash_table->size; |
416 unsigned int hcode_initial = | 378 unsigned int hcode_initial = |
417 (hash->hash_function)?(hash->hash_function(key)):((unsigned long) key); | 379 (hash_table->hash_function) ? |
418 unsigned int hcode = hcode_initial % hsize; | 380 (hash_table->hash_function (key)) : |
381 ((unsigned long) key); | |
382 unsigned int hcode = hcode_initial % size; | |
419 hentry *e = &harray [hcode]; | 383 hentry *e = &harray [hcode]; |
420 CONST void *e_key = e->key; | 384 CONST void *e_key = e->key; |
421 | 385 |
422 if (!key) | 386 if (!key) |
423 { | 387 { |
424 hash->zero_entry = 0; | 388 hash_table->zero_entry = 0; |
425 hash->zero_set = 0; | 389 hash_table->zero_set = 0; |
426 return; | 390 return; |
427 } | 391 } |
428 | 392 |
429 if ((e_key)? | 393 if (e_key ? |
430 (KEYS_DIFFER_P (e_key, key, test_function)): | 394 KEYS_DIFFER_P (e_key, key, test_function) : |
431 (e->contents == NULL_ENTRY)) | 395 e->contents == NULL_ENTRY) |
432 { | 396 { |
433 unsigned int h2 = hsize - 2; | 397 size_t h2 = size - 2; |
434 unsigned int incr = 1 + (hcode_initial % h2); | 398 unsigned int incr = 1 + (hcode_initial % h2); |
435 do | 399 do |
436 { | 400 { |
437 hcode = hcode + incr; | 401 hcode += incr; if (hcode >= size) hcode -= size; |
438 if (hcode >= hsize) hcode = hcode - hsize; | |
439 e = &harray [hcode]; | 402 e = &harray [hcode]; |
440 e_key = e->key; | 403 e_key = e->key; |
441 } | 404 } |
442 while ((e_key)? | 405 while (e_key? |
443 (KEYS_DIFFER_P (e_key, key, test_function)): | 406 KEYS_DIFFER_P (e_key, key, test_function): |
444 (e->contents == NULL_ENTRY)); | 407 e->contents == NULL_ENTRY); |
445 } | 408 } |
446 if (e_key) | 409 if (e_key) |
447 { | 410 { |
448 e->key = 0; | 411 e->key = 0; |
449 e->contents = NULL_ENTRY; | 412 e->contents = NULL_ENTRY; |
450 /* Note: you can't do fullness-- here, it breaks the world. */ | 413 /* Note: you can't do fullness-- here, it breaks the world. */ |
451 } | 414 } |
452 } | 415 } |
453 | 416 |
454 void | 417 void |
455 maphash (maphash_function mf, c_hashtable hash, void *arg) | 418 maphash (maphash_function mf, struct hash_table *hash_table, void *arg) |
456 { | 419 { |
457 hentry *e; | 420 hentry *e; |
458 hentry *limit; | 421 hentry *limit; |
459 | 422 |
460 if (hash->zero_set) | 423 if (hash_table->zero_set) |
461 { | 424 { |
462 if (((*mf) (0, hash->zero_entry, arg))) | 425 if (mf (0, hash_table->zero_entry, arg)) |
463 return; | 426 return; |
464 } | 427 } |
465 | 428 |
466 for (e = hash->harray, limit = e + hash->size; e < limit; e++) | 429 for (e = hash_table->harray, limit = e + hash_table->size; e < limit; e++) |
467 { | 430 { |
468 if (e->key) | 431 if (e->key && mf (e->key, e->contents, arg)) |
469 { | 432 return; |
470 if (((*mf) (e->key, e->contents, arg))) | 433 } |
471 return; | 434 } |
472 } | 435 |
473 } | 436 void |
474 } | 437 map_remhash (remhash_predicate predicate, struct hash_table *hash_table, void *arg) |
475 | |
476 void | |
477 map_remhash (remhash_predicate predicate, c_hashtable hash, void *arg) | |
478 { | 438 { |
479 hentry *e; | 439 hentry *e; |
480 hentry *limit; | 440 hentry *limit; |
481 | 441 |
482 if (hash->zero_set && ((*predicate) (0, hash->zero_entry, arg))) | 442 if (hash_table->zero_set && predicate (0, hash_table->zero_entry, arg)) |
483 { | 443 { |
484 hash->zero_set = 0; | 444 hash_table->zero_set = 0; |
485 hash->zero_entry = 0; | 445 hash_table->zero_entry = 0; |
486 } | 446 } |
487 | 447 |
488 for (e = hash->harray, limit = e + hash->size; e < limit; e++) | 448 for (e = hash_table->harray, limit = e + hash_table->size; e < limit; e++) |
489 if ((*predicate) (e->key, e->contents, arg)) | 449 if (predicate (e->key, e->contents, arg)) |
490 { | 450 { |
491 e->key = 0; | 451 e->key = 0; |
492 e->contents = NULL_ENTRY; | 452 e->contents = NULL_ENTRY; |
493 } | 453 } |
494 } | 454 } |