]> sjero.net Git - wget/blob - src/hash.c
ecfc96dd819a9c442a89d7826d3af117993705c1
[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) (const void *);
140   int (*test_function) (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, 2580823717UL, 3355070839UL
181   };
182   int i;
183   for (i = 0; i < ARRAY_SIZE (primes); i++)
184     if (primes[i] >= size)
185       return primes[i];
186   /* huh? */
187   return size;
188 }
189
190 /* Create a hash table of INITIAL_SIZE with hash function
191    HASH_FUNCTION and test function TEST_FUNCTION.  INITIAL_SIZE will
192    be rounded to the next prime, so you don't have to worry about it
193    being a prime number.
194
195    Consequently, if you wish to start out with a "small" table which
196    will be regrown as needed, specify INITIAL_SIZE 0.  */
197
198 struct hash_table *
199 hash_table_new (int initial_size,
200                 unsigned long (*hash_function) (const void *),
201                 int (*test_function) (const void *, const void *))
202 {
203   struct hash_table *ht
204     = (struct hash_table *)xmalloc (sizeof (struct hash_table));
205
206   ht->hash_function = hash_function;
207   ht->test_function = test_function;
208
209   ht->size = prime_size (initial_size);
210   ht->resize_threshold = ht->size * 3 / 4;
211
212   ht->count    = 0;
213
214   ht->mappings = xmalloc (ht->size * sizeof (struct mapping));
215   memset (ht->mappings, '\0', ht->size * sizeof (struct mapping));
216
217   return ht;
218 }
219
220 /* Free the data associated with hash table HT. */
221
222 void
223 hash_table_destroy (struct hash_table *ht)
224 {
225   xfree (ht->mappings);
226   xfree (ht);
227 }
228
229 /* The heart of almost all functions in this file -- find the mapping
230    whose KEY is equal to key, using linear probing.  Returns the
231    mapping that matches KEY, or NULL if none matches.  */
232
233 static inline struct mapping *
234 find_mapping (struct hash_table *ht, const void *key)
235 {
236   struct mapping *mappings = ht->mappings;
237   int size = ht->size;
238   struct mapping *mp = mappings + HASH_POSITION (ht, key);
239   int (*equals) (const void *, const void *) = ht->test_function;
240
241   LOOP_NON_EMPTY (mp, mappings, size)
242     if (equals (key, mp->key))
243       return mp;
244   return NULL;
245 }
246
247 /* Get the value that corresponds to the key KEY in the hash table HT.
248    If no value is found, return NULL.  Note that NULL is a legal value
249    for value; if you are storing NULLs in your hash table, you can use
250    hash_table_contains to be sure that a (possibly NULL) value exists
251    in the table.  Or, you can use hash_table_get_pair instead of this
252    function.  */
253
254 void *
255 hash_table_get (struct hash_table *ht, const void *key)
256 {
257   struct mapping *mp = find_mapping (ht, key);
258   if (mp)
259     return mp->value;
260   else
261     return NULL;
262 }
263
264 /* Like hash_table_get, but writes out the pointers to both key and
265    value.  Returns non-zero on success.  */
266
267 int
268 hash_table_get_pair (struct hash_table *ht, const void *lookup_key,
269                      void *orig_key, void *value)
270 {
271   struct mapping *mp = find_mapping (ht, lookup_key);
272
273   if (mp)
274     {
275       if (orig_key)
276         *(void **)orig_key = mp->key;
277       if (value)
278         *(void **)value = mp->value;
279       return 1;
280     }
281   else
282     return 0;
283 }
284
285 /* Return 1 if HT contains KEY, 0 otherwise. */
286
287 int
288 hash_table_contains (struct hash_table *ht, const void *key)
289 {
290   return find_mapping (ht, key) != NULL;
291 }
292
293 /* Grow hash table HT as necessary, and rehash all the key-value
294    mappings.  */
295
296 static void
297 grow_hash_table (struct hash_table *ht)
298 {
299   struct mapping *old_mappings = ht->mappings;
300   struct mapping *old_end      = ht->mappings + ht->size;
301   struct mapping *mp, *mappings;
302   int newsize;
303
304   newsize = prime_size (ht->size * 2);
305 #if 0
306   printf ("growing from %d to %d\n", ht->size, newsize);
307 #endif
308
309   ht->size = newsize;
310   ht->resize_threshold = newsize * 3 / 4;
311
312   mappings = xmalloc (ht->size * sizeof (struct mapping));
313   memset (mappings, '\0', ht->size * sizeof (struct mapping));
314   ht->mappings = mappings;
315
316   for (mp = old_mappings; mp < old_end; mp++)
317     if (!EMPTY_MAPPING_P (mp))
318       {
319         struct mapping *new_mp = mappings + HASH_POSITION (ht, mp->key);
320         /* We don't need to call test function and worry about
321            collisions because all the keys come from the hash table
322            and are therefore guaranteed to be unique.  */
323         LOOP_NON_EMPTY (new_mp, mappings, newsize)
324           ;
325         *new_mp = *mp;
326       }
327
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   struct mapping *mappings = ht->mappings;
338   int size = ht->size;
339   int (*equals) (const void *, const void *) = ht->test_function;
340
341   struct mapping *mp = mappings + HASH_POSITION (ht, key);
342
343   LOOP_NON_EMPTY (mp, mappings, size)
344     if (equals (key, mp->key))
345       {
346         mp->key   = (void *)key; /* const? */
347         mp->value = value;
348         return;
349       }
350
351   ++ht->count;
352   mp->key   = (void *)key;      /* const? */
353   mp->value = value;
354
355   if (ht->count > ht->resize_threshold)
356     /* When table is 75% full, regrow it. */
357     grow_hash_table (ht);
358 }
359
360 /* Remove a mapping that matches KEY from HT.  Return 0 if there was
361    no such entry; return 1 if an entry was removed.  */
362
363 int
364 hash_table_remove (struct hash_table *ht, const void *key)
365 {
366   struct mapping *mp = find_mapping (ht, key);
367   if (!mp)
368     return 0;
369   else
370     {
371       int size = ht->size;
372       struct mapping *mappings = ht->mappings;
373
374       mp->key = NULL;
375       --ht->count;
376
377       /* Rehash all the entries following MP.  The alternative
378          approach is to mark the entry as deleted, i.e. create a
379          "tombstone".  That makes remove faster, but leaves a lot of
380          garbage and slows down hash_table_get and hash_table_put.  */
381
382       mp = NEXT_MAPPING (mp, mappings, size);
383       LOOP_NON_EMPTY (mp, mappings, size)
384         {
385           const void *key2 = mp->key;
386           struct mapping *mp_new = mappings + HASH_POSITION (ht, key2);
387
388           /* Find the new location for the key. */
389
390           LOOP_NON_EMPTY (mp_new, mappings, size)
391             if (key2 == mp_new->key)
392               /* The mapping MP (key2) is already where we want it (in
393                  MP_NEW's "chain" of keys.)  */
394               goto next_rehash;
395
396           *mp_new = *mp;
397           mp->key = NULL;
398
399         next_rehash:
400           ;
401         }
402       return 1;
403     }
404 }
405
406 /* Clear HT of all entries.  After calling this function, the count
407    and the fullness of the hash table will be zero.  The size will
408    remain unchanged.  */
409
410 void
411 hash_table_clear (struct hash_table *ht)
412 {
413   memset (ht->mappings, '\0', ht->size * sizeof (struct mapping));
414   ht->count = 0;
415 }
416
417 /* Map MAPFUN over all the mappings in hash table HT.  MAPFUN is
418    called with three arguments: the key, the value, and the CLOSURE.
419
420    It is undefined what happens if you add or remove entries in the
421    hash table while hash_table_map is running.  The exception is the
422    entry you're currently mapping over; you may remove or change that
423    entry.  */
424
425 void
426 hash_table_map (struct hash_table *ht,
427                 int (*mapfun) (void *, void *, void *),
428                 void *closure)
429 {
430   struct mapping *mp  = ht->mappings;
431   struct mapping *end = ht->mappings + ht->size;
432
433   for (; mp < end; mp++)
434     if (!EMPTY_MAPPING_P (mp))
435       {
436         void *key;
437       repeat:
438         key = mp->key;
439         if (mapfun (key, mp->value, closure))
440           return;
441         /* hash_table_remove might have moved the adjacent
442            mappings. */
443         if (mp->key != key && !EMPTY_MAPPING_P (mp))
444           goto repeat;
445       }
446 }
447
448 /* Return the number of elements in the hash table.  This is not the
449    same as the physical size of the hash table, which is always
450    greater than the number of elements.  */
451
452 int
453 hash_table_count (struct hash_table *ht)
454 {
455   return ht->count;
456 }
457 \f
458 /* Functions from this point onward are meant for convenience and
459    don't strictly belong to this file.  However, this is as good a
460    place for them as any.  */
461
462 /* ========
463    Support for hash tables whose keys are strings.
464    ======== */
465
466 /* 31 bit hash function.  Taken from Gnome's glib, modified to use
467    standard C types.
468
469    We used to use the popular hash function from the Dragon Book, but
470    this one seems to perform much better.  */
471
472 unsigned long
473 string_hash (const void *key)
474 {
475   const char *p = key;
476   unsigned int h = *p;
477   
478   if (h)
479     for (p += 1; *p != '\0'; p++)
480       h = (h << 5) - h + *p;
481   
482   return h;
483 }
484
485 /* Frontend for strcmp usable for hash tables. */
486
487 int
488 string_cmp (const void *s1, const void *s2)
489 {
490   return !strcmp ((const char *)s1, (const char *)s2);
491 }
492
493 /* Return a hash table of initial size INITIAL_SIZE suitable to use
494    strings as keys.  */
495
496 struct hash_table *
497 make_string_hash_table (int initial_size)
498 {
499   return hash_table_new (initial_size, string_hash, string_cmp);
500 }
501
502 /* ========
503    Support for hash tables whose keys are strings, but which are
504    compared case-insensitively.
505    ======== */
506
507 /* Like string_hash, but produce the same hash regardless of the case. */
508
509 static unsigned long
510 string_hash_nocase (const void *key)
511 {
512   const char *p = key;
513   unsigned int h = TOLOWER (*p);
514   
515   if (h)
516     for (p += 1; *p != '\0'; p++)
517       h = (h << 5) - h + TOLOWER (*p);
518   
519   return h;
520 }
521
522 /* Like string_cmp, but doing case-insensitive compareison. */
523
524 static int
525 string_cmp_nocase (const void *s1, const void *s2)
526 {
527   return !strcasecmp ((const char *)s1, (const char *)s2);
528 }
529
530 /* Like make_string_hash_table, but uses string_hash_nocase and
531    string_cmp_nocase.  */
532
533 struct hash_table *
534 make_nocase_string_hash_table (int initial_size)
535 {
536   return hash_table_new (initial_size, string_hash_nocase, string_cmp_nocase);
537 }
538
539 #if 0
540 /* If I ever need it: hashing of integers. */
541
542 unsigned int
543 inthash (unsigned int key)
544 {
545   key += (key << 12);
546   key ^= (key >> 22);
547   key += (key << 4);
548   key ^= (key >> 9);
549   key += (key << 10);
550   key ^= (key >> 2);
551   key += (key << 7);
552   key ^= (key >> 12);
553   return key;
554 }
555 #endif
556 \f
557 #ifdef STANDALONE
558
559 #include <stdio.h>
560 #include <string.h>
561
562 int
563 print_hash_table_mapper (void *key, void *value, void *count)
564 {
565   ++*(int *)count;
566   printf ("%s: %s\n", (const char *)key, (char *)value);
567   return 0;
568 }
569
570 void
571 print_hash (struct hash_table *sht)
572 {
573   int debug_count = 0;
574   hash_table_map (sht, print_hash_table_mapper, &debug_count);
575   assert (debug_count == sht->count);
576 }
577
578 int
579 main (void)
580 {
581   struct hash_table *ht = make_string_hash_table (0);
582   char line[80];
583   while ((fgets (line, sizeof (line), stdin)))
584     {
585       int len = strlen (line);
586       if (len <= 1)
587         continue;
588       line[--len] = '\0';
589       if (!hash_table_contains (ht, line))
590         hash_table_put (ht, strdup (line), "here I am!");
591 #if 1
592       if (len % 5 == 0)
593         {
594           char *line_copy;
595           if (hash_table_get_pair (ht, line, &line_copy, NULL))
596             {
597               hash_table_remove (ht, line);
598               xfree (line_copy);
599             }
600         }
601 #endif
602     }
603 #if 0
604   print_hash (ht);
605 #endif
606 #if 1
607   printf ("%d %d\n", ht->count, ht->size);
608 #endif
609   return 0;
610 }
611 #endif