]> sjero.net Git - wget/blob - src/hash.c
[svn] Better INT_MAX and UCHAR_MAX checks.
[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 In addition, as a special exception, the Free Software Foundation
21 gives permission to link the code of its release of Wget with the
22 OpenSSL project's "OpenSSL" library (or with modified versions of it
23 that use the same license as the "OpenSSL" library), and distribute
24 the linked executables.  You must obey the GNU General Public License
25 in all respects for all of the code used other than "OpenSSL".  If you
26 modify this file, you may extend this exception to your version of the
27 file, but you are not obligated to do so.  If you do not wish to do
28 so, delete this exception statement from your version.  */
29
30 #ifdef HAVE_CONFIG_H
31 # include <config.h>
32 #endif
33
34 #ifdef HAVE_STRING_H
35 # include <string.h>
36 #else
37 # include <strings.h>
38 #endif
39 #ifdef HAVE_LIMITS_H
40 # include <limits.h>
41 #endif
42 #include <stdlib.h>
43 #include <assert.h>
44
45 #include "wget.h"
46 #include "utils.h"
47
48 #include "hash.h"
49
50 #ifdef STANDALONE
51 # undef xmalloc
52 # undef xrealloc
53 # undef xfree
54
55 # define xmalloc malloc
56 # define xrealloc realloc
57 # define xfree free
58
59 # undef TOLOWER
60 # define TOLOWER(x) ('A' <= (x) && (x) <= 'Z' ? (x) - 32 : (x))
61 #endif
62
63 /* INTERFACE:
64
65    Hash tables are a technique used to implement mapping between
66    objects with near-constant-time access and storage.  The table
67    associates keys to values, and a value can be very quickly
68    retrieved by providing the key.  Fast lookup tables are typically
69    implemented as hash tables.
70
71    The entry points are
72      hash_table_new       -- creates the table.
73      hash_table_destroy   -- destroys the table.
74      hash_table_put       -- establishes or updates key->value mapping.
75      hash_table_get       -- retrieves value of key.
76      hash_table_get_pair  -- get key/value pair for key.
77      hash_table_contains  -- test whether the table contains key.
78      hash_table_remove    -- remove the key->value mapping for key.
79      hash_table_map       -- iterate through table mappings.
80      hash_table_clear     -- clear hash table contents.
81      hash_table_count     -- return the number of entries in the table.
82
83    The hash table grows internally as new entries are added and is not
84    limited in size, except by available memory.  The table doubles
85    with each resize, which ensures that the amortized time per
86    operation remains constant.
87
88    By default, tables created by hash_table_new consider the keys to
89    be equal if their pointer values are the same.  You can use
90    make_string_hash_table to create tables whose keys are considered
91    equal if their string contents are the same.  In the general case,
92    the criterion of equality used to compare keys is specified at
93    table creation time with two callback functions, "hash" and "test".
94    The hash function transforms the key into an arbitrary number that
95    must be the same for two equal keys.  The test function accepts two
96    keys and returns non-zero if they are to be considered equal.
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    The hash table is implemented as an open-addressed table with
107    linear probing collision resolution.
108
109    In regular language, it means that all the hash entries (pairs of
110    pointers key and value) are stored in a contiguous array.  The
111    position of each mapping is determined by the hash value of its key
112    and the size of the table: location := hash(key) % size.  If two
113    different keys end up on the same position (collide), the one that
114    came second is placed at the next empty position following the
115    occupied place.  This collision resolution technique is called
116    "linear probing".
117
118    There are more advanced collision resolution methods (quadratic
119    probing, double hashing), but we don't use them because they incur
120    more non-sequential access to the array, which results in worse CPU
121    cache behavior.  Linear probing works well as long as the
122    count/size ratio (fullness) is kept below 75%.  We make sure to
123    grow and rehash the table whenever this threshold is exceeded.
124
125    Collisions make deletion tricky because clearing a position
126    followed by a colliding entry would make the position seem empty
127    and the colliding entry not found.  One solution is to leave a
128    "tombstone" instead of clearing the entry, and another is to
129    carefully rehash the entries immediately following the deleted one.
130    We use the latter method because it results in less bookkeeping and
131    faster retrieval at the (slight) expense of deletion.  */
132
133 /* Maximum allowed fullness: when hash table's fullness exceeds this
134    value, the table is resized.  */
135 #define HASH_MAX_FULLNESS 0.75
136
137 /* The hash table size is multiplied by this factor (and then rounded
138    to the next prime) with each resize.  This guarantees infrequent
139    resizes.  */
140 #define HASH_RESIZE_FACTOR 2
141
142 struct mapping {
143   void *key;
144   void *value;
145 };
146
147 typedef unsigned long (*hashfun_t) PARAMS ((const void *));
148 typedef int (*testfun_t) PARAMS ((const void *, const void *));
149
150 struct hash_table {
151   hashfun_t hash_function;
152   testfun_t test_function;
153
154   struct mapping *mappings;     /* pointer to the table entries. */
155   int size;                     /* size of the array. */
156
157   int count;                    /* number of non-empty entries. */
158   int resize_threshold;         /* after size exceeds this number of
159                                    entries, resize the table.  */
160   int prime_offset;             /* the offset of the current prime in
161                                    the prime table. */
162 };
163
164 /* We use the all-bits-set constant (INVALID_PTR) marker to mean that
165    a mapping is empty.  It is unaligned and therefore illegal as a
166    pointer.  INVALID_PTR_BYTE (0xff) is the one-byte value used to
167    initialize the mappings array as empty.
168
169    The all-bits-set value is a better choice than NULL because it
170    allows the use of NULL/0 keys.  Since the keys are either integers
171    or pointers, the only key that cannot be used is the integer value
172    -1.  This is acceptable because it still allows the use of
173    nonnegative integer keys.  */
174
175 #define INVALID_PTR ((void *) ~(unsigned long)0)
176 #ifndef UCHAR_MAX
177 # define UCHAR_MAX 0xff
178 #endif
179 #define INVALID_PTR_BYTE UCHAR_MAX
180
181 #define NON_EMPTY(mp) ((mp)->key != INVALID_PTR)
182 #define MARK_AS_EMPTY(mp) ((mp)->key = INVALID_PTR)
183
184 /* "Next" mapping is the mapping after MP, but wrapping back to
185    MAPPINGS when MP would reach MAPPINGS+SIZE.  */
186 #define NEXT_MAPPING(mp, mappings, size) (mp != mappings + (size - 1)   \
187                                           ? mp + 1 : mappings)
188
189 /* Loop over non-empty mappings starting at MP. */
190 #define LOOP_NON_EMPTY(mp, mappings, size)                              \
191   for (; NON_EMPTY (mp); mp = NEXT_MAPPING (mp, mappings, size))
192
193 /* Return the position of KEY in hash table SIZE large, hash function
194    being HASHFUN.  */
195 #define HASH_POSITION(key, hashfun, size) ((hashfun) (key) % size)
196
197 /* Find a prime near, but greather than or equal to SIZE.  The primes
198    are looked up from a table with a selection of primes convenient
199    for this purpose.
200
201    PRIME_OFFSET is a minor optimization: it specifies start position
202    for the search for the large enough prime.  The final offset is
203    stored in the same variable.  That way the list of primes does not
204    have to be scanned from the beginning each time around.  */
205
206 static int
207 prime_size (int size, int *prime_offset)
208 {
209   static const unsigned long primes [] = {
210     13, 19, 29, 41, 59, 79, 107, 149, 197, 263, 347, 457, 599, 787, 1031,
211     1361, 1777, 2333, 3037, 3967, 5167, 6719, 8737, 11369, 14783,
212     19219, 24989, 32491, 42257, 54941, 71429, 92861, 120721, 156941,
213     204047, 265271, 344857, 448321, 582821, 757693, 985003, 1280519,
214     1664681, 2164111, 2813353, 3657361, 4754591, 6180989, 8035301,
215     10445899, 13579681, 17653589, 22949669, 29834603, 38784989,
216     50420551, 65546729, 85210757, 110774011, 144006217, 187208107,
217     243370577, 316381771, 411296309, 534685237, 695090819, 903618083,
218     1174703521, 1527114613, 1985248999,
219     (unsigned long)0x99d43ea5, (unsigned long)0xc7fa5177
220   };
221   int i;
222
223   for (i = *prime_offset; i < countof (primes); i++)
224     if (primes[i] >= size)
225       {
226         /* Set the offset to the next prime.  That is safe because,
227            next time we are called, it will be with a larger SIZE,
228            which means we could never return the same prime anyway.
229            (If that is not the case, the caller can simply reset
230            *prime_offset.)  */
231         *prime_offset = i + 1;
232         return primes[i];
233       }
234
235   abort ();
236   return 0;
237 }
238
239 static unsigned long ptrhash PARAMS ((const void *));
240 static int ptrcmp PARAMS ((const void *, const void *));
241
242 /* Create a hash table with hash function HASH_FUNCTION and test
243    function TEST_FUNCTION.  The table is empty (its count is 0), but
244    pre-allocated to store at least ITEMS items.
245
246    ITEMS is the number of items that the table can accept without
247    needing to resize.  It is useful when creating a table that is to
248    be immediately filled with a known number of items.  In that case,
249    the regrows are a waste of time, and specifying ITEMS correctly
250    will avoid them altogether.
251
252    Note that hash tables grow dynamically regardless of ITEMS.  The
253    only use of ITEMS is to preallocate the table and avoid unnecessary
254    dynamic regrows.  Don't bother making ITEMS prime because it's not
255    used as size unchanged.  To start with a small table that grows as
256    needed, simply specify zero ITEMS.
257
258    If hash and test callbacks are not specified, identity mapping is
259    assumed, i.e. pointer values are used for key comparison.  (Common
260    Lisp calls such tables EQ hash tables, and Java calls them
261    IdentityHashMaps.)  If your keys require different comparison,
262    specify hash and test functions.  For easy use of C strings as hash
263    keys, you can use the convenience functions make_string_hash_table
264    and make_nocase_string_hash_table.  */
265
266 struct hash_table *
267 hash_table_new (int items,
268                 unsigned long (*hash_function) (const void *),
269                 int (*test_function) (const void *, const void *))
270 {
271   int size;
272   struct hash_table *ht = xnew (struct hash_table);
273
274   ht->hash_function = hash_function ? hash_function : ptrhash;
275   ht->test_function = test_function ? test_function : ptrcmp;
276
277   /* If the size of struct hash_table ever becomes a concern, this
278      field can go.  (Wget doesn't create many hashes.)  */
279   ht->prime_offset = 0;
280
281   /* Calculate the size that ensures that the table will store at
282      least ITEMS keys without the need to resize.  */
283   size = 1 + items / HASH_MAX_FULLNESS;
284   size = prime_size (size, &ht->prime_offset);
285   ht->size = size;
286   ht->resize_threshold = size * HASH_MAX_FULLNESS;
287   /*assert (ht->resize_threshold >= items);*/
288
289   ht->mappings = xnew_array (struct mapping, ht->size);
290   /* Mark mappings as empty.  We use 0xff rather than 0 to mark empty
291      keys because it allows us to use NULL/0 as keys.  */
292   memset (ht->mappings, INVALID_PTR_BYTE, size * sizeof (struct mapping));
293
294   ht->count = 0;
295
296   return ht;
297 }
298
299 /* Free the data associated with hash table HT. */
300
301 void
302 hash_table_destroy (struct hash_table *ht)
303 {
304   xfree (ht->mappings);
305   xfree (ht);
306 }
307
308 /* The heart of most functions in this file -- find the mapping whose
309    KEY is equal to key, using linear probing.  Returns the mapping
310    that matches KEY, or the first empty mapping if none matches.  */
311
312 static inline struct mapping *
313 find_mapping (const struct hash_table *ht, const void *key)
314 {
315   struct mapping *mappings = ht->mappings;
316   int size = ht->size;
317   struct mapping *mp = mappings + HASH_POSITION (key, ht->hash_function, size);
318   testfun_t equals = ht->test_function;
319
320   LOOP_NON_EMPTY (mp, mappings, size)
321     if (equals (key, mp->key))
322       break;
323   return mp;
324 }
325
326 /* Get the value that corresponds to the key KEY in the hash table HT.
327    If no value is found, return NULL.  Note that NULL is a legal value
328    for value; if you are storing NULLs in your hash table, you can use
329    hash_table_contains to be sure that a (possibly NULL) value exists
330    in the table.  Or, you can use hash_table_get_pair instead of this
331    function.  */
332
333 void *
334 hash_table_get (const struct hash_table *ht, const void *key)
335 {
336   struct mapping *mp = find_mapping (ht, key);
337   if (NON_EMPTY (mp))
338     return mp->value;
339   else
340     return NULL;
341 }
342
343 /* Like hash_table_get, but writes out the pointers to both key and
344    value.  Returns non-zero on success.  */
345
346 int
347 hash_table_get_pair (const struct hash_table *ht, const void *lookup_key,
348                      void *orig_key, void *value)
349 {
350   struct mapping *mp = find_mapping (ht, lookup_key);
351   if (NON_EMPTY (mp))
352     {
353       if (orig_key)
354         *(void **)orig_key = mp->key;
355       if (value)
356         *(void **)value = mp->value;
357       return 1;
358     }
359   else
360     return 0;
361 }
362
363 /* Return 1 if HT contains KEY, 0 otherwise. */
364
365 int
366 hash_table_contains (const struct hash_table *ht, const void *key)
367 {
368   struct mapping *mp = find_mapping (ht, key);
369   return NON_EMPTY (mp);
370 }
371
372 /* Grow hash table HT as necessary, and rehash all the key-value
373    mappings.  */
374
375 static void
376 grow_hash_table (struct hash_table *ht)
377 {
378   hashfun_t hasher = ht->hash_function;
379   struct mapping *old_mappings = ht->mappings;
380   struct mapping *old_end      = ht->mappings + ht->size;
381   struct mapping *mp, *mappings;
382   int newsize;
383
384   newsize = prime_size (ht->size * HASH_RESIZE_FACTOR, &ht->prime_offset);
385 #if 0
386   printf ("growing from %d to %d; fullness %.2f%% to %.2f%%\n",
387           ht->size, newsize,
388           100.0 * ht->count / ht->size,
389           100.0 * ht->count / newsize);
390 #endif
391
392   ht->size = newsize;
393   ht->resize_threshold = newsize * HASH_MAX_FULLNESS;
394
395   mappings = xnew_array (struct mapping, newsize);
396   memset (mappings, INVALID_PTR_BYTE, newsize * sizeof (struct mapping));
397   ht->mappings = mappings;
398
399   for (mp = old_mappings; mp < old_end; mp++)
400     if (NON_EMPTY (mp))
401       {
402         struct mapping *new_mp;
403         /* We don't need to test for uniqueness of keys because they
404            come from the hash table and are therefore known to be
405            unique.  */
406         new_mp = mappings + HASH_POSITION (mp->key, hasher, newsize);
407         LOOP_NON_EMPTY (new_mp, mappings, newsize)
408           ;
409         *new_mp = *mp;
410       }
411
412   xfree (old_mappings);
413 }
414
415 /* Put VALUE in the hash table HT under the key KEY.  This regrows the
416    table if necessary.  */
417
418 void
419 hash_table_put (struct hash_table *ht, const void *key, void *value)
420 {
421   struct mapping *mp = find_mapping (ht, key);
422   if (NON_EMPTY (mp))
423     {
424       /* update existing item */
425       mp->key   = (void *)key; /* const? */
426       mp->value = value;
427       return;
428     }
429
430   /* If adding the item would make the table exceed max. fullness,
431      grow the table first.  */
432   if (ht->count >= ht->resize_threshold)
433     {
434       grow_hash_table (ht);
435       mp = find_mapping (ht, key);
436     }
437
438   /* add new item */
439   ++ht->count;
440   mp->key   = (void *)key;      /* const? */
441   mp->value = value;
442 }
443
444 /* Remove a mapping that matches KEY from HT.  Return 0 if there was
445    no such entry; return 1 if an entry was removed.  */
446
447 int
448 hash_table_remove (struct hash_table *ht, const void *key)
449 {
450   struct mapping *mp = find_mapping (ht, key);
451   if (!NON_EMPTY (mp))
452     return 0;
453   else
454     {
455       int size = ht->size;
456       struct mapping *mappings = ht->mappings;
457       hashfun_t hasher = ht->hash_function;
458
459       MARK_AS_EMPTY (mp);
460       --ht->count;
461
462       /* Rehash all the entries following MP.  The alternative
463          approach is to mark the entry as deleted, i.e. create a
464          "tombstone".  That speeds up removal, but leaves a lot of
465          garbage and slows down hash_table_get and hash_table_put.  */
466
467       mp = NEXT_MAPPING (mp, mappings, size);
468       LOOP_NON_EMPTY (mp, mappings, size)
469         {
470           const void *key2 = mp->key;
471           struct mapping *mp_new;
472
473           /* Find the new location for the key. */
474           mp_new = mappings + HASH_POSITION (key2, hasher, size);
475           LOOP_NON_EMPTY (mp_new, mappings, size)
476             if (key2 == mp_new->key)
477               /* The mapping MP (key2) is already where we want it (in
478                  MP_NEW's "chain" of keys.)  */
479               goto next_rehash;
480
481           *mp_new = *mp;
482           MARK_AS_EMPTY (mp);
483
484         next_rehash:
485           ;
486         }
487       return 1;
488     }
489 }
490
491 /* Clear HT of all entries.  After calling this function, the count
492    and the fullness of the hash table will be zero.  The size will
493    remain unchanged.  */
494
495 void
496 hash_table_clear (struct hash_table *ht)
497 {
498   memset (ht->mappings, INVALID_PTR_BYTE, ht->size * sizeof (struct mapping));
499   ht->count = 0;
500 }
501
502 /* Map MAPFUN over all the mappings in hash table HT.  MAPFUN is
503    called with three arguments: the key, the value, and MAPARG.
504
505    It is undefined what happens if you add or remove entries in the
506    hash table while hash_table_map is running.  The exception is the
507    entry you're currently mapping over; you may remove or change that
508    entry.  */
509
510 void
511 hash_table_map (struct hash_table *ht,
512                 int (*mapfun) (void *, void *, void *),
513                 void *maparg)
514 {
515   struct mapping *mp  = ht->mappings;
516   struct mapping *end = ht->mappings + ht->size;
517
518   for (; mp < end; mp++)
519     if (NON_EMPTY (mp))
520       {
521         void *key;
522       repeat:
523         key = mp->key;
524         if (mapfun (key, mp->value, maparg))
525           return;
526         /* hash_table_remove might have moved the adjacent
527            mappings. */
528         if (mp->key != key && NON_EMPTY (mp))
529           goto repeat;
530       }
531 }
532
533 /* Return the number of elements in the hash table.  This is not the
534    same as the physical size of the hash table, which is always
535    greater than the number of elements.  */
536
537 int
538 hash_table_count (const struct hash_table *ht)
539 {
540   return ht->count;
541 }
542 \f
543 /* Functions from this point onward are meant for convenience and
544    don't strictly belong to this file.  However, this is as good a
545    place for them as any.  */
546
547 /* Rules for creating custom hash and test functions:
548
549    - The test function returns non-zero for keys that are considered
550      "equal", zero otherwise.
551
552    - The hash function returns a number that represents the
553      "distinctness" of the object.  In more precise terms, it means
554      that for any two objects that test "equal" under the test
555      function, the hash function MUST produce the same result.
556
557      This does not mean that all different objects must produce
558      different values (that would be "perfect" hashing), only that
559      non-distinct objects must produce the same values!  For instance,
560      a hash function that returns 0 for any given object is a
561      perfectly valid (albeit extremely bad) hash function.  A hash
562      function that hashes a string by adding up all its characters is
563      another example of a valid (but quite bad) hash function.
564
565      It is not hard to make hash and test functions agree about
566      equality.  For example, if the test function compares strings
567      case-insensitively, the hash function can lower-case the
568      characters when calculating the hash value.  That ensures that
569      two strings differing only in case will hash the same.
570
571    - If you care about performance, choose a hash function with as
572      good "spreading" as possible.  A good hash function will use all
573      the bits of the input when calculating the hash, and will react
574      to even small changes in input with a completely different
575      output.  Finally, don't make the hash function itself overly
576      slow, because you'll be incurring a non-negligible overhead to
577      all hash table operations.  */
578
579 /*
580  * Support for hash tables whose keys are strings.
581  *
582  */
583    
584 /* 31 bit hash function.  Taken from Gnome's glib, modified to use
585    standard C types.
586
587    We used to use the popular hash function from the Dragon Book, but
588    this one seems to perform much better.  */
589
590 unsigned long
591 string_hash (const void *key)
592 {
593   const char *p = key;
594   unsigned int h = *p;
595   
596   if (h)
597     for (p += 1; *p != '\0'; p++)
598       h = (h << 5) - h + *p;
599   
600   return h;
601 }
602
603 /* Frontend for strcmp usable for hash tables. */
604
605 int
606 string_cmp (const void *s1, const void *s2)
607 {
608   return !strcmp ((const char *)s1, (const char *)s2);
609 }
610
611 /* Return a hash table of preallocated to store at least ITEMS items
612    suitable to use strings as keys.  */
613
614 struct hash_table *
615 make_string_hash_table (int items)
616 {
617   return hash_table_new (items, string_hash, string_cmp);
618 }
619
620 /*
621  * Support for hash tables whose keys are strings, but which are
622  * compared case-insensitively.
623  *
624  */
625
626 /* Like string_hash, but produce the same hash regardless of the case. */
627
628 static unsigned long
629 string_hash_nocase (const void *key)
630 {
631   const char *p = key;
632   unsigned int h = TOLOWER (*p);
633   
634   if (h)
635     for (p += 1; *p != '\0'; p++)
636       h = (h << 5) - h + TOLOWER (*p);
637   
638   return h;
639 }
640
641 /* Like string_cmp, but doing case-insensitive compareison. */
642
643 static int
644 string_cmp_nocase (const void *s1, const void *s2)
645 {
646   return !strcasecmp ((const char *)s1, (const char *)s2);
647 }
648
649 /* Like make_string_hash_table, but uses string_hash_nocase and
650    string_cmp_nocase.  */
651
652 struct hash_table *
653 make_nocase_string_hash_table (int items)
654 {
655   return hash_table_new (items, string_hash_nocase, string_cmp_nocase);
656 }
657
658 /* Hashing of numeric values, such as pointers and integers.
659
660    This implementation is the Robert Jenkins' 32 bit Mix Function,
661    with a simple adaptation for 64-bit values.  It offers excellent
662    spreading of values and doesn't need to know the hash table size to
663    work (unlike the very popular Knuth's multiplication hash).  */
664
665 static unsigned long
666 ptrhash (const void *ptr)
667 {
668   unsigned long key = (unsigned long)ptr;
669   key += (key << 12);
670   key ^= (key >> 22);
671   key += (key << 4);
672   key ^= (key >> 9);
673   key += (key << 10);
674   key ^= (key >> 2);
675   key += (key << 7);
676   key ^= (key >> 12);
677 #if SIZEOF_LONG > 4
678   key += (key << 44);
679   key ^= (key >> 54);
680   key += (key << 36);
681   key ^= (key >> 41);
682   key += (key << 42);
683   key ^= (key >> 34);
684   key += (key << 39);
685   key ^= (key >> 44);
686 #endif
687   return key;
688 }
689
690 static int
691 ptrcmp (const void *ptr1, const void *ptr2)
692 {
693   return ptr1 == ptr2;
694 }
695 \f
696 #ifdef STANDALONE
697
698 #include <stdio.h>
699 #include <string.h>
700
701 int
702 print_hash_table_mapper (void *key, void *value, void *count)
703 {
704   ++*(int *)count;
705   printf ("%s: %s\n", (const char *)key, (char *)value);
706   return 0;
707 }
708
709 void
710 print_hash (struct hash_table *sht)
711 {
712   int debug_count = 0;
713   hash_table_map (sht, print_hash_table_mapper, &debug_count);
714   assert (debug_count == sht->count);
715 }
716
717 int
718 main (void)
719 {
720   struct hash_table *ht = make_string_hash_table (0);
721   char line[80];
722   while ((fgets (line, sizeof (line), stdin)))
723     {
724       int len = strlen (line);
725       if (len <= 1)
726         continue;
727       line[--len] = '\0';
728       if (!hash_table_contains (ht, line))
729         hash_table_put (ht, strdup (line), "here I am!");
730 #if 1
731       if (len % 5 == 0)
732         {
733           char *line_copy;
734           if (hash_table_get_pair (ht, line, &line_copy, NULL))
735             {
736               hash_table_remove (ht, line);
737               xfree (line_copy);
738             }
739         }
740 #endif
741     }
742 #if 0
743   print_hash (ht);
744 #endif
745 #if 1
746   printf ("%d %d\n", ht->count, ht->size);
747 #endif
748   return 0;
749 }
750 #endif