2 * UCW Library -- Universal Hash Table
4 * (c) 2002--2004 Martin Mares <mj@ucw.cz>
5 * (c) 2002--2005 Robert Spalek <robert@ucw.cz>
7 * This software may be freely distributed and used according to the terms
8 * of the GNU Lesser General Public License.
12 * This is not a normal header file, it's a generator of hash tables.
13 * Each time you include it with parameters set in the corresponding
14 * preprocessor macros, it generates a hash table with the parameters
17 * You need to specify:
19 * HASH_NODE data type where a node dwells (usually a struct).
20 * HASH_PREFIX(x) macro to add a name prefix (used on all global names
21 * defined by the hash table generator).
23 * Then decide on type of keys:
25 * HASH_KEY_ATOMIC=f use node->f as a key of an atomic type (i.e.,
26 * a type which can be compared using `==')
27 * HASH_ATOMIC_TYPE (defaults to int).
28 * | HASH_KEY_STRING=f use node->f as a string key, allocated
29 * separately from the rest of the node.
30 * | HASH_KEY_ENDSTRING=f use node->f as a string key, allocated
31 * automatically at the end of the node struct
32 * (to be declared as "char f[1]" at the end).
33 * | HASH_KEY_COMPLEX use a multi-component key; as the name suggests,
34 * the passing of parameters is a bit complex then.
35 * The HASH_KEY_COMPLEX(x) macro should expand to
36 * `x k1, x k2, ... x kn' and you should also define:
37 * HASH_KEY_DECL declaration of function parameters in which key
38 * should be passed to all hash table operations.
39 * That is, `type1 k1, type2 k2, ... typen kn'.
40 * With complex keys, HASH_GIVE_HASHFN and HASH_GIVE_EQ
42 * | HASH_KEY_MEMORY=f use node->f as a raw data key, compared using
44 * HASH_KEY_SIZE the length of the key block
46 * Then specify what operations you request (all names are automatically
47 * prefixed by calling HASH_PREFIX):
49 * <always defined> init() -- initialize the hash table.
50 * HASH_WANT_CLEANUP cleanup() -- deallocate the hash table.
51 * HASH_WANT_FIND node *find(key) -- find first node with the specified
52 * key, return NULL if no such node exists.
53 * HASH_WANT_FIND_NEXT node *find(node *start) -- find next node with the
54 * specified key, return NULL if no such node exists.
55 * HASH_WANT_NEW node *new(key) -- create new node with given key.
56 * Doesn't check whether it already exists.
57 * HASH_WANT_LOOKUP node *lookup(key) -- find node with given key,
58 * if it doesn't exist, create it. Defining
59 * HASH_GIVE_INIT_DATA is strongly recommended.
60 * HASH_WANT_DELETE int delete(key) -- delete and deallocate node
61 * with given key. Returns success.
62 * HASH_WANT_REMOVE remove(node *) -- delete and deallocate given node.
64 * You can also supply several functions:
66 * HASH_GIVE_HASHFN unsigned int hash(key) -- calculate hash value of key.
67 * We have sensible default hash functions for strings
69 * HASH_GIVE_EQ int eq(key1, key2) -- return whether keys are equal.
70 * By default, we use == for atomic types and either
71 * strcmp or strcasecmp for strings.
72 * HASH_GIVE_EXTRA_SIZE int extra_size(key) -- returns how many bytes after the
73 * node should be allocated for dynamic data. Default=0
74 * or length of the string with HASH_KEY_ENDSTRING.
75 * HASH_GIVE_INIT_KEY void init_key(node *,key) -- initialize key in a newly
76 * created node. Defaults: assignment for atomic keys
77 * and static strings, strcpy for end-allocated strings.
78 * HASH_GIVE_INIT_DATA void init_data(node *) -- initialize data fields in a
79 * newly created node. Very useful for lookup operations.
80 * HASH_GIVE_ALLOC void *alloc(unsigned int size) -- allocate space for
81 * a node. Default is xmalloc() or pooled allocation, depending
82 * on HASH_USE_POOL and HASH_AUTO_POOL switches.
83 * void free(void *) -- the converse.
85 * ... and a couple of extra parameters:
87 * HASH_NOCASE String comparisons should be case-insensitive.
88 * HASH_DEFAULT_SIZE=n Initially, use hash table of approx. `n' entries.
89 * HASH_CONSERVE_SPACE Use as little space as possible.
90 * HASH_FN_BITS=n The hash function gives only `n' significant bits.
91 * HASH_ATOMIC_TYPE=t Atomic values are of type `t' instead of int.
92 * HASH_USE_POOL=pool Allocate all nodes from given mempool. Note, however, that
93 * deallocation is not supported by mempools, so delete/remove
94 * will leak pool memory.
95 * HASH_AUTO_POOL=size Create a pool of the given block size automatically.
96 * HASH_ZERO_FILL New entries should be initialized to all zeroes.
97 * HASH_TABLE_ALLOC The hash table itself will be allocated and freed using
98 * the same allocation functions as the nodes instead of
99 * the default xmalloc().
100 * HASH_TABLE_DYNAMIC Support multiple hash tables; the first parameter of all
101 * hash table operations is struct HASH_PREFIX(table) *.
102 * HASH_TABLE_VARS Extra variables to be defined in table structure
104 * You also get a iterator macro at no extra charge:
106 * HASH_FOR_ALL(hash_prefix, variable)
108 * // node *variable gets declared automatically
109 * do_something_with_node(variable);
110 * // use HASH_BREAK and HASH_CONTINUE instead of break and continue
111 * // you must not alter contents of the hash table here
115 * (For dynamic tables, use HASH_FOR_ALL_DYNAMIC(hash_prefix, hash_table, variable) instead.)
117 * Then include "ucw/hashtable.h" and voila, you have a hash table
118 * suiting all your needs (at least those which you've revealed :) ).
120 * After including this file, all parameter macros are automatically
124 #ifndef _UCW_HASHFUNC_H
125 #include "ucw/hashfunc.h"
128 #include "ucw/prime.h"
132 /* Initial setup of parameters */
134 #if !defined(HASH_NODE) || !defined(HASH_PREFIX)
135 #error Some of the mandatory configuration macros are missing.
138 #if defined(HASH_KEY_ATOMIC) && !defined(HASH_CONSERVE_SPACE)
139 #define HASH_CONSERVE_SPACE
142 #define P(x) HASH_PREFIX(x)
144 /* Declare buckets and the hash table */
146 typedef HASH_NODE P(node);
148 typedef struct P(bucket) {
149 struct P(bucket) *next;
150 #ifndef HASH_CONSERVE_SPACE
158 uns hash_count, hash_max, hash_min, hash_hard_max;
160 #ifdef HASH_AUTO_POOL
161 struct mempool *pool;
163 #ifdef HASH_TABLE_VARS
168 #ifdef HASH_TABLE_DYNAMIC
170 #define TA struct P(table) *table
172 #define TAU TA UNUSED
173 #define TAUC TA UNUSED,
177 struct P(table) P(table);
187 /* Preset parameters */
189 #if defined(HASH_KEY_ATOMIC)
191 #define HASH_KEY(x) x HASH_KEY_ATOMIC
193 #ifndef HASH_ATOMIC_TYPE
194 # define HASH_ATOMIC_TYPE int
196 #define HASH_KEY_DECL HASH_ATOMIC_TYPE HASH_KEY( )
198 #ifndef HASH_GIVE_HASHFN
199 # define HASH_GIVE_HASHFN
200 static inline int P(hash) (TAUC HASH_ATOMIC_TYPE x)
201 { return ((sizeof(x) <= 4) ? hash_u32(x) : hash_u64(x)); }
205 # define HASH_GIVE_EQ
206 static inline int P(eq) (TAUC HASH_ATOMIC_TYPE x, HASH_ATOMIC_TYPE y)
210 #ifndef HASH_GIVE_INIT_KEY
211 # define HASH_GIVE_INIT_KEY
212 static inline void P(init_key) (TAUC P(node) *n, HASH_ATOMIC_TYPE k)
213 { HASH_KEY(n->) = k; }
216 #elif defined(HASH_KEY_MEMORY)
218 #define HASH_KEY(x) x HASH_KEY_MEMORY
220 #define HASH_KEY_DECL byte HASH_KEY( )[HASH_KEY_SIZE]
222 #ifndef HASH_GIVE_HASHFN
223 # define HASH_GIVE_HASHFN
224 static inline int P(hash) (TAUC byte *x)
225 { return hash_block(x, HASH_KEY_SIZE); }
229 # define HASH_GIVE_EQ
230 static inline int P(eq) (TAUC byte *x, byte *y)
231 { return !memcmp(x, y, HASH_KEY_SIZE); }
234 #ifndef HASH_GIVE_INIT_KEY
235 # define HASH_GIVE_INIT_KEY
236 static inline void P(init_key) (TAUC P(node) *n, byte *k)
237 { memcpy(HASH_KEY(n->), k, HASH_KEY_SIZE); }
240 #elif defined(HASH_KEY_STRING) || defined(HASH_KEY_ENDSTRING)
242 #ifdef HASH_KEY_STRING
243 # define HASH_KEY(x) x HASH_KEY_STRING
244 # ifndef HASH_GIVE_INIT_KEY
245 # define HASH_GIVE_INIT_KEY
246 static inline void P(init_key) (TAUC P(node) *n, char *k)
247 { HASH_KEY(n->) = k; }
250 # define HASH_KEY(x) x HASH_KEY_ENDSTRING
251 # define HASH_GIVE_EXTRA_SIZE
252 static inline int P(extra_size) (TAUC char *k)
253 { return strlen(k); }
254 # ifndef HASH_GIVE_INIT_KEY
255 # define HASH_GIVE_INIT_KEY
256 static inline void P(init_key) (TAUC P(node) *n, char *k)
257 { strcpy(HASH_KEY(n->), k); }
260 #define HASH_KEY_DECL char *HASH_KEY( )
262 #ifndef HASH_GIVE_HASHFN
263 #define HASH_GIVE_HASHFN
264 static inline uns P(hash) (TAUC char *k)
267 return hash_string_nocase(k);
269 return hash_string(k);
275 # define HASH_GIVE_EQ
276 static inline int P(eq) (TAUC char *x, char *y)
279 return !strcasecmp(x,y);
286 #elif defined(HASH_KEY_COMPLEX)
288 #define HASH_KEY(x) HASH_KEY_COMPLEX(x)
291 #error You forgot to set the hash key type.
294 /* Defaults for missing parameters */
296 #ifndef HASH_GIVE_HASHFN
297 #error Unable to determine which hash function to use.
301 #error Unable to determine how to compare two keys.
304 #ifdef HASH_GIVE_EXTRA_SIZE
305 /* This trickery is needed to avoid `unused parameter' warnings */
306 #define HASH_EXTRA_SIZE(x) P(extra_size)(TTC x)
309 * Beware, C macros are expanded iteratively, not recursively,
310 * hence we get only a _single_ argument, although the expansion
311 * of HASH_KEY contains commas.
313 #define HASH_EXTRA_SIZE(x) 0
316 #ifndef HASH_GIVE_INIT_KEY
317 #error Unable to determine how to initialize keys.
320 #ifndef HASH_GIVE_INIT_DATA
321 static inline void P(init_data) (TAUC P(node) *n UNUSED)
326 #ifdef HASH_GIVE_ALLOC
327 /* If the caller has requested to use his own allocation functions, do so */
328 static inline void P(init_alloc) (TAU) { }
329 static inline void P(cleanup_alloc) (TAU) { }
331 #elif defined(HASH_USE_POOL)
332 /* If the caller has requested to use his mempool, do so */
333 #include "ucw/mempool.h"
334 static inline void * P(alloc) (TAUC unsigned int size) { return mp_alloc_fast(HASH_USE_POOL, size); }
335 static inline void P(free) (TAUC void *x UNUSED) { }
336 static inline void P(init_alloc) (TAU) { }
337 static inline void P(cleanup_alloc) (TAU) { }
339 #elif defined(HASH_AUTO_POOL)
340 /* Use our own pools */
341 #include "ucw/mempool.h"
342 static inline void * P(alloc) (TAUC unsigned int size) { return mp_alloc_fast(T.pool, size); }
343 static inline void P(free) (TAUC void *x UNUSED) { }
344 static inline void P(init_alloc) (TAU) { T.pool = mp_new(HASH_AUTO_POOL); }
345 static inline void P(cleanup_alloc) (TAU) { mp_delete(T.pool); }
346 #define HASH_USE_POOL
349 /* The default allocation method */
350 static inline void * P(alloc) (TAUC unsigned int size) { return xmalloc(size); }
351 static inline void P(free) (TAUC void *x) { xfree(x); }
352 static inline void P(init_alloc) (TAU) { }
353 static inline void P(cleanup_alloc) (TAU) { }
357 #ifdef HASH_TABLE_ALLOC
358 static inline void * P(table_alloc) (TAUC unsigned int size) { return P(alloc)(TTC size); }
359 static inline void P(table_free) (TAUC void *x) { P(free)(TTC x); }
361 static inline void * P(table_alloc) (TAUC unsigned int size) { return xmalloc(size); }
362 static inline void P(table_free) (TAUC void *x) { xfree(x); }
365 #ifndef HASH_DEFAULT_SIZE
366 #define HASH_DEFAULT_SIZE 32
370 #define HASH_FN_BITS 32
373 #ifdef HASH_ZERO_FILL
374 static inline void * P(new_bucket)(TAUC uns size)
376 byte *buck = P(alloc)(TTC size);
381 static inline void * P(new_bucket)(TAUC uns size) { return P(alloc)(TTC size); }
384 /* Now the operations */
386 static void P(alloc_table) (TAU)
388 T.hash_size = next_table_prime(T.hash_size);
389 T.ht = P(table_alloc)(TTC sizeof(void *) * T.hash_size);
390 bzero(T.ht, sizeof(void *) * T.hash_size);
391 if (2*T.hash_size < T.hash_hard_max)
392 T.hash_max = 2*T.hash_size;
395 if (T.hash_size/2 > HASH_DEFAULT_SIZE)
396 T.hash_min = T.hash_size/4;
402 * Initializes the hash table.
403 * This one is available no matter what `HASH_WANT_` macros you defined or not.
405 static void HASH_PREFIX(init)(TA)
408 T.hash_size = HASH_DEFAULT_SIZE;
409 #if HASH_FN_BITS < 28
410 T.hash_hard_max = 1 << HASH_FN_BITS;
412 T.hash_hard_max = 1 << 28;
418 #ifdef HASH_WANT_CLEANUP
420 * Deallocates the hash table, including the nodes.
421 * It is available if you defined <<want_cleanup,`HASH_WANT_CLEANUP`>>.
423 static void HASH_PREFIX(cleanup)(TA)
425 #ifndef HASH_USE_POOL
429 for (i=0; i<T.hash_size; i++)
430 for (b=T.ht[i]; b; b=bb)
436 P(cleanup_alloc)(TT);
437 P(table_free)(TTC T.ht);
441 static inline uns P(bucket_hash) (TAUC P(bucket) *b)
443 #ifdef HASH_CONSERVE_SPACE
444 return P(hash)(TTC HASH_KEY(b->n.));
450 static void P(rehash) (TAC uns size)
453 P(bucket) **oldt = T.ht, **newt;
454 uns oldsize = T.hash_size;
457 DBG("Rehashing %d->%d at count %d", oldsize, size, T.hash_count);
461 for (i=0; i<oldsize; i++)
467 h = P(bucket_hash)(TTC b) % T.hash_size;
473 P(table_free)(TTC oldt);
476 #ifdef HASH_WANT_FIND
478 * Finds a node with given key (specified in the @HAS_KEY_DECL parameter).
479 * If it does not exist, NULL is returned.
481 * Enabled by the <<want_find,`HASH_WANT_FIND`>> macro.
483 static HASH_NODE* HASH_PREFIX(find)(TAC HASH_KEY_DECL)
485 uns h0 = P(hash) (TTC HASH_KEY( ));
486 uns h = h0 % T.hash_size;
489 for (b=T.ht[h]; b; b=b->next)
492 #ifndef HASH_CONSERVE_SPACE
495 P(eq)(TTC HASH_KEY( ), HASH_KEY(b->n.)))
502 #ifdef HASH_WANT_FIND_NEXT
504 * Finds next node with the same key. Returns NULL if it does not exist.
506 * Enabled by the <<want_find_next,`HASH_WANT_FIND_NEXT`>> macro.
508 static HASH_NODE* HASH_PREFIX(find_next)(TAC P(node) *start)
510 #ifndef HASH_CONSERVE_SPACE
511 uns h0 = P(hash) (TTC HASH_KEY(start->));
513 P(bucket) *b = SKIP_BACK(P(bucket), n, start);
515 for (b=b->next; b; b=b->next)
518 #ifndef HASH_CONSERVE_SPACE
521 P(eq)(TTC HASH_KEY(start->), HASH_KEY(b->n.)))
530 * Generates a new node with a given key.
532 * Enabled by the <<want_new,`HASH_WANT_NEW`>> macro.
534 static HASH_NODE * HASH_PREFIX(new)(TAC HASH_KEY_DECL)
539 h0 = P(hash) (TTC HASH_KEY( ));
540 h = h0 % T.hash_size;
541 b = P(new_bucket) (TTC sizeof(struct P(bucket)) + HASH_EXTRA_SIZE(HASH_KEY( )));
544 #ifndef HASH_CONSERVE_SPACE
547 P(init_key)(TTC &b->n, HASH_KEY( ));
548 P(init_data)(TTC &b->n);
549 if (T.hash_count++ >= T.hash_max)
550 P(rehash)(TTC 2*T.hash_size);
555 #ifdef HASH_WANT_LOOKUP
557 * Finds a node with a given key. If it does not exist, a new one is created.
558 * It is strongly recommended to use <<give_init_data,`HASH_GIVE_INIT_DATA`>>.
560 * This one is enabled by the <<want_lookup,`HASH_WANT_LOOKUP`>> macro.
562 static HASH_NODE* HASH_PREFIX(lookup)(TAC HASH_KEY_DECL)
564 uns h0 = P(hash) (TTC HASH_KEY( ));
565 uns h = h0 % T.hash_size;
568 for (b=T.ht[h]; b; b=b->next)
571 #ifndef HASH_CONSERVE_SPACE
574 P(eq)(TTC HASH_KEY( ), HASH_KEY(b->n.)))
578 b = P(new_bucket) (TTC sizeof(struct P(bucket)) + HASH_EXTRA_SIZE(HASH_KEY( )));
581 #ifndef HASH_CONSERVE_SPACE
584 P(init_key)(TTC &b->n, HASH_KEY( ));
585 P(init_data)(TTC &b->n);
586 if (T.hash_count++ >= T.hash_max)
587 P(rehash)(TTC 2*T.hash_size);
592 #ifdef HASH_WANT_DELETE
594 * Removes a node with the given key from hash table and deallocates it.
596 * Success is returned.
598 * This one is enabled by <<want_delete,`HASH_WANT_DELETE`>> macro.
600 static int HASH_PREFIX(delete)(TAC HASH_KEY_DECL)
602 uns h0 = P(hash) (TTC HASH_KEY( ));
603 uns h = h0 % T.hash_size;
606 for (bb=&T.ht[h]; b=*bb; bb=&b->next)
609 #ifndef HASH_CONSERVE_SPACE
612 P(eq)(TTC HASH_KEY( ), HASH_KEY(b->n.)))
616 if (--T.hash_count < T.hash_min)
617 P(rehash)(TTC T.hash_size/2);
625 #ifdef HASH_WANT_REMOVE
627 * Removes a given node and deallocates it.
628 * It differs from <<fun__GENERIC_LINK|HASH_PREFIX|delete,`HASH_PREFIX(delete)()`>>
629 * in its type of parameter -- this one deletes a specific node, that one looks for it by a key.
631 * Enabled by <<want_remove,`HASH_WANT_REMOVE`>> macro.
633 static void HASH_PREFIX(remove)(TAC HASH_NODE *n)
635 P(bucket) *x = SKIP_BACK(struct P(bucket), n, n);
636 uns h0 = P(bucket_hash)(TTC x);
637 uns h = h0 % T.hash_size;
640 for (bb=&T.ht[h]; (b=*bb) && b != x; bb=&b->next)
645 if (--T.hash_count < T.hash_min)
646 P(rehash)(TTC T.hash_size/2);
650 /* And the iterator */
654 #define HASH_FOR_ALL_DYNAMIC(h_px, h_table, h_var) \
657 struct GLUE_(h_px,bucket) *h_buck; \
658 for (h_slot=0; h_slot < (h_table)->hash_size; h_slot++) \
659 for (h_buck = (h_table)->ht[h_slot]; h_buck; h_buck = h_buck->next) \
661 GLUE_(h_px,node) *h_var = &h_buck->n;
662 #define HASH_FOR_ALL(h_px, h_var) HASH_FOR_ALL_DYNAMIC(h_px, &GLUE_(h_px,table), h_var)
663 #define HASH_END_FOR } } while(0)
665 #define HASH_CONTINUE continue
669 /* Finally, undefine all the parameters */
680 #undef HASH_ATOMIC_TYPE
681 #undef HASH_CONSERVE_SPACE
682 #undef HASH_DEFAULT_SIZE
683 #undef HASH_EXTRA_SIZE
685 #undef HASH_GIVE_ALLOC
687 #undef HASH_GIVE_EXTRA_SIZE
688 #undef HASH_GIVE_HASHFN
689 #undef HASH_GIVE_INIT_DATA
690 #undef HASH_GIVE_INIT_KEY
692 #undef HASH_KEY_ATOMIC
693 #undef HASH_KEY_COMPLEX
695 #undef HASH_KEY_ENDSTRING
696 #undef HASH_KEY_STRING
697 #undef HASH_KEY_MEMORY
703 #undef HASH_AUTO_POOL
704 #undef HASH_WANT_CLEANUP
705 #undef HASH_WANT_DELETE
706 #undef HASH_WANT_FIND
707 #undef HASH_WANT_FIND_NEXT
708 #undef HASH_WANT_LOOKUP
710 #undef HASH_WANT_REMOVE
711 #undef HASH_TABLE_ALLOC
712 #undef HASH_TABLE_DYNAMIC
713 #undef HASH_ZERO_FILL