librnr  1.14.5
RoadNarrows Robotics Common Library 1
hash.h
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 /*! \file
3  *
4  * \brief General purpose hash data and function declarations.
5  *
6  * This file has been modified from the original source
7  * (\ref hash_h_original_src "see below").
8  *
9  * \sa
10  * \ref example_hash under "Related Pages" for an example usage of hashing.
11  *
12  * \pkgsynopsis
13  * RoadNarrows Robotics Common Library 1
14  *
15  * \pkgcomponent{Library}
16  * librnr
17  *
18  * \pkgfile{rnr/hash.h}
19  *
20  * \author Robin Knight (robin.knight@roadnarrows.com)
21  *
22  * \pkgcopyright{2005-2018,RoadNarrows LLC.,http://www.roadnarrows.com}
23  *
24  * \license{MIT}
25  *
26  * \EulaBegin
27  * See the README and EULA files for any copyright and licensing information.
28  * \EulaEnd
29  *
30  * <hr>
31  * \anchor hash_h_original_src
32  * \par Original Source Comment Block
33  *
34  * \par Original Author
35  * Kaz Kylheku (kaz@ashi.footprints.net)
36  *
37  * \par Original Copyright
38  * (C) 1997
39  *
40  * \par Original Header
41  * \verbatim
42  * Hash Table Data Type
43  * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
44  *
45  * Free Software License:
46  *
47  * All rights are reserved by the author, with the following exceptions:
48  * Permission is granted to freely reproduce and distribute this software,
49  * possibly in exchange for a fee, provided that this copyright notice appears
50  * intact. Permission is also granted to adapt this software to produce
51  * derivative works, as long as the modified versions carry this copyright
52  * notice and additional notices stating that the work has been modified.
53  * The copyright extends to translations of this work into other languages,
54  * including machine languages.
55  * \endverbatim
56  *
57  * <hr>
58  */
59 ////////////////////////////////////////////////////////////////////////////////
60 
61 #ifndef _RNR_HASH_H
62 #define _RNR_HASH_H
63 
64 #include <limits.h>
65 
66 #ifdef KAZLIB_SIDEEFFECT_DEBUG
67 #include "sfx.h"
68 #endif
69 
70 #include "rnr/rnrconfig.h"
71 
72 /*!
73  * \brief Hash implementation (original source had different hash configs,
74  * we have one)
75  */
76 #define HASH_IMPLEMENTATION
77 
78 /*!
79  * \brief Maximum maximum hash table size
80  */
81 #define HASHCOUNT_T_MAX ULONG_MAX
82 
83 /*!
84  * \brief Maximum hashed value (a Mersenne number 2^N-1)
85  */
86 #define HASH_VAL_T_MAX ULONG_MAX
87 
88 
89 /*
90  * Blurb for inclusion into C++ translation units
91  */
93 
94 typedef unsigned long hashcount_t; ///< maximum hash table size type
95 
96 typedef unsigned long hash_val_t; ///< hashed value return type
97 
98 /*!
99  * \brief Minimum and initial size of hash table.
100  *
101  * \warning Must be a power of two.
102  */
103 #ifndef HASH_MIN_SIZE
104 #define HASH_MIN_SIZE ((hashcount_t)4)
105 #endif
106 
107 /*!
108  * \brief Maximum size of hash table.
109  */
110 #ifndef HASH_MAX_SIZE
111 #define HASH_MAX_SIZE ((hashcount_t)HASHCOUNT_T_MAX)
112 #endif
113 
114 /*!
115  * \brief Hash chain node structure.
116  *
117  * \par Notes:
118  * \b 1.
119  * This preprocessing directive is for debugging purposes. The effect is
120  * that if the preprocessor symbol KAZLIB_OPAQUE_DEBUG is defined prior to
121  * the inclusion of this header, then the structure shall be declared as
122  * having the single member int __OPAQUE__. This way, any attempts by the
123  * client code to violate the principles of information hiding (by accessing
124  * the structure directly) can be diagnosed at translation time. However,
125  * note the resulting compiled unit is not suitable for linking.\n
126  * \b 2.
127  * This is a pointer to the next node in the chain. In the last node of a
128  * chain, this pointer is null.\n
129  * \b 3.
130  * This is a back-pointer to the primary pointer to this node. The primary
131  * pointer is the previous node's next pointer to this node. If there is no
132  * previous node, the primary pointer is the pointer that resides in the
133  * hash table. This back-pointer lets us handle deletions easily without
134  * searching the chain.\n
135  * \b 4.
136  * The key is a pointer to some user supplied data that contains a unique
137  * identifier for each hash node in a given table. The interpretation of
138  * the data is up to the user. When creating or initializing a hash table,
139  * the user must supply a pointer to a function for comparing two keys,
140  * and a pointer to a function for hashing a key into a numeric value.\n
141  * \b 5.
142  * The value is a user-supplied pointer to void which may refer to
143  * any data object. It is not interpreted in any way by the hashing
144  * module.\n
145  * \b 6.
146  * The hashed key is stored in each node so that we don't have to rehash
147  * each key when the table must grow or shrink.
148  */
149 typedef struct hnode_t
150 {
151 #if defined(HASH_IMPLEMENTATION) || !defined(KAZLIB_OPAQUE_DEBUG) ///<Note 1
152  struct hnode_t *next; ///< Note 2
153  struct hnode_t **pself; ///< Note 3
154  void *key; ///< Note 4
155  void *data; ///< Note 5
156  hash_val_t hkey; ///< Note 6
157 #else
158  int OPAQUE;
159 #endif
160 } hnode_t;
161 
162 /*!
163  * \brief User comparison function override type.
164  *
165  * A comparison function takes two keys and produces a value of -1 if the left
166  * key is less than the right key, a value of 0 if the keys are equal,
167  * and a value of 1 if the left key is greater than the right key.
168  *
169  * \par Default:
170  * Built-in wrapper to strcmp().
171  *
172  * \param key1 Key 1
173  * \param key2 Key 2
174  *
175  * \sa hash_table_create()
176  */
177 typedef int (*hash_comp_t)(const void *key1, const void *key2);
178 
179 /*!
180  * \brief User hashing function type.
181  *
182  * The hashing function performs some computation on a key and produces an
183  * integral value of type hash_val_t based on that key. For best results, the
184  * function should have a good randomness properties in *all* significant bits
185  * over the set of keys that are being inserted into a given hash table. In
186  * particular, the most significant bits of hash_val_t are most significant to
187  * the hash module. Only as the hash table expands are less significant bits
188  * examined. Thus a function that has good distribution in its upper bits but
189  * not lower is preferrable to one that has poor distribution in the upper bits
190  * but not the lower ones.
191  *
192  * \par Default:
193  * Built-in hashing function that hashes over string keys.
194  *
195  * \param key Key to hash.
196  *
197  * \sa hash_table_create()
198  */
199 typedef hash_val_t (*hash_fun_t)(const void *key);
200 
201 /*!
202  * \brief User node data deallocator function.
203  *
204  * \par Default:
205  * NULL (no user key and data are deallocated).
206  *
207  * \param key Pointer to node key data.
208  * \param key Pointer to node user data.
209  *
210  * \sa hash_table_create()
211  */
212 typedef void (*hnode_data_free_t)(void *key, void *data);
213 
214 /*!
215  * \brief Hash table control structure
216  *
217  * The hash table keeps track of information about a hash table, as well as the
218  * actual hash table itself.
219  *
220  * \par Notes:
221  * \b 1.
222  * Pointer to the hash table proper. The table is an array of pointers to
223  * hash nodes (of type hnode_t). If the table is empty, every element of
224  * this table is a null pointer. A non-null entry points to the first
225  * element of a chain of nodes.\n
226  * \b 2.
227  * Minimum and initial size of the hash table (must be a power of two).\n
228  * \b 3.
229  * Maximum hash table size (must be >= minsize). The maximum size is the
230  * greatest number of nodes that can populate this table. If the table
231  * contains this many nodes, no more can be inserted, and the hash_isfull()
232  * function returns true.\n
233  * \b 4.
234  * The low mark is a minimum population threshold, measured as a number of
235  * nodes. If the table population drops below this value, a table shrinkage
236  * will occur. Only dynamic tables are subject to this reduction. No table
237  * will shrink beneath a certain absolute minimum number of nodes.\n
238  * \b 5.
239  * The high mark is a population threshold, measured as a number of nodes,
240  * which, if exceeded, will trigger a table expansion. Only dynamic hash
241  * tables are subject to this expansion.\n
242  * \b 6.
243  * This member keeps track of the size of the hash table---that is, the
244  * number of chain pointers.\n
245  * \b 7.
246  * The current hash table mask. If the size of the hash table is 2^N,
247  * this value has its low N bits set to 1, and the others clear. It is used
248  * to select bits from the result of the hashing function to compute an
249  * index into the table.\n
250  * \b 8.
251  * The count member maintains the number of elements that are presently
252  * in the hash table.\n
253  * \b 9.
254  * This is the a pointer to the hash table's comparison function. The
255  * function is set once at initialization or creation time.\n
256  * \b 10.
257  * Pointer to the table's hashing function, set once at creation or
258  * initialization time.\n
259  * \b 12.
260  * User data deallocator. Default is NULL. (i.e. nothing is done to data
261  * when hash node is deleted).\n
262  * \b 13.
263  * A flag which indicates whether the table is to be dynamically resized. It
264  * is set to 1 in dynamically allocated tables, 0 in tables that are
265  * statically allocated.
266  */
267 typedef struct hash_t
268 {
269 #if defined(HASH_IMPLEMENTATION) || !defined(KAZLIB_OPAQUE_DEBUG)
270  hnode_t **table; ///< Note 1
271  hashcount_t minsize; ///< Note 2
272  hashcount_t maxsize; ///< Note 3
273  hashcount_t highmark; ///< Note 4
274  hashcount_t lowmark; ///< Note 5
275  hashcount_t nchains; ///< Note 6
276  hash_val_t mask; ///< Note 7
277  hashcount_t count; ///< Note 8
278  hash_comp_t compare; ///< Note 9
279  hash_fun_t hash; ///< Note 10
281  bool_t dynamic; ///< Note 12
282 #else
283  int OPAQUE;
284 #endif
285 } hash_t;
286 
287 /*!
288  * \brief Hash scanner structure.
289  *
290  * The scanner is used for traversals of the data structure.
291  *
292  * \par Notes:
293  * \b 1.
294  * Pointer to the hash table that is being traversed.\n
295  * \b 2.
296  * Reference to the current chain in the table being traversed (the chain
297  * that contains the next node that shall be retrieved).\n
298  * \b 3.
299  * Pointer to the node that will be retrieved by the subsequent call to
300  * hash_scan_next().
301  */
302 typedef struct hscan_t
303 {
304 #if defined(HASH_IMPLEMENTATION) || !defined(KAZLIB_OPAQUE_DEBUG)
305  hash_t *hash; ///< Note 1
306  hash_val_t chain; ///< Note 2
307  hnode_t *next; ///< Note 3
308 #else
309  int OPAQUE;
310 #endif
311 } hscan_t;
312 
313 
314 //
315 // Prototypes
316 //
317 
318 extern hash_t *hash_table_create(bool_t isdynamic,
319  hashcount_t minsize,
320  hashcount_t maxsize,
321  hash_comp_t compfun,
322  hash_fun_t hashfun,
323  hnode_data_free_t freedatafun);
324 
325 extern void hash_table_destroy(hash_t *hash);
326 
327 extern void hash_table_delete(hash_t *hash);
328 
329 extern hash_t *hash_table_init(hash_t *hash,
330  hashcount_t minsize,
331  hashcount_t maxsize,
332  hash_comp_t compfun,
333  hash_fun_t hashfun,
334  hnode_data_free_t freedatafun,
335  hnode_t **table,
336  hashcount_t nchains);
337 
338 extern int hash_table_verify(hash_t *hash);
339 
340 extern void hash_scan_begin(hscan_t *scan, hash_t *hash);
341 
342 extern hnode_t *hash_scan_next(hscan_t *scan);
343 
344 extern void hash_node_insert(hash_t *hash, hnode_t *node, void *key);
345 
346 extern hnode_t *hash_node_unlink(hash_t *hash, hnode_t *node);
347 
348 extern hnode_t *hash_node_fast_unlink(hash_t *hash, hnode_t *node);
349 
350 extern void hash_node_delete(hash_t *hash, hnode_t *node);
351 
352 extern hnode_t *hash_lookup(hash_t *hash, const void *key);
353 
354 extern bool_t hash_insert(hash_t *hash, void *key, void *data);
355 
356 extern bool_t hash_delete(hash_t *hash, void *key);
357 
358 extern void hash_set_self_verify(bool_t selfverify);
359 
360 extern hnode_t *hnode_create(void *data);
361 
362 extern hnode_t *hnode_init(hnode_t *node, void *data);
363 
364 extern void hnode_destroy(hnode_t *node, hnode_data_free_t freedatafun);
365 
366 extern void hnode_delete(hnode_t *node);
367 
368 
369 //
370 // Helper Macros
371 //
372 
373 #if defined(HASH_IMPLEMENTATION) || !defined(KAZLIB_OPAQUE_DEBUG)
374 
375 /*!
376  * \brief Returns true if table is full, false otherwise.
377  * \param H Hash table.
378  */
379 #define hash_isfull(H) ((H)->count == (H)->maxcount)
380 
381 /*!
382  * \brief Returns true if table is empty, false otherwise.
383  * \param H Hash table.
384  */
385 #define hash_isempty(H) ((H)->count == 0)
386 
387 /*!
388  * \brief Returns number of entires in hash table.
389  * \param H Hash table.
390  */
391 #define hash_count(H) ((H)->count)
392 
393 /*!
394  * \brief Returns size of hash table.
395  * \param H Hash table.
396  */
397 #define hash_size(H) ((H)->nchains)
398 
399 /*!
400  * \brief Get hash node user data.
401  * \param N Hash node.
402  */
403 #define hnode_get(N) ((N)->data)
404 
405 /*!
406  * \brief Get hash node hash key.
407  * \param N Hash node.
408  */
409 #define hnode_getkey(N) ((N)->key)
410 
411 /*!
412  * \brief Pet hash node user data.
413  * \param N Hash node.
414  * \param V User data.
415  */
416 #define hnode_put(N, V) ((N)->data = (V))
417 
418 #endif // !HASH_IMPLEMENTATION
419 
421 
422 
423 #endif // _RNR_HASH_H
int(* hash_comp_t)(const void *key1, const void *key2)
User comparison function override type.
Definition: hash.h:177
bool_t dynamic
Note 12.
Definition: hash.h:281
hash_val_t mask
Note 7.
Definition: hash.h:276
hashcount_t nchains
Note 6.
Definition: hash.h:275
hashcount_t maxsize
Note 3.
Definition: hash.h:272
void hash_set_self_verify(bool_t selfverify)
Enable (disable) automatic self-checks during hash table modification operatations.
Definition: hash.c:1331
void hnode_delete(hnode_t *node)
Destroy a dynamically allocated node.
Definition: hash.c:1392
hashcount_t minsize
Note 2.
Definition: hash.h:271
void hash_scan_begin(hscan_t *scan, hash_t *hash)
Reset the hash scanner (iterator).
Definition: hash.c:937
void * data
Note 5.
Definition: hash.h:155
hash_t * hash
Note 1.
Definition: hash.h:305
void hash_node_insert(hash_t *hash, hnode_t *node, void *key)
Insert a node into the hash table.
Definition: hash.c:1063
void hash_node_delete(hash_t *hash, hnode_t *node)
Unlink and delete a hash node from the hash table.
Definition: hash.c:1217
hash_comp_t compare
Note 9.
Definition: hash.h:278
hash_val_t(* hash_fun_t)(const void *key)
User hashing function type.
Definition: hash.h:199
hnode_t * hnode_create(void *data)
Create a hash table node dynamically and assign it the given data.
Definition: hash.c:1343
hnode_t * hnode_init(hnode_t *node, void *data)
Initialize a client-supplied hash node.
Definition: hash.c:1362
hashcount_t highmark
Note 4.
Definition: hash.h:273
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
hnode_t ** table
Note 1.
Definition: hash.h:270
unsigned long hashcount_t
maximum hash table size type
Definition: hash.h:94
void hnode_destroy(hnode_t *node, hnode_data_free_t freedatafun)
Hash node and user data deallocator.
Definition: hash.c:1376
hashcount_t count
Note 8.
Definition: hash.h:277
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
void(* hnode_data_free_t)(void *key, void *data)
User node data deallocator function.
Definition: hash.h:212
#define C_DECLS_BEGIN
C declaration block begin in C.
Definition: rnrconfig.h:71
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_val_t chain
Note 2.
Definition: hash.h:306
unsigned long hash_val_t
hashed value return type
Definition: hash.h:96
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
hashcount_t lowmark
Note 5.
Definition: hash.h:274
int bool_t
"boolean" T/F
Definition: rnrconfig.h:187
RoadNarrows Robotics common configuration file.
Hash scanner structure.
Definition: hash.h:302
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 C_DECLS_END
C declaration block end in C.
Definition: rnrconfig.h:72
void * key
Note 4.
Definition: hash.h:154
hnode_t * hash_scan_next(hscan_t *scan)
Retrieve the next node from the hash table.
Definition: hash.c:998
hnode_data_free_t freenodedata
Note 11.
Definition: hash.h:280
hnode_t * next
Note 3.
Definition: hash.h:307
Hash table control structure.
Definition: hash.h:267
void hash_table_delete(hash_t *hash)
Frees a dynamic hash table structure.
Definition: hash.c:776
struct hash_t hash_t
Hash table control structure.
hash_fun_t hash
Note 10.
Definition: hash.h:279
Hash chain node structure.
Definition: hash.h:149
int hash_table_verify(hash_t *hash)
Verify hash table consistency.
Definition: hash.c:888
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
hnode_t * hash_node_unlink(hash_t *hash, hnode_t *node)
Unlink the given node from the hash table.
Definition: hash.c:1128
struct hscan_t hscan_t
Hash scanner structure.
struct hnode_t hnode_t
Hash chain node structure.
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