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