comparison src/hash.c @ 647:b39c14581166

[xemacs-hg @ 2001-08-13 04:45:47 by ben] removal of unsigned, size_t, etc.
author ben
date Mon, 13 Aug 2001 04:46:48 +0000
parents abe6d1db359e
children fdefd0186b75
comparison
equal deleted inserted replaced
646:00c54252fe4f 647:b39c14581166
29 #define COMFORTABLE_SIZE(size) (21 * (size) / 16) 29 #define COMFORTABLE_SIZE(size) (21 * (size) / 16)
30 30
31 #define KEYS_DIFFER_P(old, new, testfun) \ 31 #define KEYS_DIFFER_P(old, new, testfun) \
32 (((old) != (new)) && (!(testfun) || !(testfun) ((old),(new)))) 32 (((old) != (new)) && (!(testfun) || !(testfun) ((old),(new))))
33 33
34 static void rehash (hentry *harray, struct hash_table *ht, hash_size_t size); 34 static void rehash (hentry *harray, struct hash_table *ht, Element_Count size);
35 35
36 unsigned long 36 Hash_Code
37 memory_hash (const void *xv, size_t size) 37 memory_hash (const void *xv, Memory_Count size)
38 { 38 {
39 unsigned int h = 0; 39 Hash_Code h = 0;
40 unsigned const char *x = (unsigned const char *) xv; 40 unsigned const char *x = (unsigned const char *) xv;
41 41
42 if (!x) return 0; 42 if (!x) return 0;
43 43
44 while (size--) 44 while (size--)
45 { 45 {
46 unsigned int g; 46 Hash_Code g;
47 h = (h << 4) + *x++; 47 h = (h << 4) + *x++;
48 if ((g = h & 0xf0000000) != 0) 48 if ((g = h & 0xf0000000) != 0)
49 h = (h ^ (g >> 24)) ^ g; 49 h = (h ^ (g >> 24)) ^ g;
50 } 50 }
51 51
52 return h; 52 return h;
53 } 53 }
54 54
55 unsigned long 55 Hash_Code
56 string_hash (const char *xv) 56 string_hash (const char *xv)
57 { 57 {
58 unsigned int h = 0; 58 Hash_Code h = 0;
59 unsigned const char *x = (unsigned const char *) xv; 59 unsigned const char *x = (unsigned const char *) xv;
60 60
61 if (!x) return 0; 61 if (!x) return 0;
62 62
63 while (*x) 63 while (*x)
64 { 64 {
65 unsigned int g; 65 Hash_Code g;
66 h = (h << 4) + *x++; 66 h = (h << 4) + *x++;
67 if ((g = h & 0xf0000000) != 0) 67 if ((g = h & 0xf0000000) != 0)
68 h = (h ^ (g >> 24)) ^ g; 68 h = (h ^ (g >> 24)) ^ g;
69 } 69 }
70 70
71 return h; 71 return h;
72 } 72 }
73 73
74 /* Return a suitable size for a hash table, with at least SIZE slots. */ 74 /* Return a suitable size for a hash table, with at least SIZE slots. */
75 static size_t 75 static Element_Count
76 hash_table_size (size_t requested_size) 76 hash_table_size (Element_Count requested_size)
77 { 77 {
78 /* Return some prime near, but greater than or equal to, SIZE. 78 /* Return some prime near, but greater than or equal to, SIZE.
79 Decades from the time of writing, someone will have a system large 79 Decades from the time of writing, someone will have a system large
80 enough that the list below will be too short... */ 80 enough that the list below will be too short... */
81 static const size_t primes [] = 81 static const Element_Count primes [] =
82 { 82 {
83 19, 29, 41, 59, 79, 107, 149, 197, 263, 347, 457, 599, 787, 1031, 83 19, 29, 41, 59, 79, 107, 149, 197, 263, 347, 457, 599, 787, 1031,
84 1361, 1777, 2333, 3037, 3967, 5167, 6719, 8737, 11369, 14783, 84 1361, 1777, 2333, 3037, 3967, 5167, 6719, 8737, 11369, 14783,
85 19219, 24989, 32491, 42257, 54941, 71429, 92861, 120721, 156941, 85 19219, 24989, 32491, 42257, 54941, 71429, 92861, 120721, 156941,
86 204047, 265271, 344857, 448321, 582821, 757693, 985003, 1280519, 86 204047, 265271, 344857, 448321, 582821, 757693, 985003, 1280519,
87 1664681, 2164111, 2813353, 3657361, 4754591, 6180989, 8035301, 87 1664681, 2164111, 2813353, 3657361, 4754591, 6180989, 8035301,
88 10445899, 13579681, 17653589, 22949669, 29834603, 38784989, 88 10445899, 13579681, 17653589, 22949669, 29834603, 38784989,
89 50420551, 65546729, 85210757, 110774011, 144006217, 187208107, 89 50420551, 65546729, 85210757, 110774011, 144006217, 187208107,
90 243370577, 316381771, 411296309, 534685237, 695090819, 903618083, 90 243370577, 316381771, 411296309, 534685237, 695090819, 903618083,
91 1174703521, 1527114613, 1985248999, 2580823717UL, 3355070839UL 91 1174703521, 1527114613, 1985248999 /* , 2580823717UL, 3355070839UL */
92 }; 92 };
93 /* We've heard of binary search. */ 93 /* We've heard of binary search. */
94 int low, high; 94 int low, high;
95 for (low = 0, high = countof (primes) - 1; high - low > 1;) 95 for (low = 0, high = countof (primes) - 1; high - low > 1;)
96 { 96 {
114 } 114 }
115 else 115 else
116 { 116 {
117 hentry *harray = hash_table->harray; 117 hentry *harray = hash_table->harray;
118 hash_table_test_function test_function = hash_table->test_function; 118 hash_table_test_function test_function = hash_table->test_function;
119 hash_size_t size = hash_table->size; 119 Element_Count size = hash_table->size;
120 unsigned int hcode_initial = 120 Hash_Code hcode_initial =
121 hash_table->hash_function ? 121 hash_table->hash_function ?
122 hash_table->hash_function (key) : 122 hash_table->hash_function (key) :
123 (unsigned long) key; 123 (Hash_Code) key;
124 unsigned int hcode = hcode_initial % size; 124 Element_Count hcode = (Element_Count) (hcode_initial % size);
125 hentry *e = &harray [hcode]; 125 hentry *e = &harray [hcode];
126 const void *e_key = e->key; 126 const void *e_key = e->key;
127 127
128 if (e_key ? 128 if (e_key ?
129 KEYS_DIFFER_P (e_key, key, test_function) : 129 KEYS_DIFFER_P (e_key, key, test_function) :
130 e->contents == NULL_ENTRY) 130 e->contents == NULL_ENTRY)
131 { 131 {
132 size_t h2 = size - 2; 132 Element_Count h2 = size - 2;
133 unsigned int incr = 1 + (hcode_initial % h2); 133 Element_Count incr = (Element_Count) (1 + (hcode_initial % h2));
134 do 134 do
135 { 135 {
136 hcode += incr; if (hcode >= size) hcode -= size; 136 hcode += incr; if (hcode >= size) hcode -= size;
137 e = &harray [hcode]; 137 e = &harray [hcode];
138 e_key = e->key; 138 e_key = e->key;
162 xfree (hash_table->harray); 162 xfree (hash_table->harray);
163 xfree (hash_table); 163 xfree (hash_table);
164 } 164 }
165 165
166 struct hash_table* 166 struct hash_table*
167 make_hash_table (hash_size_t size) 167 make_hash_table (Element_Count size)
168 { 168 {
169 struct hash_table *hash_table = xnew_and_zero (struct hash_table); 169 struct hash_table *hash_table = xnew_and_zero (struct hash_table);
170 hash_table->size = hash_table_size (COMFORTABLE_SIZE (size)); 170 hash_table->size = hash_table_size (COMFORTABLE_SIZE (size));
171 hash_table->harray = xnew_array (hentry, hash_table->size); 171 hash_table->harray = xnew_array (hentry, hash_table->size);
172 clrhash (hash_table); 172 clrhash (hash_table);
173 return hash_table; 173 return hash_table;
174 } 174 }
175 175
176 struct hash_table * 176 struct hash_table *
177 make_general_hash_table (hash_size_t size, 177 make_general_hash_table (Element_Count size,
178 hash_table_hash_function hash_function, 178 hash_table_hash_function hash_function,
179 hash_table_test_function test_function) 179 hash_table_test_function test_function)
180 { 180 {
181 struct hash_table* hash_table = make_hash_table (size); 181 struct hash_table* hash_table = make_hash_table (size);
182 hash_table->hash_function = hash_function; 182 hash_table->hash_function = hash_function;
183 hash_table->test_function = test_function; 183 hash_table->test_function = test_function;
184 return hash_table; 184 return hash_table;
185 } 185 }
186 186
187 static void 187 static void
188 grow_hash_table (struct hash_table *hash_table, hash_size_t new_size) 188 grow_hash_table (struct hash_table *hash_table, Element_Count new_size)
189 { 189 {
190 hash_size_t old_size = hash_table->size; 190 Element_Count old_size = hash_table->size;
191 hentry *old_harray = hash_table->harray; 191 hentry *old_harray = hash_table->harray;
192 192
193 hash_table->size = hash_table_size (new_size); 193 hash_table->size = hash_table_size (new_size);
194 hash_table->harray = xnew_array (hentry, hash_table->size); 194 hash_table->harray = xnew_array (hentry, hash_table->size);
195 195
215 hash_table->zero_set = 1; 215 hash_table->zero_set = 1;
216 } 216 }
217 else 217 else
218 { 218 {
219 hash_table_test_function test_function = hash_table->test_function; 219 hash_table_test_function test_function = hash_table->test_function;
220 hash_size_t size = hash_table->size; 220 Element_Count size = hash_table->size;
221 hentry *harray = hash_table->harray; 221 hentry *harray = hash_table->harray;
222 unsigned int hcode_initial = 222 Hash_Code hcode_initial =
223 hash_table->hash_function ? 223 hash_table->hash_function ?
224 hash_table->hash_function (key) : 224 hash_table->hash_function (key) :
225 (unsigned long) key; 225 (Hash_Code) key;
226 unsigned int hcode = hcode_initial % size; 226 Element_Count hcode = (Element_Count) (hcode_initial % size);
227 size_t h2 = size - 2; 227 Element_Count h2 = size - 2;
228 unsigned int incr = 1 + (hcode_initial % h2); 228 Element_Count incr = (Element_Count) (1 + (hcode_initial % h2));
229 const void *e_key = harray [hcode].key; 229 const void *e_key = harray [hcode].key;
230 const void *oldcontents; 230 const void *oldcontents;
231 231
232 if (e_key && KEYS_DIFFER_P (e_key, key, test_function)) 232 if (e_key && KEYS_DIFFER_P (e_key, key, test_function))
233 { 233 {
266 } 266 }
267 267
268 /* only increment the fullness when we used up a new hentry */ 268 /* only increment the fullness when we used up a new hentry */
269 if (!e_key || KEYS_DIFFER_P (e_key, key, test_function)) 269 if (!e_key || KEYS_DIFFER_P (e_key, key, test_function))
270 { 270 {
271 hash_size_t comfortable_size = COMFORTABLE_SIZE (++(hash_table->fullness)); 271 Element_Count comfortable_size = COMFORTABLE_SIZE (++(hash_table->fullness));
272 if (hash_table->size < comfortable_size) 272 if (hash_table->size < comfortable_size)
273 grow_hash_table (hash_table, comfortable_size + 1); 273 grow_hash_table (hash_table, comfortable_size + 1);
274 } 274 }
275 } 275 }
276 } 276 }
277 277
278 static void 278 static void
279 rehash (hentry *harray, struct hash_table *hash_table, hash_size_t size) 279 rehash (hentry *harray, struct hash_table *hash_table, Element_Count size)
280 { 280 {
281 hentry *limit = harray + size; 281 hentry *limit = harray + size;
282 hentry *e; 282 hentry *e;
283 for (e = harray; e < limit; e++) 283 for (e = harray; e < limit; e++)
284 { 284 {
297 } 297 }
298 else 298 else
299 { 299 {
300 hentry *harray = hash_table->harray; 300 hentry *harray = hash_table->harray;
301 hash_table_test_function test_function = hash_table->test_function; 301 hash_table_test_function test_function = hash_table->test_function;
302 hash_size_t size = hash_table->size; 302 Element_Count size = hash_table->size;
303 unsigned int hcode_initial = 303 Hash_Code hcode_initial =
304 (hash_table->hash_function) ? 304 (hash_table->hash_function) ?
305 (hash_table->hash_function (key)) : 305 (hash_table->hash_function (key)) :
306 ((unsigned long) key); 306 ((Hash_Code) key);
307 unsigned int hcode = hcode_initial % size; 307 Element_Count hcode = (Element_Count) (hcode_initial % size);
308 hentry *e = &harray [hcode]; 308 hentry *e = &harray [hcode];
309 const void *e_key = e->key; 309 const void *e_key = e->key;
310 310
311 if (e_key ? 311 if (e_key ?
312 KEYS_DIFFER_P (e_key, key, test_function) : 312 KEYS_DIFFER_P (e_key, key, test_function) :
313 e->contents == NULL_ENTRY) 313 e->contents == NULL_ENTRY)
314 { 314 {
315 size_t h2 = size - 2; 315 Element_Count h2 = size - 2;
316 unsigned int incr = 1 + (hcode_initial % h2); 316 Element_Count incr = (Element_Count) (1 + (hcode_initial % h2));
317 do 317 do
318 { 318 {
319 hcode += incr; if (hcode >= size) hcode -= size; 319 hcode += incr; if (hcode >= size) hcode -= size;
320 e = &harray [hcode]; 320 e = &harray [hcode];
321 e_key = e->key; 321 e_key = e->key;