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