]>
Commit | Line | Data |
---|---|---|
beda758b | 1 | /* hash - hashing table processing. |
1029ea6d PE |
2 | |
3 | Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software | |
4 | Foundation, Inc. | |
5 | ||
beda758b | 6 | Written by Jim Meyering, 1992. |
68bd3b6b RA |
7 | |
8 | This program is free software; you can redistribute it and/or modify | |
9 | it under the terms of the GNU General Public License as published by | |
10 | the Free Software Foundation; either version 2, or (at your option) | |
11 | any later version. | |
12 | ||
13 | This program is distributed in the hope that it will be useful, | |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | GNU General Public License for more details. | |
17 | ||
18 | You should have received a copy of the GNU General Public License | |
beda758b AD |
19 | along with this program; if not, write to the Free Software Foundation, |
20 | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | |
21 | ||
22 | /* A generic hash table package. */ | |
23 | ||
24 | /* Define USE_OBSTACK to 1 if you want the allocator to use obstacks instead | |
25 | of malloc. If you change USE_OBSTACK, you have to recompile! */ | |
26 | ||
27 | #if HAVE_CONFIG_H | |
28 | # include <config.h> | |
29 | #endif | |
30 | #if HAVE_STDLIB_H | |
31 | # include <stdlib.h> | |
32 | #endif | |
1029ea6d | 33 | |
e9665d16 | 34 | #include <limits.h> |
f61aad93 | 35 | #include <stdbool.h> |
68bd3b6b | 36 | #include <stdio.h> |
beda758b AD |
37 | |
38 | #ifndef HAVE_DECL_FREE | |
eb956856 | 39 | "this configure-time declaration test was not run" |
beda758b AD |
40 | #endif |
41 | #if !HAVE_DECL_FREE | |
42 | void free (); | |
43 | #endif | |
44 | ||
45 | #ifndef HAVE_DECL_MALLOC | |
eb956856 | 46 | "this configure-time declaration test was not run" |
beda758b AD |
47 | #endif |
48 | #if !HAVE_DECL_MALLOC | |
49 | char *malloc (); | |
50 | #endif | |
51 | ||
52 | #if USE_OBSTACK | |
53 | # include "obstack.h" | |
54 | # ifndef obstack_chunk_alloc | |
55 | # define obstack_chunk_alloc malloc | |
56 | # endif | |
57 | # ifndef obstack_chunk_free | |
58 | # define obstack_chunk_free free | |
59 | # endif | |
60 | #endif | |
61 | ||
68bd3b6b | 62 | #include "hash.h" |
68bd3b6b | 63 | |
eb956856 PE |
64 | struct hash_table |
65 | { | |
66 | /* The array of buckets starts at BUCKET and extends to BUCKET_LIMIT-1, | |
67 | for a possibility of N_BUCKETS. Among those, N_BUCKETS_USED buckets | |
68 | are not empty, there are N_ENTRIES active entries in the table. */ | |
69 | struct hash_entry *bucket; | |
70 | struct hash_entry *bucket_limit; | |
71 | unsigned n_buckets; | |
72 | unsigned n_buckets_used; | |
73 | unsigned n_entries; | |
74 | ||
75 | /* Tuning arguments, kept in a physicaly separate structure. */ | |
76 | const Hash_tuning *tuning; | |
77 | ||
78 | /* Three functions are given to `hash_initialize', see the documentation | |
79 | block for this function. In a word, HASHER randomizes a user entry | |
80 | into a number up from 0 up to some maximum minus 1; COMPARATOR returns | |
81 | true if two user entries compare equally; and DATA_FREER is the cleanup | |
82 | function for a user entry. */ | |
83 | Hash_hasher hasher; | |
84 | Hash_comparator comparator; | |
85 | Hash_data_freer data_freer; | |
86 | ||
87 | /* A linked list of freed struct hash_entry structs. */ | |
88 | struct hash_entry *free_entry_list; | |
89 | ||
90 | #if USE_OBSTACK | |
91 | /* Whenever obstacks are used, it is possible to allocate all overflowed | |
92 | entries into a single stack, so they all can be freed in a single | |
93 | operation. It is not clear if the speedup is worth the trouble. */ | |
94 | struct obstack entry_stack; | |
95 | #endif | |
96 | }; | |
97 | ||
beda758b AD |
98 | /* A hash table contains many internal entries, each holding a pointer to |
99 | some user provided data (also called a user entry). An entry indistinctly | |
100 | refers to both the internal entry and its associated user entry. A user | |
101 | entry contents may be hashed by a randomization function (the hashing | |
102 | function, or just `hasher' for short) into a number (or `slot') between 0 | |
103 | and the current table size. At each slot position in the hash table, | |
104 | starts a linked chain of entries for which the user data all hash to this | |
105 | slot. A bucket is the collection of all entries hashing to the same slot. | |
106 | ||
107 | A good `hasher' function will distribute entries rather evenly in buckets. | |
108 | In the ideal case, the length of each bucket is roughly the number of | |
109 | entries divided by the table size. Finding the slot for a data is usually | |
110 | done in constant time by the `hasher', and the later finding of a precise | |
111 | entry is linear in time with the size of the bucket. Consequently, a | |
112 | larger hash table size (that is, a larger number of buckets) is prone to | |
113 | yielding shorter chains, *given* the `hasher' function behaves properly. | |
114 | ||
115 | Long buckets slow down the lookup algorithm. One might use big hash table | |
116 | sizes in hope to reduce the average length of buckets, but this might | |
117 | become inordinate, as unused slots in the hash table take some space. The | |
118 | best bet is to make sure you are using a good `hasher' function (beware | |
119 | that those are not that easy to write! :-), and to use a table size | |
120 | larger than the actual number of entries. */ | |
121 | ||
122 | /* If an insertion makes the ratio of nonempty buckets to table size larger | |
123 | than the growth threshold (a number between 0.0 and 1.0), then increase | |
124 | the table size by multiplying by the growth factor (a number greater than | |
125 | 1.0). The growth threshold defaults to 0.8, and the growth factor | |
126 | defaults to 1.414, meaning that the table will have doubled its size | |
127 | every second time 80% of the buckets get used. */ | |
128 | #define DEFAULT_GROWTH_THRESHOLD 0.8 | |
129 | #define DEFAULT_GROWTH_FACTOR 1.414 | |
130 | ||
131 | /* If a deletion empties a bucket and causes the ratio of used buckets to | |
132 | table size to become smaller than the shrink threshold (a number between | |
133 | 0.0 and 1.0), then shrink the table by multiplying by the shrink factor (a | |
134 | number greater than the shrink threshold but smaller than 1.0). The shrink | |
135 | threshold and factor default to 0.0 and 1.0, meaning that the table never | |
136 | shrinks. */ | |
137 | #define DEFAULT_SHRINK_THRESHOLD 0.0 | |
138 | #define DEFAULT_SHRINK_FACTOR 1.0 | |
139 | ||
140 | /* Use this to initialize or reset a TUNING structure to | |
141 | some sensible values. */ | |
142 | static const Hash_tuning default_tuning = | |
143 | { | |
144 | DEFAULT_SHRINK_THRESHOLD, | |
145 | DEFAULT_SHRINK_FACTOR, | |
146 | DEFAULT_GROWTH_THRESHOLD, | |
147 | DEFAULT_GROWTH_FACTOR, | |
148 | false | |
149 | }; | |
150 | ||
151 | /* Information and lookup. */ | |
152 | ||
153 | /* The following few functions provide information about the overall hash | |
154 | table organization: the number of entries, number of buckets and maximum | |
155 | length of buckets. */ | |
156 | ||
157 | /* Return the number of buckets in the hash table. The table size, the total | |
158 | number of buckets (used plus unused), or the maximum number of slots, are | |
159 | the same quantity. */ | |
160 | ||
161 | unsigned | |
162 | hash_get_n_buckets (const Hash_table *table) | |
163 | { | |
164 | return table->n_buckets; | |
165 | } | |
68bd3b6b | 166 | |
beda758b | 167 | /* Return the number of slots in use (non-empty buckets). */ |
68bd3b6b | 168 | |
beda758b AD |
169 | unsigned |
170 | hash_get_n_buckets_used (const Hash_table *table) | |
171 | { | |
172 | return table->n_buckets_used; | |
173 | } | |
68bd3b6b | 174 | |
beda758b | 175 | /* Return the number of active entries. */ |
68bd3b6b | 176 | |
beda758b AD |
177 | unsigned |
178 | hash_get_n_entries (const Hash_table *table) | |
68bd3b6b | 179 | { |
beda758b | 180 | return table->n_entries; |
68bd3b6b RA |
181 | } |
182 | ||
beda758b | 183 | /* Return the length of the longest chain (bucket). */ |
68bd3b6b | 184 | |
beda758b AD |
185 | unsigned |
186 | hash_get_max_bucket_length (const Hash_table *table) | |
68bd3b6b | 187 | { |
beda758b AD |
188 | struct hash_entry *bucket; |
189 | unsigned max_bucket_length = 0; | |
190 | ||
191 | for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) | |
68bd3b6b | 192 | { |
beda758b AD |
193 | if (bucket->data) |
194 | { | |
195 | struct hash_entry *cursor = bucket; | |
196 | unsigned bucket_length = 1; | |
197 | ||
198 | while (cursor = cursor->next, cursor) | |
199 | bucket_length++; | |
200 | ||
201 | if (bucket_length > max_bucket_length) | |
202 | max_bucket_length = bucket_length; | |
203 | } | |
68bd3b6b | 204 | } |
beda758b AD |
205 | |
206 | return max_bucket_length; | |
68bd3b6b RA |
207 | } |
208 | ||
beda758b AD |
209 | /* Do a mild validation of a hash table, by traversing it and checking two |
210 | statistics. */ | |
68bd3b6b | 211 | |
beda758b AD |
212 | bool |
213 | hash_table_ok (const Hash_table *table) | |
68bd3b6b | 214 | { |
beda758b AD |
215 | struct hash_entry *bucket; |
216 | unsigned n_buckets_used = 0; | |
217 | unsigned n_entries = 0; | |
68bd3b6b | 218 | |
beda758b | 219 | for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) |
68bd3b6b | 220 | { |
beda758b | 221 | if (bucket->data) |
68bd3b6b | 222 | { |
beda758b AD |
223 | struct hash_entry *cursor = bucket; |
224 | ||
225 | /* Count bucket head. */ | |
226 | n_buckets_used++; | |
227 | n_entries++; | |
228 | ||
229 | /* Count bucket overflow. */ | |
230 | while (cursor = cursor->next, cursor) | |
231 | n_entries++; | |
68bd3b6b | 232 | } |
68bd3b6b | 233 | } |
beda758b AD |
234 | |
235 | if (n_buckets_used == table->n_buckets_used && n_entries == table->n_entries) | |
236 | return true; | |
237 | ||
238 | return false; | |
239 | } | |
240 | ||
241 | void | |
242 | hash_print_statistics (const Hash_table *table, FILE *stream) | |
243 | { | |
244 | unsigned n_entries = hash_get_n_entries (table); | |
245 | unsigned n_buckets = hash_get_n_buckets (table); | |
246 | unsigned n_buckets_used = hash_get_n_buckets_used (table); | |
247 | unsigned max_bucket_length = hash_get_max_bucket_length (table); | |
248 | ||
249 | fprintf (stream, "# entries: %u\n", n_entries); | |
250 | fprintf (stream, "# buckets: %u\n", n_buckets); | |
251 | fprintf (stream, "# buckets used: %u (%.2f%%)\n", n_buckets_used, | |
252 | (100.0 * n_buckets_used) / n_buckets); | |
253 | fprintf (stream, "max bucket length: %u\n", max_bucket_length); | |
68bd3b6b RA |
254 | } |
255 | ||
beda758b AD |
256 | /* If ENTRY matches an entry already in the hash table, return the |
257 | entry from the table. Otherwise, return NULL. */ | |
258 | ||
68bd3b6b | 259 | void * |
beda758b | 260 | hash_lookup (const Hash_table *table, const void *entry) |
68bd3b6b | 261 | { |
beda758b AD |
262 | struct hash_entry *bucket |
263 | = table->bucket + table->hasher (entry, table->n_buckets); | |
264 | struct hash_entry *cursor; | |
265 | ||
4f395381 | 266 | if (! (bucket < table->bucket_limit)) |
937fd864 | 267 | abort (); |
beda758b AD |
268 | |
269 | if (bucket->data == NULL) | |
270 | return NULL; | |
271 | ||
272 | for (cursor = bucket; cursor; cursor = cursor->next) | |
273 | if (table->comparator (entry, cursor->data)) | |
274 | return cursor->data; | |
275 | ||
276 | return NULL; | |
68bd3b6b RA |
277 | } |
278 | ||
beda758b AD |
279 | /* Walking. */ |
280 | ||
281 | /* The functions in this page traverse the hash table and process the | |
282 | contained entries. For the traversal to work properly, the hash table | |
283 | should not be resized nor modified while any particular entry is being | |
284 | processed. In particular, entries should not be added or removed. */ | |
285 | ||
286 | /* Return the first data in the table, or NULL if the table is empty. */ | |
287 | ||
288 | void * | |
289 | hash_get_first (const Hash_table *table) | |
68bd3b6b | 290 | { |
beda758b AD |
291 | struct hash_entry *bucket; |
292 | ||
293 | if (table->n_entries == 0) | |
294 | return NULL; | |
295 | ||
937fd864 | 296 | for (bucket = table->bucket; ; bucket++) |
4f395381 | 297 | if (! (bucket < table->bucket_limit)) |
937fd864 PE |
298 | abort (); |
299 | else if (bucket->data) | |
beda758b | 300 | return bucket->data; |
68bd3b6b RA |
301 | } |
302 | ||
beda758b AD |
303 | /* Return the user data for the entry following ENTRY, where ENTRY has been |
304 | returned by a previous call to either `hash_get_first' or `hash_get_next'. | |
305 | Return NULL if there are no more entries. */ | |
306 | ||
307 | void * | |
308 | hash_get_next (const Hash_table *table, const void *entry) | |
309 | { | |
310 | struct hash_entry *bucket | |
311 | = table->bucket + table->hasher (entry, table->n_buckets); | |
312 | struct hash_entry *cursor; | |
313 | ||
4f395381 | 314 | if (! (bucket < table->bucket_limit)) |
937fd864 | 315 | abort (); |
beda758b AD |
316 | |
317 | /* Find next entry in the same bucket. */ | |
318 | for (cursor = bucket; cursor; cursor = cursor->next) | |
319 | if (cursor->data == entry && cursor->next) | |
320 | return cursor->next->data; | |
321 | ||
322 | /* Find first entry in any subsequent bucket. */ | |
323 | while (++bucket < table->bucket_limit) | |
324 | if (bucket->data) | |
325 | return bucket->data; | |
326 | ||
327 | /* None found. */ | |
328 | return NULL; | |
329 | } | |
330 | ||
331 | /* Fill BUFFER with pointers to active user entries in the hash table, then | |
332 | return the number of pointers copied. Do not copy more than BUFFER_SIZE | |
333 | pointers. */ | |
334 | ||
335 | unsigned | |
336 | hash_get_entries (const Hash_table *table, void **buffer, | |
337 | unsigned buffer_size) | |
68bd3b6b | 338 | { |
beda758b AD |
339 | unsigned counter = 0; |
340 | struct hash_entry *bucket; | |
341 | struct hash_entry *cursor; | |
342 | ||
343 | for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) | |
68bd3b6b | 344 | { |
beda758b AD |
345 | if (bucket->data) |
346 | { | |
347 | for (cursor = bucket; cursor; cursor = cursor->next) | |
348 | { | |
349 | if (counter >= buffer_size) | |
350 | return counter; | |
351 | buffer[counter++] = cursor->data; | |
352 | } | |
353 | } | |
68bd3b6b | 354 | } |
beda758b AD |
355 | |
356 | return counter; | |
68bd3b6b RA |
357 | } |
358 | ||
beda758b AD |
359 | /* Call a PROCESSOR function for each entry of a hash table, and return the |
360 | number of entries for which the processor function returned success. A | |
361 | pointer to some PROCESSOR_DATA which will be made available to each call to | |
362 | the processor function. The PROCESSOR accepts two arguments: the first is | |
363 | the user entry being walked into, the second is the value of PROCESSOR_DATA | |
364 | as received. The walking continue for as long as the PROCESSOR function | |
365 | returns nonzero. When it returns zero, the walking is interrupted. */ | |
366 | ||
367 | unsigned | |
368 | hash_do_for_each (const Hash_table *table, Hash_processor processor, | |
369 | void *processor_data) | |
68bd3b6b | 370 | { |
beda758b AD |
371 | unsigned counter = 0; |
372 | struct hash_entry *bucket; | |
373 | struct hash_entry *cursor; | |
374 | ||
375 | for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) | |
376 | { | |
377 | if (bucket->data) | |
378 | { | |
379 | for (cursor = bucket; cursor; cursor = cursor->next) | |
380 | { | |
381 | if (!(*processor) (cursor->data, processor_data)) | |
382 | return counter; | |
383 | counter++; | |
384 | } | |
385 | } | |
386 | } | |
387 | ||
388 | return counter; | |
68bd3b6b RA |
389 | } |
390 | ||
beda758b AD |
391 | /* Allocation and clean-up. */ |
392 | ||
393 | /* Return a hash index for a NUL-terminated STRING between 0 and N_BUCKETS-1. | |
394 | This is a convenience routine for constructing other hashing functions. */ | |
395 | ||
396 | #if USE_DIFF_HASH | |
397 | ||
398 | /* About hashings, Paul Eggert writes to me (FP), on 1994-01-01: "Please see | |
399 | B. J. McKenzie, R. Harries & T. Bell, Selecting a hashing algorithm, | |
400 | Software--practice & experience 20, 2 (Feb 1990), 209-224. Good hash | |
401 | algorithms tend to be domain-specific, so what's good for [diffutils'] io.c | |
402 | may not be good for your application." */ | |
403 | ||
404 | unsigned | |
405 | hash_string (const char *string, unsigned n_buckets) | |
68bd3b6b | 406 | { |
beda758b AD |
407 | # define ROTATE_LEFT(Value, Shift) \ |
408 | ((Value) << (Shift) | (Value) >> ((sizeof (unsigned) * CHAR_BIT) - (Shift))) | |
409 | # define HASH_ONE_CHAR(Value, Byte) \ | |
410 | ((Byte) + ROTATE_LEFT (Value, 7)) | |
411 | ||
412 | unsigned value = 0; | |
413 | ||
414 | for (; *string; string++) | |
415 | value = HASH_ONE_CHAR (value, *(const unsigned char *) string); | |
416 | return value % n_buckets; | |
417 | ||
418 | # undef ROTATE_LEFT | |
419 | # undef HASH_ONE_CHAR | |
420 | } | |
421 | ||
422 | #else /* not USE_DIFF_HASH */ | |
423 | ||
424 | /* This one comes from `recode', and performs a bit better than the above as | |
425 | per a few experiments. It is inspired from a hashing routine found in the | |
426 | very old Cyber `snoop', itself written in typical Greg Mansfield style. | |
427 | (By the way, what happened to this excellent man? Is he still alive?) */ | |
428 | ||
429 | unsigned | |
430 | hash_string (const char *string, unsigned n_buckets) | |
431 | { | |
432 | unsigned value = 0; | |
433 | ||
434 | while (*string) | |
435 | value = ((value * 31 + (int) *(const unsigned char *) string++) | |
436 | % n_buckets); | |
437 | return value; | |
438 | } | |
439 | ||
440 | #endif /* not USE_DIFF_HASH */ | |
441 | ||
442 | /* Return true if CANDIDATE is a prime number. CANDIDATE should be an odd | |
443 | number at least equal to 11. */ | |
444 | ||
445 | static bool | |
446 | is_prime (unsigned long candidate) | |
447 | { | |
448 | unsigned long divisor = 3; | |
449 | unsigned long square = divisor * divisor; | |
450 | ||
451 | while (square < candidate && (candidate % divisor)) | |
68bd3b6b | 452 | { |
beda758b AD |
453 | divisor++; |
454 | square += 4 * divisor; | |
455 | divisor++; | |
68bd3b6b | 456 | } |
beda758b AD |
457 | |
458 | return (candidate % divisor ? true : false); | |
459 | } | |
460 | ||
461 | /* Round a given CANDIDATE number up to the nearest prime, and return that | |
462 | prime. Primes lower than 10 are merely skipped. */ | |
463 | ||
464 | static unsigned long | |
465 | next_prime (unsigned long candidate) | |
466 | { | |
467 | /* Skip small primes. */ | |
468 | if (candidate < 10) | |
469 | candidate = 10; | |
470 | ||
471 | /* Make it definitely odd. */ | |
472 | candidate |= 1; | |
473 | ||
474 | while (!is_prime (candidate)) | |
475 | candidate += 2; | |
476 | ||
477 | return candidate; | |
68bd3b6b RA |
478 | } |
479 | ||
480 | void | |
beda758b AD |
481 | hash_reset_tuning (Hash_tuning *tuning) |
482 | { | |
483 | *tuning = default_tuning; | |
484 | } | |
485 | ||
486 | /* For the given hash TABLE, check the user supplied tuning structure for | |
487 | reasonable values, and return true if there is no gross error with it. | |
488 | Otherwise, definitively reset the TUNING field to some acceptable default | |
489 | in the hash table (that is, the user loses the right of further modifying | |
490 | tuning arguments), and return false. */ | |
491 | ||
492 | static bool | |
493 | check_tuning (Hash_table *table) | |
68bd3b6b | 494 | { |
beda758b AD |
495 | const Hash_tuning *tuning = table->tuning; |
496 | ||
497 | if (tuning->growth_threshold > 0.0 | |
498 | && tuning->growth_threshold < 1.0 | |
499 | && tuning->growth_factor > 1.0 | |
500 | && tuning->shrink_threshold >= 0.0 | |
501 | && tuning->shrink_threshold < 1.0 | |
502 | && tuning->shrink_factor > tuning->shrink_threshold | |
503 | && tuning->shrink_factor <= 1.0 | |
504 | && tuning->shrink_threshold < tuning->growth_threshold) | |
505 | return true; | |
506 | ||
507 | table->tuning = &default_tuning; | |
508 | return false; | |
509 | } | |
510 | ||
511 | /* Allocate and return a new hash table, or NULL upon failure. The initial | |
512 | number of buckets is automatically selected so as to _guarantee_ that you | |
513 | may insert at least CANDIDATE different user entries before any growth of | |
514 | the hash table size occurs. So, if have a reasonably tight a-priori upper | |
515 | bound on the number of entries you intend to insert in the hash table, you | |
516 | may save some table memory and insertion time, by specifying it here. If | |
517 | the IS_N_BUCKETS field of the TUNING structure is true, the CANDIDATE | |
518 | argument has its meaning changed to the wanted number of buckets. | |
519 | ||
520 | TUNING points to a structure of user-supplied values, in case some fine | |
521 | tuning is wanted over the default behavior of the hasher. If TUNING is | |
522 | NULL, the default tuning parameters are used instead. | |
523 | ||
524 | The user-supplied HASHER function should be provided. It accepts two | |
525 | arguments ENTRY and TABLE_SIZE. It computes, by hashing ENTRY contents, a | |
526 | slot number for that entry which should be in the range 0..TABLE_SIZE-1. | |
527 | This slot number is then returned. | |
528 | ||
529 | The user-supplied COMPARATOR function should be provided. It accepts two | |
530 | arguments pointing to user data, it then returns true for a pair of entries | |
531 | that compare equal, or false otherwise. This function is internally called | |
532 | on entries which are already known to hash to the same bucket index. | |
533 | ||
534 | The user-supplied DATA_FREER function, when not NULL, may be later called | |
535 | with the user data as an argument, just before the entry containing the | |
536 | data gets freed. This happens from within `hash_free' or `hash_clear'. | |
537 | You should specify this function only if you want these functions to free | |
538 | all of your `data' data. This is typically the case when your data is | |
539 | simply an auxiliary struct that you have malloc'd to aggregate several | |
540 | values. */ | |
541 | ||
542 | Hash_table * | |
543 | hash_initialize (unsigned candidate, const Hash_tuning *tuning, | |
544 | Hash_hasher hasher, Hash_comparator comparator, | |
545 | Hash_data_freer data_freer) | |
546 | { | |
547 | Hash_table *table; | |
548 | struct hash_entry *bucket; | |
549 | ||
550 | if (hasher == NULL || comparator == NULL) | |
551 | return NULL; | |
552 | ||
553 | table = (Hash_table *) malloc (sizeof (Hash_table)); | |
554 | if (table == NULL) | |
555 | return NULL; | |
556 | ||
557 | if (!tuning) | |
558 | tuning = &default_tuning; | |
559 | table->tuning = tuning; | |
560 | if (!check_tuning (table)) | |
68bd3b6b | 561 | { |
beda758b AD |
562 | /* Fail if the tuning options are invalid. This is the only occasion |
563 | when the user gets some feedback about it. Once the table is created, | |
564 | if the user provides invalid tuning options, we silently revert to | |
565 | using the defaults, and ignore further request to change the tuning | |
566 | options. */ | |
567 | free (table); | |
568 | return NULL; | |
68bd3b6b | 569 | } |
beda758b AD |
570 | |
571 | table->n_buckets | |
572 | = next_prime (tuning->is_n_buckets ? candidate | |
573 | : (unsigned) (candidate / tuning->growth_threshold)); | |
574 | ||
575 | table->bucket = (struct hash_entry *) | |
576 | malloc (table->n_buckets * sizeof (struct hash_entry)); | |
577 | if (table->bucket == NULL) | |
578 | { | |
579 | free (table); | |
580 | return NULL; | |
581 | } | |
582 | table->bucket_limit = table->bucket + table->n_buckets; | |
583 | ||
584 | for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) | |
585 | { | |
586 | bucket->data = NULL; | |
587 | bucket->next = NULL; | |
588 | } | |
589 | table->n_buckets_used = 0; | |
590 | table->n_entries = 0; | |
591 | ||
592 | table->hasher = hasher; | |
593 | table->comparator = comparator; | |
594 | table->data_freer = data_freer; | |
595 | ||
596 | table->free_entry_list = NULL; | |
597 | #if USE_OBSTACK | |
598 | obstack_init (&table->entry_stack); | |
599 | #endif | |
600 | return table; | |
68bd3b6b RA |
601 | } |
602 | ||
beda758b AD |
603 | /* Make all buckets empty, placing any chained entries on the free list. |
604 | Apply the user-specified function data_freer (if any) to the datas of any | |
605 | affected entries. */ | |
606 | ||
68bd3b6b | 607 | void |
beda758b | 608 | hash_clear (Hash_table *table) |
68bd3b6b | 609 | { |
beda758b | 610 | struct hash_entry *bucket; |
beda758b AD |
611 | |
612 | for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) | |
613 | { | |
614 | if (bucket->data) | |
615 | { | |
eb956856 PE |
616 | struct hash_entry *cursor; |
617 | struct hash_entry *next; | |
618 | ||
beda758b | 619 | /* Free the bucket overflow. */ |
eb956856 | 620 | for (cursor = bucket->next; cursor; cursor = next) |
beda758b AD |
621 | { |
622 | if (table->data_freer) | |
623 | (*table->data_freer) (cursor->data); | |
624 | cursor->data = NULL; | |
625 | ||
eb956856 | 626 | next = cursor->next; |
beda758b AD |
627 | /* Relinking is done one entry at a time, as it is to be expected |
628 | that overflows are either rare or short. */ | |
629 | cursor->next = table->free_entry_list; | |
630 | table->free_entry_list = cursor; | |
631 | } | |
632 | ||
633 | /* Free the bucket head. */ | |
634 | if (table->data_freer) | |
635 | (*table->data_freer) (bucket->data); | |
636 | bucket->data = NULL; | |
637 | bucket->next = NULL; | |
638 | } | |
639 | } | |
640 | ||
641 | table->n_buckets_used = 0; | |
642 | table->n_entries = 0; | |
68bd3b6b RA |
643 | } |
644 | ||
beda758b AD |
645 | /* Reclaim all storage associated with a hash table. If a data_freer |
646 | function has been supplied by the user when the hash table was created, | |
647 | this function applies it to the data of each entry before freeing that | |
648 | entry. */ | |
649 | ||
68bd3b6b | 650 | void |
beda758b | 651 | hash_free (Hash_table *table) |
68bd3b6b | 652 | { |
beda758b AD |
653 | struct hash_entry *bucket; |
654 | struct hash_entry *cursor; | |
655 | struct hash_entry *next; | |
656 | ||
657 | /* Call the user data_freer function. */ | |
658 | if (table->data_freer && table->n_entries) | |
659 | { | |
660 | for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) | |
661 | { | |
662 | if (bucket->data) | |
663 | { | |
664 | for (cursor = bucket; cursor; cursor = cursor->next) | |
665 | { | |
666 | (*table->data_freer) (cursor->data); | |
667 | } | |
668 | } | |
669 | } | |
670 | } | |
671 | ||
672 | #if USE_OBSTACK | |
673 | ||
674 | obstack_free (&table->entry_stack, NULL); | |
675 | ||
676 | #else | |
677 | ||
678 | /* Free all bucket overflowed entries. */ | |
679 | for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) | |
680 | { | |
681 | for (cursor = bucket->next; cursor; cursor = next) | |
682 | { | |
683 | next = cursor->next; | |
684 | free (cursor); | |
685 | } | |
686 | } | |
687 | ||
688 | /* Also reclaim the internal list of previously freed entries. */ | |
689 | for (cursor = table->free_entry_list; cursor; cursor = next) | |
690 | { | |
691 | next = cursor->next; | |
692 | free (cursor); | |
693 | } | |
694 | ||
695 | #endif | |
696 | ||
697 | /* Free the remainder of the hash table structure. */ | |
698 | free (table->bucket); | |
699 | free (table); | |
68bd3b6b RA |
700 | } |
701 | ||
beda758b AD |
702 | /* Insertion and deletion. */ |
703 | ||
704 | /* Get a new hash entry for a bucket overflow, possibly by reclying a | |
705 | previously freed one. If this is not possible, allocate a new one. */ | |
706 | ||
707 | static struct hash_entry * | |
708 | allocate_entry (Hash_table *table) | |
68bd3b6b | 709 | { |
beda758b | 710 | struct hash_entry *new; |
68bd3b6b | 711 | |
beda758b AD |
712 | if (table->free_entry_list) |
713 | { | |
714 | new = table->free_entry_list; | |
715 | table->free_entry_list = new->next; | |
716 | } | |
717 | else | |
68bd3b6b | 718 | { |
beda758b AD |
719 | #if USE_OBSTACK |
720 | new = (struct hash_entry *) | |
721 | obstack_alloc (&table->entry_stack, sizeof (struct hash_entry)); | |
722 | #else | |
723 | new = (struct hash_entry *) malloc (sizeof (struct hash_entry)); | |
724 | #endif | |
68bd3b6b | 725 | } |
beda758b AD |
726 | |
727 | return new; | |
68bd3b6b RA |
728 | } |
729 | ||
beda758b AD |
730 | /* Free a hash entry which was part of some bucket overflow, |
731 | saving it for later recycling. */ | |
68bd3b6b RA |
732 | |
733 | static void | |
beda758b AD |
734 | free_entry (Hash_table *table, struct hash_entry *entry) |
735 | { | |
736 | entry->data = NULL; | |
737 | entry->next = table->free_entry_list; | |
738 | table->free_entry_list = entry; | |
739 | } | |
740 | ||
741 | /* This private function is used to help with insertion and deletion. When | |
742 | ENTRY matches an entry in the table, return a pointer to the corresponding | |
743 | user data and set *BUCKET_HEAD to the head of the selected bucket. | |
744 | Otherwise, return NULL. When DELETE is true and ENTRY matches an entry in | |
745 | the table, unlink the matching entry. */ | |
746 | ||
747 | static void * | |
748 | hash_find_entry (Hash_table *table, const void *entry, | |
749 | struct hash_entry **bucket_head, bool delete) | |
68bd3b6b | 750 | { |
beda758b AD |
751 | struct hash_entry *bucket |
752 | = table->bucket + table->hasher (entry, table->n_buckets); | |
753 | struct hash_entry *cursor; | |
754 | ||
4f395381 | 755 | if (! (bucket < table->bucket_limit)) |
937fd864 PE |
756 | abort (); |
757 | ||
beda758b AD |
758 | *bucket_head = bucket; |
759 | ||
760 | /* Test for empty bucket. */ | |
761 | if (bucket->data == NULL) | |
762 | return NULL; | |
763 | ||
764 | /* See if the entry is the first in the bucket. */ | |
765 | if ((*table->comparator) (entry, bucket->data)) | |
766 | { | |
767 | void *data = bucket->data; | |
768 | ||
769 | if (delete) | |
770 | { | |
771 | if (bucket->next) | |
772 | { | |
773 | struct hash_entry *next = bucket->next; | |
774 | ||
775 | /* Bump the first overflow entry into the bucket head, then save | |
776 | the previous first overflow entry for later recycling. */ | |
777 | *bucket = *next; | |
778 | free_entry (table, next); | |
779 | } | |
780 | else | |
781 | { | |
782 | bucket->data = NULL; | |
783 | } | |
784 | } | |
68bd3b6b | 785 | |
beda758b AD |
786 | return data; |
787 | } | |
68bd3b6b | 788 | |
beda758b AD |
789 | /* Scan the bucket overflow. */ |
790 | for (cursor = bucket; cursor->next; cursor = cursor->next) | |
68bd3b6b | 791 | { |
beda758b AD |
792 | if ((*table->comparator) (entry, cursor->next->data)) |
793 | { | |
794 | void *data = cursor->next->data; | |
795 | ||
796 | if (delete) | |
797 | { | |
798 | struct hash_entry *next = cursor->next; | |
799 | ||
800 | /* Unlink the entry to delete, then save the freed entry for later | |
801 | recycling. */ | |
802 | cursor->next = next->next; | |
803 | free_entry (table, next); | |
804 | } | |
805 | ||
806 | return data; | |
807 | } | |
68bd3b6b | 808 | } |
beda758b AD |
809 | |
810 | /* No entry found. */ | |
811 | return NULL; | |
68bd3b6b RA |
812 | } |
813 | ||
beda758b AD |
814 | /* For an already existing hash table, change the number of buckets through |
815 | specifying CANDIDATE. The contents of the hash table are preserved. The | |
816 | new number of buckets is automatically selected so as to _guarantee_ that | |
817 | the table may receive at least CANDIDATE different user entries, including | |
818 | those already in the table, before any other growth of the hash table size | |
819 | occurs. If TUNING->IS_N_BUCKETS is true, then CANDIDATE specifies the | |
820 | exact number of buckets desired. */ | |
821 | ||
822 | bool | |
823 | hash_rehash (Hash_table *table, unsigned candidate) | |
68bd3b6b | 824 | { |
beda758b AD |
825 | Hash_table *new_table; |
826 | struct hash_entry *bucket; | |
827 | struct hash_entry *cursor; | |
828 | struct hash_entry *next; | |
829 | ||
830 | new_table = hash_initialize (candidate, table->tuning, table->hasher, | |
831 | table->comparator, table->data_freer); | |
832 | if (new_table == NULL) | |
833 | return false; | |
834 | ||
835 | /* Merely reuse the extra old space into the new table. */ | |
836 | #if USE_OBSTACK | |
837 | obstack_free (&new_table->entry_stack, NULL); | |
838 | new_table->entry_stack = table->entry_stack; | |
839 | #endif | |
840 | new_table->free_entry_list = table->free_entry_list; | |
841 | ||
842 | for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) | |
843 | if (bucket->data) | |
844 | for (cursor = bucket; cursor; cursor = next) | |
845 | { | |
846 | void *data = cursor->data; | |
847 | struct hash_entry *new_bucket | |
848 | = (new_table->bucket | |
849 | + new_table->hasher (data, new_table->n_buckets)); | |
850 | ||
4f395381 | 851 | if (! (new_bucket < new_table->bucket_limit)) |
937fd864 PE |
852 | abort (); |
853 | ||
beda758b AD |
854 | next = cursor->next; |
855 | ||
856 | if (new_bucket->data) | |
857 | { | |
858 | if (cursor == bucket) | |
859 | { | |
860 | /* Allocate or recycle an entry, when moving from a bucket | |
861 | header into a bucket overflow. */ | |
862 | struct hash_entry *new_entry = allocate_entry (new_table); | |
863 | ||
864 | if (new_entry == NULL) | |
865 | return false; | |
866 | ||
867 | new_entry->data = data; | |
868 | new_entry->next = new_bucket->next; | |
869 | new_bucket->next = new_entry; | |
870 | } | |
871 | else | |
872 | { | |
873 | /* Merely relink an existing entry, when moving from a | |
874 | bucket overflow into a bucket overflow. */ | |
875 | cursor->next = new_bucket->next; | |
876 | new_bucket->next = cursor; | |
877 | } | |
878 | } | |
879 | else | |
880 | { | |
881 | /* Free an existing entry, when moving from a bucket | |
882 | overflow into a bucket header. Also take care of the | |
883 | simple case of moving from a bucket header into a bucket | |
884 | header. */ | |
885 | new_bucket->data = data; | |
886 | new_table->n_buckets_used++; | |
887 | if (cursor != bucket) | |
888 | free_entry (new_table, cursor); | |
889 | } | |
890 | } | |
891 | ||
892 | free (table->bucket); | |
893 | table->bucket = new_table->bucket; | |
894 | table->bucket_limit = new_table->bucket_limit; | |
895 | table->n_buckets = new_table->n_buckets; | |
896 | table->n_buckets_used = new_table->n_buckets_used; | |
897 | table->free_entry_list = new_table->free_entry_list; | |
898 | /* table->n_entries already holds its value. */ | |
899 | #if USE_OBSTACK | |
900 | table->entry_stack = new_table->entry_stack; | |
901 | #endif | |
902 | free (new_table); | |
903 | ||
904 | return true; | |
68bd3b6b RA |
905 | } |
906 | ||
beda758b AD |
907 | /* If ENTRY matches an entry already in the hash table, return the pointer |
908 | to the entry from the table. Otherwise, insert ENTRY and return ENTRY. | |
909 | Return NULL if the storage required for insertion cannot be allocated. */ | |
68bd3b6b | 910 | |
beda758b AD |
911 | void * |
912 | hash_insert (Hash_table *table, const void *entry) | |
68bd3b6b | 913 | { |
beda758b AD |
914 | void *data; |
915 | struct hash_entry *bucket; | |
916 | ||
937fd864 PE |
917 | /* The caller cannot insert a NULL entry. */ |
918 | if (! entry) | |
919 | abort (); | |
beda758b AD |
920 | |
921 | /* If there's a matching entry already in the table, return that. */ | |
922 | if ((data = hash_find_entry (table, entry, &bucket, false)) != NULL) | |
923 | return data; | |
924 | ||
925 | /* ENTRY is not matched, it should be inserted. */ | |
926 | ||
927 | if (bucket->data) | |
928 | { | |
929 | struct hash_entry *new_entry = allocate_entry (table); | |
930 | ||
931 | if (new_entry == NULL) | |
932 | return NULL; | |
933 | ||
934 | /* Add ENTRY in the overflow of the bucket. */ | |
935 | ||
936 | new_entry->data = (void *) entry; | |
937 | new_entry->next = bucket->next; | |
938 | bucket->next = new_entry; | |
939 | table->n_entries++; | |
940 | return (void *) entry; | |
941 | } | |
942 | ||
943 | /* Add ENTRY right in the bucket head. */ | |
944 | ||
945 | bucket->data = (void *) entry; | |
946 | table->n_entries++; | |
947 | table->n_buckets_used++; | |
948 | ||
949 | /* If the growth threshold of the buckets in use has been reached, increase | |
950 | the table size and rehash. There's no point in checking the number of | |
951 | entries: if the hashing function is ill-conditioned, rehashing is not | |
952 | likely to improve it. */ | |
953 | ||
954 | if (table->n_buckets_used | |
955 | > table->tuning->growth_threshold * table->n_buckets) | |
956 | { | |
957 | /* Check more fully, before starting real work. If tuning arguments | |
958 | became invalid, the second check will rely on proper defaults. */ | |
959 | check_tuning (table); | |
960 | if (table->n_buckets_used | |
961 | > table->tuning->growth_threshold * table->n_buckets) | |
962 | { | |
963 | const Hash_tuning *tuning = table->tuning; | |
964 | unsigned candidate | |
965 | = (unsigned) (tuning->is_n_buckets | |
966 | ? (table->n_buckets * tuning->growth_factor) | |
967 | : (table->n_buckets * tuning->growth_factor | |
968 | * tuning->growth_threshold)); | |
969 | ||
970 | /* If the rehash fails, arrange to return NULL. */ | |
971 | if (!hash_rehash (table, candidate)) | |
972 | entry = NULL; | |
973 | } | |
974 | } | |
975 | ||
976 | return (void *) entry; | |
68bd3b6b RA |
977 | } |
978 | ||
beda758b AD |
979 | /* If ENTRY is already in the table, remove it and return the just-deleted |
980 | data (the user may want to deallocate its storage). If ENTRY is not in the | |
981 | table, don't modify the table and return NULL. */ | |
68bd3b6b | 982 | |
beda758b AD |
983 | void * |
984 | hash_delete (Hash_table *table, const void *entry) | |
985 | { | |
986 | void *data; | |
987 | struct hash_entry *bucket; | |
988 | ||
989 | data = hash_find_entry (table, entry, &bucket, true); | |
990 | if (!data) | |
991 | return NULL; | |
992 | ||
993 | table->n_entries--; | |
994 | if (!bucket->data) | |
995 | { | |
996 | table->n_buckets_used--; | |
997 | ||
998 | /* If the shrink threshold of the buckets in use has been reached, | |
999 | rehash into a smaller table. */ | |
1000 | ||
1001 | if (table->n_buckets_used | |
1002 | < table->tuning->shrink_threshold * table->n_buckets) | |
1003 | { | |
1004 | /* Check more fully, before starting real work. If tuning arguments | |
1005 | became invalid, the second check will rely on proper defaults. */ | |
1006 | check_tuning (table); | |
1007 | if (table->n_buckets_used | |
1008 | < table->tuning->shrink_threshold * table->n_buckets) | |
1009 | { | |
1010 | const Hash_tuning *tuning = table->tuning; | |
1011 | unsigned candidate | |
1012 | = (unsigned) (tuning->is_n_buckets | |
1013 | ? table->n_buckets * tuning->shrink_factor | |
1014 | : (table->n_buckets * tuning->shrink_factor | |
1015 | * tuning->growth_threshold)); | |
1016 | ||
1017 | hash_rehash (table, candidate); | |
1018 | } | |
1019 | } | |
1020 | } | |
1021 | ||
1022 | return data; | |
1023 | } | |
1024 | ||
1025 | /* Testing. */ | |
1026 | ||
1027 | #if TESTING | |
1028 | ||
1029 | void | |
1030 | hash_print (const Hash_table *table) | |
68bd3b6b | 1031 | { |
beda758b | 1032 | struct hash_entry *bucket; |
68bd3b6b | 1033 | |
beda758b | 1034 | for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) |
68bd3b6b | 1035 | { |
beda758b AD |
1036 | struct hash_entry *cursor; |
1037 | ||
1038 | if (bucket) | |
eb956856 | 1039 | printf ("%d:\n", bucket - table->bucket); |
beda758b AD |
1040 | |
1041 | for (cursor = bucket; cursor; cursor = cursor->next) | |
1042 | { | |
1043 | char *s = (char *) cursor->data; | |
1044 | /* FIXME */ | |
eb956856 PE |
1045 | if (s) |
1046 | printf (" %s\n", s); | |
beda758b | 1047 | } |
68bd3b6b | 1048 | } |
68bd3b6b | 1049 | } |
beda758b AD |
1050 | |
1051 | #endif /* TESTING */ |