xref: /libbtbb/lib/src/uthash.h (revision 935bdedbede4663938901e2a8e673ecb9dc59175)
1e25b118aSDominic Spill /*
2*935bdedbSDominic Spill Copyright (c) 2003-2013, Troy D. Hanson     http://troydhanson.github.com/uthash/
3e25b118aSDominic Spill All rights reserved.
4e25b118aSDominic Spill 
5e25b118aSDominic Spill Redistribution and use in source and binary forms, with or without
6e25b118aSDominic Spill modification, are permitted provided that the following conditions are met:
7e25b118aSDominic Spill 
8e25b118aSDominic Spill     * Redistributions of source code must retain the above copyright
9e25b118aSDominic Spill       notice, this list of conditions and the following disclaimer.
10e25b118aSDominic Spill 
11e25b118aSDominic Spill THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
12e25b118aSDominic Spill IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
13e25b118aSDominic Spill TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
14e25b118aSDominic Spill PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
15e25b118aSDominic Spill OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
16e25b118aSDominic Spill EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17e25b118aSDominic Spill PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
18e25b118aSDominic Spill PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
19e25b118aSDominic Spill LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
20e25b118aSDominic Spill NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21e25b118aSDominic Spill SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22e25b118aSDominic Spill */
23e25b118aSDominic Spill 
24e25b118aSDominic Spill #ifndef UTHASH_H
25e25b118aSDominic Spill #define UTHASH_H
26e25b118aSDominic Spill 
27e25b118aSDominic Spill #include <string.h>   /* memcmp,strlen */
28e25b118aSDominic Spill #include <stddef.h>   /* ptrdiff_t */
29e25b118aSDominic Spill #include <stdlib.h>   /* exit() */
30e25b118aSDominic Spill 
31e25b118aSDominic Spill /* These macros use decltype or the earlier __typeof GNU extension.
32e25b118aSDominic Spill    As decltype is only available in newer compilers (VS2010 or gcc 4.3+
33e25b118aSDominic Spill    when compiling c++ source) this code uses whatever method is needed
34e25b118aSDominic Spill    or, for VS2008 where neither is available, uses casting workarounds. */
35e25b118aSDominic Spill #ifdef _MSC_VER         /* MS compiler */
36e25b118aSDominic Spill #if _MSC_VER >= 1600 && defined(__cplusplus)  /* VS2010 or newer in C++ mode */
37e25b118aSDominic Spill #define DECLTYPE(x) (decltype(x))
38e25b118aSDominic Spill #else                   /* VS2008 or older (or VS2010 in C mode) */
39e25b118aSDominic Spill #define NO_DECLTYPE
40e25b118aSDominic Spill #define DECLTYPE(x)
41e25b118aSDominic Spill #endif
42e25b118aSDominic Spill #else                   /* GNU, Sun and other compilers */
43e25b118aSDominic Spill #define DECLTYPE(x) (__typeof(x))
44e25b118aSDominic Spill #endif
45e25b118aSDominic Spill 
46e25b118aSDominic Spill #ifdef NO_DECLTYPE
47e25b118aSDominic Spill #define DECLTYPE_ASSIGN(dst,src)                                                 \
48e25b118aSDominic Spill do {                                                                             \
49e25b118aSDominic Spill   char **_da_dst = (char**)(&(dst));                                             \
50e25b118aSDominic Spill   *_da_dst = (char*)(src);                                                       \
51e25b118aSDominic Spill } while(0)
52e25b118aSDominic Spill #else
53e25b118aSDominic Spill #define DECLTYPE_ASSIGN(dst,src)                                                 \
54e25b118aSDominic Spill do {                                                                             \
55e25b118aSDominic Spill   (dst) = DECLTYPE(dst)(src);                                                    \
56e25b118aSDominic Spill } while(0)
57e25b118aSDominic Spill #endif
58e25b118aSDominic Spill 
59e25b118aSDominic Spill /* a number of the hash function use uint32_t which isn't defined on win32 */
60e25b118aSDominic Spill #ifdef _MSC_VER
61e25b118aSDominic Spill typedef unsigned int uint32_t;
62e25b118aSDominic Spill typedef unsigned char uint8_t;
63e25b118aSDominic Spill #else
64e25b118aSDominic Spill #include <inttypes.h>   /* uint32_t */
65e25b118aSDominic Spill #endif
66e25b118aSDominic Spill 
67*935bdedbSDominic Spill #define UTHASH_VERSION 1.9.8
68e25b118aSDominic Spill 
69e25b118aSDominic Spill #ifndef uthash_fatal
70e25b118aSDominic Spill #define uthash_fatal(msg) exit(-1)        /* fatal error (out of memory,etc) */
71e25b118aSDominic Spill #endif
72e25b118aSDominic Spill #ifndef uthash_malloc
73e25b118aSDominic Spill #define uthash_malloc(sz) malloc(sz)      /* malloc fcn                      */
74e25b118aSDominic Spill #endif
75e25b118aSDominic Spill #ifndef uthash_free
76e25b118aSDominic Spill #define uthash_free(ptr,sz) free(ptr)     /* free fcn                        */
77e25b118aSDominic Spill #endif
78e25b118aSDominic Spill 
79e25b118aSDominic Spill #ifndef uthash_noexpand_fyi
80e25b118aSDominic Spill #define uthash_noexpand_fyi(tbl)          /* can be defined to log noexpand  */
81e25b118aSDominic Spill #endif
82e25b118aSDominic Spill #ifndef uthash_expand_fyi
83e25b118aSDominic Spill #define uthash_expand_fyi(tbl)            /* can be defined to log expands   */
84e25b118aSDominic Spill #endif
85e25b118aSDominic Spill 
86e25b118aSDominic Spill /* initial number of buckets */
87e25b118aSDominic Spill #define HASH_INITIAL_NUM_BUCKETS 32      /* initial number of buckets        */
88e25b118aSDominic Spill #define HASH_INITIAL_NUM_BUCKETS_LOG2 5  /* lg2 of initial number of buckets */
89e25b118aSDominic Spill #define HASH_BKT_CAPACITY_THRESH 10      /* expand when bucket count reaches */
90e25b118aSDominic Spill 
91e25b118aSDominic Spill /* calculate the element whose hash handle address is hhe */
92e25b118aSDominic Spill #define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho)))
93e25b118aSDominic Spill 
94e25b118aSDominic Spill #define HASH_FIND(hh,head,keyptr,keylen,out)                                     \
95e25b118aSDominic Spill do {                                                                             \
96e25b118aSDominic Spill   unsigned _hf_bkt,_hf_hashv;                                                    \
97e25b118aSDominic Spill   out=NULL;                                                                      \
98e25b118aSDominic Spill   if (head) {                                                                    \
99e25b118aSDominic Spill      HASH_FCN(keyptr,keylen, (head)->hh.tbl->num_buckets, _hf_hashv, _hf_bkt);   \
100e25b118aSDominic Spill      if (HASH_BLOOM_TEST((head)->hh.tbl, _hf_hashv)) {                           \
101e25b118aSDominic Spill        HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ],  \
102e25b118aSDominic Spill                         keyptr,keylen,out);                                      \
103e25b118aSDominic Spill      }                                                                           \
104e25b118aSDominic Spill   }                                                                              \
105e25b118aSDominic Spill } while (0)
106e25b118aSDominic Spill 
107e25b118aSDominic Spill #ifdef HASH_BLOOM
108e25b118aSDominic Spill #define HASH_BLOOM_BITLEN (1ULL << HASH_BLOOM)
109e25b118aSDominic Spill #define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8) + ((HASH_BLOOM_BITLEN%8) ? 1:0)
110e25b118aSDominic Spill #define HASH_BLOOM_MAKE(tbl)                                                     \
111e25b118aSDominic Spill do {                                                                             \
112e25b118aSDominic Spill   (tbl)->bloom_nbits = HASH_BLOOM;                                               \
113e25b118aSDominic Spill   (tbl)->bloom_bv = (uint8_t*)uthash_malloc(HASH_BLOOM_BYTELEN);                 \
114e25b118aSDominic Spill   if (!((tbl)->bloom_bv))  { uthash_fatal( "out of memory"); }                   \
115e25b118aSDominic Spill   memset((tbl)->bloom_bv, 0, HASH_BLOOM_BYTELEN);                                \
116e25b118aSDominic Spill   (tbl)->bloom_sig = HASH_BLOOM_SIGNATURE;                                       \
117e25b118aSDominic Spill } while (0)
118e25b118aSDominic Spill 
119e25b118aSDominic Spill #define HASH_BLOOM_FREE(tbl)                                                     \
120e25b118aSDominic Spill do {                                                                             \
121e25b118aSDominic Spill   uthash_free((tbl)->bloom_bv, HASH_BLOOM_BYTELEN);                              \
122e25b118aSDominic Spill } while (0)
123e25b118aSDominic Spill 
124e25b118aSDominic Spill #define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8] |= (1U << ((idx)%8)))
125e25b118aSDominic Spill #define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8] & (1U << ((idx)%8)))
126e25b118aSDominic Spill 
127e25b118aSDominic Spill #define HASH_BLOOM_ADD(tbl,hashv)                                                \
128e25b118aSDominic Spill   HASH_BLOOM_BITSET((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1)))
129e25b118aSDominic Spill 
130e25b118aSDominic Spill #define HASH_BLOOM_TEST(tbl,hashv)                                               \
131e25b118aSDominic Spill   HASH_BLOOM_BITTEST((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1)))
132e25b118aSDominic Spill 
133e25b118aSDominic Spill #else
134e25b118aSDominic Spill #define HASH_BLOOM_MAKE(tbl)
135e25b118aSDominic Spill #define HASH_BLOOM_FREE(tbl)
136e25b118aSDominic Spill #define HASH_BLOOM_ADD(tbl,hashv)
137e25b118aSDominic Spill #define HASH_BLOOM_TEST(tbl,hashv) (1)
138*935bdedbSDominic Spill #define HASH_BLOOM_BYTELEN 0
139e25b118aSDominic Spill #endif
140e25b118aSDominic Spill 
141e25b118aSDominic Spill #define HASH_MAKE_TABLE(hh,head)                                                 \
142e25b118aSDominic Spill do {                                                                             \
143e25b118aSDominic Spill   (head)->hh.tbl = (UT_hash_table*)uthash_malloc(                                \
144e25b118aSDominic Spill                   sizeof(UT_hash_table));                                        \
145e25b118aSDominic Spill   if (!((head)->hh.tbl))  { uthash_fatal( "out of memory"); }                    \
146e25b118aSDominic Spill   memset((head)->hh.tbl, 0, sizeof(UT_hash_table));                              \
147e25b118aSDominic Spill   (head)->hh.tbl->tail = &((head)->hh);                                          \
148e25b118aSDominic Spill   (head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS;                        \
149e25b118aSDominic Spill   (head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2;              \
150e25b118aSDominic Spill   (head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head);                    \
151e25b118aSDominic Spill   (head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc(                      \
152e25b118aSDominic Spill           HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket));               \
153e25b118aSDominic Spill   if (! (head)->hh.tbl->buckets) { uthash_fatal( "out of memory"); }             \
154e25b118aSDominic Spill   memset((head)->hh.tbl->buckets, 0,                                             \
155e25b118aSDominic Spill           HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket));               \
156e25b118aSDominic Spill   HASH_BLOOM_MAKE((head)->hh.tbl);                                               \
157e25b118aSDominic Spill   (head)->hh.tbl->signature = HASH_SIGNATURE;                                    \
158e25b118aSDominic Spill } while(0)
159e25b118aSDominic Spill 
160e25b118aSDominic Spill #define HASH_ADD(hh,head,fieldname,keylen_in,add)                                \
161e25b118aSDominic Spill         HASH_ADD_KEYPTR(hh,head,&((add)->fieldname),keylen_in,add)
162e25b118aSDominic Spill 
163*935bdedbSDominic Spill #define HASH_REPLACE(hh,head,fieldname,keylen_in,add,replaced)                   \
164*935bdedbSDominic Spill do {                                                                             \
165*935bdedbSDominic Spill   replaced=NULL;                                                                 \
166*935bdedbSDominic Spill   HASH_FIND(hh,head,&((add)->fieldname),keylen_in,replaced);                     \
167*935bdedbSDominic Spill   if (replaced!=NULL) {                                                          \
168*935bdedbSDominic Spill      HASH_DELETE(hh,head,replaced);                                              \
169*935bdedbSDominic Spill   };                                                                             \
170*935bdedbSDominic Spill   HASH_ADD(hh,head,fieldname,keylen_in,add);                                     \
171*935bdedbSDominic Spill } while(0)
172*935bdedbSDominic Spill 
173e25b118aSDominic Spill #define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add)                            \
174e25b118aSDominic Spill do {                                                                             \
175e25b118aSDominic Spill  unsigned _ha_bkt;                                                               \
176e25b118aSDominic Spill  (add)->hh.next = NULL;                                                          \
177e25b118aSDominic Spill  (add)->hh.key = (char*)keyptr;                                                  \
178e25b118aSDominic Spill  (add)->hh.keylen = (unsigned)keylen_in;                                                   \
179e25b118aSDominic Spill  if (!(head)) {                                                                  \
180e25b118aSDominic Spill     head = (add);                                                                \
181e25b118aSDominic Spill     (head)->hh.prev = NULL;                                                      \
182e25b118aSDominic Spill     HASH_MAKE_TABLE(hh,head);                                                    \
183e25b118aSDominic Spill  } else {                                                                        \
184e25b118aSDominic Spill     (head)->hh.tbl->tail->next = (add);                                          \
185e25b118aSDominic Spill     (add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail);         \
186e25b118aSDominic Spill     (head)->hh.tbl->tail = &((add)->hh);                                         \
187e25b118aSDominic Spill  }                                                                               \
188e25b118aSDominic Spill  (head)->hh.tbl->num_items++;                                                    \
189e25b118aSDominic Spill  (add)->hh.tbl = (head)->hh.tbl;                                                 \
190e25b118aSDominic Spill  HASH_FCN(keyptr,keylen_in, (head)->hh.tbl->num_buckets,                         \
191e25b118aSDominic Spill          (add)->hh.hashv, _ha_bkt);                                              \
192e25b118aSDominic Spill  HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt],&(add)->hh);                   \
193e25b118aSDominic Spill  HASH_BLOOM_ADD((head)->hh.tbl,(add)->hh.hashv);                                 \
194e25b118aSDominic Spill  HASH_EMIT_KEY(hh,head,keyptr,keylen_in);                                        \
195e25b118aSDominic Spill  HASH_FSCK(hh,head);                                                             \
196e25b118aSDominic Spill } while(0)
197e25b118aSDominic Spill 
198e25b118aSDominic Spill #define HASH_TO_BKT( hashv, num_bkts, bkt )                                      \
199e25b118aSDominic Spill do {                                                                             \
200e25b118aSDominic Spill   bkt = ((hashv) & ((num_bkts) - 1));                                            \
201e25b118aSDominic Spill } while(0)
202e25b118aSDominic Spill 
203e25b118aSDominic Spill /* delete "delptr" from the hash table.
204e25b118aSDominic Spill  * "the usual" patch-up process for the app-order doubly-linked-list.
205e25b118aSDominic Spill  * The use of _hd_hh_del below deserves special explanation.
206e25b118aSDominic Spill  * These used to be expressed using (delptr) but that led to a bug
207e25b118aSDominic Spill  * if someone used the same symbol for the head and deletee, like
208e25b118aSDominic Spill  *  HASH_DELETE(hh,users,users);
209e25b118aSDominic Spill  * We want that to work, but by changing the head (users) below
210e25b118aSDominic Spill  * we were forfeiting our ability to further refer to the deletee (users)
211e25b118aSDominic Spill  * in the patch-up process. Solution: use scratch space to
212e25b118aSDominic Spill  * copy the deletee pointer, then the latter references are via that
213e25b118aSDominic Spill  * scratch pointer rather than through the repointed (users) symbol.
214e25b118aSDominic Spill  */
215e25b118aSDominic Spill #define HASH_DELETE(hh,head,delptr)                                              \
216e25b118aSDominic Spill do {                                                                             \
217e25b118aSDominic Spill     unsigned _hd_bkt;                                                            \
218e25b118aSDominic Spill     struct UT_hash_handle *_hd_hh_del;                                           \
219e25b118aSDominic Spill     if ( ((delptr)->hh.prev == NULL) && ((delptr)->hh.next == NULL) )  {         \
220e25b118aSDominic Spill         uthash_free((head)->hh.tbl->buckets,                                     \
221e25b118aSDominic Spill                     (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \
222e25b118aSDominic Spill         HASH_BLOOM_FREE((head)->hh.tbl);                                         \
223e25b118aSDominic Spill         uthash_free((head)->hh.tbl, sizeof(UT_hash_table));                      \
224e25b118aSDominic Spill         head = NULL;                                                             \
225e25b118aSDominic Spill     } else {                                                                     \
226e25b118aSDominic Spill         _hd_hh_del = &((delptr)->hh);                                            \
227e25b118aSDominic Spill         if ((delptr) == ELMT_FROM_HH((head)->hh.tbl,(head)->hh.tbl->tail)) {     \
228e25b118aSDominic Spill             (head)->hh.tbl->tail =                                               \
229e25b118aSDominic Spill                 (UT_hash_handle*)((ptrdiff_t)((delptr)->hh.prev) +               \
230e25b118aSDominic Spill                 (head)->hh.tbl->hho);                                            \
231e25b118aSDominic Spill         }                                                                        \
232e25b118aSDominic Spill         if ((delptr)->hh.prev) {                                                 \
233e25b118aSDominic Spill             ((UT_hash_handle*)((ptrdiff_t)((delptr)->hh.prev) +                  \
234e25b118aSDominic Spill                     (head)->hh.tbl->hho))->next = (delptr)->hh.next;             \
235e25b118aSDominic Spill         } else {                                                                 \
236e25b118aSDominic Spill             DECLTYPE_ASSIGN(head,(delptr)->hh.next);                             \
237e25b118aSDominic Spill         }                                                                        \
238e25b118aSDominic Spill         if (_hd_hh_del->next) {                                                  \
239e25b118aSDominic Spill             ((UT_hash_handle*)((ptrdiff_t)_hd_hh_del->next +                     \
240e25b118aSDominic Spill                     (head)->hh.tbl->hho))->prev =                                \
241e25b118aSDominic Spill                     _hd_hh_del->prev;                                            \
242e25b118aSDominic Spill         }                                                                        \
243e25b118aSDominic Spill         HASH_TO_BKT( _hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt);   \
244e25b118aSDominic Spill         HASH_DEL_IN_BKT(hh,(head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del);        \
245e25b118aSDominic Spill         (head)->hh.tbl->num_items--;                                             \
246e25b118aSDominic Spill     }                                                                            \
247e25b118aSDominic Spill     HASH_FSCK(hh,head);                                                          \
248e25b118aSDominic Spill } while (0)
249e25b118aSDominic Spill 
250e25b118aSDominic Spill 
251e25b118aSDominic Spill /* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */
252e25b118aSDominic Spill #define HASH_FIND_STR(head,findstr,out)                                          \
253e25b118aSDominic Spill     HASH_FIND(hh,head,findstr,strlen(findstr),out)
254e25b118aSDominic Spill #define HASH_ADD_STR(head,strfield,add)                                          \
255e25b118aSDominic Spill     HASH_ADD(hh,head,strfield,strlen(add->strfield),add)
256*935bdedbSDominic Spill #define HASH_REPLACE_STR(head,strfield,add,replaced)                             \
257*935bdedbSDominic Spill   HASH_REPLACE(hh,head,strfield,strlen(add->strfield),add,replaced)
258e25b118aSDominic Spill #define HASH_FIND_INT(head,findint,out)                                          \
259e25b118aSDominic Spill     HASH_FIND(hh,head,findint,sizeof(int),out)
260e25b118aSDominic Spill #define HASH_ADD_INT(head,intfield,add)                                          \
261e25b118aSDominic Spill     HASH_ADD(hh,head,intfield,sizeof(int),add)
262*935bdedbSDominic Spill #define HASH_REPLACE_INT(head,intfield,add,replaced)                             \
263*935bdedbSDominic Spill     HASH_REPLACE(hh,head,intfield,sizeof(int),add,replaced)
264e25b118aSDominic Spill #define HASH_FIND_PTR(head,findptr,out)                                          \
265e25b118aSDominic Spill     HASH_FIND(hh,head,findptr,sizeof(void *),out)
266e25b118aSDominic Spill #define HASH_ADD_PTR(head,ptrfield,add)                                          \
267e25b118aSDominic Spill     HASH_ADD(hh,head,ptrfield,sizeof(void *),add)
268*935bdedbSDominic Spill #define HASH_REPLACE_PTR(head,ptrfield,add)                                      \
269*935bdedbSDominic Spill     HASH_REPLACE(hh,head,ptrfield,sizeof(void *),add,replaced)
270e25b118aSDominic Spill #define HASH_DEL(head,delptr)                                                    \
271e25b118aSDominic Spill     HASH_DELETE(hh,head,delptr)
272e25b118aSDominic Spill 
273e25b118aSDominic Spill /* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined.
274e25b118aSDominic Spill  * This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined.
275e25b118aSDominic Spill  */
276e25b118aSDominic Spill #ifdef HASH_DEBUG
277e25b118aSDominic Spill #define HASH_OOPS(...) do { fprintf(stderr,__VA_ARGS__); exit(-1); } while (0)
278e25b118aSDominic Spill #define HASH_FSCK(hh,head)                                                       \
279e25b118aSDominic Spill do {                                                                             \
280e25b118aSDominic Spill     unsigned _bkt_i;                                                             \
281e25b118aSDominic Spill     unsigned _count, _bkt_count;                                                 \
282e25b118aSDominic Spill     char *_prev;                                                                 \
283e25b118aSDominic Spill     struct UT_hash_handle *_thh;                                                 \
284e25b118aSDominic Spill     if (head) {                                                                  \
285e25b118aSDominic Spill         _count = 0;                                                              \
286e25b118aSDominic Spill         for( _bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; _bkt_i++) {       \
287e25b118aSDominic Spill             _bkt_count = 0;                                                      \
288e25b118aSDominic Spill             _thh = (head)->hh.tbl->buckets[_bkt_i].hh_head;                      \
289e25b118aSDominic Spill             _prev = NULL;                                                        \
290e25b118aSDominic Spill             while (_thh) {                                                       \
291e25b118aSDominic Spill                if (_prev != (char*)(_thh->hh_prev)) {                            \
292e25b118aSDominic Spill                    HASH_OOPS("invalid hh_prev %p, actual %p\n",                  \
293e25b118aSDominic Spill                     _thh->hh_prev, _prev );                                      \
294e25b118aSDominic Spill                }                                                                 \
295e25b118aSDominic Spill                _bkt_count++;                                                     \
296e25b118aSDominic Spill                _prev = (char*)(_thh);                                            \
297e25b118aSDominic Spill                _thh = _thh->hh_next;                                             \
298e25b118aSDominic Spill             }                                                                    \
299e25b118aSDominic Spill             _count += _bkt_count;                                                \
300e25b118aSDominic Spill             if ((head)->hh.tbl->buckets[_bkt_i].count !=  _bkt_count) {          \
301e25b118aSDominic Spill                HASH_OOPS("invalid bucket count %d, actual %d\n",                 \
302e25b118aSDominic Spill                 (head)->hh.tbl->buckets[_bkt_i].count, _bkt_count);              \
303e25b118aSDominic Spill             }                                                                    \
304e25b118aSDominic Spill         }                                                                        \
305e25b118aSDominic Spill         if (_count != (head)->hh.tbl->num_items) {                               \
306e25b118aSDominic Spill             HASH_OOPS("invalid hh item count %d, actual %d\n",                   \
307e25b118aSDominic Spill                 (head)->hh.tbl->num_items, _count );                             \
308e25b118aSDominic Spill         }                                                                        \
309e25b118aSDominic Spill         /* traverse hh in app order; check next/prev integrity, count */         \
310e25b118aSDominic Spill         _count = 0;                                                              \
311e25b118aSDominic Spill         _prev = NULL;                                                            \
312e25b118aSDominic Spill         _thh =  &(head)->hh;                                                     \
313e25b118aSDominic Spill         while (_thh) {                                                           \
314e25b118aSDominic Spill            _count++;                                                             \
315e25b118aSDominic Spill            if (_prev !=(char*)(_thh->prev)) {                                    \
316e25b118aSDominic Spill               HASH_OOPS("invalid prev %p, actual %p\n",                          \
317e25b118aSDominic Spill                     _thh->prev, _prev );                                         \
318e25b118aSDominic Spill            }                                                                     \
319e25b118aSDominic Spill            _prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh);                    \
320e25b118aSDominic Spill            _thh = ( _thh->next ?  (UT_hash_handle*)((char*)(_thh->next) +        \
321e25b118aSDominic Spill                                   (head)->hh.tbl->hho) : NULL );                 \
322e25b118aSDominic Spill         }                                                                        \
323e25b118aSDominic Spill         if (_count != (head)->hh.tbl->num_items) {                               \
324e25b118aSDominic Spill             HASH_OOPS("invalid app item count %d, actual %d\n",                  \
325e25b118aSDominic Spill                 (head)->hh.tbl->num_items, _count );                             \
326e25b118aSDominic Spill         }                                                                        \
327e25b118aSDominic Spill     }                                                                            \
328e25b118aSDominic Spill } while (0)
329e25b118aSDominic Spill #else
330e25b118aSDominic Spill #define HASH_FSCK(hh,head)
331e25b118aSDominic Spill #endif
332e25b118aSDominic Spill 
333e25b118aSDominic Spill /* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to
334e25b118aSDominic Spill  * the descriptor to which this macro is defined for tuning the hash function.
335e25b118aSDominic Spill  * The app can #include <unistd.h> to get the prototype for write(2). */
336e25b118aSDominic Spill #ifdef HASH_EMIT_KEYS
337e25b118aSDominic Spill #define HASH_EMIT_KEY(hh,head,keyptr,fieldlen)                                   \
338e25b118aSDominic Spill do {                                                                             \
339e25b118aSDominic Spill     unsigned _klen = fieldlen;                                                   \
340e25b118aSDominic Spill     write(HASH_EMIT_KEYS, &_klen, sizeof(_klen));                                \
341e25b118aSDominic Spill     write(HASH_EMIT_KEYS, keyptr, fieldlen);                                     \
342e25b118aSDominic Spill } while (0)
343e25b118aSDominic Spill #else
344e25b118aSDominic Spill #define HASH_EMIT_KEY(hh,head,keyptr,fieldlen)
345e25b118aSDominic Spill #endif
346e25b118aSDominic Spill 
347e25b118aSDominic Spill /* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */
348e25b118aSDominic Spill #ifdef HASH_FUNCTION
349e25b118aSDominic Spill #define HASH_FCN HASH_FUNCTION
350e25b118aSDominic Spill #else
351e25b118aSDominic Spill #define HASH_FCN HASH_JEN
352e25b118aSDominic Spill #endif
353e25b118aSDominic Spill 
354e25b118aSDominic Spill /* The Bernstein hash function, used in Perl prior to v5.6 */
355e25b118aSDominic Spill #define HASH_BER(key,keylen,num_bkts,hashv,bkt)                                  \
356e25b118aSDominic Spill do {                                                                             \
357e25b118aSDominic Spill   unsigned _hb_keylen=keylen;                                                    \
358e25b118aSDominic Spill   char *_hb_key=(char*)(key);                                                    \
359e25b118aSDominic Spill   (hashv) = 0;                                                                   \
360e25b118aSDominic Spill   while (_hb_keylen--)  { (hashv) = ((hashv) * 33) + *_hb_key++; }               \
361e25b118aSDominic Spill   bkt = (hashv) & (num_bkts-1);                                                  \
362e25b118aSDominic Spill } while (0)
363e25b118aSDominic Spill 
364e25b118aSDominic Spill 
365e25b118aSDominic Spill /* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at
366e25b118aSDominic Spill  * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */
367e25b118aSDominic Spill #define HASH_SAX(key,keylen,num_bkts,hashv,bkt)                                  \
368e25b118aSDominic Spill do {                                                                             \
369e25b118aSDominic Spill   unsigned _sx_i;                                                                \
370e25b118aSDominic Spill   char *_hs_key=(char*)(key);                                                    \
371e25b118aSDominic Spill   hashv = 0;                                                                     \
372e25b118aSDominic Spill   for(_sx_i=0; _sx_i < keylen; _sx_i++)                                          \
373e25b118aSDominic Spill       hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i];                     \
374e25b118aSDominic Spill   bkt = hashv & (num_bkts-1);                                                    \
375e25b118aSDominic Spill } while (0)
376e25b118aSDominic Spill 
377e25b118aSDominic Spill #define HASH_FNV(key,keylen,num_bkts,hashv,bkt)                                  \
378e25b118aSDominic Spill do {                                                                             \
379e25b118aSDominic Spill   unsigned _fn_i;                                                                \
380e25b118aSDominic Spill   char *_hf_key=(char*)(key);                                                    \
381e25b118aSDominic Spill   hashv = 2166136261UL;                                                          \
382e25b118aSDominic Spill   for(_fn_i=0; _fn_i < keylen; _fn_i++)                                          \
383e25b118aSDominic Spill       hashv = (hashv * 16777619) ^ _hf_key[_fn_i];                               \
384e25b118aSDominic Spill   bkt = hashv & (num_bkts-1);                                                    \
385e25b118aSDominic Spill } while(0)
386e25b118aSDominic Spill 
387e25b118aSDominic Spill #define HASH_OAT(key,keylen,num_bkts,hashv,bkt)                                  \
388e25b118aSDominic Spill do {                                                                             \
389e25b118aSDominic Spill   unsigned _ho_i;                                                                \
390e25b118aSDominic Spill   char *_ho_key=(char*)(key);                                                    \
391e25b118aSDominic Spill   hashv = 0;                                                                     \
392e25b118aSDominic Spill   for(_ho_i=0; _ho_i < keylen; _ho_i++) {                                        \
393e25b118aSDominic Spill       hashv += _ho_key[_ho_i];                                                   \
394e25b118aSDominic Spill       hashv += (hashv << 10);                                                    \
395e25b118aSDominic Spill       hashv ^= (hashv >> 6);                                                     \
396e25b118aSDominic Spill   }                                                                              \
397e25b118aSDominic Spill   hashv += (hashv << 3);                                                         \
398e25b118aSDominic Spill   hashv ^= (hashv >> 11);                                                        \
399e25b118aSDominic Spill   hashv += (hashv << 15);                                                        \
400e25b118aSDominic Spill   bkt = hashv & (num_bkts-1);                                                    \
401e25b118aSDominic Spill } while(0)
402e25b118aSDominic Spill 
403e25b118aSDominic Spill #define HASH_JEN_MIX(a,b,c)                                                      \
404e25b118aSDominic Spill do {                                                                             \
405e25b118aSDominic Spill   a -= b; a -= c; a ^= ( c >> 13 );                                              \
406e25b118aSDominic Spill   b -= c; b -= a; b ^= ( a << 8 );                                               \
407e25b118aSDominic Spill   c -= a; c -= b; c ^= ( b >> 13 );                                              \
408e25b118aSDominic Spill   a -= b; a -= c; a ^= ( c >> 12 );                                              \
409e25b118aSDominic Spill   b -= c; b -= a; b ^= ( a << 16 );                                              \
410e25b118aSDominic Spill   c -= a; c -= b; c ^= ( b >> 5 );                                               \
411e25b118aSDominic Spill   a -= b; a -= c; a ^= ( c >> 3 );                                               \
412e25b118aSDominic Spill   b -= c; b -= a; b ^= ( a << 10 );                                              \
413e25b118aSDominic Spill   c -= a; c -= b; c ^= ( b >> 15 );                                              \
414e25b118aSDominic Spill } while (0)
415e25b118aSDominic Spill 
416e25b118aSDominic Spill #define HASH_JEN(key,keylen,num_bkts,hashv,bkt)                                  \
417e25b118aSDominic Spill do {                                                                             \
418e25b118aSDominic Spill   unsigned _hj_i,_hj_j,_hj_k;                                                    \
419*935bdedbSDominic Spill   unsigned char *_hj_key=(unsigned char*)(key);                                  \
420e25b118aSDominic Spill   hashv = 0xfeedbeef;                                                            \
421e25b118aSDominic Spill   _hj_i = _hj_j = 0x9e3779b9;                                                    \
422e25b118aSDominic Spill   _hj_k = (unsigned)keylen;                                                      \
423e25b118aSDominic Spill   while (_hj_k >= 12) {                                                          \
424e25b118aSDominic Spill     _hj_i +=    (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 )                      \
425e25b118aSDominic Spill         + ( (unsigned)_hj_key[2] << 16 )                                         \
426e25b118aSDominic Spill         + ( (unsigned)_hj_key[3] << 24 ) );                                      \
427e25b118aSDominic Spill     _hj_j +=    (_hj_key[4] + ( (unsigned)_hj_key[5] << 8 )                      \
428e25b118aSDominic Spill         + ( (unsigned)_hj_key[6] << 16 )                                         \
429e25b118aSDominic Spill         + ( (unsigned)_hj_key[7] << 24 ) );                                      \
430e25b118aSDominic Spill     hashv += (_hj_key[8] + ( (unsigned)_hj_key[9] << 8 )                         \
431e25b118aSDominic Spill         + ( (unsigned)_hj_key[10] << 16 )                                        \
432e25b118aSDominic Spill         + ( (unsigned)_hj_key[11] << 24 ) );                                     \
433e25b118aSDominic Spill                                                                                  \
434e25b118aSDominic Spill      HASH_JEN_MIX(_hj_i, _hj_j, hashv);                                          \
435e25b118aSDominic Spill                                                                                  \
436e25b118aSDominic Spill      _hj_key += 12;                                                              \
437e25b118aSDominic Spill      _hj_k -= 12;                                                                \
438e25b118aSDominic Spill   }                                                                              \
439e25b118aSDominic Spill   hashv += keylen;                                                               \
440e25b118aSDominic Spill   switch ( _hj_k ) {                                                             \
441e25b118aSDominic Spill      case 11: hashv += ( (unsigned)_hj_key[10] << 24 );                          \
442e25b118aSDominic Spill      case 10: hashv += ( (unsigned)_hj_key[9] << 16 );                           \
443e25b118aSDominic Spill      case 9:  hashv += ( (unsigned)_hj_key[8] << 8 );                            \
444e25b118aSDominic Spill      case 8:  _hj_j += ( (unsigned)_hj_key[7] << 24 );                           \
445e25b118aSDominic Spill      case 7:  _hj_j += ( (unsigned)_hj_key[6] << 16 );                           \
446e25b118aSDominic Spill      case 6:  _hj_j += ( (unsigned)_hj_key[5] << 8 );                            \
447e25b118aSDominic Spill      case 5:  _hj_j += _hj_key[4];                                               \
448e25b118aSDominic Spill      case 4:  _hj_i += ( (unsigned)_hj_key[3] << 24 );                           \
449e25b118aSDominic Spill      case 3:  _hj_i += ( (unsigned)_hj_key[2] << 16 );                           \
450e25b118aSDominic Spill      case 2:  _hj_i += ( (unsigned)_hj_key[1] << 8 );                            \
451e25b118aSDominic Spill      case 1:  _hj_i += _hj_key[0];                                               \
452e25b118aSDominic Spill   }                                                                              \
453e25b118aSDominic Spill   HASH_JEN_MIX(_hj_i, _hj_j, hashv);                                             \
454e25b118aSDominic Spill   bkt = hashv & (num_bkts-1);                                                    \
455e25b118aSDominic Spill } while(0)
456e25b118aSDominic Spill 
457e25b118aSDominic Spill /* The Paul Hsieh hash function */
458e25b118aSDominic Spill #undef get16bits
459e25b118aSDominic Spill #if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__)             \
460e25b118aSDominic Spill   || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)
461e25b118aSDominic Spill #define get16bits(d) (*((const uint16_t *) (d)))
462e25b118aSDominic Spill #endif
463e25b118aSDominic Spill 
464e25b118aSDominic Spill #if !defined (get16bits)
465e25b118aSDominic Spill #define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)             \
466e25b118aSDominic Spill                        +(uint32_t)(((const uint8_t *)(d))[0]) )
467e25b118aSDominic Spill #endif
468e25b118aSDominic Spill #define HASH_SFH(key,keylen,num_bkts,hashv,bkt)                                  \
469e25b118aSDominic Spill do {                                                                             \
470*935bdedbSDominic Spill   unsigned char *_sfh_key=(unsigned char*)(key);                                 \
471e25b118aSDominic Spill   uint32_t _sfh_tmp, _sfh_len = keylen;                                          \
472e25b118aSDominic Spill                                                                                  \
473e25b118aSDominic Spill   int _sfh_rem = _sfh_len & 3;                                                   \
474e25b118aSDominic Spill   _sfh_len >>= 2;                                                                \
475e25b118aSDominic Spill   hashv = 0xcafebabe;                                                            \
476e25b118aSDominic Spill                                                                                  \
477e25b118aSDominic Spill   /* Main loop */                                                                \
478e25b118aSDominic Spill   for (;_sfh_len > 0; _sfh_len--) {                                              \
479e25b118aSDominic Spill     hashv    += get16bits (_sfh_key);                                            \
480*935bdedbSDominic Spill     _sfh_tmp       = (uint32_t)(get16bits (_sfh_key+2)) << 11  ^ hashv;          \
481e25b118aSDominic Spill     hashv     = (hashv << 16) ^ _sfh_tmp;                                        \
482e25b118aSDominic Spill     _sfh_key += 2*sizeof (uint16_t);                                             \
483e25b118aSDominic Spill     hashv    += hashv >> 11;                                                     \
484e25b118aSDominic Spill   }                                                                              \
485e25b118aSDominic Spill                                                                                  \
486e25b118aSDominic Spill   /* Handle end cases */                                                         \
487e25b118aSDominic Spill   switch (_sfh_rem) {                                                            \
488e25b118aSDominic Spill     case 3: hashv += get16bits (_sfh_key);                                       \
489e25b118aSDominic Spill             hashv ^= hashv << 16;                                                \
490*935bdedbSDominic Spill             hashv ^= (uint32_t)(_sfh_key[sizeof (uint16_t)] << 18);              \
491e25b118aSDominic Spill             hashv += hashv >> 11;                                                \
492e25b118aSDominic Spill             break;                                                               \
493e25b118aSDominic Spill     case 2: hashv += get16bits (_sfh_key);                                       \
494e25b118aSDominic Spill             hashv ^= hashv << 11;                                                \
495e25b118aSDominic Spill             hashv += hashv >> 17;                                                \
496e25b118aSDominic Spill             break;                                                               \
497e25b118aSDominic Spill     case 1: hashv += *_sfh_key;                                                  \
498e25b118aSDominic Spill             hashv ^= hashv << 10;                                                \
499e25b118aSDominic Spill             hashv += hashv >> 1;                                                 \
500e25b118aSDominic Spill   }                                                                              \
501e25b118aSDominic Spill                                                                                  \
502e25b118aSDominic Spill     /* Force "avalanching" of final 127 bits */                                  \
503e25b118aSDominic Spill     hashv ^= hashv << 3;                                                         \
504e25b118aSDominic Spill     hashv += hashv >> 5;                                                         \
505e25b118aSDominic Spill     hashv ^= hashv << 4;                                                         \
506e25b118aSDominic Spill     hashv += hashv >> 17;                                                        \
507e25b118aSDominic Spill     hashv ^= hashv << 25;                                                        \
508e25b118aSDominic Spill     hashv += hashv >> 6;                                                         \
509e25b118aSDominic Spill     bkt = hashv & (num_bkts-1);                                                  \
510e25b118aSDominic Spill } while(0)
511e25b118aSDominic Spill 
512e25b118aSDominic Spill #ifdef HASH_USING_NO_STRICT_ALIASING
513e25b118aSDominic Spill /* The MurmurHash exploits some CPU's (x86,x86_64) tolerance for unaligned reads.
514e25b118aSDominic Spill  * For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error.
515e25b118aSDominic Spill  * MurmurHash uses the faster approach only on CPU's where we know it's safe.
516e25b118aSDominic Spill  *
517e25b118aSDominic Spill  * Note the preprocessor built-in defines can be emitted using:
518e25b118aSDominic Spill  *
519e25b118aSDominic Spill  *   gcc -m64 -dM -E - < /dev/null                  (on gcc)
520e25b118aSDominic Spill  *   cc -## a.c (where a.c is a simple test file)   (Sun Studio)
521e25b118aSDominic Spill  */
522e25b118aSDominic Spill #if (defined(__i386__) || defined(__x86_64__)  || defined(_M_IX86))
523e25b118aSDominic Spill #define MUR_GETBLOCK(p,i) p[i]
524e25b118aSDominic Spill #else /* non intel */
525e25b118aSDominic Spill #define MUR_PLUS0_ALIGNED(p) (((unsigned long)p & 0x3) == 0)
526e25b118aSDominic Spill #define MUR_PLUS1_ALIGNED(p) (((unsigned long)p & 0x3) == 1)
527e25b118aSDominic Spill #define MUR_PLUS2_ALIGNED(p) (((unsigned long)p & 0x3) == 2)
528e25b118aSDominic Spill #define MUR_PLUS3_ALIGNED(p) (((unsigned long)p & 0x3) == 3)
529e25b118aSDominic Spill #define WP(p) ((uint32_t*)((unsigned long)(p) & ~3UL))
530e25b118aSDominic Spill #if (defined(__BIG_ENDIAN__) || defined(SPARC) || defined(__ppc__) || defined(__ppc64__))
531e25b118aSDominic Spill #define MUR_THREE_ONE(p) ((((*WP(p))&0x00ffffff) << 8) | (((*(WP(p)+1))&0xff000000) >> 24))
532e25b118aSDominic Spill #define MUR_TWO_TWO(p)   ((((*WP(p))&0x0000ffff) <<16) | (((*(WP(p)+1))&0xffff0000) >> 16))
533e25b118aSDominic Spill #define MUR_ONE_THREE(p) ((((*WP(p))&0x000000ff) <<24) | (((*(WP(p)+1))&0xffffff00) >>  8))
534e25b118aSDominic Spill #else /* assume little endian non-intel */
535e25b118aSDominic Spill #define MUR_THREE_ONE(p) ((((*WP(p))&0xffffff00) >> 8) | (((*(WP(p)+1))&0x000000ff) << 24))
536e25b118aSDominic Spill #define MUR_TWO_TWO(p)   ((((*WP(p))&0xffff0000) >>16) | (((*(WP(p)+1))&0x0000ffff) << 16))
537e25b118aSDominic Spill #define MUR_ONE_THREE(p) ((((*WP(p))&0xff000000) >>24) | (((*(WP(p)+1))&0x00ffffff) <<  8))
538e25b118aSDominic Spill #endif
539e25b118aSDominic Spill #define MUR_GETBLOCK(p,i) (MUR_PLUS0_ALIGNED(p) ? ((p)[i]) :           \
540e25b118aSDominic Spill                             (MUR_PLUS1_ALIGNED(p) ? MUR_THREE_ONE(p) : \
541e25b118aSDominic Spill                              (MUR_PLUS2_ALIGNED(p) ? MUR_TWO_TWO(p) :  \
542e25b118aSDominic Spill                                                       MUR_ONE_THREE(p))))
543e25b118aSDominic Spill #endif
544e25b118aSDominic Spill #define MUR_ROTL32(x,r) (((x) << (r)) | ((x) >> (32 - (r))))
545e25b118aSDominic Spill #define MUR_FMIX(_h) \
546e25b118aSDominic Spill do {                 \
547e25b118aSDominic Spill   _h ^= _h >> 16;    \
548e25b118aSDominic Spill   _h *= 0x85ebca6b;  \
549e25b118aSDominic Spill   _h ^= _h >> 13;    \
550e25b118aSDominic Spill   _h *= 0xc2b2ae35l; \
551e25b118aSDominic Spill   _h ^= _h >> 16;    \
552e25b118aSDominic Spill } while(0)
553e25b118aSDominic Spill 
554e25b118aSDominic Spill #define HASH_MUR(key,keylen,num_bkts,hashv,bkt)                        \
555e25b118aSDominic Spill do {                                                                   \
556e25b118aSDominic Spill   const uint8_t *_mur_data = (const uint8_t*)(key);                    \
557e25b118aSDominic Spill   const int _mur_nblocks = (keylen) / 4;                               \
558e25b118aSDominic Spill   uint32_t _mur_h1 = 0xf88D5353;                                       \
559e25b118aSDominic Spill   uint32_t _mur_c1 = 0xcc9e2d51;                                       \
560e25b118aSDominic Spill   uint32_t _mur_c2 = 0x1b873593;                                       \
561e25b118aSDominic Spill   uint32_t _mur_k1 = 0;                                                \
562e25b118aSDominic Spill   const uint8_t *_mur_tail;                                            \
563e25b118aSDominic Spill   const uint32_t *_mur_blocks = (const uint32_t*)(_mur_data+_mur_nblocks*4); \
564e25b118aSDominic Spill   int _mur_i;                                                          \
565e25b118aSDominic Spill   for(_mur_i = -_mur_nblocks; _mur_i; _mur_i++) {                      \
566e25b118aSDominic Spill     _mur_k1 = MUR_GETBLOCK(_mur_blocks,_mur_i);                        \
567e25b118aSDominic Spill     _mur_k1 *= _mur_c1;                                                \
568e25b118aSDominic Spill     _mur_k1 = MUR_ROTL32(_mur_k1,15);                                  \
569e25b118aSDominic Spill     _mur_k1 *= _mur_c2;                                                \
570e25b118aSDominic Spill                                                                        \
571e25b118aSDominic Spill     _mur_h1 ^= _mur_k1;                                                \
572e25b118aSDominic Spill     _mur_h1 = MUR_ROTL32(_mur_h1,13);                                  \
573e25b118aSDominic Spill     _mur_h1 = _mur_h1*5+0xe6546b64;                                    \
574e25b118aSDominic Spill   }                                                                    \
575e25b118aSDominic Spill   _mur_tail = (const uint8_t*)(_mur_data + _mur_nblocks*4);            \
576e25b118aSDominic Spill   _mur_k1=0;                                                           \
577e25b118aSDominic Spill   switch((keylen) & 3) {                                               \
578e25b118aSDominic Spill     case 3: _mur_k1 ^= _mur_tail[2] << 16;                             \
579e25b118aSDominic Spill     case 2: _mur_k1 ^= _mur_tail[1] << 8;                              \
580e25b118aSDominic Spill     case 1: _mur_k1 ^= _mur_tail[0];                                   \
581e25b118aSDominic Spill     _mur_k1 *= _mur_c1;                                                \
582e25b118aSDominic Spill     _mur_k1 = MUR_ROTL32(_mur_k1,15);                                  \
583e25b118aSDominic Spill     _mur_k1 *= _mur_c2;                                                \
584e25b118aSDominic Spill     _mur_h1 ^= _mur_k1;                                                \
585e25b118aSDominic Spill   }                                                                    \
586e25b118aSDominic Spill   _mur_h1 ^= (keylen);                                                 \
587e25b118aSDominic Spill   MUR_FMIX(_mur_h1);                                                   \
588e25b118aSDominic Spill   hashv = _mur_h1;                                                     \
589e25b118aSDominic Spill   bkt = hashv & (num_bkts-1);                                          \
590e25b118aSDominic Spill } while(0)
591e25b118aSDominic Spill #endif  /* HASH_USING_NO_STRICT_ALIASING */
592e25b118aSDominic Spill 
593e25b118aSDominic Spill /* key comparison function; return 0 if keys equal */
594e25b118aSDominic Spill #define HASH_KEYCMP(a,b,len) memcmp(a,b,len)
595e25b118aSDominic Spill 
596e25b118aSDominic Spill /* iterate over items in a known bucket to find desired item */
597e25b118aSDominic Spill #define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,out)                       \
598e25b118aSDominic Spill do {                                                                             \
599e25b118aSDominic Spill  if (head.hh_head) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,head.hh_head));          \
600e25b118aSDominic Spill  else out=NULL;                                                                  \
601e25b118aSDominic Spill  while (out) {                                                                   \
602e25b118aSDominic Spill     if ((out)->hh.keylen == keylen_in) {                                           \
603e25b118aSDominic Spill         if ((HASH_KEYCMP((out)->hh.key,keyptr,keylen_in)) == 0) break;             \
604e25b118aSDominic Spill     }                                                                            \
605e25b118aSDominic Spill     if ((out)->hh.hh_next) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,(out)->hh.hh_next)); \
606e25b118aSDominic Spill     else out = NULL;                                                             \
607e25b118aSDominic Spill  }                                                                               \
608e25b118aSDominic Spill } while(0)
609e25b118aSDominic Spill 
610e25b118aSDominic Spill /* add an item to a bucket  */
611e25b118aSDominic Spill #define HASH_ADD_TO_BKT(head,addhh)                                              \
612e25b118aSDominic Spill do {                                                                             \
613e25b118aSDominic Spill  head.count++;                                                                   \
614e25b118aSDominic Spill  (addhh)->hh_next = head.hh_head;                                                \
615e25b118aSDominic Spill  (addhh)->hh_prev = NULL;                                                        \
616e25b118aSDominic Spill  if (head.hh_head) { (head).hh_head->hh_prev = (addhh); }                        \
617e25b118aSDominic Spill  (head).hh_head=addhh;                                                           \
618e25b118aSDominic Spill  if (head.count >= ((head.expand_mult+1) * HASH_BKT_CAPACITY_THRESH)             \
619e25b118aSDominic Spill      && (addhh)->tbl->noexpand != 1) {                                           \
620e25b118aSDominic Spill        HASH_EXPAND_BUCKETS((addhh)->tbl);                                        \
621e25b118aSDominic Spill  }                                                                               \
622e25b118aSDominic Spill } while(0)
623e25b118aSDominic Spill 
624e25b118aSDominic Spill /* remove an item from a given bucket */
625e25b118aSDominic Spill #define HASH_DEL_IN_BKT(hh,head,hh_del)                                          \
626e25b118aSDominic Spill     (head).count--;                                                              \
627e25b118aSDominic Spill     if ((head).hh_head == hh_del) {                                              \
628e25b118aSDominic Spill       (head).hh_head = hh_del->hh_next;                                          \
629e25b118aSDominic Spill     }                                                                            \
630e25b118aSDominic Spill     if (hh_del->hh_prev) {                                                       \
631e25b118aSDominic Spill         hh_del->hh_prev->hh_next = hh_del->hh_next;                              \
632e25b118aSDominic Spill     }                                                                            \
633e25b118aSDominic Spill     if (hh_del->hh_next) {                                                       \
634e25b118aSDominic Spill         hh_del->hh_next->hh_prev = hh_del->hh_prev;                              \
635e25b118aSDominic Spill     }
636e25b118aSDominic Spill 
637e25b118aSDominic Spill /* Bucket expansion has the effect of doubling the number of buckets
638e25b118aSDominic Spill  * and redistributing the items into the new buckets. Ideally the
639e25b118aSDominic Spill  * items will distribute more or less evenly into the new buckets
640e25b118aSDominic Spill  * (the extent to which this is true is a measure of the quality of
641e25b118aSDominic Spill  * the hash function as it applies to the key domain).
642e25b118aSDominic Spill  *
643e25b118aSDominic Spill  * With the items distributed into more buckets, the chain length
644e25b118aSDominic Spill  * (item count) in each bucket is reduced. Thus by expanding buckets
645e25b118aSDominic Spill  * the hash keeps a bound on the chain length. This bounded chain
646e25b118aSDominic Spill  * length is the essence of how a hash provides constant time lookup.
647e25b118aSDominic Spill  *
648e25b118aSDominic Spill  * The calculation of tbl->ideal_chain_maxlen below deserves some
649e25b118aSDominic Spill  * explanation. First, keep in mind that we're calculating the ideal
650e25b118aSDominic Spill  * maximum chain length based on the *new* (doubled) bucket count.
651e25b118aSDominic Spill  * In fractions this is just n/b (n=number of items,b=new num buckets).
652e25b118aSDominic Spill  * Since the ideal chain length is an integer, we want to calculate
653e25b118aSDominic Spill  * ceil(n/b). We don't depend on floating point arithmetic in this
654e25b118aSDominic Spill  * hash, so to calculate ceil(n/b) with integers we could write
655e25b118aSDominic Spill  *
656e25b118aSDominic Spill  *      ceil(n/b) = (n/b) + ((n%b)?1:0)
657e25b118aSDominic Spill  *
658e25b118aSDominic Spill  * and in fact a previous version of this hash did just that.
659e25b118aSDominic Spill  * But now we have improved things a bit by recognizing that b is
660e25b118aSDominic Spill  * always a power of two. We keep its base 2 log handy (call it lb),
661e25b118aSDominic Spill  * so now we can write this with a bit shift and logical AND:
662e25b118aSDominic Spill  *
663e25b118aSDominic Spill  *      ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0)
664e25b118aSDominic Spill  *
665e25b118aSDominic Spill  */
666e25b118aSDominic Spill #define HASH_EXPAND_BUCKETS(tbl)                                                 \
667e25b118aSDominic Spill do {                                                                             \
668e25b118aSDominic Spill     unsigned _he_bkt;                                                            \
669e25b118aSDominic Spill     unsigned _he_bkt_i;                                                          \
670e25b118aSDominic Spill     struct UT_hash_handle *_he_thh, *_he_hh_nxt;                                 \
671e25b118aSDominic Spill     UT_hash_bucket *_he_new_buckets, *_he_newbkt;                                \
672e25b118aSDominic Spill     _he_new_buckets = (UT_hash_bucket*)uthash_malloc(                            \
673e25b118aSDominic Spill              2 * tbl->num_buckets * sizeof(struct UT_hash_bucket));              \
674e25b118aSDominic Spill     if (!_he_new_buckets) { uthash_fatal( "out of memory"); }                    \
675e25b118aSDominic Spill     memset(_he_new_buckets, 0,                                                   \
676e25b118aSDominic Spill             2 * tbl->num_buckets * sizeof(struct UT_hash_bucket));               \
677e25b118aSDominic Spill     tbl->ideal_chain_maxlen =                                                    \
678e25b118aSDominic Spill        (tbl->num_items >> (tbl->log2_num_buckets+1)) +                           \
679e25b118aSDominic Spill        ((tbl->num_items & ((tbl->num_buckets*2)-1)) ? 1 : 0);                    \
680e25b118aSDominic Spill     tbl->nonideal_items = 0;                                                     \
681e25b118aSDominic Spill     for(_he_bkt_i = 0; _he_bkt_i < tbl->num_buckets; _he_bkt_i++)                \
682e25b118aSDominic Spill     {                                                                            \
683e25b118aSDominic Spill         _he_thh = tbl->buckets[ _he_bkt_i ].hh_head;                             \
684e25b118aSDominic Spill         while (_he_thh) {                                                        \
685e25b118aSDominic Spill            _he_hh_nxt = _he_thh->hh_next;                                        \
686e25b118aSDominic Spill            HASH_TO_BKT( _he_thh->hashv, tbl->num_buckets*2, _he_bkt);            \
687e25b118aSDominic Spill            _he_newbkt = &(_he_new_buckets[ _he_bkt ]);                           \
688e25b118aSDominic Spill            if (++(_he_newbkt->count) > tbl->ideal_chain_maxlen) {                \
689e25b118aSDominic Spill              tbl->nonideal_items++;                                              \
690e25b118aSDominic Spill              _he_newbkt->expand_mult = _he_newbkt->count /                       \
691e25b118aSDominic Spill                                         tbl->ideal_chain_maxlen;                 \
692e25b118aSDominic Spill            }                                                                     \
693e25b118aSDominic Spill            _he_thh->hh_prev = NULL;                                              \
694e25b118aSDominic Spill            _he_thh->hh_next = _he_newbkt->hh_head;                               \
695e25b118aSDominic Spill            if (_he_newbkt->hh_head) _he_newbkt->hh_head->hh_prev =               \
696e25b118aSDominic Spill                 _he_thh;                                                         \
697e25b118aSDominic Spill            _he_newbkt->hh_head = _he_thh;                                        \
698e25b118aSDominic Spill            _he_thh = _he_hh_nxt;                                                 \
699e25b118aSDominic Spill         }                                                                        \
700e25b118aSDominic Spill     }                                                                            \
701e25b118aSDominic Spill     uthash_free( tbl->buckets, tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \
702e25b118aSDominic Spill     tbl->num_buckets *= 2;                                                       \
703e25b118aSDominic Spill     tbl->log2_num_buckets++;                                                     \
704e25b118aSDominic Spill     tbl->buckets = _he_new_buckets;                                              \
705e25b118aSDominic Spill     tbl->ineff_expands = (tbl->nonideal_items > (tbl->num_items >> 1)) ?         \
706e25b118aSDominic Spill         (tbl->ineff_expands+1) : 0;                                              \
707e25b118aSDominic Spill     if (tbl->ineff_expands > 1) {                                                \
708e25b118aSDominic Spill         tbl->noexpand=1;                                                         \
709e25b118aSDominic Spill         uthash_noexpand_fyi(tbl);                                                \
710e25b118aSDominic Spill     }                                                                            \
711e25b118aSDominic Spill     uthash_expand_fyi(tbl);                                                      \
712e25b118aSDominic Spill } while(0)
713e25b118aSDominic Spill 
714e25b118aSDominic Spill 
715e25b118aSDominic Spill /* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */
716e25b118aSDominic Spill /* Note that HASH_SORT assumes the hash handle name to be hh.
717e25b118aSDominic Spill  * HASH_SRT was added to allow the hash handle name to be passed in. */
718e25b118aSDominic Spill #define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn)
719e25b118aSDominic Spill #define HASH_SRT(hh,head,cmpfcn)                                                 \
720e25b118aSDominic Spill do {                                                                             \
721e25b118aSDominic Spill   unsigned _hs_i;                                                                \
722e25b118aSDominic Spill   unsigned _hs_looping,_hs_nmerges,_hs_insize,_hs_psize,_hs_qsize;               \
723e25b118aSDominic Spill   struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail;            \
724e25b118aSDominic Spill   if (head) {                                                                    \
725e25b118aSDominic Spill       _hs_insize = 1;                                                            \
726e25b118aSDominic Spill       _hs_looping = 1;                                                           \
727e25b118aSDominic Spill       _hs_list = &((head)->hh);                                                  \
728e25b118aSDominic Spill       while (_hs_looping) {                                                      \
729e25b118aSDominic Spill           _hs_p = _hs_list;                                                      \
730e25b118aSDominic Spill           _hs_list = NULL;                                                       \
731e25b118aSDominic Spill           _hs_tail = NULL;                                                       \
732e25b118aSDominic Spill           _hs_nmerges = 0;                                                       \
733e25b118aSDominic Spill           while (_hs_p) {                                                        \
734e25b118aSDominic Spill               _hs_nmerges++;                                                     \
735e25b118aSDominic Spill               _hs_q = _hs_p;                                                     \
736e25b118aSDominic Spill               _hs_psize = 0;                                                     \
737e25b118aSDominic Spill               for ( _hs_i = 0; _hs_i  < _hs_insize; _hs_i++ ) {                  \
738e25b118aSDominic Spill                   _hs_psize++;                                                   \
739e25b118aSDominic Spill                   _hs_q = (UT_hash_handle*)((_hs_q->next) ?                      \
740e25b118aSDominic Spill                           ((void*)((char*)(_hs_q->next) +                        \
741e25b118aSDominic Spill                           (head)->hh.tbl->hho)) : NULL);                         \
742e25b118aSDominic Spill                   if (! (_hs_q) ) break;                                         \
743e25b118aSDominic Spill               }                                                                  \
744e25b118aSDominic Spill               _hs_qsize = _hs_insize;                                            \
745e25b118aSDominic Spill               while ((_hs_psize > 0) || ((_hs_qsize > 0) && _hs_q )) {           \
746e25b118aSDominic Spill                   if (_hs_psize == 0) {                                          \
747e25b118aSDominic Spill                       _hs_e = _hs_q;                                             \
748e25b118aSDominic Spill                       _hs_q = (UT_hash_handle*)((_hs_q->next) ?                  \
749e25b118aSDominic Spill                               ((void*)((char*)(_hs_q->next) +                    \
750e25b118aSDominic Spill                               (head)->hh.tbl->hho)) : NULL);                     \
751e25b118aSDominic Spill                       _hs_qsize--;                                               \
752e25b118aSDominic Spill                   } else if ( (_hs_qsize == 0) || !(_hs_q) ) {                   \
753e25b118aSDominic Spill                       _hs_e = _hs_p;                                             \
754*935bdedbSDominic Spill                       if (_hs_p){                                                \
755e25b118aSDominic Spill                         _hs_p = (UT_hash_handle*)((_hs_p->next) ?                \
756e25b118aSDominic Spill                                 ((void*)((char*)(_hs_p->next) +                  \
757e25b118aSDominic Spill                                 (head)->hh.tbl->hho)) : NULL);                   \
758*935bdedbSDominic Spill                        }                                                         \
759e25b118aSDominic Spill                       _hs_psize--;                                               \
760e25b118aSDominic Spill                   } else if ((                                                   \
761e25b118aSDominic Spill                       cmpfcn(DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_p)), \
762e25b118aSDominic Spill                              DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_q))) \
763e25b118aSDominic Spill                              ) <= 0) {                                           \
764e25b118aSDominic Spill                       _hs_e = _hs_p;                                             \
765*935bdedbSDominic Spill                       if (_hs_p){                                                \
766e25b118aSDominic Spill                         _hs_p = (UT_hash_handle*)((_hs_p->next) ?                \
767e25b118aSDominic Spill                                ((void*)((char*)(_hs_p->next) +                   \
768e25b118aSDominic Spill                                (head)->hh.tbl->hho)) : NULL);                    \
769*935bdedbSDominic Spill                        }                                                         \
770e25b118aSDominic Spill                       _hs_psize--;                                               \
771e25b118aSDominic Spill                   } else {                                                       \
772e25b118aSDominic Spill                       _hs_e = _hs_q;                                             \
773e25b118aSDominic Spill                       _hs_q = (UT_hash_handle*)((_hs_q->next) ?                  \
774e25b118aSDominic Spill                               ((void*)((char*)(_hs_q->next) +                    \
775e25b118aSDominic Spill                               (head)->hh.tbl->hho)) : NULL);                     \
776e25b118aSDominic Spill                       _hs_qsize--;                                               \
777e25b118aSDominic Spill                   }                                                              \
778e25b118aSDominic Spill                   if ( _hs_tail ) {                                              \
779e25b118aSDominic Spill                       _hs_tail->next = ((_hs_e) ?                                \
780e25b118aSDominic Spill                             ELMT_FROM_HH((head)->hh.tbl,_hs_e) : NULL);          \
781e25b118aSDominic Spill                   } else {                                                       \
782e25b118aSDominic Spill                       _hs_list = _hs_e;                                          \
783e25b118aSDominic Spill                   }                                                              \
784*935bdedbSDominic Spill                   if (_hs_e) {                                                   \
785e25b118aSDominic Spill                   _hs_e->prev = ((_hs_tail) ?                                    \
786e25b118aSDominic Spill                      ELMT_FROM_HH((head)->hh.tbl,_hs_tail) : NULL);              \
787*935bdedbSDominic Spill                   }                                                              \
788e25b118aSDominic Spill                   _hs_tail = _hs_e;                                              \
789e25b118aSDominic Spill               }                                                                  \
790e25b118aSDominic Spill               _hs_p = _hs_q;                                                     \
791e25b118aSDominic Spill           }                                                                      \
792*935bdedbSDominic Spill           if (_hs_tail){                                                         \
793e25b118aSDominic Spill             _hs_tail->next = NULL;                                               \
794*935bdedbSDominic Spill           }                                                                      \
795e25b118aSDominic Spill           if ( _hs_nmerges <= 1 ) {                                              \
796e25b118aSDominic Spill               _hs_looping=0;                                                     \
797e25b118aSDominic Spill               (head)->hh.tbl->tail = _hs_tail;                                   \
798e25b118aSDominic Spill               DECLTYPE_ASSIGN(head,ELMT_FROM_HH((head)->hh.tbl, _hs_list));      \
799e25b118aSDominic Spill           }                                                                      \
800e25b118aSDominic Spill           _hs_insize *= 2;                                                       \
801e25b118aSDominic Spill       }                                                                          \
802e25b118aSDominic Spill       HASH_FSCK(hh,head);                                                        \
803e25b118aSDominic Spill  }                                                                               \
804e25b118aSDominic Spill } while (0)
805e25b118aSDominic Spill 
806e25b118aSDominic Spill /* This function selects items from one hash into another hash.
807e25b118aSDominic Spill  * The end result is that the selected items have dual presence
808e25b118aSDominic Spill  * in both hashes. There is no copy of the items made; rather
809e25b118aSDominic Spill  * they are added into the new hash through a secondary hash
810e25b118aSDominic Spill  * hash handle that must be present in the structure. */
811e25b118aSDominic Spill #define HASH_SELECT(hh_dst, dst, hh_src, src, cond)                              \
812e25b118aSDominic Spill do {                                                                             \
813e25b118aSDominic Spill   unsigned _src_bkt, _dst_bkt;                                                   \
814e25b118aSDominic Spill   void *_last_elt=NULL, *_elt;                                                   \
815e25b118aSDominic Spill   UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL;                         \
816e25b118aSDominic Spill   ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst));                 \
817e25b118aSDominic Spill   if (src) {                                                                     \
818e25b118aSDominic Spill     for(_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) {     \
819e25b118aSDominic Spill       for(_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head;                \
820e25b118aSDominic Spill           _src_hh;                                                               \
821e25b118aSDominic Spill           _src_hh = _src_hh->hh_next) {                                          \
822e25b118aSDominic Spill           _elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh);                       \
823e25b118aSDominic Spill           if (cond(_elt)) {                                                      \
824e25b118aSDominic Spill             _dst_hh = (UT_hash_handle*)(((char*)_elt) + _dst_hho);               \
825e25b118aSDominic Spill             _dst_hh->key = _src_hh->key;                                         \
826e25b118aSDominic Spill             _dst_hh->keylen = _src_hh->keylen;                                   \
827e25b118aSDominic Spill             _dst_hh->hashv = _src_hh->hashv;                                     \
828e25b118aSDominic Spill             _dst_hh->prev = _last_elt;                                           \
829e25b118aSDominic Spill             _dst_hh->next = NULL;                                                \
830e25b118aSDominic Spill             if (_last_elt_hh) { _last_elt_hh->next = _elt; }                     \
831e25b118aSDominic Spill             if (!dst) {                                                          \
832e25b118aSDominic Spill               DECLTYPE_ASSIGN(dst,_elt);                                         \
833e25b118aSDominic Spill               HASH_MAKE_TABLE(hh_dst,dst);                                       \
834e25b118aSDominic Spill             } else {                                                             \
835e25b118aSDominic Spill               _dst_hh->tbl = (dst)->hh_dst.tbl;                                  \
836e25b118aSDominic Spill             }                                                                    \
837e25b118aSDominic Spill             HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt);    \
838e25b118aSDominic Spill             HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt],_dst_hh);            \
839e25b118aSDominic Spill             (dst)->hh_dst.tbl->num_items++;                                      \
840e25b118aSDominic Spill             _last_elt = _elt;                                                    \
841e25b118aSDominic Spill             _last_elt_hh = _dst_hh;                                              \
842e25b118aSDominic Spill           }                                                                      \
843e25b118aSDominic Spill       }                                                                          \
844e25b118aSDominic Spill     }                                                                            \
845e25b118aSDominic Spill   }                                                                              \
846e25b118aSDominic Spill   HASH_FSCK(hh_dst,dst);                                                         \
847e25b118aSDominic Spill } while (0)
848e25b118aSDominic Spill 
849e25b118aSDominic Spill #define HASH_CLEAR(hh,head)                                                      \
850e25b118aSDominic Spill do {                                                                             \
851e25b118aSDominic Spill   if (head) {                                                                    \
852e25b118aSDominic Spill     uthash_free((head)->hh.tbl->buckets,                                         \
853e25b118aSDominic Spill                 (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket));      \
854e25b118aSDominic Spill     HASH_BLOOM_FREE((head)->hh.tbl);                                             \
855e25b118aSDominic Spill     uthash_free((head)->hh.tbl, sizeof(UT_hash_table));                          \
856e25b118aSDominic Spill     (head)=NULL;                                                                 \
857e25b118aSDominic Spill   }                                                                              \
858e25b118aSDominic Spill } while(0)
859e25b118aSDominic Spill 
860*935bdedbSDominic Spill #define HASH_OVERHEAD(hh,head)                                                   \
861*935bdedbSDominic Spill  (size_t)((((head)->hh.tbl->num_items   * sizeof(UT_hash_handle))   +            \
862*935bdedbSDominic Spill            ((head)->hh.tbl->num_buckets * sizeof(UT_hash_bucket))   +            \
863*935bdedbSDominic Spill             (sizeof(UT_hash_table))                                 +            \
864*935bdedbSDominic Spill             (HASH_BLOOM_BYTELEN)))
865*935bdedbSDominic Spill 
866e25b118aSDominic Spill #ifdef NO_DECLTYPE
867e25b118aSDominic Spill #define HASH_ITER(hh,head,el,tmp)                                                \
868e25b118aSDominic Spill for((el)=(head), (*(char**)(&(tmp)))=(char*)((head)?(head)->hh.next:NULL);       \
869e25b118aSDominic Spill   el; (el)=(tmp),(*(char**)(&(tmp)))=(char*)((tmp)?(tmp)->hh.next:NULL))
870e25b118aSDominic Spill #else
871e25b118aSDominic Spill #define HASH_ITER(hh,head,el,tmp)                                                \
872e25b118aSDominic Spill for((el)=(head),(tmp)=DECLTYPE(el)((head)?(head)->hh.next:NULL);                 \
873e25b118aSDominic Spill   el; (el)=(tmp),(tmp)=DECLTYPE(el)((tmp)?(tmp)->hh.next:NULL))
874e25b118aSDominic Spill #endif
875e25b118aSDominic Spill 
876e25b118aSDominic Spill /* obtain a count of items in the hash */
877e25b118aSDominic Spill #define HASH_COUNT(head) HASH_CNT(hh,head)
878e25b118aSDominic Spill #define HASH_CNT(hh,head) ((head)?((head)->hh.tbl->num_items):0)
879e25b118aSDominic Spill 
880e25b118aSDominic Spill typedef struct UT_hash_bucket {
881e25b118aSDominic Spill    struct UT_hash_handle *hh_head;
882e25b118aSDominic Spill    unsigned count;
883e25b118aSDominic Spill 
884e25b118aSDominic Spill    /* expand_mult is normally set to 0. In this situation, the max chain length
885e25b118aSDominic Spill     * threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If
886e25b118aSDominic Spill     * the bucket's chain exceeds this length, bucket expansion is triggered).
887e25b118aSDominic Spill     * However, setting expand_mult to a non-zero value delays bucket expansion
888e25b118aSDominic Spill     * (that would be triggered by additions to this particular bucket)
889e25b118aSDominic Spill     * until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH.
890e25b118aSDominic Spill     * (The multiplier is simply expand_mult+1). The whole idea of this
891e25b118aSDominic Spill     * multiplier is to reduce bucket expansions, since they are expensive, in
892e25b118aSDominic Spill     * situations where we know that a particular bucket tends to be overused.
893e25b118aSDominic Spill     * It is better to let its chain length grow to a longer yet-still-bounded
894e25b118aSDominic Spill     * value, than to do an O(n) bucket expansion too often.
895e25b118aSDominic Spill     */
896e25b118aSDominic Spill    unsigned expand_mult;
897e25b118aSDominic Spill 
898e25b118aSDominic Spill } UT_hash_bucket;
899e25b118aSDominic Spill 
900e25b118aSDominic Spill /* random signature used only to find hash tables in external analysis */
901e25b118aSDominic Spill #define HASH_SIGNATURE 0xa0111fe1
902e25b118aSDominic Spill #define HASH_BLOOM_SIGNATURE 0xb12220f2
903e25b118aSDominic Spill 
904e25b118aSDominic Spill typedef struct UT_hash_table {
905e25b118aSDominic Spill    UT_hash_bucket *buckets;
906e25b118aSDominic Spill    unsigned num_buckets, log2_num_buckets;
907e25b118aSDominic Spill    unsigned num_items;
908e25b118aSDominic Spill    struct UT_hash_handle *tail; /* tail hh in app order, for fast append    */
909e25b118aSDominic Spill    ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */
910e25b118aSDominic Spill 
911e25b118aSDominic Spill    /* in an ideal situation (all buckets used equally), no bucket would have
912e25b118aSDominic Spill     * more than ceil(#items/#buckets) items. that's the ideal chain length. */
913e25b118aSDominic Spill    unsigned ideal_chain_maxlen;
914e25b118aSDominic Spill 
915e25b118aSDominic Spill    /* nonideal_items is the number of items in the hash whose chain position
916e25b118aSDominic Spill     * exceeds the ideal chain maxlen. these items pay the penalty for an uneven
917e25b118aSDominic Spill     * hash distribution; reaching them in a chain traversal takes >ideal steps */
918e25b118aSDominic Spill    unsigned nonideal_items;
919e25b118aSDominic Spill 
920e25b118aSDominic Spill    /* ineffective expands occur when a bucket doubling was performed, but
921e25b118aSDominic Spill     * afterward, more than half the items in the hash had nonideal chain
922e25b118aSDominic Spill     * positions. If this happens on two consecutive expansions we inhibit any
923e25b118aSDominic Spill     * further expansion, as it's not helping; this happens when the hash
924e25b118aSDominic Spill     * function isn't a good fit for the key domain. When expansion is inhibited
925e25b118aSDominic Spill     * the hash will still work, albeit no longer in constant time. */
926e25b118aSDominic Spill    unsigned ineff_expands, noexpand;
927e25b118aSDominic Spill 
928e25b118aSDominic Spill    uint32_t signature; /* used only to find hash tables in external analysis */
929e25b118aSDominic Spill #ifdef HASH_BLOOM
930e25b118aSDominic Spill    uint32_t bloom_sig; /* used only to test bloom exists in external analysis */
931e25b118aSDominic Spill    uint8_t *bloom_bv;
932e25b118aSDominic Spill    char bloom_nbits;
933e25b118aSDominic Spill #endif
934e25b118aSDominic Spill 
935e25b118aSDominic Spill } UT_hash_table;
936e25b118aSDominic Spill 
937e25b118aSDominic Spill typedef struct UT_hash_handle {
938e25b118aSDominic Spill    struct UT_hash_table *tbl;
939e25b118aSDominic Spill    void *prev;                       /* prev element in app order      */
940e25b118aSDominic Spill    void *next;                       /* next element in app order      */
941e25b118aSDominic Spill    struct UT_hash_handle *hh_prev;   /* previous hh in bucket order    */
942e25b118aSDominic Spill    struct UT_hash_handle *hh_next;   /* next hh in bucket order        */
943e25b118aSDominic Spill    void *key;                        /* ptr to enclosing struct's key  */
944e25b118aSDominic Spill    unsigned keylen;                  /* enclosing struct's key len     */
945e25b118aSDominic Spill    unsigned hashv;                   /* result of hash-fcn(key)        */
946e25b118aSDominic Spill } UT_hash_handle;
947e25b118aSDominic Spill 
948e25b118aSDominic Spill #endif /* UTHASH_H */
949