]> sjero.net Git - wget/blob - src/hash.c
[svn] Allow Wget to be compiled with a K&R compiler.
[wget] / src / hash.c
1 /* Hash tables.
2    Copyright (C) 2000, 2001 Free Software Foundation, Inc.
3
4 This file is part of GNU Wget.
5
6 GNU Wget 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 GNU Wget 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 Wget; 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 #ifdef HAVE_STRING_H
25 # include <string.h>
26 #else
27 # include <strings.h>
28 #endif /* HAVE_STRING_H */
29 #include <stdlib.h>
30 #include <assert.h>
31
32 #include "wget.h"
33 #include "utils.h"
34
35 #include "hash.h"
36
37 #ifdef STANDALONE
38 # undef xmalloc
39 # undef xrealloc
40 # undef xfree
41
42 # define xmalloc malloc
43 # define xrealloc realloc
44 # define xfree free
45 #endif
46
47 /* INTERFACE:
48
49    Hash tables are an implementation technique used to implement
50    mapping between objects.  Provided a good hashing function is used,
51    they guarantee constant-time access and storing of information.
52    Duplicate keys are not allowed.
53
54    The basics are all covered.  hash_table_new creates a hash table,
55    and hash_table_destroy deletes it.  hash_table_put establishes a
56    mapping between a key and a value.  hash_table_get retrieves the
57    value that corresponds to a key.  hash_table_contains queries
58    whether a key is stored in a table at all.  hash_table_remove
59    removes a mapping that corresponds to a key.  hash_table_map allows
60    you to map through all the entries in a hash table.
61    hash_table_clear clears all the entries from the hash table.
62
63    The number of mappings in a table is not limited, except by the
64    amount of memory.  As you add new elements to a table, it regrows
65    as necessary.  If you have an idea about how many elements you will
66    store, you can provide a hint to hash_table_new().
67
68    The hashing and equality functions are normally provided by the
69    user.  For the special (and frequent) case of hashing strings, you
70    can use the pre-canned make_string_hash_table(), which provides an
71    efficient string hashing function, and a string equality wrapper
72    around strcmp().
73
74    When specifying your own hash and test functions, make sure the
75    following holds true:
76
77    - The test function returns non-zero for keys that are considered
78      "equal", zero otherwise.
79
80    - The hash function returns a number that represents the
81      "distinctness" of the object.  In more precise terms, it means
82      that for any two objects that test "equal" under the test
83      function, the hash function MUST produce the same result.
84
85      This does not mean that each distinct object must produce a
86      distinct value, only that non-distinct objects must produce the
87      same values!  For instance, a hash function that returns 0 for
88      any given object is a perfectly valid (albeit extremely bad) hash
89      function.  A hash function that hashes a string by adding up all
90      its characters is another example of a valid (but quite bad) hash
91      function.
92
93      The above stated rule is quite easy to enforce.  For example, if
94      your testing function compares strings case-insensitively, all
95      your function needs to do is lower-case the string characters
96      before calculating a hash.  That way you have easily guaranteed
97      that case differences will not result in a different hash.
98
99    - (optional) Choose the hash function to get as good "spreading" as
100      possible.  A good hash function will react to even a small change
101      in its input with a completely different resulting hash.
102      Finally, don't make your hash function extremely slow, because
103      you're then defeating the purpose of hashing.
104
105    Note that neither keys nor values are copied when inserted into the
106    hash table, so they must exist for the lifetime of the table.  This
107    means that e.g. the use of static strings is OK, but objects with a
108    shorter life-time need to be copied (with strdup() or the like in
109    the case of strings) before being inserted.  */
110
111 /* IMPLEMENTATION:
112
113    All the hash mappings (key-value pairs of pointers) are stored in a
114    contiguous array.  The position of each mapping is determined by
115    applying the hash function to the key: location = hash(key) % size.
116    If two different keys end up on the same position, the collision is
117    resolved by placing the second mapping at the next empty place in
118    the array following the occupied place.  This method of collision
119    resolution is called "linear probing".
120
121    There are more advanced collision resolution mechanisms (quadratic
122    probing, double hashing), but we don't use them because they
123    involve more non-sequential access to the array, and therefore
124    worse cache behavior.  Linear probing works well as long as the
125    fullness/size ratio is kept below 75%.  We make sure to regrow or
126    rehash the hash table whenever this threshold is exceeded.
127
128    Collisions make deletion tricky because finding collisions again
129    relies on new empty spots not being created.  That's why
130    hash_table_remove is careful to rehash the mappings that follow the
131    deleted one.  */
132
133 struct mapping {
134   void *key;
135   void *value;
136 };
137
138 struct hash_table {
139   unsigned long (*hash_function) PARAMS ((const void *));
140   int (*test_function) PARAMS ((const void *, const void *));
141
142   int size;                     /* size of the array */
143   int count;                    /* number of non-empty, non-deleted
144                                    fields. */
145
146   int resize_threshold;         /* after size exceeds this number of
147                                    entries, resize the table.  */
148
149   struct mapping *mappings;
150 };
151
152 #define EMPTY_MAPPING_P(mp)  ((mp)->key == NULL)
153 #define NEXT_MAPPING(mp, mappings, size) (mp == mappings + (size - 1)   \
154                                           ? mappings : mp + 1)
155
156 #define LOOP_NON_EMPTY(mp, mappings, size)                              \
157   for (; !EMPTY_MAPPING_P (mp); mp = NEXT_MAPPING (mp, mappings, size))
158
159 /* #### We might want to multiply with the "golden ratio" here to get
160    better randomness for keys that do not result from a good hash
161    function.  This is currently not a problem in Wget because we only
162    use the string hash tables.  */
163
164 #define HASH_POSITION(ht, key) (ht->hash_function (key) % ht->size)
165
166 /* Find a prime near, but greather than or equal to SIZE. */
167
168 static int
169 prime_size (int size)
170 {
171   static const unsigned long primes [] = {
172     19, 29, 41, 59, 79, 107, 149, 197, 263, 347, 457, 599, 787, 1031,
173     1361, 1777, 2333, 3037, 3967, 5167, 6719, 8737, 11369, 14783,
174     19219, 24989, 32491, 42257, 54941, 71429, 92861, 120721, 156941,
175     204047, 265271, 344857, 448321, 582821, 757693, 985003, 1280519,
176     1664681, 2164111, 2813353, 3657361, 4754591, 6180989, 8035301,
177     10445899, 13579681, 17653589, 22949669, 29834603, 38784989,
178     50420551, 65546729, 85210757, 110774011, 144006217, 187208107,
179     243370577, 316381771, 411296309, 534685237, 695090819, 903618083,
180     1174703521, 1527114613, 1985248999,
181     (unsigned long)0x99d43ea5, (unsigned long)0xc7fa5177
182   };
183   int i;
184   for (i = 0; i < ARRAY_SIZE (primes); i++)
185     if (primes[i] >= size)
186       return primes[i];
187   /* huh? */
188   return size;
189 }
190
191 /* Create a hash table of INITIAL_SIZE with hash function
192    HASH_FUNCTION and test function TEST_FUNCTION.  INITIAL_SIZE will
193    be rounded to the next prime, so you don't have to worry about it
194    being a prime number.
195
196    Consequently, if you wish to start out with a "small" table which
197    will be regrown as needed, specify INITIAL_SIZE 0.  */
198
199 struct hash_table *
200 hash_table_new (int initial_size,
201                 unsigned long (*hash_function) (const void *),
202                 int (*test_function) (const void *, const void *))
203 {
204   struct hash_table *ht
205     = (struct hash_table *)xmalloc (sizeof (struct hash_table));
206
207   ht->hash_function = hash_function;
208   ht->test_function = test_function;
209
210   ht->size = prime_size (initial_size);
211   ht->resize_threshold = ht->size * 3 / 4;
212
213   ht->count    = 0;
214
215   ht->mappings = xmalloc (ht->size * sizeof (struct mapping));
216   memset (ht->mappings, '\0', ht->size * sizeof (struct mapping));
217
218   return ht;
219 }
220
221 /* Free the data associated with hash table HT. */
222
223 void
224 hash_table_destroy (struct hash_table *ht)
225 {
226   xfree (ht->mappings);
227   xfree (ht);
228 }
229
230 /* The heart of almost all functions in this file -- find the mapping
231    whose KEY is equal to key, using linear probing.  Returns the
232    mapping that matches KEY, or NULL if none matches.  */
233
234 static inline struct mapping *
235 find_mapping (struct hash_table *ht, const void *key)
236 {
237   struct mapping *mappings = ht->mappings;
238   int size = ht->size;
239   struct mapping *mp = mappings + HASH_POSITION (ht, key);
240   int (*equals) PARAMS ((const void *, const void *)) = ht->test_function;
241
242   LOOP_NON_EMPTY (mp, mappings, size)
243     if (equals (key, mp->key))
244       return mp;
245   return NULL;
246 }
247
248 /* Get the value that corresponds to the key KEY in the hash table HT.
249    If no value is found, return NULL.  Note that NULL is a legal value
250    for value; if you are storing NULLs in your hash table, you can use
251    hash_table_contains to be sure that a (possibly NULL) value exists
252    in the table.  Or, you can use hash_table_get_pair instead of this
253    function.  */
254
255 void *
256 hash_table_get (struct hash_table *ht, const void *key)
257 {
258   struct mapping *mp = find_mapping (ht, key);
259   if (mp)
260     return mp->value;
261   else
262     return NULL;
263 }
264
265 /* Like hash_table_get, but writes out the pointers to both key and
266    value.  Returns non-zero on success.  */
267
268 int
269 hash_table_get_pair (struct hash_table *ht, const void *lookup_key,
270                      void *orig_key, void *value)
271 {
272   struct mapping *mp = find_mapping (ht, lookup_key);
273
274   if (mp)
275     {
276       if (orig_key)
277         *(void **)orig_key = mp->key;
278       if (value)
279         *(void **)value = mp->value;
280       return 1;
281     }
282   else
283     return 0;
284 }
285
286 /* Return 1 if HT contains KEY, 0 otherwise. */
287
288 int
289 hash_table_contains (struct hash_table *ht, const void *key)
290 {
291   return find_mapping (ht, key) != NULL;
292 }
293
294 /* Grow hash table HT as necessary, and rehash all the key-value
295    mappings.  */
296
297 static void
298 grow_hash_table (struct hash_table *ht)
299 {
300   struct mapping *old_mappings = ht->mappings;
301   struct mapping *old_end      = ht->mappings + ht->size;
302   struct mapping *mp, *mappings;
303   int newsize;
304
305   newsize = prime_size (ht->size * 2);
306 #if 0
307   printf ("growing from %d to %d\n", ht->size, newsize);
308 #endif
309
310   ht->size = newsize;
311   ht->resize_threshold = newsize * 3 / 4;
312
313   mappings = xmalloc (ht->size * sizeof (struct mapping));
314   memset (mappings, '\0', ht->size * sizeof (struct mapping));
315   ht->mappings = mappings;
316
317   for (mp = old_mappings; mp < old_end; mp++)
318     if (!EMPTY_MAPPING_P (mp))
319       {
320         struct mapping *new_mp = mappings + HASH_POSITION (ht, mp->key);
321         /* We don't need to call test function and worry about
322            collisions because all the keys come from the hash table
323            and are therefore guaranteed to be unique.  */
324         LOOP_NON_EMPTY (new_mp, mappings, newsize)
325           ;
326         *new_mp = *mp;
327       }
328
329   xfree (old_mappings);
330 }
331
332 /* Put VALUE in the hash table HT under the key KEY.  This regrows the
333    table if necessary.  */
334
335 void
336 hash_table_put (struct hash_table *ht, const void *key, void *value)
337 {
338   struct mapping *mappings = ht->mappings;
339   int size = ht->size;
340   int (*equals) PARAMS ((const void *, const void *)) = ht->test_function;
341
342   struct mapping *mp = mappings + HASH_POSITION (ht, key);
343
344   LOOP_NON_EMPTY (mp, mappings, size)
345     if (equals (key, mp->key))
346       {
347         mp->key   = (void *)key; /* const? */
348         mp->value = value;
349         return;
350       }
351
352   ++ht->count;
353   mp->key   = (void *)key;      /* const? */
354   mp->value = value;
355
356   if (ht->count > ht->resize_threshold)
357     /* When table is 75% full, regrow it. */
358     grow_hash_table (ht);
359 }
360
361 /* Remove a mapping that matches KEY from HT.  Return 0 if there was
362    no such entry; return 1 if an entry was removed.  */
363
364 int
365 hash_table_remove (struct hash_table *ht, const void *key)
366 {
367   struct mapping *mp = find_mapping (ht, key);
368   if (!mp)
369     return 0;
370   else
371     {
372       int size = ht->size;
373       struct mapping *mappings = ht->mappings;
374
375       mp->key = NULL;
376       --ht->count;
377
378       /* Rehash all the entries following MP.  The alternative
379          approach is to mark the entry as deleted, i.e. create a
380          "tombstone".  That makes remove faster, but leaves a lot of
381          garbage and slows down hash_table_get and hash_table_put.  */
382
383       mp = NEXT_MAPPING (mp, mappings, size);
384       LOOP_NON_EMPTY (mp, mappings, size)
385         {
386           const void *key2 = mp->key;
387           struct mapping *mp_new = mappings + HASH_POSITION (ht, key2);
388
389           /* Find the new location for the key. */
390
391           LOOP_NON_EMPTY (mp_new, mappings, size)
392             if (key2 == mp_new->key)
393               /* The mapping MP (key2) is already where we want it (in
394                  MP_NEW's "chain" of keys.)  */
395               goto next_rehash;
396
397           *mp_new = *mp;
398           mp->key = NULL;
399
400         next_rehash:
401           ;
402         }
403       return 1;
404     }
405 }
406
407 /* Clear HT of all entries.  After calling this function, the count
408    and the fullness of the hash table will be zero.  The size will
409    remain unchanged.  */
410
411 void
412 hash_table_clear (struct hash_table *ht)
413 {
414   memset (ht->mappings, '\0', ht->size * sizeof (struct mapping));
415   ht->count = 0;
416 }
417
418 /* Map MAPFUN over all the mappings in hash table HT.  MAPFUN is
419    called with three arguments: the key, the value, and the CLOSURE.
420
421    It is undefined what happens if you add or remove entries in the
422    hash table while hash_table_map is running.  The exception is the
423    entry you're currently mapping over; you may remove or change that
424    entry.  */
425
426 void
427 hash_table_map (struct hash_table *ht,
428                 int (*mapfun) (void *, void *, void *),
429                 void *closure)
430 {
431   struct mapping *mp  = ht->mappings;
432   struct mapping *end = ht->mappings + ht->size;
433
434   for (; mp < end; mp++)
435     if (!EMPTY_MAPPING_P (mp))
436       {
437         void *key;
438       repeat:
439         key = mp->key;
440         if (mapfun (key, mp->value, closure))
441           return;
442         /* hash_table_remove might have moved the adjacent
443            mappings. */
444         if (mp->key != key && !EMPTY_MAPPING_P (mp))
445           goto repeat;
446       }
447 }
448
449 /* Return the number of elements in the hash table.  This is not the
450    same as the physical size of the hash table, which is always
451    greater than the number of elements.  */
452
453 int
454 hash_table_count (struct hash_table *ht)
455 {
456   return ht->count;
457 }
458 \f
459 /* Functions from this point onward are meant for convenience and
460    don't strictly belong to this file.  However, this is as good a
461    place for them as any.  */
462
463 /* ========
464    Support for hash tables whose keys are strings.
465    ======== */
466
467 /* 31 bit hash function.  Taken from Gnome's glib, modified to use
468    standard C types.
469
470    We used to use the popular hash function from the Dragon Book, but
471    this one seems to perform much better.  */
472
473 unsigned long
474 string_hash (const void *key)
475 {
476   const char *p = key;
477   unsigned int h = *p;
478   
479   if (h)
480     for (p += 1; *p != '\0'; p++)
481       h = (h << 5) - h + *p;
482   
483   return h;
484 }
485
486 /* Frontend for strcmp usable for hash tables. */
487
488 int
489 string_cmp (const void *s1, const void *s2)
490 {
491   return !strcmp ((const char *)s1, (const char *)s2);
492 }
493
494 /* Return a hash table of initial size INITIAL_SIZE suitable to use
495    strings as keys.  */
496
497 struct hash_table *
498 make_string_hash_table (int initial_size)
499 {
500   return hash_table_new (initial_size, string_hash, string_cmp);
501 }
502
503 /* ========
504    Support for hash tables whose keys are strings, but which are
505    compared case-insensitively.
506    ======== */
507
508 /* Like string_hash, but produce the same hash regardless of the case. */
509
510 static unsigned long
511 string_hash_nocase (const void *key)
512 {
513   const char *p = key;
514   unsigned int h = TOLOWER (*p);
515   
516   if (h)
517     for (p += 1; *p != '\0'; p++)
518       h = (h << 5) - h + TOLOWER (*p);
519   
520   return h;
521 }
522
523 /* Like string_cmp, but doing case-insensitive compareison. */
524
525 static int
526 string_cmp_nocase (const void *s1, const void *s2)
527 {
528   return !strcasecmp ((const char *)s1, (const char *)s2);
529 }
530
531 /* Like make_string_hash_table, but uses string_hash_nocase and
532    string_cmp_nocase.  */
533
534 struct hash_table *
535 make_nocase_string_hash_table (int initial_size)
536 {
537   return hash_table_new (initial_size, string_hash_nocase, string_cmp_nocase);
538 }
539
540 #if 0
541 /* If I ever need it: hashing of integers. */
542
543 unsigned int
544 inthash (unsigned int key)
545 {
546   key += (key << 12);
547   key ^= (key >> 22);
548   key += (key << 4);
549   key ^= (key >> 9);
550   key += (key << 10);
551   key ^= (key >> 2);
552   key += (key << 7);
553   key ^= (key >> 12);
554   return key;
555 }
556 #endif
557 \f
558 #ifdef STANDALONE
559
560 #include <stdio.h>
561 #include <string.h>
562
563 int
564 print_hash_table_mapper (void *key, void *value, void *count)
565 {
566   ++*(int *)count;
567   printf ("%s: %s\n", (const char *)key, (char *)value);
568   return 0;
569 }
570
571 void
572 print_hash (struct hash_table *sht)
573 {
574   int debug_count = 0;
575   hash_table_map (sht, print_hash_table_mapper, &debug_count);
576   assert (debug_count == sht->count);
577 }
578
579 int
580 main (void)
581 {
582   struct hash_table *ht = make_string_hash_table (0);
583   char line[80];
584   while ((fgets (line, sizeof (line), stdin)))
585     {
586       int len = strlen (line);
587       if (len <= 1)
588         continue;
589       line[--len] = '\0';
590       if (!hash_table_contains (ht, line))
591         hash_table_put (ht, strdup (line), "here I am!");
592 #if 1
593       if (len % 5 == 0)
594         {
595           char *line_copy;
596           if (hash_table_get_pair (ht, line, &line_copy, NULL))
597             {
598               hash_table_remove (ht, line);
599               xfree (line_copy);
600             }
601         }
602 #endif
603     }
604 #if 0
605   print_hash (ht);
606 #endif
607 #if 1
608   printf ("%d %d\n", ht->count, ht->size);
609 #endif
610   return 0;
611 }
612 #endif