librnr  1.14.5
RoadNarrows Robotics Common Library 1
hash.c
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // Package: RoadNarrows Robotics Common Library 1
4 //
5 // Library: librnr
6 //
7 // File: hash.c
8 //
9 /*! \file
10  *
11  * $LastChangedDate: 2010-03-24 10:19:36 -0600 (Wed, 24 Mar 2010) $
12  * $Rev: 307 $
13  *
14  * \brief General purpose hash data and function declarations.
15  *
16  * This file has been modified from the original source (see below).
17  *
18  * Exceptons map to assert() calls that terminate the calling application.
19  *
20  * \todo
21  * Convert the assert() error handling to appropriate return codes and librnr
22  * error handling.
23  *
24  * \author Robin Knight (robin.knight@roadnarrows.com)
25  *
26  * \pkgcopyright{2005-2018,RoadNarrows LLC.,http://www.roadnarrows.com}
27  *
28  * <hr>
29  * \par Original Source and Copyright:
30  *
31  * \par Original Author:
32  * Kaz Kylheku (kaz@ashi.footprints.net)
33  *
34  * \par Original Copyright:
35  * (C) 1997
36  *
37  * \par Original Header:
38  * See "Original Source Header EULA" in source file.
39  *
40  * <hr>
41  */
42 // Permission is hereby granted, without written agreement and without
43 // license or royalty fees, to use, copy, modify, and distribute this
44 // software and its documentation for any purpose, provided that
45 // (1) The above copyright notice and the following two paragraphs
46 // appear in all copies of the source code and (2) redistributions
47 // including binaries reproduces these notices in the supporting
48 // documentation. Substantial modifications to this software may be
49 // copyrighted by their authors and need not follow the licensing terms
50 // described here, provided that the new terms are clearly indicated in
51 // all files where they apply.
52 //
53 // IN NO EVENT SHALL THE AUTHOR, ROADNARROWS LLC, OR ANY MEMBERS/EMPLOYEES
54 // OF ROADNARROW LLC OR DISTRIBUTORS OF THIS SOFTWARE BE LIABLE TO ANY
55 // PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
56 // DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
57 // EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN ADVISED OF
58 // THE POSSIBILITY OF SUCH DAMAGE.
59 //
60 // THE AUTHOR AND ROADNARROWS LLC SPECIFICALLY DISCLAIM ANY WARRANTIES,
61 // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
62 // FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN
63 // "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO
64 // PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
65 //
66 // Original Source Header EULA:
67 //
68 // Hash Table Data Type
69 // Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
70 //
71 // Free Software License:
72 //
73 // All rights are reserved by the author, with the following exceptions:
74 // Permission is granted to freely reproduce and distribute this software,
75 // possibly in exchange for a fee, provided that this copyright notice appears
76 // intact. Permission is also granted to adapt this software to produce
77 // derivative works, as long as the modified versions carry this copyright
78 // notice and additional notices stating that the work has been modified.
79 // The copyright extends to translations of this work into other languages,
80 // including machine languages.
81 //
82 // $Id: hash.h,v 1.1 1999/11/05 00:22:34 jtravis Exp $
83 // $Name: $
84 //
85 ////////////////////////////////////////////////////////////////////////////////
86 
87 #include <stdlib.h>
88 #include <stddef.h>
89 #include <assert.h>
90 #include <string.h>
91 
92 #include "rnr/rnrconfig.h"
93 #include "rnr/new.h"
94 #include "rnr/log.h"
95 
96 #include "rnr/hash.h"
97 
98 // ---------------------------------------------------------------------------
99 // Private Interface
100 // ---------------------------------------------------------------------------
101 
102 //
103 // Original RCS Id and copyright strings. Note used, but keep.
104 //
105 #if 0
106 static const char rcsid[] = "$Id: hash.c,v 1.2 2002/03/11 00:51:44 jick Exp $";
107 static const char right[] = "Copyright (C) 1997 Kaz Kylheku";
108 #endif
109 
110 
111 /*!
112  * \brief Number of bits in hashed value. Must be a power of 2.
113  */
114 static int hash_val_t_bit = 0;
115 
116 /*!
117  * \brief Do [not] perform auto-verification after hash table operations.
118  */
119 static bool_t hash_self_verify = false;
120 
121 /*!
122  * \brief Compute the number of bits in the \ref hash_val_t type.
123  *
124  * We know that \ref hash_val_t is an unsigned integral type.
125  * Thus the highest value it can hold is a
126  * Mersenne number (power of two, less one). We initialize a \ref hash_val_t
127  * object with this value and then shift bits out one by one while counting.
128  *
129  * \par Notes &amp; Steps:
130  * \b 1.
131  * \ref HASH_VAL_T_MAX is a Mersenne number---one that is one less than a
132  * power of two. This means that its binary representation consists of all
133  * one bits, and hence ``val'' is initialized to all one bits.\n
134  * \b 2.
135  * We reset the bit count to zero in case this function is invoked more than
136  * once.\n
137  * \b 3.
138  * While bits remain in val, we increment the bit count and shift it to the
139  * right, replacing the topmost bit by zero.
140  */
141 static void compute_bits()
142 {
143  hash_val_t val = HASH_VAL_T_MAX; // Steps 1
144  int bits = 0;
145 
146  // Steps 3
147  while(val)
148  {
149  bits++;
150  val >>= 1;
151  }
152 
153  hash_val_t_bit = bits;
154 }
155 
156 /*!
157  * \brief Verify whether the given argument is a power of two.
158  *
159  * \param arg Argument to test.
160  *
161  * \return Returns true if arg is a power of 2, false otherwise.
162  */
164 {
165  if( arg == 0 )
166  {
167  return false;
168  }
169 
170  while( (arg & 0x01) == 0 )
171  {
172  arg >>= 1;
173  }
174 
175  return arg == 1? true: false;
176 }
177 
178 /*!
179  * \brief Compute a mask for a given table size.
180  *
181  * \param size Table size.
182  *
183  * \return Shift amount.
184  */
186 {
187  hash_val_t mask = size;
188 
189  assert(is_power_of_two(size));
190  assert(size >= 2);
191 
192  mask /= 2;
193 
194  while( (mask & 0x01) == 0 )
195  {
196  mask |= (mask >> 1);
197  }
198 
199  return mask;
200 }
201 
202 
203 /*!
204  * \brief Initialize the table size values.
205  *
206  * The minimum size is adjusted to be a power of two and is guaranteed to be
207  * at least \ref HASH_MIN_SIZE.
208  *
209  * The maximum size adjusted to be >= minsize.
210  *
211  * \param hash Hash table.
212  * \param minsize Desired minimum and initial size.
213  * \param maxsize Desired maximum size.
214  */
215 static void init_hash_sizes(hash_t *hash,
216  hashcount_t minsize,
217  hashcount_t maxsize)
218 {
219  size_t numbits, rshift, lshift;
220 
221  // number of bits in hashcount_t
222  numbits = sizeof(hashcount_t) * 8;
223 
224  // round down to the closest power of two value
225  for(rshift=0, lshift=0; rshift<numbits; ++rshift)
226  {
227  if( minsize & 0x01 )
228  {
229  lshift = rshift;
230  }
231  minsize >>= 1;
232  }
233  minsize = lshift>0? (((hashcount_t)(0x01)) << lshift):
235 
236  // absolute minimum
237  if( minsize < HASH_MIN_SIZE )
238  {
239  minsize = HASH_MIN_SIZE;
240  }
241 
242  if( maxsize < minsize )
243  {
244  maxsize = minsize;
245  }
246 
247  hash->minsize = minsize;
248  hash->maxsize = maxsize;
249  hash->lowmark = minsize / 2;
250  hash->highmark = minsize * 2;
251 
252  LOGDIAG4("minsize=%lu, maxsize=%lu, lowmark=%lu, highmark=%lu",
253  hash->minsize, hash->maxsize, hash->lowmark, hash->highmark);
254 }
255 
256 /*!
257  * \brief Default hashing function over null-terminated string keys.
258  *
259  * \param key Null-terminated key string.
260  *
261  * \return Hashed value.
262  */
263 static hash_val_t hash_fun_default(const void *key)
264 {
265  static unsigned long randbox[] =
266  {
267  0x49848f1bU, 0xe6255dbaU, 0x36da5bdcU, 0x47bf94e9U,
268  0x8cbcce22U, 0x559fc06aU, 0xd268f536U, 0xe10af79aU,
269  0xc1af4d69U, 0x1d2917b5U, 0xec4c304dU, 0x9ee5016cU,
270  0x69232f74U, 0xfead7bb3U, 0xe9089ab6U, 0xf012f6aeU,
271  };
272 
273  const unsigned char *str = (const unsigned char *)key;
274  hash_val_t acc = 0;
275 
276  while( *str )
277  {
278  acc ^= randbox[(*str + acc) & 0xf];
279  acc = (acc << 1) | (acc >> 31);
280  acc &= 0xffffffffU;
281  acc ^= randbox[((*str++ >> 4) + acc) & 0xf];
282  acc = (acc << 2) | (acc >> 30);
283  acc &= 0xffffffffU;
284  }
285  return acc;
286 }
287 
288 /*!
289  * \brief Default hash key comparator function of null-terminated key strings.
290  *
291  * \param key1 Key string 1.
292  * \param key2 Key string 2.
293  *
294  * \return
295  * Returns <0, 0, >0 if key1 is lexigraphically less than key2, respectively.
296  */
297 static int hash_comp_default(const void *key1, const void *key2)
298 {
299  return strcmp((const char *)key1, (const char *)key2);
300 }
301 
302 /*!
303  * \brief Initialize the table of pointers to null.
304  *
305  * \param hash Hash table.
306  */
307 static void clear_table(hash_t *hash)
308 {
309  hash_val_t i;
310 
311  for(i=0; i<hash->nchains; i++)
312  {
313  hash->table[i] = NULL;
314  }
315 }
316 
317 /*!
318  * \brief Double the size of a dynamic table.
319  *
320  * This works as follows:
321  *
322  * Each chain splits into two adjacent chains. The shift amount increases by
323  * one, exposing an additional bit of each hashed key. For each node in the
324  * original chain, the value of this newly exposed bit will decide which of the
325  * two new chains will receive the node: if the bit is 1, the chain with the
326  * higher index will have the node, otherwise the lower chain will receive the
327  * node. In this manner, the hash table will continue to function exactly as
328  * before without having to rehash any of the keys.
329  *
330  * \par Notes &amp; Steps:
331  * \b 1.
332  * Overflow check.\n
333  * \b 2.
334  * The new number of chains is twice the old number of chains.\n
335  * \b 3.
336  * The new mask is one bit wider than the previous, revealing a
337  * new bit in all hashed keys.\n
338  * \b 4.
339  * Allocate a new table of chain pointers that is twice as large as the
340  * previous one.\n
341  * \b 5.
342  * If the reallocation was successful, we perform the rest of the growth
343  * algorithm, otherwise we do nothing.\n
344  * \b 6.
345  * The exposed_bit variable holds a mask with which each hashed key can be
346  * AND-ed to test the value of its newly exposed bit.\n
347  * \b 7.
348  * Loop over the lower half of the table, which, at first, holds all of
349  * the chains.\n
350  * \b 8.
351  * Each chain from the original table must be split into two chains.
352  * The nodes of each chain are examined in turn. The ones whose key value's
353  * newly exposed bit is 1 are removed from the chain and put into newchain
354  * (Steps 9 through 14). After this separation, the new chain is assigned
355  * into its appropriate place in the upper half of the table (Step 15).\n
356  * \b 9.
357  * Since we have relocated the table of pointers, we have to fix the
358  * back-reference from the first node of each non-empty chain so it
359  * properly refers to the moved pointer.\n
360  * \b 10.
361  * We loop over the even chain looking for any nodes whose exposed bit is
362  * set. Such nodes are removed from the lower-half chain and put into its
363  * upper-half sister.\n
364  * \b 11.
365  * Before moving the node to the other chain, we remember what the next
366  * node is so we can coninue the loop. We have to do this because we will
367  * be overwriting the node's next pointer when we insert it to its new
368  * home.\n
369  * \b 12.
370  * The next node's back pointer must be updated to skip to the previous
371  * node.\n
372  * \b 13.
373  * The deleted node's back pointer must be updated to refer to the next
374  * node.\n
375  * \b 14.
376  * We insert the node at the beginning of the new chain.\n
377  * \b 15.
378  * Place the new chain into an upper-half slot.\n
379  * \b 16.
380  * We have finished dealing with the chains and nodes. We now update
381  * the various bookeeping fields of the hash structure.
382  *
383  * \param hash Hash table.
384  *
385  * \exception "Table Overflow" Reached system limits.
386  * \exception "Verification Failed" Only if \ref hash_self_verify enabled.
387  */
388 static void grow_table(hash_t *hash)
389 {
390  hnode_t **newtable;
391  size_t size;
392 
393  LOGDIAG4CALL(_TPTR(hash));
394 
395  // Step 1
396  assert(2 * hash->nchains > hash->nchains);
397 
398  // Step 4
399  size = sizeof(hnode_t *) * hash->nchains;
400  newtable = new_overs(hash->table, size, size *2);
401 
402  // Step 5
403  if( newtable )
404  {
405  // Step 3
406  hash_val_t mask = (hash->mask << 1) | 1;
407 
408  // Step 6
409  hash_val_t exposed_bit = mask ^ hash->mask;
410 
411  hash_val_t chain;
412 
413  assert(mask != hash->mask);
414 
415  // Step 7
416  for(chain = 0; chain < hash->nchains; chain++)
417  {
418  // Step 8
419  hnode_t *hptr = newtable[chain];
420  hnode_t *newchain = NULL;
421 
422  // Step 9
423  if(hptr)
424  {
425  hptr->pself = &newtable[chain];
426  }
427 
428  // Step 10
429  while(hptr)
430  {
431  if((hptr->hkey & exposed_bit))
432  {
433  // Step 11
434  hnode_t *next = hptr->next;
435 
436  // Step 12
437  if(next)
438  {
439  next->pself = hptr->pself;
440  }
441 
442  // Step 13
443  *hptr->pself = next;
444 
445  // Step 14
446  hptr->next = newchain;
447  if(newchain)
448  {
449  newchain->pself = &hptr->next;
450  }
451  newchain = hptr;
452  hptr->pself = &newchain;
453  hptr = next;
454  }
455  else
456  {
457  hptr = hptr->next;
458  }
459  }
460  // Step 15
461  newtable[chain + hash->nchains] = newchain;
462  if(newchain)
463  {
464  newchain->pself = &newtable[chain + hash->nchains];
465  }
466  }
467 
468  // Step 16
469  hash->table = newtable;
470  hash->mask = mask;
471  hash->nchains *= 2;
472  hash->lowmark *= 2;
473  hash->highmark *= 2;
474  }
475 
476  LOGDIAG4(_VARFMT(hash->nchains, "%lu") ", " _VARFMT(hash->lowmark, "%lu") ", "
477  _VARFMT(hash->highmark, "%lu") ", " _VARFMT(hash->mask, "0x%lx"),
478  hash->nchains, hash->lowmark, hash->highmark, hash->mask);
479 
480  if( hash_self_verify )
481  {
482  assert(hash_table_verify(hash));
483  }
484 }
485 
486 /*!
487  * \brief Cut a dynamic table size in half.
488  *
489  * This is done by folding together adjacent chains and populating the lower
490  * half of the table with these chains. The chains are simply spliced together.
491  * Once this is done, the whole table is reallocated to a smaller object.
492  *
493  * \par Notes &amp; Steps:
494  * \b 1.
495  * It is illegal to have a hash table with one slot. This would mean that
496  * hash->shift is equal to hash_val_t_bit, an illegal shift value.
497  * Also, other things could go wrong, such as hash->lowmark becoming zero.\n
498  * \b 2.
499  * Looping over each adjacent chain of pairs, the lo_chain is set to
500  * reference the lower-numbered member of the pair, whereas hi_chain
501  * is the index of the higher-numbered one.\n
502  * \b 3.
503  * The intent here is to compute a pointer to the last node of the
504  * lower chain into the lo_tail variable. If this chain is empty,
505  * lo_tail ends up with a null value.\n
506  * \b 4.
507  * If the lower chain is not empty, we have to merge chains, but only
508  * if the upper chain is also not empty. In either case, the lower chain
509  * will come first, with the upper one appended to it.\n
510  * \b 5.
511  * The first part of the join is done by having the tail node of the lower
512  * chain point to the head node of the upper chain. If the upper chain
513  * is empty, this is remains a null pointer.\n
514  * \b 6.
515  * If the upper chain is non-empty, we must do the additional house-keeping
516  * task of ensuring that the upper chain's first node's back-pointer
517  * references the tail node of the lower chain properly.\n
518  * \b 7. (defunct)
519  * \b 8.
520  * If the low chain is empty, but the high chain is not, then the
521  * high chain simply becomes the new chain.\n
522  * \b 9.
523  * Otherwise if both chains are empty, then the merged chain is also
524  * empty.\n
525  * \b 10.
526  * All the chain pointers are in the lower half of the table now, so
527  * we reallocate it to a smaller object. This, of course, invalidates
528  * all pointer-to-pointers which reference into the table from the
529  * first node of each chain.\n
530  * \b 11.
531  * Though it's unlikely, the reallocation may fail. In this case we
532  * pretend that the table _was_ reallocated to a smaller object.\n
533  * \b 12.
534  * This loop performs the housekeeping task of updating the back pointers
535  * from the first node of each chain so that they reference their
536  * corresponding table entries.\n
537  * \b 13.
538  * Finally, update the various table parameters to reflect the new size.
539  *
540  * \param hash Hash table.
541  *
542  * \exception "Table Overflow" Reached system limits.
543  * \exception "Verification Failed" Only if \ref hash_self_verify enabled.
544  */
545 static void shrink_table(hash_t *hash)
546 {
547  hashcount_t chain, nchains;
548  size_t size;
549  hnode_t **newtable, *lo_tail, *lo_chain, *hi_chain;
550 
551  LOGDIAG4CALL(_TPTR(hash));
552 
553  // Step 1
554  assert(hash->nchains >= 2);
555 
556  // downsize chains
557  nchains = hash->nchains / 2;
558 
559  // Step 2
560  for(chain = 0; chain < nchains; chain++)
561  {
562  lo_chain = hash->table[chain];
563  hi_chain = hash->table[chain + nchains];
564 
565  // Step 3
566  for(lo_tail=lo_chain; lo_tail && lo_tail->next; lo_tail=lo_tail->next)
567  {
568  ;
569  }
570 
571  // Step 4
572  if(lo_chain)
573  {
574  // Step 5
575  lo_tail->next = hi_chain;
576 
577  // Step 6
578  if(hi_chain)
579  {
580  hi_chain->pself = &lo_tail->next;
581  }
582  }
583 
584  // Step 8
585  else if(hi_chain)
586  {
587  hash->table[chain] = hi_chain;
588  }
589 
590  // Step 9
591  else
592  {
593  hash->table[chain] = NULL;
594  }
595  }
596 
597  // Step 10
598  size = sizeof(hnode_t *) * nchains; // downsized size
599  newtable = new_overs(hash->table, size, size);
600 
601  // Step 11
602  if(newtable)
603  {
604  hash->table = newtable;
605  }
606 
607  // Step 12
608  for(chain = 0; chain < nchains; chain++)
609  {
610  if(hash->table[chain])
611  {
612  hash->table[chain]->pself = &hash->table[chain];
613  }
614  }
615 
616  // Step 13
617  hash->mask >>= 1;
618  hash->nchains = nchains;
619  hash->lowmark /= 2;
620  hash->highmark /= 2;
621 
622  LOGDIAG4(_VARFMT(hash->nchains, "%lu") ", " _VARFMT(hash->lowmark, "%lu") ", "
623  _VARFMT(hash->highmark, "%lu") ", " _VARFMT(hash->mask, "0x%lx"),
624  hash->nchains, hash->lowmark, hash->highmark, hash->mask);
625 
626  if( hash_self_verify )
627  {
628  assert(hash_table_verify(hash));
629  }
630 }
631 
632 
633 // ---------------------------------------------------------------------------
634 // Public Interface
635 // ---------------------------------------------------------------------------
636 
637 /*!
638  * \brief Create a dynamic hash table.
639  *
640  * Both the hash table structure and the table itself are dynamically allocated.
641  * Furthermore, the table is extendible in that it will automatically grow as
642  * its load factor increases beyond a certain threshold.
643  *
644  * \par Notes &amp; Steps:
645  * \b 1.
646  * If the number of bits in the hash_val_t type has not been computed yet,
647  * we do so here, because this is likely to be the first function that the
648  * user calls.\n
649  * \b 2.
650  * Allocate hash table.\n
651  * \b 3.
652  * Initialize hash table sizes. The minsize should be a power of two.
653  * The maxsize should be >= minsize. Both values will be adjusted. The high
654  * and low marks are always set to be twice the table size and half the
655  * table size respectively. When the number of nodes in the table grows
656  * beyond the high size (beyond load factor 2), it will double in size to
657  * cut the load factor down to about about 1. If the table shrinks down to
658  * or beneath load factor 0.5, it will shrink, bringing the load up to
659  * about 1. However, the table will never shrink beneath minsize even if
660  * it's emptied.\n
661  * \b 4.
662  * Allocate the table of hash chains.\n
663  * \b 5.
664  * Finish initializing the hash structure and the table.
665  * \b 6.
666  * This indicates that the table is dynamically allocated and dynamically
667  * resized on the fly. A table that has this value set to zero is
668  * assumed to be statically allocated and will not be resized.\n
669  * \b 7.
670  * The table of chains must be properly reset to all null pointers.
671  * \b 8.
672  * Verify table's correctness, if self-verification is true.
673  *
674  * \param isdynamic The hash table is [not] automatically grow. If set to
675  * false, the hash table is initialized t be fixed at
676  * minsize and maxsize is ignored.
677  * \param minsize Minimum and initial number of hash entries that will be
678  * supported.
679  * \param maxsize Maximum number of hash entries that will be supported.
680  * \param compfun Hash key comparator function. NULL will use the default
681  * strcmp() wrapper.
682  * \param hashfun Hashing function. NULL will used the default string
683  * hashing function.
684  * \param freedatafun User key and data deallocator function. NULL will cause
685  * no user key or data to be deleted.
686  *
687  * \return Newly created, empty hash table.
688  *
689  * \exception "Verification Failed" Only if \ref hash_self_verify enabled.
690  */
692  hashcount_t minsize,
693  hashcount_t maxsize,
694  hash_comp_t compfun,
695  hash_fun_t hashfun,
696  hnode_data_free_t freedatafun)
697 {
698  hash_t *hash;
699 
700  LOGDIAG4CALL(_TBOOL(isdynamic), _TULONG(minsize), _TULONG(maxsize),
701  _TPTR(compfun), _TPTR(hashfun), _TPTR(freedatafun));
702 
703  // Step 1
704  if( hash_val_t_bit == 0 )
705  {
706  compute_bits();
707  }
708 
709  // Step 2
710  hash = NEW(hash_t);
711 
712  // Step 3
713  init_hash_sizes(hash, minsize, maxsize);
714 
715  // Step 4
716  hash->table = (hnode_t **)new(sizeof(hnode_t *) * hash->minsize);
717 
718  // Step 5
719  hash->nchains = minsize;
720  hash->mask = compute_mask(hash->nchains);
721  hash->count = 0;
722  hash->compare = compfun ? compfun : hash_comp_default;
723  hash->hash = hashfun ? hashfun : hash_fun_default;
724  hash->freenodedata = freedatafun;
725 
726  // Step 6
727  hash->dynamic = isdynamic;
728 
729  // Step 7
730  clear_table(hash);
731 
732  // Step 8
733  if( hash_self_verify )
734  {
735  assert(hash_table_verify(hash));
736  }
737 
738  LOGDIAG4("min=%lu, max=%lu, high=%lu, low=%lu, nchains=%lu, mask=0x%lx\n",
739  hash->minsize, hash->maxsize, hash->highmark,
740  hash->lowmark, hash->nchains, hash->mask);
741 
742  return hash;
743 }
744 
745 /*!
746  * \brief Delete the hash table, all of its entries, and all of the user data.
747  *
748  * \param hash Hash table.
749  */
751 {
752  hscan_t hs;
753  hnode_t *node;
754 
755  LOGDIAG4CALL(_TPTR(hash));
756 
757  hash_scan_begin(&hs, hash);
758  while((node = hash_scan_next(&hs)))
759  {
760  hash_node_fast_unlink(hash, node);
761  hnode_destroy(node, hash->freenodedata);
762  }
763  hash_table_delete(hash);
764 }
765 
766 /*!
767  * \brief Frees a dynamic hash table structure.
768  *
769  * \param hash Hash table.
770  *
771  * \warning The hash table must be empty.
772  *
773  * \exception "Not Initialzed" Hashing not initialized.
774  * \exception "Not Empty" Hash table not empty.
775  */
777 {
778  assert(hash_val_t_bit != 0);
779  assert(hash_isempty(hash));
780 
781  delete(hash->table);
782  delete(hash);
783 }
784 
785 /*!
786  * \brief Initialize a user supplied hash table.
787  *
788  * The user also supplies a table of chains which is assigned to the hash
789  * table . The table is static---it will not grow or shrink.
790  *
791  * \par Notes &amp; Steps:
792  * \b 1.
793  * Initialize hashing.\n
794  * \b 2.
795  * Assign hash chains. The user supplied array of pointers hopefully
796  * contains nchains nodes.\n
797  * \b 3.
798  * Fixed size.
799  * \b 4.
800  * We must dynamically compute the mask from the given power of two table
801  * size. \n
802  * \b 5.
803  * The user supplied table can't be assumed to contain null pointers,
804  * so we reset it here.
805  *
806  * \warning All data in destination hash table is overwritten.
807  *
808  * \sa hash_table_create()
809  *
810  * \param hash The destination hash table.
811  * \param minsize Minimum and initial number of hash entries that will be
812  * supported.
813  * \param maxsize Maximum number of hash entries that will be supported.
814  * \param compfun Hash key comparator function. NULL will use the default
815  * strcmp() wrapper.
816  * \param hashfun Hashing function. NULL will used the default string
817  * hashing function.
818  * \param freedatafun User key and data deallocator function. NULL will cause
819  * no user key or data to be deleted.
820  * \param table The actual hash chain table to attach.
821  * \param nchains Number of nodes in hash chain.
822  *
823  * \return Hash table.
824  *
825  * \exception "Bad Parameter" nchain not a power of 2.
826  * \exception "Verification Failed" Only if \ref hash_self_verify enabled.
827  */
829  hash_comp_t compfun, hash_fun_t hashfun,
830  hnode_data_free_t freedatafun,
831  hnode_t **table, hashcount_t nchains)
832 {
833  LOGDIAG4CALL(_TPTR(hash), _TULONG(minsize), _TULONG(maxsize),
834  _TPTR(compfun), _TPTR(hashfun), _TPTR(freedatafun),
835  _TPTR(table), _TULONG(nchains));
836 
837  // Step 1
838  if(hash_val_t_bit == 0)
839  {
840  compute_bits();
841  }
842 
843  assert(is_power_of_two(nchains));
844 
845  init_hash_sizes(hash, minsize, maxsize);
846 
847  // Step 2
848  hash->table = table;
849  hash->nchains = nchains;
850  hash->mask = compute_mask(nchains); // Step 4
851  hash->count = 0;
852  hash->compare = compfun ? compfun : hash_comp_default;
853  hash->hash = hashfun ? hashfun : hash_fun_default;
854  hash->freenodedata = freedatafun;
855  hash->dynamic = false; // Step 3
856 
857  clear_table(hash); // Step 5
858 
859  if( hash_self_verify )
860  {
861  assert (hash_table_verify(hash));
862  }
863 
864  LOGDIAG4("min=%lu, max=%lu, high=%lu, low=%lu, nchains=%lu, mask=0x%lx\n",
865  hash->minsize, hash->maxsize, hash->highmark,
866  hash->lowmark, hash->nchains, hash->mask);
867 
868  return hash;
869 }
870 
871 /*!
872  * \brief Verify hash table consistency.
873  *
874  * If \ref hash_self_verify enabled (see \ref hash_set_self_verify()), this
875  * call is automatically called during hash table modification operations.
876  *
877  * \par Notes &amp; Steps:
878  * \b 1.
879  * If the hash table is dynamic, verify whether the high and
880  * low expansion/shrinkage thresholds are powers of two.
881  * \b 2.
882  * For each chain, verify whether the back pointers are correctly
883  * set. Count all nodes in the table, and test each hash value
884  * to see whether it is correct for the node's chain.
885  *
886  * \return Returns true is the table is okay, else returns false.
887  */
889 {
890  hashcount_t count = 0;
891  hash_val_t chain;
892  hnode_t **npp;
893 
894  // Step 1
895  if (hash->dynamic)
896  {
897  CHKEXPR_ULONG(hash->lowmark, (hash->lowmark < hash->highmark), false);
898  CHKEXPR_ULONG(hash->lowmark, is_power_of_two(hash->lowmark), false);
899  CHKEXPR_ULONG(hash->highmark, is_power_of_two(hash->highmark), false);
900  }
901 
902  // Step 2
903  for(chain = 0; chain < hash->nchains; chain++)
904  {
905  for(npp = hash->table + chain; *npp; npp = &(*npp)->next)
906  {
907  CHKEXPR_PTR(npp, ((*npp)->pself == npp), false);
908  CHKEXPR_PTR(npp, (((*npp)->hkey & hash->mask) == chain), false);
909  count++;
910  }
911  }
912 
913  CHKEXPR_ULONG(hash->count, (hash->count == count), false);
914 
915  return true;
916 }
917 
918 /*!
919  * \brief Reset the hash scanner (iterator).
920  *
921  * After this call the next element retrieved by \ref hash_scan_next() shall
922  * be the first element on the first non-empty chain.
923  *
924  * \par Notes &amp; Steps:
925  * \b 1.
926  * Locate the first non empty chain.\n
927  * \b 2.
928  * If an empty chain is found, remember which one it is and set the next
929  * pointer to refer to its first element.\n
930  * \b 3.
931  * Otherwise if a chain is not found, set the next pointer to NULL
932  * so that hash_scan_next() shall indicate failure.
933  *
934  * \param scan Hash iterator.
935  * \param hash Hash table.
936  */
937 void hash_scan_begin(hscan_t *scan, hash_t *hash)
938 {
939  hash_val_t nchains = hash->nchains;
940  hash_val_t chain;
941 
942  scan->hash = hash;
943 
944  // Step 1
945  for(chain = 0; chain < nchains && hash->table[chain] == 0; chain++);
946 
947  // Step 2
948  if(chain < nchains)
949  {
950  scan->chain = chain;
951  scan->next = hash->table[chain];
952  }
953 
954  // Step 3
955  else
956  {
957  scan->next = NULL;
958  }
959 }
960 
961 /*!
962  * \brief Retrieve the next node from the hash table.
963  *
964  * The scanner (iterator) updates the pointer for the next invocation of
965  * hash_scan_next().
966  *
967  * \par Notes &amp; Steps:
968  * \b 1.
969  * Remember the next pointer in a temporary value so that it can be
970  * returned.\n
971  * \b 2.
972  * This assertion essentially checks whether the module has been properly
973  * initialized. The first point of interaction with the module should be
974  * either hash_table_create() or hash_init(), both of which set
975  * hash_val_t_bit to a non zero value.\n
976  * \b 3.
977  * If the next pointer we are returning is not NULL, then the user is
978  * allowed to call hash_scan_next() again. We prepare the new next pointer
979  * for that call right now. That way the user is allowed to delete the node
980  * we are about to return, since we will no longer be needing it to locate
981  * the next node.\n
982  * \b 4.
983  * If there is a next node in the chain (next->next), then that becomes the
984  * new next node, otherwise ...\n
985  * \b 5.
986  * We have exhausted the current chain, and must locate the next subsequent
987  * non-empty chain in the table.\n
988  * \b 6.
989  * If a non-empty chain is found, the first element of that chain becomes
990  * the new next node. Otherwise there is no new next node and we set the
991  * pointer to NULL so that the next time hash_scan_next() is called, a null
992  * pointer shall be immediately returned.\n
993  *
994  * \return Returns next node on success, NULL if no more nodes.
995  *
996  * \exception "Not Initialzed" Hashing not initialized.
997  */
999 {
1000  hnode_t *next = scan->next; // Step 1
1001  hash_t *hash = scan->hash;
1002  hash_val_t chain = scan->chain + 1;
1003  hash_val_t nchains = hash->nchains;
1004 
1005  assert(hash_val_t_bit != 0); // Step 2
1006 
1007  // Step 3
1008  if(next)
1009  {
1010  // Step 4
1011  if(next->next)
1012  {
1013  scan->next = next->next;
1014  }
1015  else
1016  {
1017  // Step 5
1018  while(chain < nchains && hash->table[chain] == 0)
1019  {
1020  chain++;
1021  }
1022  // Step 6
1023  if (chain < nchains)
1024  {
1025  scan->chain = chain;
1026  scan->next = hash->table[chain];
1027  }
1028  else
1029  {
1030  scan->next = NULL;
1031  }
1032  }
1033  }
1034  return next;
1035 }
1036 
1037 /*!
1038  * \brief Insert a node into the hash table.
1039  *
1040  * \par Steps &amp; Notes:
1041  * \b 1.
1042  * It's illegal to insert more than the maximum number of nodes. The client
1043  * should verify that the hash table is not full before attempting an
1044  * insertion.\n
1045  * \b 2.
1046  * The same key may not be inserted into a table twice.\n
1047  * \b 3.
1048  * If the table is dynamic and the load factor is already at >= 2,
1049  * grow the table.\n
1050  * \b 4.
1051  * We take the top N bits of the hash value to derive the chain index,
1052  * where N is the base 2 logarithm of the size of the hash table.
1053  *
1054  * \param hash Hash table.
1055  * \param node Node to insert.
1056  * \param key Hash key.
1057  *
1058  * \exception "Not Initialzed" Hashing not initialized.
1059  * \exception "Too Big" Reached maximum table size.
1060  * \exception "Duplicate Key" Node with key already exists.
1061  * \exception "Verification Failed" Only if \ref hash_self_verify enabled.
1062  */
1063 void hash_node_insert(hash_t *hash, hnode_t *node, void *key)
1064 {
1065  LOGDIAG4CALL(_TPTR(hash), _TPTR(node), _TPTR(key));
1066 
1067  hash_val_t hkey, chain;
1068 
1069  assert(hash_val_t_bit != 0);
1070  assert(hash->count < hash->maxsize); // Step 1
1071  assert(hash_lookup(hash, key) == NULL); // Step 2
1072 
1073  // Step 3
1074  if(hash->dynamic && (hash->count+1) >= hash->highmark)
1075  {
1076  grow_table(hash);
1077  }
1078 
1079  hkey = hash->hash(key);
1080  chain = hkey & hash->mask; // Step 4
1081 
1082  node->key = key;
1083  node->hkey = hkey;
1084  node->pself = hash->table + chain;
1085  node->next = hash->table[chain];
1086  if (node->next)
1087  {
1088  node->next->pself = &node->next;
1089  }
1090  hash->table[chain] = node;
1091  hash->count++;
1092 
1093  if( hash_self_verify )
1094  {
1095  assert(hash_table_verify(hash));
1096  }
1097 }
1098 
1099 /*!
1100  * \brief Unlink the given node from the hash table.
1101  *
1102  * This is easy, because each node contains a back pointer to the previous
1103  * node's next pointer.
1104  *
1105  * No data are deleted.
1106  *
1107  * \par Notes &amp; Steps:
1108  * \b 1.
1109  * The node must belong to this hash table, and its key must not have
1110  * been tampered with.\n
1111  * \b 2.
1112  * If there is a next node, then we must update its back pointer to
1113  * skip this node.\n
1114  * \b 3.
1115  * We must update the pointer that is pointed at by the back-pointer
1116  * to skip over the node that is being deleted and instead point to
1117  * the successor (or to NULL if the node being deleted is the last one).
1118  *
1119  * \param hash Hash table.
1120  * \param node Hash node to unlink.
1121  *
1122  * \return Unlinked node.
1123  *
1124  * \exception "Not Initialzed" Hashing not initialized.
1125  * \exception "No Key" Hash key not found.
1126  * \exception "Verification Failed" Only if \ref hash_self_verify enabled.
1127  */
1129 {
1130  LOGDIAG4CALL(_TPTR(hash), _TPTR(node));
1131 
1132  assert(hash_val_t_bit != 0);
1133  assert(hash_lookup(hash, node->key) == node); // Step 1
1134 
1135  if(hash->dynamic && (hash->count-1) <= hash->lowmark
1136  && hash->count > hash->minsize)
1137  {
1138  shrink_table(hash);
1139  }
1140 
1141  // Step 2
1142  if (node->next)
1143  {
1144  node->next->pself = node->pself;
1145  }
1146 
1147  // Step 3
1148  *node->pself = node->next;
1149 
1150  hash->count--;
1151 
1152  if( hash_self_verify )
1153  {
1154  assert(hash_table_verify(hash));
1155  }
1156 
1157  return node;
1158 }
1159 
1160 /*!
1161  * \brief Fast version to unlink the given node from the hash table.
1162  *
1163  * Same as \ref hash_node_unlink() except does not trigger table shrinkage.
1164  * This call is optimized for hash table scan operations.
1165  *
1166  * \sa hash_node_unlink().
1167  *
1168  * \param hash Hash table.
1169  * \param node Node to unlink, typically found by scanning.
1170  *
1171  * \return Unlinked node.
1172  *
1173  * \exception "Not Initialzed" Hashing not initialized.
1174  * \exception "No Key" Hash key not found.
1175  * \exception "Verification Failed" Only if \ref hash_self_verify enabled.
1176  *
1177  */
1179 {
1180  LOGDIAG4CALL(_TPTR(hash), _TPTR(node));
1181 
1182  assert(hash_val_t_bit != 0);
1183  assert(hash_lookup(hash, node->key) == node); /* 1 */
1184 
1185  // Step 2 as in hash_node_inlink()
1186  if (node->next)
1187  {
1188  node->next->pself = node->pself;
1189  }
1190 
1191  // Step 3 as in hash_node_inlink()
1192  *node->pself = node->next;
1193 
1194  hash->count--;
1195 
1196  if( hash_self_verify )
1197  {
1198  assert(hash_table_verify(hash));
1199  }
1200 
1201  return node;
1202 }
1203 
1204 /*!
1205  * \brief Unlink and delete a hash node from the hash table.
1206  *
1207  * The user data and key are deallocated as per the any user supplied
1208  * data free function. The node is then deallocated.
1209  *
1210  * \param hash Hash table.
1211  * \param node Hash node to delete.
1212  *
1213  * \exception "Not Initialzed" Hashing not initialized.
1214  * \exception "No Key" Hash key not found.
1215  * \exception "Verification Failed" Only if \ref hash_self_verify enabled.
1216  */
1217 void hash_node_delete(hash_t *hash, hnode_t *node)
1218 {
1219  hash_node_unlink(hash, node);
1220  hnode_destroy(node, hash->freenodedata);
1221 }
1222 
1223 /*!
1224  * \brief Find a node in the hash table and return a pointer to it.
1225  *
1226  * \par Notes &amp; Steps:
1227  * \b 1.
1228  * We hash the key and keep the entire hash value. As an optimization, when
1229  * we descend down the chain, we can compare hash values first and only if
1230  * hash values match do we perform a full key comparison.\n
1231  * \b 2.
1232  * To locate the chain from among 2^N chains, we look at the lower N bits of
1233  * the hash value by anding them with the current mask.\n
1234  * \b 3.
1235  * Looping through the chain, we compare the stored hash value inside each
1236  * node against our computed hash. If they match, then we do a full
1237  * comparison between the unhashed keys. If these match, we have located the
1238  * entry.
1239  *
1240  *
1241  * \param hash Hash table.
1242  * \param key Hash key.
1243  *
1244  * \return Returns node with key on success, NULL if node not found.
1245  */
1246 hnode_t *hash_lookup(hash_t *hash, const void *key)
1247 {
1248  hash_val_t hkey, chain;
1249  hnode_t *nptr;
1250 
1251  hkey = hash->hash(key); // Step 1
1252  chain = hkey & hash->mask; // Step 2
1253 
1254  // Step 3
1255  for(nptr = hash->table[chain]; nptr; nptr = nptr->next)
1256  {
1257  if(nptr->hkey == hkey && hash->compare(nptr->key, key) == 0)
1258  {
1259  return nptr;
1260  }
1261  }
1262 
1263  return NULL;
1264 }
1265 
1266 /*!
1267  * \brief Insert user data with the given key into the hash table.
1268  *
1269  * The data and key are attached to new hash node which is automatically
1270  * allocated and the node is inserted into the hash table.
1271  *
1272  * \param hash Hash table.
1273  * \param key Hash key.
1274  * \param data User data.
1275  *
1276  * \return Returns true if successful, else returns false.
1277  *
1278  * \exception "Not Initialzed" Hashing not initialized.
1279  * \exception "Too Big" Reached maximum table size.
1280  * \exception "Duplicate Key" Node with key already exists.
1281  * \exception "Verification Failed" Only if \ref hash_self_verify enabled.
1282  */
1283 bool_t hash_insert(hash_t *hash, void *key, void *data)
1284 {
1285  hnode_t *node = hnode_create(data);
1286 
1287  if (node)
1288  {
1289  hash_node_insert(hash, node, key);
1290  return true;
1291  }
1292 
1293  return false;
1294 }
1295 
1296 /*!
1297  * \brief Unlink and delete a hash node with the given key from the hash table.
1298  *
1299  * The user data and key are deallocated as per the any user supplied
1300  * data free function. The node is then deallocated.
1301  *
1302  * \param hash Hash table.
1303  * \param key Hash key.
1304  *
1305  * \return Returns true if successful, else returns false.
1306  *
1307  * \exception "Not Initialzed" Hashing not initialized.
1308  * \exception "Verification Failed" Only if \ref hash_self_verify enabled.
1309  */
1310 bool_t hash_delete(hash_t *hash, void *key)
1311 {
1312  hnode_t *node;
1313 
1314  if( (node = hash_lookup(hash, key)) != NULL )
1315  {
1316  hash_node_unlink(hash, node);
1317  hnode_destroy(node, hash->freenodedata);
1318  return true;
1319  }
1320  return false;
1321 }
1322 
1323 /*!
1324  * \brief Enable (disable) automatic self-checks during hash table modification
1325  * operatations.
1326  *
1327  * \param selfverify True to enable, false to disable.
1328  *
1329  * \sa hash_table_verify()
1330  */
1332 {
1333  hash_self_verify = selfverify;
1334 }
1335 
1336 /*!
1337  * \brief Create a hash table node dynamically and assign it the given data.
1338  *
1339  * \param data User data.
1340  *
1341  * \return New hash node.
1342  */
1343 hnode_t *hnode_create(void *data)
1344 {
1345  hnode_t *node = NEW(hnode_t);
1346 
1347  node->data = data;
1348  node->next = NULL;
1349  node->pself = NULL;
1350 
1351  return node;
1352 }
1353 
1354 /*!
1355  * \brief Initialize a client-supplied hash node.
1356  *
1357  * \param node Hash node.
1358  * \param data User data.
1359  *
1360  * \return Same hash node.
1361  */
1362 hnode_t *hnode_init(hnode_t *node, void *data)
1363 {
1364  node->data = data;
1365  node->next = NULL;
1366  node->pself = NULL;
1367  return node;
1368 }
1369 
1370 /*!
1371  * \brief Hash node and user data deallocator.
1372  *
1373  * \param node Node to deallocate.
1374  * \param freedatafun User key and data deallocator. May be NULL.
1375  */
1376 void hnode_destroy(hnode_t *node, hnode_data_free_t freedatafun)
1377 {
1378  if( freedatafun != NULL )
1379  {
1380  freedatafun(node->key, node->data);
1381  }
1382  delete(node);
1383 }
1384 
1385 /*!
1386  * \brief Destroy a dynamically allocated node.
1387  *
1388  * User data and key are not touched.
1389  *
1390  * \param node Hash node.
1391  */
1393 {
1394  delete(node);
1395 }
void hash_node_insert(hash_t *hash, hnode_t *node, void *key)
Insert a node into the hash table.
Definition: hash.c:1063
int(* hash_comp_t)(const void *key1, const void *key2)
User comparison function override type.
Definition: hash.h:177
static void compute_bits()
Compute the number of bits in the hash_val_t type.
Definition: hash.c:141
bool_t dynamic
Note 12.
Definition: hash.h:281
struct hnode_t ** pself
Note 3.
Definition: hash.h:153
hash_val_t mask
Note 7.
Definition: hash.h:276
hnode_t * hash_scan_next(hscan_t *scan)
Retrieve the next node from the hash table.
Definition: hash.c:998
hashcount_t nchains
Note 6.
Definition: hash.h:275
hashcount_t maxsize
Note 3.
Definition: hash.h:272
hashcount_t minsize
Note 2.
Definition: hash.h:271
void * data
Note 5.
Definition: hash.h:155
static void clear_table(hash_t *hash)
Initialize the table of pointers to null.
Definition: hash.c:307
hash_t * hash
Note 1.
Definition: hash.h:305
#define NULL
null pointer
Definition: rnrconfig.h:199
General purpose hash data and function declarations.
#define _TULONG(var)
unsigned long int (decimal)
Definition: log.h:580
hnode_t * hash_node_fast_unlink(hash_t *hash, hnode_t *node)
Fast version to unlink the given node from the hash table.
Definition: hash.c:1178
#define CHKEXPR_PTR(val, expr,...)
check pointer
Definition: log.h:712
Memory allocation and deallocation declarations.
hnode_t * hash_lookup(hash_t *hash, const void *key)
Find a node in the hash table and return a pointer to it.
Definition: hash.c:1246
hash_comp_t compare
Note 9.
Definition: hash.h:278
static hash_val_t hash_fun_default(const void *key)
Default hashing function over null-terminated string keys.
Definition: hash.c:263
hash_val_t(* hash_fun_t)(const void *key)
User hashing function type.
Definition: hash.h:199
static void grow_table(hash_t *hash)
Double the size of a dynamic table.
Definition: hash.c:388
struct hnode_t * next
<Note 1
Definition: hash.h:152
bool_t hash_delete(hash_t *hash, void *key)
Unlink and delete a hash node with the given key from the hash table.
Definition: hash.c:1310
hashcount_t highmark
Note 4.
Definition: hash.h:273
void hash_set_self_verify(bool_t selfverify)
Enable (disable) automatic self-checks during hash table modification operatations.
Definition: hash.c:1331
void hash_table_delete(hash_t *hash)
Frees a dynamic hash table structure.
Definition: hash.c:776
#define HASH_MIN_SIZE
Minimum and initial size of hash table.
Definition: hash.h:104
hnode_t ** table
Note 1.
Definition: hash.h:270
unsigned long hashcount_t
maximum hash table size type
Definition: hash.h:94
static int hash_val_t_bit
Number of bits in hashed value. Must be a power of 2.
Definition: hash.c:114
static bool_t hash_self_verify
Do [not] perform auto-verification after hash table operations.
Definition: hash.c:119
hashcount_t count
Note 8.
Definition: hash.h:277
void(* hnode_data_free_t)(void *key, void *data)
User node data deallocator function.
Definition: hash.h:212
#define LOGDIAG4(fmt,...)
Standard Diagnostic Level 4 logging.
Definition: log.h:386
hnode_t * hash_node_unlink(hash_t *hash, hnode_t *node)
Unlink the given node from the hash table.
Definition: hash.c:1128
hash_val_t chain
Note 2.
Definition: hash.h:306
unsigned long hash_val_t
hashed value return type
Definition: hash.h:96
#define NEW(T)
Allocate new type.
Definition: new.h:49
#define _VARFMT(var, fmt)
log Variable Format.
Definition: log.h:555
void * new_overs(void *pSrc, size_t sizeDup, size_t sizeNew)
Allocate and duplicate.
Definition: new.c:112
hashcount_t lowmark
Note 5.
Definition: hash.h:274
void hash_scan_begin(hscan_t *scan, hash_t *hash)
Reset the hash scanner (iterator).
Definition: hash.c:937
hnode_t * hnode_init(hnode_t *node, void *data)
Initialize a client-supplied hash node.
Definition: hash.c:1362
int bool_t
"boolean" T/F
Definition: rnrconfig.h:187
RoadNarrows Robotics common configuration file.
#define _TBOOL(var)
boolean
Definition: log.h:588
hash_t * hash_table_init(hash_t *hash, hashcount_t minsize, hashcount_t maxsize, hash_comp_t compfun, hash_fun_t hashfun, hnode_data_free_t freedatafun, hnode_t **table, hashcount_t nchains)
Initialize a user supplied hash table.
Definition: hash.c:828
Hash scanner structure.
Definition: hash.h:302
static hash_val_t compute_mask(hashcount_t size)
Compute a mask for a given table size.
Definition: hash.c:185
hash_t * hash_table_create(bool_t isdynamic, hashcount_t minsize, hashcount_t maxsize, hash_comp_t compfun, hash_fun_t hashfun, hnode_data_free_t freedatafun)
Create a dynamic hash table.
Definition: hash.c:691
void * key
Note 4.
Definition: hash.h:154
#define _TPTR(var)
pointer
Definition: log.h:587
#define LOGDIAG4CALL(...)
Standard Diagnostic Level 4 function call tracing.
Definition: log.h:442
hnode_data_free_t freenodedata
Note 11.
Definition: hash.h:280
hnode_t * hnode_create(void *data)
Create a hash table node dynamically and assign it the given data.
Definition: hash.c:1343
static void shrink_table(hash_t *hash)
Cut a dynamic table size in half.
Definition: hash.c:545
hnode_t * next
Note 3.
Definition: hash.h:307
Hash table control structure.
Definition: hash.h:267
hash_fun_t hash
Note 10.
Definition: hash.h:279
Hash chain node structure.
Definition: hash.h:149
void hash_node_delete(hash_t *hash, hnode_t *node)
Unlink and delete a hash node from the hash table.
Definition: hash.c:1217
bool_t hash_table_verify(hash_t *hash)
Verify hash table consistency.
Definition: hash.c:888
void hnode_destroy(hnode_t *node, hnode_data_free_t freedatafun)
Hash node and user data deallocator.
Definition: hash.c:1376
static bool_t is_power_of_two(hash_val_t arg)
Verify whether the given argument is a power of two.
Definition: hash.c:163
Logger declarations.
bool_t hash_insert(hash_t *hash, void *key, void *data)
Insert user data with the given key into the hash table.
Definition: hash.c:1283
hash_val_t hkey
Note 6.
Definition: hash.h:156
#define HASH_VAL_T_MAX
Maximum hashed value (a Mersenne number 2^N-1)
Definition: hash.h:86
static void init_hash_sizes(hash_t *hash, hashcount_t minsize, hashcount_t maxsize)
Initialize the table size values.
Definition: hash.c:215
void hnode_delete(hnode_t *node)
Destroy a dynamically allocated node.
Definition: hash.c:1392
void hash_table_destroy(hash_t *hash)
Delete the hash table, all of its entries, and all of the user data.
Definition: hash.c:750
#define CHKEXPR_ULONG(val, expr,...)
check unsigned long integer
Definition: log.h:697
static int hash_comp_default(const void *key1, const void *key2)
Default hash key comparator function of null-terminated key strings.
Definition: hash.c:297
#define hash_isempty(H)
Returns true if table is empty, false otherwise.
Definition: hash.h:385