renamed the package to libgedcom-dev
[gedcom-parse.git] / gedcom / hash.c
1 /* This file is taken from kazlib 1.20 (see URL
2    http://users.footprints.net/~kaz/kazlib.html)
3    Only this initial comment has been added (plus two "unused" variable
4    attributes and a protection for the original CVS keywords).
5    The next comment gives the original copyright notice.
6 */
7
8 /*
9  * Hash Table Data Type
10  * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
11  *
12  * Free Software License:
13  *
14  * All rights are reserved by the author, with the following exceptions:
15  * Permission is granted to freely reproduce and distribute this software,
16  * possibly in exchange for a fee, provided that this copyright notice appears
17  * intact. Permission is also granted to adapt this software to produce
18  * derivative works, as long as the modified versions carry this copyright
19  * notice and additional notices stating that the work has been modified.
20  * This source code may be translated into executable form and incorporated
21  * into proprietary software; there is no requirement for such software to
22  * contain a copyright notice related to this source.
23  *
24  * $kkId: hash.c,v 1.36.2.11 2000/11/13 01:36:45 kaz Exp $
25  * $kkName: kazlib_1_20 $
26  */
27
28 #include <stdlib.h>
29 #include <stddef.h>
30 #include <assert.h>
31 #include <string.h>
32 #define HASH_IMPLEMENTATION
33 #include "hash.h"
34
35 #ifdef KAZLIB_RCSID
36 static const char rcsid[] = "$kkId: hash.c,v 1.36.2.11 2000/11/13 01:36:45 kaz Exp $";
37 #endif
38
39 #define INIT_BITS       6
40 #define INIT_SIZE       (1UL << (INIT_BITS))    /* must be power of two         */
41 #define INIT_MASK       ((INIT_SIZE) - 1)
42
43 #define next hash_next
44 #define key hash_key
45 #define data hash_data
46 #define hkey hash_hkey
47
48 #define table hash_table
49 #define nchains hash_nchains
50 #define nodecount hash_nodecount
51 #define maxcount hash_maxcount
52 #define highmark hash_highmark
53 #define lowmark hash_lowmark
54 #define compare hash_compare
55 #define function hash_function
56 #define allocnode hash_allocnode
57 #define freenode hash_freenode
58 #define context hash_context
59 #define mask hash_mask
60 #define dynamic hash_dynamic
61
62 #define table hash_table
63 #define chain hash_chain
64
65 static hnode_t *hnode_alloc(void *context);
66 static void hnode_free(hnode_t *node, void *context);
67 static hash_val_t hash_fun_default(const void *key);
68 static int hash_comp_default(const void *key1, const void *key2);
69
70 int hash_val_t_bit;
71
72 /*
73  * Compute the number of bits in the hash_val_t type.  We know that hash_val_t
74  * is an unsigned integral type. Thus the highest value it can hold is a
75  * Mersenne number (power of two, less one). We initialize a hash_val_t
76  * object with this value and then shift bits out one by one while counting.
77  * Notes:
78  * 1. HASH_VAL_T_MAX is a Mersenne number---one that is one less than a power
79  *    of two. This means that its binary representation consists of all one
80  *    bits, and hence ``val'' is initialized to all one bits.
81  * 2. While bits remain in val, we increment the bit count and shift it to the
82  *    right, replacing the topmost bit by zero.
83  */
84
85 static void compute_bits(void)
86 {
87     hash_val_t val = HASH_VAL_T_MAX;    /* 1 */
88     int bits = 0;
89
90     while (val) {       /* 2 */
91         bits++;
92         val >>= 1;
93     }
94
95     hash_val_t_bit = bits;
96 }
97
98 /*
99  * Verify whether the given argument is a power of two.
100  */
101
102 static int is_power_of_two(hash_val_t arg)
103 {
104     if (arg == 0)
105         return 0;
106     while ((arg & 1) == 0)
107         arg >>= 1;
108     return (arg == 1);
109 }
110
111 /*
112  * Compute a shift amount from a given table size 
113  */
114
115 static hash_val_t compute_mask(hashcount_t size)
116 {
117     assert (is_power_of_two(size));
118     assert (size >= 2);
119
120     return size - 1;
121 }
122
123 /*
124  * Initialize the table of pointers to null.
125  */
126
127 static void clear_table(hash_t *hash)
128 {
129     hash_val_t i;
130
131     for (i = 0; i < hash->nchains; i++)
132         hash->table[i] = NULL;
133 }
134
135 /*
136  * Double the size of a dynamic table. This works as follows. Each chain splits
137  * into two adjacent chains.  The shift amount increases by one, exposing an
138  * additional bit of each hashed key. For each node in the original chain, the
139  * value of this newly exposed bit will decide which of the two new chains will
140  * receive the node: if the bit is 1, the chain with the higher index will have
141  * the node, otherwise the lower chain will receive the node. In this manner,
142  * the hash table will continue to function exactly as before without having to
143  * rehash any of the keys.
144  * Notes:
145  * 1.  Overflow check.
146  * 2.  The new number of chains is twice the old number of chains.
147  * 3.  The new mask is one bit wider than the previous, revealing a
148  *     new bit in all hashed keys.
149  * 4.  Allocate a new table of chain pointers that is twice as large as the
150  *     previous one.
151  * 5.  If the reallocation was successful, we perform the rest of the growth
152  *     algorithm, otherwise we do nothing.
153  * 6.  The exposed_bit variable holds a mask with which each hashed key can be
154  *     AND-ed to test the value of its newly exposed bit.
155  * 7.  Now loop over each chain in the table and sort its nodes into two
156  *     chains based on the value of each node's newly exposed hash bit.
157  * 8.  The low chain replaces the current chain.  The high chain goes
158  *     into the corresponding sister chain in the upper half of the table.
159  * 9.  We have finished dealing with the chains and nodes. We now update
160  *     the various bookeeping fields of the hash structure.
161  */
162
163 static void grow_table(hash_t *hash)
164 {
165     hnode_t **newtable;
166
167     assert (2 * hash->nchains > hash->nchains); /* 1 */
168
169     newtable = realloc(hash->table,
170             sizeof *newtable * hash->nchains * 2);      /* 4 */
171
172     if (newtable) {     /* 5 */
173         hash_val_t mask = (hash->mask << 1) | 1;        /* 3 */
174         hash_val_t exposed_bit = mask ^ hash->mask;     /* 6 */
175         hash_val_t chain;
176
177         assert (mask != hash->mask);
178
179         for (chain = 0; chain < hash->nchains; chain++) { /* 7 */
180             hnode_t *low_chain = 0, *high_chain = 0, *hptr, *next;
181
182             for (hptr = newtable[chain]; hptr != 0; hptr = next) {
183                 next = hptr->next;
184
185                 if (hptr->hkey & exposed_bit) {
186                     hptr->next = high_chain;
187                     high_chain = hptr;
188                 } else {
189                     hptr->next = low_chain;
190                     low_chain = hptr;
191                 }
192             }
193
194             newtable[chain] = low_chain;        /* 8 */
195             newtable[chain + hash->nchains] = high_chain;
196         }
197
198         hash->table = newtable;                 /* 9 */
199         hash->mask = mask;
200         hash->nchains *= 2;
201         hash->lowmark *= 2;
202         hash->highmark *= 2;
203     }
204     assert (hash_verify(hash));
205 }
206
207 /*
208  * Cut a table size in half. This is done by folding together adjacent chains
209  * and populating the lower half of the table with these chains. The chains are
210  * simply spliced together. Once this is done, the whole table is reallocated
211  * to a smaller object.
212  * Notes:
213  * 1.  It is illegal to have a hash table with one slot. This would mean that
214  *     hash->shift is equal to hash_val_t_bit, an illegal shift value.
215  *     Also, other things could go wrong, such as hash->lowmark becoming zero.
216  * 2.  Looping over each pair of sister chains, the low_chain is set to
217  *     point to the head node of the chain in the lower half of the table, 
218  *     and high_chain points to the head node of the sister in the upper half.
219  * 3.  The intent here is to compute a pointer to the last node of the
220  *     lower chain into the low_tail variable. If this chain is empty,
221  *     low_tail ends up with a null value.
222  * 4.  If the lower chain is not empty, we simply tack the upper chain onto it.
223  *     If the upper chain is a null pointer, nothing happens.
224  * 5.  Otherwise if the lower chain is empty but the upper one is not,
225  *     If the low chain is empty, but the high chain is not, then the
226  *     high chain is simply transferred to the lower half of the table.
227  * 6.  Otherwise if both chains are empty, there is nothing to do.
228  * 7.  All the chain pointers are in the lower half of the table now, so
229  *     we reallocate it to a smaller object. This, of course, invalidates
230  *     all pointer-to-pointers which reference into the table from the
231  *     first node of each chain.
232  * 8.  Though it's unlikely, the reallocation may fail. In this case we
233  *     pretend that the table _was_ reallocated to a smaller object.
234  * 9.  Finally, update the various table parameters to reflect the new size.
235  */
236
237 static void shrink_table(hash_t *hash)
238 {
239     hash_val_t chain, nchains;
240     hnode_t **newtable, *low_tail, *low_chain, *high_chain;
241
242     assert (hash->nchains >= 2);                        /* 1 */
243     nchains = hash->nchains / 2;
244
245     for (chain = 0; chain < nchains; chain++) {
246         low_chain = hash->table[chain];         /* 2 */
247         high_chain = hash->table[chain + nchains];
248         for (low_tail = low_chain; low_tail && low_tail->next; low_tail = low_tail->next)
249             ;   /* 3 */
250         if (low_chain != 0)                             /* 4 */
251             low_tail->next = high_chain;
252         else if (high_chain != 0)                       /* 5 */
253             hash->table[chain] = high_chain;
254         else
255             assert (hash->table[chain] == NULL);        /* 6 */
256     }
257     newtable = realloc(hash->table,
258             sizeof *newtable * nchains);                /* 7 */
259     if (newtable)                                       /* 8 */
260         hash->table = newtable;
261     hash->mask >>= 1;                   /* 9 */
262     hash->nchains = nchains;
263     hash->lowmark /= 2;
264     hash->highmark /= 2;
265     assert (hash_verify(hash));
266 }
267
268
269 /*
270  * Create a dynamic hash table. Both the hash table structure and the table
271  * itself are dynamically allocated. Furthermore, the table is extendible in
272  * that it will automatically grow as its load factor increases beyond a
273  * certain threshold.
274  * Notes:
275  * 1. If the number of bits in the hash_val_t type has not been computed yet,
276  *    we do so here, because this is likely to be the first function that the
277  *    user calls.
278  * 2. Allocate a hash table control structure.
279  * 3. If a hash table control structure is successfully allocated, we
280  *    proceed to initialize it. Otherwise we return a null pointer.
281  * 4. We try to allocate the table of hash chains.
282  * 5. If we were able to allocate the hash chain table, we can finish
283  *    initializing the hash structure and the table. Otherwise, we must
284  *    backtrack by freeing the hash structure.
285  * 6. INIT_SIZE should be a power of two. The high and low marks are always set
286  *    to be twice the table size and half the table size respectively. When the
287  *    number of nodes in the table grows beyond the high size (beyond load
288  *    factor 2), it will double in size to cut the load factor down to about
289  *    about 1. If the table shrinks down to or beneath load factor 0.5,
290  *    it will shrink, bringing the load up to about 1. However, the table
291  *    will never shrink beneath INIT_SIZE even if it's emptied.
292  * 7. This indicates that the table is dynamically allocated and dynamically
293  *    resized on the fly. A table that has this value set to zero is
294  *    assumed to be statically allocated and will not be resized.
295  * 8. The table of chains must be properly reset to all null pointers.
296  */
297
298 hash_t *hash_create(hashcount_t maxcount, hash_comp_t compfun,
299         hash_fun_t hashfun)
300 {
301     hash_t *hash;
302
303     if (hash_val_t_bit == 0)    /* 1 */
304         compute_bits();
305
306     hash = malloc(sizeof *hash);        /* 2 */
307
308     if (hash) {         /* 3 */
309         hash->table = malloc(sizeof *hash->table * INIT_SIZE);  /* 4 */
310         if (hash->table) {      /* 5 */
311             hash->nchains = INIT_SIZE;          /* 6 */
312             hash->highmark = INIT_SIZE * 2;
313             hash->lowmark = INIT_SIZE / 2;
314             hash->nodecount = 0;
315             hash->maxcount = maxcount;
316             hash->compare = compfun ? compfun : hash_comp_default;
317             hash->function = hashfun ? hashfun : hash_fun_default;
318             hash->allocnode = hnode_alloc;
319             hash->freenode = hnode_free;
320             hash->context = NULL;
321             hash->mask = INIT_MASK;
322             hash->dynamic = 1;                  /* 7 */
323             clear_table(hash);                  /* 8 */
324             assert (hash_verify(hash));
325             return hash;
326         } 
327         free(hash);
328     }
329
330     return NULL;
331 }
332
333 /*
334  * Select a different set of node allocator routines.
335  */
336
337 void hash_set_allocator(hash_t *hash, hnode_alloc_t al,
338         hnode_free_t fr, void *context)
339 {
340     assert (hash_count(hash) == 0);
341     assert ((al == 0 && fr == 0) || (al != 0 && fr != 0));
342
343     hash->allocnode = al ? al : hnode_alloc;
344     hash->freenode = fr ? fr : hnode_free;
345     hash->context = context;
346 }
347
348 /*
349  * Free every node in the hash using the hash->freenode() function pointer, and
350  * cause the hash to become empty.
351  */
352
353 void hash_free_nodes(hash_t *hash)
354 {
355     hscan_t hs;
356     hnode_t *node;
357     hash_scan_begin(&hs, hash);
358     while ((node = hash_scan_next(&hs))) {
359         hash_scan_delete(hash, node);
360         hash->freenode(node, hash->context);
361     }
362     hash->nodecount = 0;
363     clear_table(hash);
364 }
365
366 /*
367  * Obsolescent function for removing all nodes from a table,
368  * freeing them and then freeing the table all in one step.
369  */
370
371 void hash_free(hash_t *hash)
372 {
373 #ifdef KAZLIB_OBSOLESCENT_DEBUG
374     assert ("call to obsolescent function hash_free()" && 0);
375 #endif
376     hash_free_nodes(hash);
377     hash_destroy(hash);
378 }
379
380 /*
381  * Free a dynamic hash table structure.
382  */
383
384 void hash_destroy(hash_t *hash)
385 {
386     assert (hash_val_t_bit != 0);
387     assert (hash_isempty(hash));
388     free(hash->table);
389     free(hash);
390 }
391
392 /*
393  * Initialize a user supplied hash structure. The user also supplies a table of
394  * chains which is assigned to the hash structure. The table is static---it
395  * will not grow or shrink.
396  * 1. See note 1. in hash_create().
397  * 2. The user supplied array of pointers hopefully contains nchains nodes.
398  * 3. See note 7. in hash_create().
399  * 4. We must dynamically compute the mask from the given power of two table
400  *    size. 
401  * 5. The user supplied table can't be assumed to contain null pointers,
402  *    so we reset it here.
403  */
404
405 hash_t *hash_init(hash_t *hash, hashcount_t maxcount,
406         hash_comp_t compfun, hash_fun_t hashfun, hnode_t **table,
407         hashcount_t nchains)
408 {
409     if (hash_val_t_bit == 0)    /* 1 */
410         compute_bits();
411
412     assert (is_power_of_two(nchains));
413
414     hash->table = table;        /* 2 */
415     hash->nchains = nchains;
416     hash->nodecount = 0;
417     hash->maxcount = maxcount;
418     hash->compare = compfun ? compfun : hash_comp_default;
419     hash->function = hashfun ? hashfun : hash_fun_default;
420     hash->dynamic = 0;          /* 3 */
421     hash->mask = compute_mask(nchains); /* 4 */
422     clear_table(hash);          /* 5 */
423
424     assert (hash_verify(hash));
425
426     return hash;
427 }
428
429 /*
430  * Reset the hash scanner so that the next element retrieved by
431  * hash_scan_next() shall be the first element on the first non-empty chain. 
432  * Notes:
433  * 1. Locate the first non empty chain.
434  * 2. If an empty chain is found, remember which one it is and set the next
435  *    pointer to refer to its first element.
436  * 3. Otherwise if a chain is not found, set the next pointer to NULL
437  *    so that hash_scan_next() shall indicate failure.
438  */
439
440 void hash_scan_begin(hscan_t *scan, hash_t *hash)
441 {
442     hash_val_t nchains = hash->nchains;
443     hash_val_t chain;
444
445     scan->table = hash;
446
447     /* 1 */
448
449     for (chain = 0; chain < nchains && hash->table[chain] == 0; chain++)
450         ;
451
452     if (chain < nchains) {      /* 2 */
453         scan->chain = chain;
454         scan->next = hash->table[chain];
455     } else {                    /* 3 */
456         scan->next = NULL;
457     }
458 }
459
460 /*
461  * Retrieve the next node from the hash table, and update the pointer
462  * for the next invocation of hash_scan_next(). 
463  * Notes:
464  * 1. Remember the next pointer in a temporary value so that it can be
465  *    returned.
466  * 2. This assertion essentially checks whether the module has been properly
467  *    initialized. The first point of interaction with the module should be
468  *    either hash_create() or hash_init(), both of which set hash_val_t_bit to
469  *    a non zero value.
470  * 3. If the next pointer we are returning is not NULL, then the user is
471  *    allowed to call hash_scan_next() again. We prepare the new next pointer
472  *    for that call right now. That way the user is allowed to delete the node
473  *    we are about to return, since we will no longer be needing it to locate
474  *    the next node.
475  * 4. If there is a next node in the chain (next->next), then that becomes the
476  *    new next node, otherwise ...
477  * 5. We have exhausted the current chain, and must locate the next subsequent
478  *    non-empty chain in the table.
479  * 6. If a non-empty chain is found, the first element of that chain becomes
480  *    the new next node. Otherwise there is no new next node and we set the
481  *    pointer to NULL so that the next time hash_scan_next() is called, a null
482  *    pointer shall be immediately returned.
483  */
484
485
486 hnode_t *hash_scan_next(hscan_t *scan)
487 {
488     hnode_t *next = scan->next;         /* 1 */
489     hash_t *hash = scan->table;
490     hash_val_t chain = scan->chain + 1;
491     hash_val_t nchains = hash->nchains;
492
493     assert (hash_val_t_bit != 0);       /* 2 */
494
495     if (next) {                 /* 3 */
496         if (next->next) {       /* 4 */
497             scan->next = next->next;
498         } else {
499             while (chain < nchains && hash->table[chain] == 0)  /* 5 */
500                 chain++;
501             if (chain < nchains) {      /* 6 */
502                 scan->chain = chain;
503                 scan->next = hash->table[chain];
504             } else {
505                 scan->next = NULL;
506             }
507         }
508     }
509     return next;
510 }
511
512 /*
513  * Insert a node into the hash table.
514  * Notes:
515  * 1. It's illegal to insert more than the maximum number of nodes. The client
516  *    should verify that the hash table is not full before attempting an
517  *    insertion.
518  * 2. The same key may not be inserted into a table twice.
519  * 3. If the table is dynamic and the load factor is already at >= 2,
520  *    grow the table.
521  * 4. We take the bottom N bits of the hash value to derive the chain index,
522  *    where N is the base 2 logarithm of the size of the hash table. 
523  */
524
525 void hash_insert(hash_t *hash, hnode_t *node, const void *key)
526 {
527     hash_val_t hkey, chain;
528
529     assert (hash_val_t_bit != 0);
530     assert (node->next == NULL);
531     assert (hash->nodecount < hash->maxcount);  /* 1 */
532     assert (hash_lookup(hash, key) == NULL);    /* 2 */
533
534     if (hash->dynamic && hash->nodecount >= hash->highmark)     /* 3 */
535         grow_table(hash);
536
537     hkey = hash->function(key);
538     chain = hkey & hash->mask;  /* 4 */
539
540     node->key = key;
541     node->hkey = hkey;
542     node->next = hash->table[chain];
543     hash->table[chain] = node;
544     hash->nodecount++;
545
546     assert (hash_verify(hash));
547 }
548
549 /*
550  * Find a node in the hash table and return a pointer to it.
551  * Notes:
552  * 1. We hash the key and keep the entire hash value. As an optimization, when
553  *    we descend down the chain, we can compare hash values first and only if
554  *    hash values match do we perform a full key comparison. 
555  * 2. To locate the chain from among 2^N chains, we look at the lower N bits of
556  *    the hash value by anding them with the current mask.
557  * 3. Looping through the chain, we compare the stored hash value inside each
558  *    node against our computed hash. If they match, then we do a full
559  *    comparison between the unhashed keys. If these match, we have located the
560  *    entry.
561  */
562
563 hnode_t *hash_lookup(hash_t *hash, const void *key)
564 {
565     hash_val_t hkey, chain;
566     hnode_t *nptr;
567
568     hkey = hash->function(key);         /* 1 */
569     chain = hkey & hash->mask;          /* 2 */
570
571     for (nptr = hash->table[chain]; nptr; nptr = nptr->next) {  /* 3 */
572         if (nptr->hkey == hkey && hash->compare(nptr->key, key) == 0)
573             return nptr;
574     }
575
576     return NULL;
577 }
578
579 /*
580  * Delete the given node from the hash table.  Since the chains
581  * are singly linked, we must locate the start of the node's chain
582  * and traverse.
583  * Notes:
584  * 1. The node must belong to this hash table, and its key must not have
585  *    been tampered with.
586  * 2. If this deletion will take the node count below the low mark, we
587  *    shrink the table now. 
588  * 3. Determine which chain the node belongs to, and fetch the pointer
589  *    to the first node in this chain.
590  * 4. If the node being deleted is the first node in the chain, then
591  *    simply update the chain head pointer.
592  * 5. Otherwise advance to the node's predecessor, and splice out
593  *    by updating the predecessor's next pointer.
594  * 6. Indicate that the node is no longer in a hash table.
595  */
596
597 hnode_t *hash_delete(hash_t *hash, hnode_t *node)
598 {
599     hash_val_t chain;
600     hnode_t *hptr;
601
602     assert (hash_lookup(hash, node->key) == node);      /* 1 */
603     assert (hash_val_t_bit != 0);
604
605     if (hash->dynamic && hash->nodecount <= hash->lowmark
606             && hash->nodecount > INIT_SIZE)
607         shrink_table(hash);                             /* 2 */
608
609     chain = node->hkey & hash->mask;                    /* 3 */
610     hptr = hash->table[chain];
611
612     if (hptr == node) {                                 /* 4 */
613         hash->table[chain] = node->next;
614     } else {
615         while (hptr->next != node) {                    /* 5 */
616             assert (hptr != 0);
617             hptr = hptr->next;
618         }
619         assert (hptr->next == node);
620         hptr->next = node->next;
621     }
622         
623     hash->nodecount--;
624     assert (hash_verify(hash));
625
626     node->next = NULL;                                  /* 6 */
627     return node;
628 }
629
630 int hash_alloc_insert(hash_t *hash, const void *key, void *data)
631 {
632     hnode_t *node = hash->allocnode(hash->context);
633
634     if (node) {
635         hnode_init(node, data);
636         hash_insert(hash, node, key);
637         return 1;
638     }
639     return 0;
640 }
641
642 void hash_delete_free(hash_t *hash, hnode_t *node)
643 {
644     hash_delete(hash, node);
645     hash->freenode(node, hash->context);
646 }
647
648 /*
649  *  Exactly like hash_delete, except does not trigger table shrinkage. This is to be
650  *  used from within a hash table scan operation. See notes for hash_delete.
651  */
652
653 hnode_t *hash_scan_delete(hash_t *hash, hnode_t *node)
654 {
655     hash_val_t chain;
656     hnode_t *hptr;
657
658     assert (hash_lookup(hash, node->key) == node);
659     assert (hash_val_t_bit != 0);
660
661     chain = node->hkey & hash->mask;
662     hptr = hash->table[chain];
663
664     if (hptr == node) {
665         hash->table[chain] = node->next;
666     } else {
667         while (hptr->next != node) 
668             hptr = hptr->next;
669         hptr->next = node->next;
670     }
671         
672     hash->nodecount--;
673     assert (hash_verify(hash));
674     node->next = NULL;
675
676     return node;
677 }
678
679 /*
680  * Like hash_delete_free but based on hash_scan_delete.
681  */
682
683 void hash_scan_delfree(hash_t *hash, hnode_t *node)
684 {
685     hash_scan_delete(hash, node);
686     hash->freenode(node, hash->context);
687 }
688
689 /*
690  * Verify whether the given object is a valid hash table. This means
691  * Notes:
692  * 1. If the hash table is dynamic, verify whether the high and
693  *    low expansion/shrinkage thresholds are powers of two.
694  * 2. Count all nodes in the table, and test each hash value
695  *    to see whether it is correct for the node's chain.
696  */
697
698 int hash_verify(hash_t *hash)
699 {
700     hashcount_t count = 0;
701     hash_val_t chain;
702     hnode_t *hptr;
703
704     if (hash->dynamic) {        /* 1 */
705         if (hash->lowmark >= hash->highmark)
706             return 0;
707         if (!is_power_of_two(hash->highmark))
708             return 0;
709         if (!is_power_of_two(hash->lowmark))
710             return 0;
711     }
712
713     for (chain = 0; chain < hash->nchains; chain++) {   /* 2 */
714         for (hptr = hash->table[chain]; hptr != 0; hptr = hptr->next) {
715             if ((hptr->hkey & hash->mask) != chain)
716                 return 0;
717             count++;
718         }
719     }
720
721     if (count != hash->nodecount)
722         return 0;
723
724     return 1;
725 }
726
727 /*
728  * Test whether the hash table is full and return 1 if this is true,
729  * 0 if it is false.
730  */
731
732 #undef hash_isfull
733 int hash_isfull(hash_t *hash)
734 {
735     return hash->nodecount == hash->maxcount;
736 }
737
738 /*
739  * Test whether the hash table is empty and return 1 if this is true,
740  * 0 if it is false.
741  */
742
743 #undef hash_isempty
744 int hash_isempty(hash_t *hash)
745 {
746     return hash->nodecount == 0;
747 }
748
749 static hnode_t *hnode_alloc(void *context __attribute__((unused)))
750 {
751     return malloc(sizeof *hnode_alloc(NULL));
752 }
753
754 static void hnode_free(hnode_t *node, void *context __attribute__((unused)))
755 {
756     free(node);
757 }
758
759
760 /*
761  * Create a hash table node dynamically and assign it the given data.
762  */
763
764 hnode_t *hnode_create(void *data)
765 {
766     hnode_t *node = malloc(sizeof *node);
767     if (node) {
768         node->data = data;
769         node->next = NULL;
770     }
771     return node;
772 }
773
774 /*
775  * Initialize a client-supplied node 
776  */
777
778 hnode_t *hnode_init(hnode_t *hnode, void *data)
779 {
780     hnode->data = data;
781     hnode->next = NULL;
782     return hnode;
783 }
784
785 /*
786  * Destroy a dynamically allocated node.
787  */
788
789 void hnode_destroy(hnode_t *hnode)
790 {
791     free(hnode);
792 }
793
794 #undef hnode_put
795 void hnode_put(hnode_t *node, void *data)
796 {
797     node->data = data;
798 }
799
800 #undef hnode_get
801 void *hnode_get(hnode_t *node)
802 {
803     return node->data;
804 }
805
806 #undef hnode_getkey
807 const void *hnode_getkey(hnode_t *node)
808 {
809     return node->key;
810 }
811
812 #undef hash_count
813 hashcount_t hash_count(hash_t *hash)
814 {
815     return hash->nodecount;
816 }
817
818 #undef hash_size
819 hashcount_t hash_size(hash_t *hash)
820 {
821     return hash->nchains;
822 }
823
824 static hash_val_t hash_fun_default(const void *key)
825 {
826     static unsigned long randbox[] = {
827         0x49848f1bU, 0xe6255dbaU, 0x36da5bdcU, 0x47bf94e9U,
828         0x8cbcce22U, 0x559fc06aU, 0xd268f536U, 0xe10af79aU,
829         0xc1af4d69U, 0x1d2917b5U, 0xec4c304dU, 0x9ee5016cU,
830         0x69232f74U, 0xfead7bb3U, 0xe9089ab6U, 0xf012f6aeU,
831     };
832
833     const unsigned char *str = key;
834     hash_val_t acc = 0;
835
836     while (*str) {
837         acc ^= randbox[(*str + acc) & 0xf];
838         acc = (acc << 1) | (acc >> 31);
839         acc &= 0xffffffffU;
840         acc ^= randbox[((*str++ >> 4) + acc) & 0xf];
841         acc = (acc << 2) | (acc >> 30);
842         acc &= 0xffffffffU;
843     }
844     return acc;
845 }
846
847 static int hash_comp_default(const void *key1, const void *key2)
848 {
849     return strcmp(key1, key2);
850 }
851
852 #ifdef KAZLIB_TEST_MAIN
853
854 #include <stdio.h>
855 #include <ctype.h>
856 #include <stdarg.h>
857
858 typedef char input_t[256];
859
860 static int tokenize(char *string, ...)
861 {
862     char **tokptr; 
863     va_list arglist;
864     int tokcount = 0;
865
866     va_start(arglist, string);
867     tokptr = va_arg(arglist, char **);
868     while (tokptr) {
869         while (*string && isspace((unsigned char) *string))
870             string++;
871         if (!*string)
872             break;
873         *tokptr = string;
874         while (*string && !isspace((unsigned char) *string))
875             string++;
876         tokptr = va_arg(arglist, char **);
877         tokcount++;
878         if (!*string)
879             break;
880         *string++ = 0;
881     }
882     va_end(arglist);
883
884     return tokcount;
885 }
886
887 static char *dupstring(char *str)
888 {
889     int sz = strlen(str) + 1;
890     char *new = malloc(sz);
891     if (new)
892         memcpy(new, str, sz);
893     return new;
894 }
895
896 static hnode_t *new_node(void *c)
897 {
898     static hnode_t few[5];
899     static int count;
900
901     if (count < 5)
902         return few + count++;
903
904     return NULL;
905 }
906
907 static void del_node(hnode_t *n, void *c)
908 {
909 }
910
911 int main(void)
912 {
913     input_t in;
914     hash_t *h = hash_create(HASHCOUNT_T_MAX, 0, 0);
915     hnode_t *hn;
916     hscan_t hs;
917     char *tok1, *tok2, *val;
918     const char *key;
919     int prompt = 0;
920
921     char *help =
922         "a <key> <val>          add value to hash table\n"
923         "d <key>                delete value from hash table\n"
924         "l <key>                lookup value in hash table\n"
925         "n                      show size of hash table\n"
926         "c                      show number of entries\n"
927         "t                      dump whole hash table\n"
928         "+                      increase hash table (private func)\n"
929         "-                      decrease hash table (private func)\n"
930         "b                      print hash_t_bit value\n"
931         "p                      turn prompt on\n"
932         "s                      switch to non-functioning allocator\n"
933         "q                      quit";
934
935     if (!h)
936         puts("hash_create failed");
937
938     for (;;) {
939         if (prompt)
940             putchar('>');
941         fflush(stdout);
942
943         if (!fgets(in, sizeof(input_t), stdin))
944             break;
945
946         switch(in[0]) {
947             case '?':
948                 puts(help);
949                 break;
950             case 'b':
951                 printf("%d\n", hash_val_t_bit);
952                 break;
953             case 'a':
954                 if (tokenize(in+1, &tok1, &tok2, (char **) 0) != 2) {
955                     puts("what?");
956                     break;
957                 }
958                 key = dupstring(tok1);
959                 val = dupstring(tok2);
960
961                 if (!key || !val) {
962                     puts("out of memory");
963                     free((void *) key);
964                     free(val);
965                 }
966
967                 if (!hash_alloc_insert(h, key, val)) {
968                     puts("hash_alloc_insert failed");
969                     free((void *) key);
970                     free(val);
971                     break;
972                 }
973                 break;
974             case 'd':
975                 if (tokenize(in+1, &tok1, (char **) 0) != 1) {
976                     puts("what?");
977                     break;
978                 }
979                 hn = hash_lookup(h, tok1);
980                 if (!hn) {
981                     puts("hash_lookup failed");
982                     break;
983                 }
984                 val = hnode_get(hn);
985                 key = hnode_getkey(hn);
986                 hash_scan_delfree(h, hn);
987                 free((void *) key);
988                 free(val);
989                 break;
990             case 'l':
991                 if (tokenize(in+1, &tok1, (char **) 0) != 1) {
992                     puts("what?");
993                     break;
994                 }
995                 hn = hash_lookup(h, tok1);
996                 if (!hn) {
997                     puts("hash_lookup failed");
998                     break;
999                 }
1000                 val = hnode_get(hn);
1001                 puts(val);
1002                 break;
1003             case 'n':
1004                 printf("%lu\n", (unsigned long) hash_size(h));
1005                 break;
1006             case 'c':
1007                 printf("%lu\n", (unsigned long) hash_count(h));
1008                 break;
1009             case 't':
1010                 hash_scan_begin(&hs, h);
1011                 while ((hn = hash_scan_next(&hs)))
1012                     printf("%s\t%s\n", (char*) hnode_getkey(hn),
1013                             (char*) hnode_get(hn));
1014                 break;
1015             case '+':
1016                 grow_table(h);          /* private function     */
1017                 break;
1018             case '-':
1019                 shrink_table(h);        /* private function     */
1020                 break;
1021             case 'q':
1022                 exit(0);
1023                 break;
1024             case '\0':
1025                 break;
1026             case 'p':
1027                 prompt = 1;
1028                 break;
1029             case 's':
1030                 hash_set_allocator(h, new_node, del_node, NULL);
1031                 break;
1032             default:
1033                 putchar('?');
1034                 putchar('\n');
1035                 break;
1036         }
1037     }
1038
1039     return 0;
1040 }
1041
1042 #endif