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