]> sjero.net Git - wget/blob - src/hash.c
[svn] Undef xmalloc and friends before redefining them when standalone.
[wget] / src / hash.c
1 /* Hash tables.
2    Copyright (C) 2000 Free Software Foundation, Inc.
3
4 This file is part of Wget.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or (at
9 your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
19
20 #ifdef HAVE_CONFIG_H
21 # include <config.h>
22 #endif
23
24 #include <stdlib.h>
25 #include <assert.h>
26
27 #include "wget.h"
28 #include "utils.h"
29
30 #include "hash.h"
31
32 #ifdef STANDALONE
33 # undef xmalloc
34 # undef xrealloc
35 # undef xfree
36
37 # define xmalloc malloc
38 # define xrealloc realloc
39 # define xfree free
40 #endif
41
42 /* INTERFACE:
43
44    Hash tables are an implementation technique used to implement
45    mapping between objects.  Provided a good hashing function is used,
46    they guarantee constant-time access and storing of information.
47    Duplicate keys are not allowed.
48
49    The basics are all covered.  hash_table_new creates a hash table,
50    and hash_table_destroy deletes it.  hash_table_put establishes a
51    mapping between a key and a value.  hash_table_get retrieves the
52    value that corresponds to a key.  hash_table_exists queries whether
53    a key is stored in a table at all.  hash_table_remove removes a
54    mapping that corresponds to a key.  hash_table_map allows you to
55    map through all the entries in a hash table.  hash_table_clear
56    clears all the entries from the hash table.
57
58    The number of mappings in a table is not limited, except by the
59    amount of memory.  As you add new elements to a table, it regrows
60    as necessary.  If you have an idea about how many elements you will
61    store, you can provide a hint to hash_table_new().
62
63    The hashing and equality functions are normally provided by the
64    user.  For the special (and frequent) case of hashing strings, you
65    can use the pre-canned make_string_hash_table(), which provides the
66    string hashing function from the Dragon Book, and a string equality
67    wrapper around strcmp().
68
69    When specifying your own hash and test functions, make sure the
70    following holds true:
71
72    - The test function returns non-zero for keys that are considered
73      "equal", zero otherwise.
74
75    - The hash function returns a number that represents the
76      "distinctness" of the object.  In more precise terms, it means
77      that for any two objects that test "equal" under the test
78      function, the hash function MUST produce the same result.
79
80      This does not mean that each distinct object must produce a
81      distinct value, only that non-distinct objects must produce the
82      same values!  For instance, a hash function that returns 0 for
83      any given object is a perfectly valid (albeit extremely bad) hash
84      function.
85
86      The above stated rule is quite easy to enforce.  For example, if
87      your testing function compares strings case-insensitively, all
88      your function needs to do is lower-case the string characters
89      before calculating a hash.  That way you have easily guaranteed
90      that changes in case will not result in a different hash.
91
92    - (optional) Choose the hash function to get as good "spreading" as
93      possible.  A good hash function will react to even a small change
94      in its input with a completely different resulting hash.
95      Finally, don't make your hash function extremely slow, because
96      you're then defeating the purpose of hashing.
97
98    Note that neither keys nor values are copied when inserted into the
99    hash table, so they must exist for the lifetime of the table.  This
100    means that e.g. the use of static strings is OK, but objects with a
101    shorter life-time need to be copied (with strdup() or the like in
102    the case of strings) before being inserted.  */
103
104 /* IMPLEMENTATION:
105
106    All the hash mappings (key-value pairs of pointers) are stored in a
107    contiguous array.  The position of each mapping is determined by
108    applying the hash function to the key: location = hash(key) % size.
109    If two different keys end up on the same position, the collision is
110    resolved by placing the second mapping at the next empty place in
111    the array following the occupied place.  This method of collision
112    resolution is called "linear probing".
113
114    There are more advanced collision resolution mechanisms (quadratic
115    probing, double hashing), but we don't use them because they
116    involve more non-sequential access to the array, and therefore
117    worse cache behavior.  Linear probing works well as long as the
118    fullness/size ratio is kept below 75%.  We make sure to regrow or
119    rehash the hash table whenever this threshold is exceeded.
120
121    Collisions make deletion tricky because finding collisions again
122    relies on new empty spots not being created.  That's why
123    hash_table_remove only marks the spot as deleted rather than really
124    making it empty. */
125
126 struct mapping {
127   void *key;
128   void *value;
129 };
130
131 struct hash_table {
132   unsigned long (*hash_function) (const void *);
133   int (*test_function) (const void *, const void *);
134
135   int size;                     /* size of the array */
136   int fullness;                 /* number of non-empty fields */
137   int count;                    /* number of non-empty, non-deleted
138                                    fields. */
139
140   struct mapping *mappings;
141 };
142
143 #define ENTRY_DELETED ((void *)0xdeadbeef)
144 #define ENTRY_EMPTY   NULL
145
146 #define DELETED_ENTRY_P(ptr) ((ptr) == ENTRY_DELETED)
147 #define EMPTY_ENTRY_P(ptr)   ((ptr) == ENTRY_EMPTY)
148
149 /* Find a prime near, but greather than or equal to SIZE. */
150
151 int
152 prime_size (int size)
153 {
154   static const unsigned long primes [] = {
155     19, 29, 41, 59, 79, 107, 149, 197, 263, 347, 457, 599, 787, 1031,
156     1361, 1777, 2333, 3037, 3967, 5167, 6719, 8737, 11369, 14783,
157     19219, 24989, 32491, 42257, 54941, 71429, 92861, 120721, 156941,
158     204047, 265271, 344857, 448321, 582821, 757693, 985003, 1280519,
159     1664681, 2164111, 2813353, 3657361, 4754591, 6180989, 8035301,
160     10445899, 13579681, 17653589, 22949669, 29834603, 38784989,
161     50420551, 65546729, 85210757, 110774011, 144006217, 187208107,
162     243370577, 316381771, 411296309, 534685237, 695090819, 903618083,
163     1174703521, 1527114613, 1985248999, 2580823717UL, 3355070839UL
164   };
165   int i;
166   for (i = 0; i < ARRAY_SIZE (primes); i++)
167     if (primes[i] >= size)
168       return primes[i];
169   /* huh? */
170   return size;
171 }
172
173 /* Create a hash table of INITIAL_SIZE with hash function
174    HASH_FUNCTION and test function TEST_FUNCTION.  If you wish to
175    start out with a "small" table which will be regrown as needed,
176    specify 0 as INITIAL_SIZE.  */
177
178 struct hash_table *
179 hash_table_new (int initial_size,
180                 unsigned long (*hash_function) (const void *),
181                 int (*test_function) (const void *, const void *))
182 {
183   struct hash_table *ht
184     = (struct hash_table *)xmalloc (sizeof (struct hash_table));
185   ht->hash_function = hash_function;
186   ht->test_function = test_function;
187   ht->size = prime_size (initial_size);
188   ht->fullness = 0;
189   ht->count    = 0;
190   ht->mappings = xmalloc (ht->size * sizeof (struct mapping));
191   memset (ht->mappings, '\0', ht->size * sizeof (struct mapping));
192   return ht;
193 }
194
195 /* Free the data associated with hash table HT. */
196
197 void
198 hash_table_destroy (struct hash_table *ht)
199 {
200   xfree (ht->mappings);
201   xfree (ht);
202 }
203
204 /* The heart of almost all functions in this file -- find the mapping
205    whose KEY is equal to key, using a linear probing loop.  Returns
206    the offset of the mapping in ht->mappings.  This should probably be
207    declared inline.  */
208
209 static int
210 find_mapping (struct hash_table *ht, const void *key)
211 {
212   struct mapping *mappings = ht->mappings;
213   int size = ht->size;
214   int location = ht->hash_function (key) % size;
215   while (1)
216     {
217       struct mapping *mp = mappings + location;
218       void *mp_key = mp->key;
219
220       if (EMPTY_ENTRY_P (mp_key))
221         return -1;
222       else if (DELETED_ENTRY_P (mp_key)
223                || !ht->test_function (key, mp_key))
224         {
225           if (++location == size)
226             location = 0;
227         }
228       else
229         return location;
230     }
231 }
232
233 /* Get the value that corresponds to the key KEY in the hash table HT.
234    If no value is found, return NULL.  Note that NULL is a legal value
235    for value; if you are storing NULLs in your hash table, you can use
236    hash_table_exists to be sure that a (possibly NULL) value exists in
237    the table.  Or, you can use hash_table_get_pair instead of this
238    function.  */
239
240 void *
241 hash_table_get (struct hash_table *ht, const void *key)
242 {
243   int location = find_mapping (ht, key);
244   if (location < 0)
245     return NULL;
246   else
247     return ht->mappings[location].value;
248 }
249
250 /* Like hash_table_get, but writes out the pointers to both key and
251    value.  Returns non-zero on success.  */
252
253 int
254 hash_table_get_pair (struct hash_table *ht, const void *lookup_key,
255                      void *orig_key, void *value)
256 {
257   int location = find_mapping (ht, lookup_key);
258   if (location < 0)
259     return 0;
260   else
261     {
262       struct mapping *mp = ht->mappings + location;
263       if (orig_key)
264         *(void **)orig_key = mp->key;
265       if (value)
266         *(void **)value = mp->value;
267       return 1;
268     }
269 }
270
271 /* Return 1 if KEY exists in HT, 0 otherwise. */
272
273 int
274 hash_table_exists (struct hash_table *ht, const void *key)
275 {
276   return find_mapping (ht, key) >= 0;
277 }
278
279 #define MAX(i, j) (((i) >= (j)) ? (i) : (j))
280
281 /* Grow hash table HT as necessary, and rehash all the key-value
282    mappings.  */
283
284 static void
285 grow_hash_table (struct hash_table *ht)
286 {
287   int i;
288   struct mapping *old_mappings = ht->mappings;
289   int old_count = ht->count;    /* for assert() below */
290   int old_size = ht->size;
291
292   /* To minimize the number of regrowth, we'd like to resize the hash
293      table exponentially.  Normally, this would be done by doubling
294      ht->size (and round it to next prime) on each regrow:
295
296          ht->size = prime_size (ht->size * 2);
297
298      But it is possible that the table has large fullness because of
299      the many deleted entries.  If that is the case, we don't want to
300      blindly grow the table; we just want to rehash it.  For that
301      reason, we use ht->count as the relevant parameter.  MAX is used
302      only because we don't want to actually shrink the table.  (But
303      maybe that's wrong.)  */
304
305   int needed_size = prime_size (ht->count * 3);
306   ht->size = MAX (old_size, needed_size);
307
308 #if 0
309   printf ("growing from %d to %d\n", old_size, ht->size);
310 #endif
311
312   ht->mappings = xmalloc (ht->size * sizeof (struct mapping));
313   memset (ht->mappings, '\0', ht->size * sizeof (struct mapping));
314
315   /* Need to reset these two; hash_table_put will reinitialize them.  */
316   ht->fullness = 0;
317   ht->count    = 0;
318   for (i = 0; i < old_size; i++)
319     {
320       struct mapping *mp = old_mappings + i;
321       void *mp_key = mp->key;
322
323       if (!EMPTY_ENTRY_P (mp_key)
324           && !DELETED_ENTRY_P (mp_key))
325         hash_table_put (ht, mp_key, mp->value);
326     }
327   assert (ht->count == old_count);
328   xfree (old_mappings);
329 }
330
331 /* Put VALUE in the hash table HT under the key KEY.  This regrows the
332    table if necessary.  */
333
334 void
335 hash_table_put (struct hash_table *ht, const void *key, void *value)
336 {
337   /* Cannot use find_mapping here because we're actually looking for
338      an *empty* entry.  */
339
340   struct mapping *mappings = ht->mappings;
341   int size = ht->size;
342   int location = ht->hash_function (key) % size;
343   while (1)
344     {
345       struct mapping *mp = mappings + location;
346       void *mp_key = mp->key;
347
348       if (EMPTY_ENTRY_P (mp_key))
349         {
350           ++ht->fullness;
351           ++ht->count;
352         just_insert:
353           mp->key = (void *)key; /* const? */
354           mp->value = value;
355           break;
356         }
357       else if (DELETED_ENTRY_P (mp_key)
358                || !ht->test_function (key, mp_key))
359         {
360           if (++location == size)
361             location = 0;
362         }
363       else                      /* equal to key and not deleted */
364         {
365           /* We're replacing an existing entry, so ht->count and
366              ht->fullness remain unchanged.  */
367           goto just_insert;
368         }
369     }
370   if (ht->fullness * 4 > ht->size * 3)
371     /* When fullness exceeds 75% of size, regrow the table. */
372     grow_hash_table (ht);
373 }
374
375 /* Remove KEY from HT. */
376
377 int
378 hash_table_remove (struct hash_table *ht, const void *key)
379 {
380   int location = find_mapping (ht, key);
381   if (location < 0)
382     return 0;
383   else
384     {
385       struct mapping *mappings = ht->mappings;
386       struct mapping *mp = mappings + location;
387       /* We don't really remove an entry from the hash table: we just
388          mark it as deleted.  This is because there may be other
389          entries located after this entry whose hash points to a
390          location before this entry.  (Example: keys A, B and C have
391          the same hash.  If you were to really *delete* B from the
392          table, C could no longer be found.) */
393
394       /* Optimization addendum: if the mapping that follows LOCATION
395          is already empty, that is a sure sign that nobody depends on
396          LOCATION being non-empty.  (This is because we're using
397          linear probing.  This would not be the case with double
398          hashing.)  In that case, we may safely delete the mapping.  */
399
400       /* This could be generalized so that the all the non-empty
401          locations following LOCATION are simply shifted leftward.  It
402          would make deletion a bit slower, but it would remove the
403          ugly DELETED_ENTRY_P checks from all the rest of the code,
404          making the whole thing faster.  */
405       int location_after = (location + 1) == ht->size ? 0 : location + 1;
406       struct mapping *mp_after = mappings + location_after;
407
408       if (EMPTY_ENTRY_P (mp_after->key))
409         {
410           mp->key = ENTRY_EMPTY;
411           --ht->fullness;
412         }
413       else
414         mp->key = ENTRY_DELETED;
415
416       --ht->count;
417       return 1;
418     }
419 }
420
421 /* Clear HT of all entries.  After calling this function, the count
422    and the fullness of the hash table will be zero.  The size will
423    remain unchanged.  */
424
425 void
426 hash_table_clear (struct hash_table *ht)
427 {
428   memset (ht->mappings, '\0', ht->size * sizeof (struct mapping));
429   ht->fullness = 0;
430   ht->count    = 0;
431 }
432
433 /* Map MAPFUN over all the mappings in hash table HT.  MAPFUN is
434    called with three arguments: the key, the value, and the CLOSURE.
435    Don't add or remove entries from HT while hash_table_map is being
436    called, or strange things may happen.  */
437
438 void
439 hash_table_map (struct hash_table *ht,
440                 int (*mapfun) (void *, void *, void *),
441                 void *closure)
442 {
443   struct mapping *mappings = ht->mappings;
444   int i;
445   for (i = 0; i < ht->size; i++)
446     {
447       struct mapping *mp = mappings + i;
448       void *mp_key = mp->key;
449
450       if (!EMPTY_ENTRY_P (mp_key)
451           && !DELETED_ENTRY_P (mp_key))
452         if (mapfun (mp_key, mp->value, closure))
453           return;
454     }
455 }
456 \f
457 /* Support for hash tables whose keys are strings.  */
458
459 /* supposedly from the Dragon Book P436. */
460 unsigned long
461 string_hash (const void *sv)
462 {
463   unsigned int h = 0;
464   unsigned const char *x = (unsigned const char *) sv;
465
466   while (*x)
467     {
468       unsigned int g;
469       h = (h << 4) + *x++;
470       if ((g = h & 0xf0000000) != 0)
471         h = (h ^ (g >> 24)) ^ g;
472     }
473
474   return h;
475 }
476
477 #if 0
478 /* If I ever need it: hashing of integers. */
479
480 unsigned int
481 inthash (unsigned int key)
482 {
483   key += (key << 12);
484   key ^= (key >> 22);
485   key += (key << 4);
486   key ^= (key >> 9);
487   key += (key << 10);
488   key ^= (key >> 2);
489   key += (key << 7);
490   key ^= (key >> 12);
491   return key;
492 }
493 #endif
494
495 int
496 string_cmp (const void *s1, const void *s2)
497 {
498   return !strcmp ((const char *)s1, (const char *)s2);
499 }
500
501 /* Return a hash table of initial size INITIAL_SIZE suitable to use
502    strings as keys.  */
503
504 struct hash_table *
505 make_string_hash_table (int initial_size)
506 {
507   return hash_table_new (initial_size, string_hash, string_cmp);
508 }
509
510 \f
511 #ifdef STANDALONE
512
513 #include <stdio.h>
514 #include <string.h>
515
516 int
517 print_hash_table_mapper (void *key, void *value, void *count)
518 {
519   ++*(int *)count;
520   printf ("%s: %s\n", (const char *)key, (char *)value);
521   return 0;
522 }
523
524 void
525 print_hash (struct hash_table *sht)
526 {
527   int debug_count = 0;
528   hash_table_map (sht, print_hash_table_mapper, &debug_count);
529   assert (debug_count == sht->count);
530 }
531
532 int
533 main (void)
534 {
535   struct hash_table *ht = make_string_hash_table (0);
536   char line[80];
537   while ((fgets (line, sizeof (line), stdin)))
538     {
539       int len = strlen (line);
540       if (len <= 1)
541         continue;
542       line[--len] = '\0';
543       if (!hash_table_exists (ht, line))
544         hash_table_put (ht, strdup (line), "here I am!");
545 #if 1
546       if (len % 3)
547         {
548           char *line_copy;
549           if (hash_table_get_pair (ht, line, &line_copy, NULL))
550             {
551               hash_table_remove (ht, line);
552               xfree (line_copy);
553             }
554         }
555 #endif
556     }
557 #if 0
558   print_hash (ht);
559 #endif
560 #if 1
561   printf ("%d %d %d\n", ht->count, ht->fullness, ht->size);
562 #endif
563   return 0;
564 }
565 #endif