Blame intel/uthash.h

Packit 631bab
/*
Packit 631bab
Copyright (c) 2003-2016, Troy D. Hanson     http://troydhanson.github.com/uthash/
Packit 631bab
All rights reserved.
Packit 631bab
Packit 631bab
Redistribution and use in source and binary forms, with or without
Packit 631bab
modification, are permitted provided that the following conditions are met:
Packit 631bab
Packit 631bab
    * Redistributions of source code must retain the above copyright
Packit 631bab
      notice, this list of conditions and the following disclaimer.
Packit 631bab
Packit 631bab
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
Packit 631bab
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
Packit 631bab
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
Packit 631bab
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
Packit 631bab
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
Packit 631bab
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
Packit 631bab
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
Packit 631bab
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
Packit 631bab
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
Packit 631bab
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
Packit 631bab
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit 631bab
*/
Packit 631bab
Packit 631bab
#ifndef UTHASH_H
Packit 631bab
#define UTHASH_H
Packit 631bab
Packit 631bab
#define UTHASH_VERSION 2.0.1
Packit 631bab
Packit 631bab
#include <string.h>   /* memcmp,strlen */
Packit 631bab
#include <stddef.h>   /* ptrdiff_t */
Packit 631bab
#include <stdlib.h>   /* exit() */
Packit 631bab
Packit 631bab
/* These macros use decltype or the earlier __typeof GNU extension.
Packit 631bab
   As decltype is only available in newer compilers (VS2010 or gcc 4.3+
Packit 631bab
   when compiling c++ source) this code uses whatever method is needed
Packit 631bab
   or, for VS2008 where neither is available, uses casting workarounds. */
Packit 631bab
#if defined(_MSC_VER)   /* MS compiler */
Packit 631bab
#if _MSC_VER >= 1600 && defined(__cplusplus)  /* VS2010 or newer in C++ mode */
Packit 631bab
#define DECLTYPE(x) (decltype(x))
Packit 631bab
#else                   /* VS2008 or older (or VS2010 in C mode) */
Packit 631bab
#define NO_DECLTYPE
Packit 631bab
#define DECLTYPE(x)
Packit 631bab
#endif
Packit 631bab
#elif defined(__BORLANDC__) || defined(__LCC__) || defined(__WATCOMC__)
Packit 631bab
#define NO_DECLTYPE
Packit 631bab
#define DECLTYPE(x)
Packit 631bab
#else                   /* GNU, Sun and other compilers */
Packit 631bab
#define DECLTYPE(x) (__typeof(x))
Packit 631bab
#endif
Packit 631bab
Packit 631bab
#ifdef NO_DECLTYPE
Packit 631bab
#define DECLTYPE_ASSIGN(dst,src)                                                 \
Packit 631bab
do {                                                                             \
Packit 631bab
  char **_da_dst = (char**)(&(dst));                                             \
Packit 631bab
  *_da_dst = (char*)(src);                                                       \
Packit 631bab
} while (0)
Packit 631bab
#else
Packit 631bab
#define DECLTYPE_ASSIGN(dst,src)                                                 \
Packit 631bab
do {                                                                             \
Packit 631bab
  (dst) = DECLTYPE(dst)(src);                                                    \
Packit 631bab
} while (0)
Packit 631bab
#endif
Packit 631bab
Packit 631bab
/* a number of the hash function use uint32_t which isn't defined on Pre VS2010 */
Packit 631bab
#if defined(_WIN32)
Packit 631bab
#if defined(_MSC_VER) && _MSC_VER >= 1600
Packit 631bab
#include <stdint.h>
Packit 631bab
#elif defined(__WATCOMC__) || defined(__MINGW32__) || defined(__CYGWIN__)
Packit 631bab
#include <stdint.h>
Packit 631bab
#else
Packit 631bab
typedef unsigned int uint32_t;
Packit 631bab
typedef unsigned char uint8_t;
Packit 631bab
#endif
Packit 631bab
#elif defined(__GNUC__) && !defined(__VXWORKS__)
Packit 631bab
#include <stdint.h>
Packit 631bab
#else
Packit 631bab
typedef unsigned int uint32_t;
Packit 631bab
typedef unsigned char uint8_t;
Packit 631bab
#endif
Packit 631bab
Packit 631bab
#ifndef uthash_fatal
Packit 631bab
#define uthash_fatal(msg) exit(-1)        /* fatal error (out of memory,etc) */
Packit 631bab
#endif
Packit 631bab
#ifndef uthash_malloc
Packit 631bab
#define uthash_malloc(sz) malloc(sz)      /* malloc fcn                      */
Packit 631bab
#endif
Packit 631bab
#ifndef uthash_free
Packit 631bab
#define uthash_free(ptr,sz) free(ptr)     /* free fcn                        */
Packit 631bab
#endif
Packit 631bab
#ifndef uthash_strlen
Packit 631bab
#define uthash_strlen(s) strlen(s)
Packit 631bab
#endif
Packit 631bab
#ifndef uthash_memcmp
Packit 631bab
#define uthash_memcmp(a,b,n) memcmp(a,b,n)
Packit 631bab
#endif
Packit 631bab
Packit 631bab
#ifndef uthash_noexpand_fyi
Packit 631bab
#define uthash_noexpand_fyi(tbl)          /* can be defined to log noexpand  */
Packit 631bab
#endif
Packit 631bab
#ifndef uthash_expand_fyi
Packit 631bab
#define uthash_expand_fyi(tbl)            /* can be defined to log expands   */
Packit 631bab
#endif
Packit 631bab
Packit 631bab
/* initial number of buckets */
Packit 631bab
#define HASH_INITIAL_NUM_BUCKETS 32U     /* initial number of buckets        */
Packit 631bab
#define HASH_INITIAL_NUM_BUCKETS_LOG2 5U /* lg2 of initial number of buckets */
Packit 631bab
#define HASH_BKT_CAPACITY_THRESH 10U     /* expand when bucket count reaches */
Packit 631bab
Packit 631bab
/* calculate the element whose hash handle address is hhp */
Packit 631bab
#define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho)))
Packit 631bab
/* calculate the hash handle from element address elp */
Packit 631bab
#define HH_FROM_ELMT(tbl,elp) ((UT_hash_handle *)(((char*)(elp)) + ((tbl)->hho)))
Packit 631bab
Packit 631bab
#define HASH_VALUE(keyptr,keylen,hashv)                                          \
Packit 631bab
do {                                                                             \
Packit 631bab
  HASH_FCN(keyptr, keylen, hashv);                                               \
Packit 631bab
} while (0)
Packit 631bab
Packit 631bab
#define HASH_FIND_BYHASHVALUE(hh,head,keyptr,keylen,hashval,out)                 \
Packit 631bab
do {                                                                             \
Packit 631bab
  (out) = NULL;                                                                  \
Packit 631bab
  if (head) {                                                                    \
Packit 631bab
    unsigned _hf_bkt;                                                            \
Packit 631bab
    HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _hf_bkt);                  \
Packit 631bab
    if (HASH_BLOOM_TEST((head)->hh.tbl, hashval) != 0) {                         \
Packit 631bab
      HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], keyptr, keylen, hashval, out); \
Packit 631bab
    }                                                                            \
Packit 631bab
  }                                                                              \
Packit 631bab
} while (0)
Packit 631bab
Packit 631bab
#define HASH_FIND(hh,head,keyptr,keylen,out)                                     \
Packit 631bab
do {                                                                             \
Packit 631bab
  unsigned _hf_hashv;                                                            \
Packit 631bab
  HASH_VALUE(keyptr, keylen, _hf_hashv);                                         \
Packit 631bab
  HASH_FIND_BYHASHVALUE(hh, head, keyptr, keylen, _hf_hashv, out);               \
Packit 631bab
} while (0)
Packit 631bab
Packit 631bab
#ifdef HASH_BLOOM
Packit 631bab
#define HASH_BLOOM_BITLEN (1UL << HASH_BLOOM)
Packit 631bab
#define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8UL) + (((HASH_BLOOM_BITLEN%8UL)!=0UL) ? 1UL : 0UL)
Packit 631bab
#define HASH_BLOOM_MAKE(tbl)                                                     \
Packit 631bab
do {                                                                             \
Packit 631bab
  (tbl)->bloom_nbits = HASH_BLOOM;                                               \
Packit 631bab
  (tbl)->bloom_bv = (uint8_t*)uthash_malloc(HASH_BLOOM_BYTELEN);                 \
Packit 631bab
  if (!((tbl)->bloom_bv))  { uthash_fatal( "out of memory"); }                   \
Packit 631bab
  memset((tbl)->bloom_bv, 0, HASH_BLOOM_BYTELEN);                                \
Packit 631bab
  (tbl)->bloom_sig = HASH_BLOOM_SIGNATURE;                                       \
Packit 631bab
} while (0)
Packit 631bab
Packit 631bab
#define HASH_BLOOM_FREE(tbl)                                                     \
Packit 631bab
do {                                                                             \
Packit 631bab
  uthash_free((tbl)->bloom_bv, HASH_BLOOM_BYTELEN);                              \
Packit 631bab
} while (0)
Packit 631bab
Packit 631bab
#define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8U] |= (1U << ((idx)%8U)))
Packit 631bab
#define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8U] & (1U << ((idx)%8U)))
Packit 631bab
Packit 631bab
#define HASH_BLOOM_ADD(tbl,hashv)                                                \
Packit 631bab
  HASH_BLOOM_BITSET((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1U)))
Packit 631bab
Packit 631bab
#define HASH_BLOOM_TEST(tbl,hashv)                                               \
Packit 631bab
  HASH_BLOOM_BITTEST((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1U)))
Packit 631bab
Packit 631bab
#else
Packit 631bab
#define HASH_BLOOM_MAKE(tbl)
Packit 631bab
#define HASH_BLOOM_FREE(tbl)
Packit 631bab
#define HASH_BLOOM_ADD(tbl,hashv)
Packit 631bab
#define HASH_BLOOM_TEST(tbl,hashv) (1)
Packit 631bab
#define HASH_BLOOM_BYTELEN 0U
Packit 631bab
#endif
Packit 631bab
Packit 631bab
#define HASH_MAKE_TABLE(hh,head)                                                 \
Packit 631bab
do {                                                                             \
Packit 631bab
  (head)->hh.tbl = (UT_hash_table*)uthash_malloc(                                \
Packit 631bab
                  sizeof(UT_hash_table));                                        \
Packit 631bab
  if (!((head)->hh.tbl))  { uthash_fatal( "out of memory"); }                    \
Packit 631bab
  memset((head)->hh.tbl, 0, sizeof(UT_hash_table));                              \
Packit 631bab
  (head)->hh.tbl->tail = &((head)->hh);                                          \
Packit 631bab
  (head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS;                        \
Packit 631bab
  (head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2;              \
Packit 631bab
  (head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head);                    \
Packit 631bab
  (head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc(                      \
Packit 631bab
          HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket));               \
Packit 631bab
  if (! (head)->hh.tbl->buckets) { uthash_fatal( "out of memory"); }             \
Packit 631bab
  memset((head)->hh.tbl->buckets, 0,                                             \
Packit 631bab
          HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket));               \
Packit 631bab
  HASH_BLOOM_MAKE((head)->hh.tbl);                                               \
Packit 631bab
  (head)->hh.tbl->signature = HASH_SIGNATURE;                                    \
Packit 631bab
} while (0)
Packit 631bab
Packit 631bab
#define HASH_REPLACE_BYHASHVALUE_INORDER(hh,head,fieldname,keylen_in,hashval,add,replaced,cmpfcn) \
Packit 631bab
do {                                                                             \
Packit 631bab
  (replaced) = NULL;                                                             \
Packit 631bab
  HASH_FIND_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, replaced); \
Packit 631bab
  if (replaced) {                                                                \
Packit 631bab
     HASH_DELETE(hh, head, replaced);                                            \
Packit 631bab
  }                                                                              \
Packit 631bab
  HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, &((add)->fieldname), keylen_in, hashval, add, cmpfcn); \
Packit 631bab
} while (0)
Packit 631bab
Packit 631bab
#define HASH_REPLACE_BYHASHVALUE(hh,head,fieldname,keylen_in,hashval,add,replaced) \
Packit 631bab
do {                                                                             \
Packit 631bab
  (replaced) = NULL;                                                             \
Packit 631bab
  HASH_FIND_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, replaced); \
Packit 631bab
  if (replaced) {                                                                \
Packit 631bab
     HASH_DELETE(hh, head, replaced);                                            \
Packit 631bab
  }                                                                              \
Packit 631bab
  HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, add); \
Packit 631bab
} while (0)
Packit 631bab
Packit 631bab
#define HASH_REPLACE(hh,head,fieldname,keylen_in,add,replaced)                   \
Packit 631bab
do {                                                                             \
Packit 631bab
  unsigned _hr_hashv;                                                            \
Packit 631bab
  HASH_VALUE(&((add)->fieldname), keylen_in, _hr_hashv);                         \
Packit 631bab
  HASH_REPLACE_BYHASHVALUE(hh, head, fieldname, keylen_in, _hr_hashv, add, replaced); \
Packit 631bab
} while (0)
Packit 631bab
Packit 631bab
#define HASH_REPLACE_INORDER(hh,head,fieldname,keylen_in,add,replaced,cmpfcn)    \
Packit 631bab
do {                                                                             \
Packit 631bab
  unsigned _hr_hashv;                                                            \
Packit 631bab
  HASH_VALUE(&((add)->fieldname), keylen_in, _hr_hashv);                         \
Packit 631bab
  HASH_REPLACE_BYHASHVALUE_INORDER(hh, head, fieldname, keylen_in, _hr_hashv, add, replaced, cmpfcn); \
Packit 631bab
} while (0)
Packit 631bab
Packit 631bab
#define HASH_APPEND_LIST(hh, head, add)                                          \
Packit 631bab
do {                                                                             \
Packit 631bab
  (add)->hh.next = NULL;                                                         \
Packit 631bab
  (add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail);           \
Packit 631bab
  (head)->hh.tbl->tail->next = (add);                                            \
Packit 631bab
  (head)->hh.tbl->tail = &((add)->hh);                                           \
Packit 631bab
} while (0)
Packit 631bab
Packit 631bab
#define HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh,head,keyptr,keylen_in,hashval,add,cmpfcn) \
Packit 631bab
do {                                                                             \
Packit 631bab
  unsigned _ha_bkt;                                                              \
Packit 631bab
  (add)->hh.hashv = (hashval);                                                   \
Packit 631bab
  (add)->hh.key = (char*) (keyptr);                                              \
Packit 631bab
  (add)->hh.keylen = (unsigned) (keylen_in);                                     \
Packit 631bab
  if (!(head)) {                                                                 \
Packit 631bab
    (add)->hh.next = NULL;                                                       \
Packit 631bab
    (add)->hh.prev = NULL;                                                       \
Packit 631bab
    (head) = (add);                                                              \
Packit 631bab
    HASH_MAKE_TABLE(hh, head);                                                   \
Packit 631bab
  } else {                                                                       \
Packit 631bab
    struct UT_hash_handle *_hs_iter = &(head)->hh;                               \
Packit 631bab
    (add)->hh.tbl = (head)->hh.tbl;                                              \
Packit 631bab
    do {                                                                         \
Packit 631bab
      if (cmpfcn(DECLTYPE(head) ELMT_FROM_HH((head)->hh.tbl, _hs_iter), add) > 0) \
Packit 631bab
        break;                                                                   \
Packit 631bab
    } while ((_hs_iter = _hs_iter->next));                                       \
Packit 631bab
    if (_hs_iter) {                                                              \
Packit 631bab
      (add)->hh.next = _hs_iter;                                                 \
Packit 631bab
      if (((add)->hh.prev = _hs_iter->prev)) {                                   \
Packit 631bab
        HH_FROM_ELMT((head)->hh.tbl, _hs_iter->prev)->next = (add);              \
Packit 631bab
      } else {                                                                   \
Packit 631bab
        (head) = (add);                                                          \
Packit 631bab
      }                                                                          \
Packit 631bab
      _hs_iter->prev = (add);                                                    \
Packit 631bab
    } else {                                                                     \
Packit 631bab
      HASH_APPEND_LIST(hh, head, add);                                           \
Packit 631bab
    }                                                                            \
Packit 631bab
  }                                                                              \
Packit 631bab
  (head)->hh.tbl->num_items++;                                                   \
Packit 631bab
  HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _ha_bkt);                    \
Packit 631bab
  HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt], &(add)->hh);                 \
Packit 631bab
  HASH_BLOOM_ADD((head)->hh.tbl, hashval);                                       \
Packit 631bab
  HASH_EMIT_KEY(hh, head, keyptr, keylen_in);                                    \
Packit 631bab
  HASH_FSCK(hh, head);                                                           \
Packit 631bab
} while (0)
Packit 631bab
Packit 631bab
#define HASH_ADD_KEYPTR_INORDER(hh,head,keyptr,keylen_in,add,cmpfcn)             \
Packit 631bab
do {                                                                             \
Packit 631bab
  unsigned _hs_hashv;                                                            \
Packit 631bab
  HASH_VALUE(keyptr, keylen_in, _hs_hashv);                                      \
Packit 631bab
  HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, keyptr, keylen_in, _hs_hashv, add, cmpfcn); \
Packit 631bab
} while (0)
Packit 631bab
Packit 631bab
#define HASH_ADD_BYHASHVALUE_INORDER(hh,head,fieldname,keylen_in,hashval,add,cmpfcn) \
Packit 631bab
  HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, &((add)->fieldname), keylen_in, hashval, add, cmpfcn)
Packit 631bab
Packit 631bab
#define HASH_ADD_INORDER(hh,head,fieldname,keylen_in,add,cmpfcn)                 \
Packit 631bab
  HASH_ADD_KEYPTR_INORDER(hh, head, &((add)->fieldname), keylen_in, add, cmpfcn)
Packit 631bab
Packit 631bab
#define HASH_ADD_KEYPTR_BYHASHVALUE(hh,head,keyptr,keylen_in,hashval,add)        \
Packit 631bab
do {                                                                             \
Packit 631bab
  unsigned _ha_bkt;                                                              \
Packit 631bab
  (add)->hh.hashv = (hashval);                                                   \
Packit 631bab
  (add)->hh.key = (char*) (keyptr);                                              \
Packit 631bab
  (add)->hh.keylen = (unsigned) (keylen_in);                                     \
Packit 631bab
  if (!(head)) {                                                                 \
Packit 631bab
    (add)->hh.next = NULL;                                                       \
Packit 631bab
    (add)->hh.prev = NULL;                                                       \
Packit 631bab
    (head) = (add);                                                              \
Packit 631bab
    HASH_MAKE_TABLE(hh, head);                                                   \
Packit 631bab
  } else {                                                                       \
Packit 631bab
    (add)->hh.tbl = (head)->hh.tbl;                                              \
Packit 631bab
    HASH_APPEND_LIST(hh, head, add);                                             \
Packit 631bab
  }                                                                              \
Packit 631bab
  (head)->hh.tbl->num_items++;                                                   \
Packit 631bab
  HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _ha_bkt);                    \
Packit 631bab
  HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt], &(add)->hh);                 \
Packit 631bab
  HASH_BLOOM_ADD((head)->hh.tbl, hashval);                                       \
Packit 631bab
  HASH_EMIT_KEY(hh, head, keyptr, keylen_in);                                    \
Packit 631bab
  HASH_FSCK(hh, head);                                                           \
Packit 631bab
} while (0)
Packit 631bab
Packit 631bab
#define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add)                            \
Packit 631bab
do {                                                                             \
Packit 631bab
  unsigned _ha_hashv;                                                            \
Packit 631bab
  HASH_VALUE(keyptr, keylen_in, _ha_hashv);                                      \
Packit 631bab
  HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, keyptr, keylen_in, _ha_hashv, add);      \
Packit 631bab
} while (0)
Packit 631bab
Packit 631bab
#define HASH_ADD_BYHASHVALUE(hh,head,fieldname,keylen_in,hashval,add)            \
Packit 631bab
  HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, add)
Packit 631bab
Packit 631bab
#define HASH_ADD(hh,head,fieldname,keylen_in,add)                                \
Packit 631bab
  HASH_ADD_KEYPTR(hh, head, &((add)->fieldname), keylen_in, add)
Packit 631bab
Packit 631bab
#define HASH_TO_BKT(hashv,num_bkts,bkt)                                          \
Packit 631bab
do {                                                                             \
Packit 631bab
  bkt = ((hashv) & ((num_bkts) - 1U));                                           \
Packit 631bab
} while (0)
Packit 631bab
Packit 631bab
/* delete "delptr" from the hash table.
Packit 631bab
 * "the usual" patch-up process for the app-order doubly-linked-list.
Packit 631bab
 * The use of _hd_hh_del below deserves special explanation.
Packit 631bab
 * These used to be expressed using (delptr) but that led to a bug
Packit 631bab
 * if someone used the same symbol for the head and deletee, like
Packit 631bab
 *  HASH_DELETE(hh,users,users);
Packit 631bab
 * We want that to work, but by changing the head (users) below
Packit 631bab
 * we were forfeiting our ability to further refer to the deletee (users)
Packit 631bab
 * in the patch-up process. Solution: use scratch space to
Packit 631bab
 * copy the deletee pointer, then the latter references are via that
Packit 631bab
 * scratch pointer rather than through the repointed (users) symbol.
Packit 631bab
 */
Packit 631bab
#define HASH_DELETE(hh,head,delptr)                                              \
Packit 631bab
do {                                                                             \
Packit 631bab
    struct UT_hash_handle *_hd_hh_del;                                           \
Packit 631bab
    if ( ((delptr)->hh.prev == NULL) && ((delptr)->hh.next == NULL) )  {         \
Packit 631bab
        uthash_free((head)->hh.tbl->buckets,                                     \
Packit 631bab
                    (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \
Packit 631bab
        HASH_BLOOM_FREE((head)->hh.tbl);                                         \
Packit 631bab
        uthash_free((head)->hh.tbl, sizeof(UT_hash_table));                      \
Packit 631bab
        head = NULL;                                                             \
Packit 631bab
    } else {                                                                     \
Packit 631bab
        unsigned _hd_bkt;                                                        \
Packit 631bab
        _hd_hh_del = &((delptr)->hh);                                            \
Packit 631bab
        if ((delptr) == ELMT_FROM_HH((head)->hh.tbl,(head)->hh.tbl->tail)) {     \
Packit 631bab
            (head)->hh.tbl->tail =                                               \
Packit 631bab
                (UT_hash_handle*)((ptrdiff_t)((delptr)->hh.prev) +               \
Packit 631bab
                (head)->hh.tbl->hho);                                            \
Packit 631bab
        }                                                                        \
Packit 631bab
        if ((delptr)->hh.prev != NULL) {                                         \
Packit 631bab
            ((UT_hash_handle*)((ptrdiff_t)((delptr)->hh.prev) +                  \
Packit 631bab
                    (head)->hh.tbl->hho))->next = (delptr)->hh.next;             \
Packit 631bab
        } else {                                                                 \
Packit 631bab
            DECLTYPE_ASSIGN(head,(delptr)->hh.next);                             \
Packit 631bab
        }                                                                        \
Packit 631bab
        if (_hd_hh_del->next != NULL) {                                          \
Packit 631bab
            ((UT_hash_handle*)((ptrdiff_t)_hd_hh_del->next +                     \
Packit 631bab
                    (head)->hh.tbl->hho))->prev =                                \
Packit 631bab
                    _hd_hh_del->prev;                                            \
Packit 631bab
        }                                                                        \
Packit 631bab
        HASH_TO_BKT( _hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt);   \
Packit 631bab
        HASH_DEL_IN_BKT(hh,(head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del);        \
Packit 631bab
        (head)->hh.tbl->num_items--;                                             \
Packit 631bab
    }                                                                            \
Packit 631bab
    HASH_FSCK(hh,head);                                                          \
Packit 631bab
} while (0)
Packit 631bab
Packit 631bab
Packit 631bab
/* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */
Packit 631bab
#define HASH_FIND_STR(head,findstr,out)                                          \
Packit 631bab
    HASH_FIND(hh,head,findstr,(unsigned)uthash_strlen(findstr),out)
Packit 631bab
#define HASH_ADD_STR(head,strfield,add)                                          \
Packit 631bab
    HASH_ADD(hh,head,strfield[0],(unsigned)uthash_strlen(add->strfield),add)
Packit 631bab
#define HASH_REPLACE_STR(head,strfield,add,replaced)                             \
Packit 631bab
    HASH_REPLACE(hh,head,strfield[0],(unsigned)uthash_strlen(add->strfield),add,replaced)
Packit 631bab
#define HASH_FIND_INT(head,findint,out)                                          \
Packit 631bab
    HASH_FIND(hh,head,findint,sizeof(int),out)
Packit 631bab
#define HASH_ADD_INT(head,intfield,add)                                          \
Packit 631bab
    HASH_ADD(hh,head,intfield,sizeof(int),add)
Packit 631bab
#define HASH_REPLACE_INT(head,intfield,add,replaced)                             \
Packit 631bab
    HASH_REPLACE(hh,head,intfield,sizeof(int),add,replaced)
Packit 631bab
#define HASH_FIND_PTR(head,findptr,out)                                          \
Packit 631bab
    HASH_FIND(hh,head,findptr,sizeof(void *),out)
Packit 631bab
#define HASH_ADD_PTR(head,ptrfield,add)                                          \
Packit 631bab
    HASH_ADD(hh,head,ptrfield,sizeof(void *),add)
Packit 631bab
#define HASH_REPLACE_PTR(head,ptrfield,add,replaced)                             \
Packit 631bab
    HASH_REPLACE(hh,head,ptrfield,sizeof(void *),add,replaced)
Packit 631bab
#define HASH_DEL(head,delptr)                                                    \
Packit 631bab
    HASH_DELETE(hh,head,delptr)
Packit 631bab
Packit 631bab
/* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined.
Packit 631bab
 * This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined.
Packit 631bab
 */
Packit 631bab
#ifdef HASH_DEBUG
Packit 631bab
#define HASH_OOPS(...) do { fprintf(stderr,__VA_ARGS__); exit(-1); } while (0)
Packit 631bab
#define HASH_FSCK(hh,head)                                                       \
Packit 631bab
do {                                                                             \
Packit 631bab
    struct UT_hash_handle *_thh;                                                 \
Packit 631bab
    if (head) {                                                                  \
Packit 631bab
        unsigned _bkt_i;                                                         \
Packit 631bab
        unsigned _count;                                                         \
Packit 631bab
        char *_prev;                                                             \
Packit 631bab
        _count = 0;                                                              \
Packit 631bab
        for( _bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; _bkt_i++) {       \
Packit 631bab
            unsigned _bkt_count = 0;                                             \
Packit 631bab
            _thh = (head)->hh.tbl->buckets[_bkt_i].hh_head;                      \
Packit 631bab
            _prev = NULL;                                                        \
Packit 631bab
            while (_thh) {                                                       \
Packit 631bab
               if (_prev != (char*)(_thh->hh_prev)) {                            \
Packit 631bab
                   HASH_OOPS("invalid hh_prev %p, actual %p\n",                  \
Packit 631bab
                    _thh->hh_prev, _prev );                                      \
Packit 631bab
               }                                                                 \
Packit 631bab
               _bkt_count++;                                                     \
Packit 631bab
               _prev = (char*)(_thh);                                            \
Packit 631bab
               _thh = _thh->hh_next;                                             \
Packit 631bab
            }                                                                    \
Packit 631bab
            _count += _bkt_count;                                                \
Packit 631bab
            if ((head)->hh.tbl->buckets[_bkt_i].count !=  _bkt_count) {          \
Packit 631bab
               HASH_OOPS("invalid bucket count %u, actual %u\n",                 \
Packit 631bab
                (head)->hh.tbl->buckets[_bkt_i].count, _bkt_count);              \
Packit 631bab
            }                                                                    \
Packit 631bab
        }                                                                        \
Packit 631bab
        if (_count != (head)->hh.tbl->num_items) {                               \
Packit 631bab
            HASH_OOPS("invalid hh item count %u, actual %u\n",                   \
Packit 631bab
                (head)->hh.tbl->num_items, _count );                             \
Packit 631bab
        }                                                                        \
Packit 631bab
        /* traverse hh in app order; check next/prev integrity, count */         \
Packit 631bab
        _count = 0;                                                              \
Packit 631bab
        _prev = NULL;                                                            \
Packit 631bab
        _thh =  &(head)->hh;                                                     \
Packit 631bab
        while (_thh) {                                                           \
Packit 631bab
           _count++;                                                             \
Packit 631bab
           if (_prev !=(char*)(_thh->prev)) {                                    \
Packit 631bab
              HASH_OOPS("invalid prev %p, actual %p\n",                          \
Packit 631bab
                    _thh->prev, _prev );                                         \
Packit 631bab
           }                                                                     \
Packit 631bab
           _prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh);                    \
Packit 631bab
           _thh = ( _thh->next ?  (UT_hash_handle*)((char*)(_thh->next) +        \
Packit 631bab
                                  (head)->hh.tbl->hho) : NULL );                 \
Packit 631bab
        }                                                                        \
Packit 631bab
        if (_count != (head)->hh.tbl->num_items) {                               \
Packit 631bab
            HASH_OOPS("invalid app item count %u, actual %u\n",                  \
Packit 631bab
                (head)->hh.tbl->num_items, _count );                             \
Packit 631bab
        }                                                                        \
Packit 631bab
    }                                                                            \
Packit 631bab
} while (0)
Packit 631bab
#else
Packit 631bab
#define HASH_FSCK(hh,head)
Packit 631bab
#endif
Packit 631bab
Packit 631bab
/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to
Packit 631bab
 * the descriptor to which this macro is defined for tuning the hash function.
Packit 631bab
 * The app can #include <unistd.h> to get the prototype for write(2). */
Packit 631bab
#ifdef HASH_EMIT_KEYS
Packit 631bab
#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen)                                   \
Packit 631bab
do {                                                                             \
Packit 631bab
    unsigned _klen = fieldlen;                                                   \
Packit 631bab
    write(HASH_EMIT_KEYS, &_klen, sizeof(_klen));                                \
Packit 631bab
    write(HASH_EMIT_KEYS, keyptr, (unsigned long)fieldlen);                      \
Packit 631bab
} while (0)
Packit 631bab
#else
Packit 631bab
#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen)
Packit 631bab
#endif
Packit 631bab
Packit 631bab
/* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */
Packit 631bab
#ifdef HASH_FUNCTION
Packit 631bab
#define HASH_FCN HASH_FUNCTION
Packit 631bab
#else
Packit 631bab
#define HASH_FCN HASH_JEN
Packit 631bab
#endif
Packit 631bab
Packit 631bab
/* The Bernstein hash function, used in Perl prior to v5.6. Note (x<<5+x)=x*33. */
Packit 631bab
#define HASH_BER(key,keylen,hashv)                                               \
Packit 631bab
do {                                                                             \
Packit 631bab
  unsigned _hb_keylen=(unsigned)keylen;                                          \
Packit 631bab
  const unsigned char *_hb_key=(const unsigned char*)(key);                      \
Packit 631bab
  (hashv) = 0;                                                                   \
Packit 631bab
  while (_hb_keylen-- != 0U) {                                                   \
Packit 631bab
      (hashv) = (((hashv) << 5) + (hashv)) + *_hb_key++;                         \
Packit 631bab
  }                                                                              \
Packit 631bab
} while (0)
Packit 631bab
Packit 631bab
Packit 631bab
/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at
Packit 631bab
 * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */
Packit 631bab
#define HASH_SAX(key,keylen,hashv)                                               \
Packit 631bab
do {                                                                             \
Packit 631bab
  unsigned _sx_i;                                                                \
Packit 631bab
  const unsigned char *_hs_key=(const unsigned char*)(key);                      \
Packit 631bab
  hashv = 0;                                                                     \
Packit 631bab
  for(_sx_i=0; _sx_i < keylen; _sx_i++) {                                        \
Packit 631bab
      hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i];                     \
Packit 631bab
  }                                                                              \
Packit 631bab
} while (0)
Packit 631bab
/* FNV-1a variation */
Packit 631bab
#define HASH_FNV(key,keylen,hashv)                                               \
Packit 631bab
do {                                                                             \
Packit 631bab
  unsigned _fn_i;                                                                \
Packit 631bab
  const unsigned char *_hf_key=(const unsigned char*)(key);                      \
Packit 631bab
  hashv = 2166136261U;                                                           \
Packit 631bab
  for(_fn_i=0; _fn_i < keylen; _fn_i++) {                                        \
Packit 631bab
      hashv = hashv ^ _hf_key[_fn_i];                                            \
Packit 631bab
      hashv = hashv * 16777619U;                                                 \
Packit 631bab
  }                                                                              \
Packit 631bab
} while (0)
Packit 631bab
Packit 631bab
#define HASH_OAT(key,keylen,hashv)                                               \
Packit 631bab
do {                                                                             \
Packit 631bab
  unsigned _ho_i;                                                                \
Packit 631bab
  const unsigned char *_ho_key=(const unsigned char*)(key);                      \
Packit 631bab
  hashv = 0;                                                                     \
Packit 631bab
  for(_ho_i=0; _ho_i < keylen; _ho_i++) {                                        \
Packit 631bab
      hashv += _ho_key[_ho_i];                                                   \
Packit 631bab
      hashv += (hashv << 10);                                                    \
Packit 631bab
      hashv ^= (hashv >> 6);                                                     \
Packit 631bab
  }                                                                              \
Packit 631bab
  hashv += (hashv << 3);                                                         \
Packit 631bab
  hashv ^= (hashv >> 11);                                                        \
Packit 631bab
  hashv += (hashv << 15);                                                        \
Packit 631bab
} while (0)
Packit 631bab
Packit 631bab
#define HASH_JEN_MIX(a,b,c)                                                      \
Packit 631bab
do {                                                                             \
Packit 631bab
  a -= b; a -= c; a ^= ( c >> 13 );                                              \
Packit 631bab
  b -= c; b -= a; b ^= ( a << 8 );                                               \
Packit 631bab
  c -= a; c -= b; c ^= ( b >> 13 );                                              \
Packit 631bab
  a -= b; a -= c; a ^= ( c >> 12 );                                              \
Packit 631bab
  b -= c; b -= a; b ^= ( a << 16 );                                              \
Packit 631bab
  c -= a; c -= b; c ^= ( b >> 5 );                                               \
Packit 631bab
  a -= b; a -= c; a ^= ( c >> 3 );                                               \
Packit 631bab
  b -= c; b -= a; b ^= ( a << 10 );                                              \
Packit 631bab
  c -= a; c -= b; c ^= ( b >> 15 );                                              \
Packit 631bab
} while (0)
Packit 631bab
Packit 631bab
#define HASH_JEN(key,keylen,hashv)                                               \
Packit 631bab
do {                                                                             \
Packit 631bab
  unsigned _hj_i,_hj_j,_hj_k;                                                    \
Packit 631bab
  unsigned const char *_hj_key=(unsigned const char*)(key);                      \
Packit 631bab
  hashv = 0xfeedbeefu;                                                           \
Packit 631bab
  _hj_i = _hj_j = 0x9e3779b9u;                                                   \
Packit 631bab
  _hj_k = (unsigned)(keylen);                                                    \
Packit 631bab
  while (_hj_k >= 12U) {                                                         \
Packit 631bab
    _hj_i +=    (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 )                      \
Packit 631bab
        + ( (unsigned)_hj_key[2] << 16 )                                         \
Packit 631bab
        + ( (unsigned)_hj_key[3] << 24 ) );                                      \
Packit 631bab
    _hj_j +=    (_hj_key[4] + ( (unsigned)_hj_key[5] << 8 )                      \
Packit 631bab
        + ( (unsigned)_hj_key[6] << 16 )                                         \
Packit 631bab
        + ( (unsigned)_hj_key[7] << 24 ) );                                      \
Packit 631bab
    hashv += (_hj_key[8] + ( (unsigned)_hj_key[9] << 8 )                         \
Packit 631bab
        + ( (unsigned)_hj_key[10] << 16 )                                        \
Packit 631bab
        + ( (unsigned)_hj_key[11] << 24 ) );                                     \
Packit 631bab
                                                                                 \
Packit 631bab
     HASH_JEN_MIX(_hj_i, _hj_j, hashv);                                          \
Packit 631bab
                                                                                 \
Packit 631bab
     _hj_key += 12;                                                              \
Packit 631bab
     _hj_k -= 12U;                                                               \
Packit 631bab
  }                                                                              \
Packit 631bab
  hashv += (unsigned)(keylen);                                                   \
Packit 631bab
  switch ( _hj_k ) {                                                             \
Packit 631bab
     case 11: hashv += ( (unsigned)_hj_key[10] << 24 ); /* FALLTHROUGH */        \
Packit 631bab
     case 10: hashv += ( (unsigned)_hj_key[9] << 16 );  /* FALLTHROUGH */        \
Packit 631bab
     case 9:  hashv += ( (unsigned)_hj_key[8] << 8 );   /* FALLTHROUGH */        \
Packit 631bab
     case 8:  _hj_j += ( (unsigned)_hj_key[7] << 24 );  /* FALLTHROUGH */        \
Packit 631bab
     case 7:  _hj_j += ( (unsigned)_hj_key[6] << 16 );  /* FALLTHROUGH */        \
Packit 631bab
     case 6:  _hj_j += ( (unsigned)_hj_key[5] << 8 );   /* FALLTHROUGH */        \
Packit 631bab
     case 5:  _hj_j += _hj_key[4];                      /* FALLTHROUGH */        \
Packit 631bab
     case 4:  _hj_i += ( (unsigned)_hj_key[3] << 24 );  /* FALLTHROUGH */        \
Packit 631bab
     case 3:  _hj_i += ( (unsigned)_hj_key[2] << 16 );  /* FALLTHROUGH */        \
Packit 631bab
     case 2:  _hj_i += ( (unsigned)_hj_key[1] << 8 );   /* FALLTHROUGH */        \
Packit 631bab
     case 1:  _hj_i += _hj_key[0];                                               \
Packit 631bab
  }                                                                              \
Packit 631bab
  HASH_JEN_MIX(_hj_i, _hj_j, hashv);                                             \
Packit 631bab
} while (0)
Packit 631bab
Packit 631bab
/* The Paul Hsieh hash function */
Packit 631bab
#undef get16bits
Packit 631bab
#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__)             \
Packit 631bab
  || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)
Packit 631bab
#define get16bits(d) (*((const uint16_t *) (d)))
Packit 631bab
#endif
Packit 631bab
Packit 631bab
#if !defined (get16bits)
Packit 631bab
#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)             \
Packit 631bab
                       +(uint32_t)(((const uint8_t *)(d))[0]) )
Packit 631bab
#endif
Packit 631bab
#define HASH_SFH(key,keylen,hashv)                                               \
Packit 631bab
do {                                                                             \
Packit 631bab
  unsigned const char *_sfh_key=(unsigned const char*)(key);                     \
Packit 631bab
  uint32_t _sfh_tmp, _sfh_len = (uint32_t)keylen;                                \
Packit 631bab
                                                                                 \
Packit 631bab
  unsigned _sfh_rem = _sfh_len & 3U;                                             \
Packit 631bab
  _sfh_len >>= 2;                                                                \
Packit 631bab
  hashv = 0xcafebabeu;                                                           \
Packit 631bab
                                                                                 \
Packit 631bab
  /* Main loop */                                                                \
Packit 631bab
  for (;_sfh_len > 0U; _sfh_len--) {                                             \
Packit 631bab
    hashv    += get16bits (_sfh_key);                                            \
Packit 631bab
    _sfh_tmp  = ((uint32_t)(get16bits (_sfh_key+2)) << 11) ^ hashv;              \
Packit 631bab
    hashv     = (hashv << 16) ^ _sfh_tmp;                                        \
Packit 631bab
    _sfh_key += 2U*sizeof (uint16_t);                                            \
Packit 631bab
    hashv    += hashv >> 11;                                                     \
Packit 631bab
  }                                                                              \
Packit 631bab
                                                                                 \
Packit 631bab
  /* Handle end cases */                                                         \
Packit 631bab
  switch (_sfh_rem) {                                                            \
Packit 631bab
    case 3: hashv += get16bits (_sfh_key);                                       \
Packit 631bab
            hashv ^= hashv << 16;                                                \
Packit 631bab
            hashv ^= (uint32_t)(_sfh_key[sizeof (uint16_t)]) << 18;              \
Packit 631bab
            hashv += hashv >> 11;                                                \
Packit 631bab
            break;                                                               \
Packit 631bab
    case 2: hashv += get16bits (_sfh_key);                                       \
Packit 631bab
            hashv ^= hashv << 11;                                                \
Packit 631bab
            hashv += hashv >> 17;                                                \
Packit 631bab
            break;                                                               \
Packit 631bab
    case 1: hashv += *_sfh_key;                                                  \
Packit 631bab
            hashv ^= hashv << 10;                                                \
Packit 631bab
            hashv += hashv >> 1;                                                 \
Packit 631bab
  }                                                                              \
Packit 631bab
                                                                                 \
Packit 631bab
    /* Force "avalanching" of final 127 bits */                                  \
Packit 631bab
    hashv ^= hashv << 3;                                                         \
Packit 631bab
    hashv += hashv >> 5;                                                         \
Packit 631bab
    hashv ^= hashv << 4;                                                         \
Packit 631bab
    hashv += hashv >> 17;                                                        \
Packit 631bab
    hashv ^= hashv << 25;                                                        \
Packit 631bab
    hashv += hashv >> 6;                                                         \
Packit 631bab
} while (0)
Packit 631bab
Packit 631bab
#ifdef HASH_USING_NO_STRICT_ALIASING
Packit 631bab
/* The MurmurHash exploits some CPU's (x86,x86_64) tolerance for unaligned reads.
Packit 631bab
 * For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error.
Packit 631bab
 * MurmurHash uses the faster approach only on CPU's where we know it's safe.
Packit 631bab
 *
Packit 631bab
 * Note the preprocessor built-in defines can be emitted using:
Packit 631bab
 *
Packit 631bab
 *   gcc -m64 -dM -E - < /dev/null                  (on gcc)
Packit 631bab
 *   cc -## a.c (where a.c is a simple test file)   (Sun Studio)
Packit 631bab
 */
Packit 631bab
#if (defined(__i386__) || defined(__x86_64__)  || defined(_M_IX86))
Packit 631bab
#define MUR_GETBLOCK(p,i) p[i]
Packit 631bab
#else /* non intel */
Packit 631bab
#define MUR_PLUS0_ALIGNED(p) (((unsigned long)p & 3UL) == 0UL)
Packit 631bab
#define MUR_PLUS1_ALIGNED(p) (((unsigned long)p & 3UL) == 1UL)
Packit 631bab
#define MUR_PLUS2_ALIGNED(p) (((unsigned long)p & 3UL) == 2UL)
Packit 631bab
#define MUR_PLUS3_ALIGNED(p) (((unsigned long)p & 3UL) == 3UL)
Packit 631bab
#define WP(p) ((uint32_t*)((unsigned long)(p) & ~3UL))
Packit 631bab
#if (defined(__BIG_ENDIAN__) || defined(SPARC) || defined(__ppc__) || defined(__ppc64__))
Packit 631bab
#define MUR_THREE_ONE(p) ((((*WP(p))&0x00ffffff) << 8) | (((*(WP(p)+1))&0xff000000) >> 24))
Packit 631bab
#define MUR_TWO_TWO(p)   ((((*WP(p))&0x0000ffff) <<16) | (((*(WP(p)+1))&0xffff0000) >> 16))
Packit 631bab
#define MUR_ONE_THREE(p) ((((*WP(p))&0x000000ff) <<24) | (((*(WP(p)+1))&0xffffff00) >>  8))
Packit 631bab
#else /* assume little endian non-intel */
Packit 631bab
#define MUR_THREE_ONE(p) ((((*WP(p))&0xffffff00) >> 8) | (((*(WP(p)+1))&0x000000ff) << 24))
Packit 631bab
#define MUR_TWO_TWO(p)   ((((*WP(p))&0xffff0000) >>16) | (((*(WP(p)+1))&0x0000ffff) << 16))
Packit 631bab
#define MUR_ONE_THREE(p) ((((*WP(p))&0xff000000) >>24) | (((*(WP(p)+1))&0x00ffffff) <<  8))
Packit 631bab
#endif
Packit 631bab
#define MUR_GETBLOCK(p,i) (MUR_PLUS0_ALIGNED(p) ? ((p)[i]) :           \
Packit 631bab
                            (MUR_PLUS1_ALIGNED(p) ? MUR_THREE_ONE(p) : \
Packit 631bab
                             (MUR_PLUS2_ALIGNED(p) ? MUR_TWO_TWO(p) :  \
Packit 631bab
                                                      MUR_ONE_THREE(p))))
Packit 631bab
#endif
Packit 631bab
#define MUR_ROTL32(x,r) (((x) << (r)) | ((x) >> (32 - (r))))
Packit 631bab
#define MUR_FMIX(_h) \
Packit 631bab
do {                 \
Packit 631bab
  _h ^= _h >> 16;    \
Packit 631bab
  _h *= 0x85ebca6bu; \
Packit 631bab
  _h ^= _h >> 13;    \
Packit 631bab
  _h *= 0xc2b2ae35u; \
Packit 631bab
  _h ^= _h >> 16;    \
Packit 631bab
} while (0)
Packit 631bab
Packit 631bab
#define HASH_MUR(key,keylen,hashv)                                     \
Packit 631bab
do {                                                                   \
Packit 631bab
  const uint8_t *_mur_data = (const uint8_t*)(key);                    \
Packit 631bab
  const int _mur_nblocks = (int)(keylen) / 4;                          \
Packit 631bab
  uint32_t _mur_h1 = 0xf88D5353u;                                      \
Packit 631bab
  uint32_t _mur_c1 = 0xcc9e2d51u;                                      \
Packit 631bab
  uint32_t _mur_c2 = 0x1b873593u;                                      \
Packit 631bab
  uint32_t _mur_k1 = 0;                                                \
Packit 631bab
  const uint8_t *_mur_tail;                                            \
Packit 631bab
  const uint32_t *_mur_blocks = (const uint32_t*)(_mur_data+(_mur_nblocks*4)); \
Packit 631bab
  int _mur_i;                                                          \
Packit 631bab
  for(_mur_i = -_mur_nblocks; _mur_i!=0; _mur_i++) {                   \
Packit 631bab
    _mur_k1 = MUR_GETBLOCK(_mur_blocks,_mur_i);                        \
Packit 631bab
    _mur_k1 *= _mur_c1;                                                \
Packit 631bab
    _mur_k1 = MUR_ROTL32(_mur_k1,15);                                  \
Packit 631bab
    _mur_k1 *= _mur_c2;                                                \
Packit 631bab
                                                                       \
Packit 631bab
    _mur_h1 ^= _mur_k1;                                                \
Packit 631bab
    _mur_h1 = MUR_ROTL32(_mur_h1,13);                                  \
Packit 631bab
    _mur_h1 = (_mur_h1*5U) + 0xe6546b64u;                              \
Packit 631bab
  }                                                                    \
Packit 631bab
  _mur_tail = (const uint8_t*)(_mur_data + (_mur_nblocks*4));          \
Packit 631bab
  _mur_k1=0;                                                           \
Packit 631bab
  switch((keylen) & 3U) {                                              \
Packit 631bab
    case 3: _mur_k1 ^= (uint32_t)_mur_tail[2] << 16; /* FALLTHROUGH */ \
Packit 631bab
    case 2: _mur_k1 ^= (uint32_t)_mur_tail[1] << 8;  /* FALLTHROUGH */ \
Packit 631bab
    case 1: _mur_k1 ^= (uint32_t)_mur_tail[0];                         \
Packit 631bab
    _mur_k1 *= _mur_c1;                                                \
Packit 631bab
    _mur_k1 = MUR_ROTL32(_mur_k1,15);                                  \
Packit 631bab
    _mur_k1 *= _mur_c2;                                                \
Packit 631bab
    _mur_h1 ^= _mur_k1;                                                \
Packit 631bab
  }                                                                    \
Packit 631bab
  _mur_h1 ^= (uint32_t)(keylen);                                       \
Packit 631bab
  MUR_FMIX(_mur_h1);                                                   \
Packit 631bab
  hashv = _mur_h1;                                                     \
Packit 631bab
} while (0)
Packit 631bab
#endif  /* HASH_USING_NO_STRICT_ALIASING */
Packit 631bab
Packit 631bab
/* iterate over items in a known bucket to find desired item */
Packit 631bab
#define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,hashval,out)               \
Packit 631bab
do {                                                                             \
Packit 631bab
  if ((head).hh_head != NULL) {                                                  \
Packit 631bab
    DECLTYPE_ASSIGN(out, ELMT_FROM_HH(tbl, (head).hh_head));                     \
Packit 631bab
  } else {                                                                       \
Packit 631bab
    (out) = NULL;                                                                \
Packit 631bab
  }                                                                              \
Packit 631bab
  while ((out) != NULL) {                                                        \
Packit 631bab
    if ((out)->hh.hashv == (hashval) && (out)->hh.keylen == (keylen_in)) {       \
Packit 631bab
      if (uthash_memcmp((out)->hh.key, keyptr, keylen_in) == 0) {                \
Packit 631bab
        break;                                                                   \
Packit 631bab
      }                                                                          \
Packit 631bab
    }                                                                            \
Packit 631bab
    if ((out)->hh.hh_next != NULL) {                                             \
Packit 631bab
      DECLTYPE_ASSIGN(out, ELMT_FROM_HH(tbl, (out)->hh.hh_next));                \
Packit 631bab
    } else {                                                                     \
Packit 631bab
      (out) = NULL;                                                              \
Packit 631bab
    }                                                                            \
Packit 631bab
  }                                                                              \
Packit 631bab
} while (0)
Packit 631bab
Packit 631bab
/* add an item to a bucket  */
Packit 631bab
#define HASH_ADD_TO_BKT(head,addhh)                                              \
Packit 631bab
do {                                                                             \
Packit 631bab
 head.count++;                                                                   \
Packit 631bab
 (addhh)->hh_next = head.hh_head;                                                \
Packit 631bab
 (addhh)->hh_prev = NULL;                                                        \
Packit 631bab
 if (head.hh_head != NULL) { (head).hh_head->hh_prev = (addhh); }                \
Packit 631bab
 (head).hh_head=addhh;                                                           \
Packit 631bab
 if ((head.count >= ((head.expand_mult+1U) * HASH_BKT_CAPACITY_THRESH))          \
Packit 631bab
     && ((addhh)->tbl->noexpand != 1U)) {                                        \
Packit 631bab
       HASH_EXPAND_BUCKETS((addhh)->tbl);                                        \
Packit 631bab
 }                                                                               \
Packit 631bab
} while (0)
Packit 631bab
Packit 631bab
/* remove an item from a given bucket */
Packit 631bab
#define HASH_DEL_IN_BKT(hh,head,hh_del)                                          \
Packit 631bab
    (head).count--;                                                              \
Packit 631bab
    if ((head).hh_head == hh_del) {                                              \
Packit 631bab
      (head).hh_head = hh_del->hh_next;                                          \
Packit 631bab
    }                                                                            \
Packit 631bab
    if (hh_del->hh_prev) {                                                       \
Packit 631bab
        hh_del->hh_prev->hh_next = hh_del->hh_next;                              \
Packit 631bab
    }                                                                            \
Packit 631bab
    if (hh_del->hh_next) {                                                       \
Packit 631bab
        hh_del->hh_next->hh_prev = hh_del->hh_prev;                              \
Packit 631bab
    }
Packit 631bab
Packit 631bab
/* Bucket expansion has the effect of doubling the number of buckets
Packit 631bab
 * and redistributing the items into the new buckets. Ideally the
Packit 631bab
 * items will distribute more or less evenly into the new buckets
Packit 631bab
 * (the extent to which this is true is a measure of the quality of
Packit 631bab
 * the hash function as it applies to the key domain).
Packit 631bab
 *
Packit 631bab
 * With the items distributed into more buckets, the chain length
Packit 631bab
 * (item count) in each bucket is reduced. Thus by expanding buckets
Packit 631bab
 * the hash keeps a bound on the chain length. This bounded chain
Packit 631bab
 * length is the essence of how a hash provides constant time lookup.
Packit 631bab
 *
Packit 631bab
 * The calculation of tbl->ideal_chain_maxlen below deserves some
Packit 631bab
 * explanation. First, keep in mind that we're calculating the ideal
Packit 631bab
 * maximum chain length based on the *new* (doubled) bucket count.
Packit 631bab
 * In fractions this is just n/b (n=number of items,b=new num buckets).
Packit 631bab
 * Since the ideal chain length is an integer, we want to calculate
Packit 631bab
 * ceil(n/b). We don't depend on floating point arithmetic in this
Packit 631bab
 * hash, so to calculate ceil(n/b) with integers we could write
Packit 631bab
 *
Packit 631bab
 *      ceil(n/b) = (n/b) + ((n%b)?1:0)
Packit 631bab
 *
Packit 631bab
 * and in fact a previous version of this hash did just that.
Packit 631bab
 * But now we have improved things a bit by recognizing that b is
Packit 631bab
 * always a power of two. We keep its base 2 log handy (call it lb),
Packit 631bab
 * so now we can write this with a bit shift and logical AND:
Packit 631bab
 *
Packit 631bab
 *      ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0)
Packit 631bab
 *
Packit 631bab
 */
Packit 631bab
#define HASH_EXPAND_BUCKETS(tbl)                                                 \
Packit 631bab
do {                                                                             \
Packit 631bab
    unsigned _he_bkt;                                                            \
Packit 631bab
    unsigned _he_bkt_i;                                                          \
Packit 631bab
    struct UT_hash_handle *_he_thh, *_he_hh_nxt;                                 \
Packit 631bab
    UT_hash_bucket *_he_new_buckets, *_he_newbkt;                                \
Packit 631bab
    _he_new_buckets = (UT_hash_bucket*)uthash_malloc(                            \
Packit 631bab
             2UL * tbl->num_buckets * sizeof(struct UT_hash_bucket));            \
Packit 631bab
    if (!_he_new_buckets) { uthash_fatal( "out of memory"); }                    \
Packit 631bab
    memset(_he_new_buckets, 0,                                                   \
Packit 631bab
            2UL * tbl->num_buckets * sizeof(struct UT_hash_bucket));             \
Packit 631bab
    tbl->ideal_chain_maxlen =                                                    \
Packit 631bab
       (tbl->num_items >> (tbl->log2_num_buckets+1U)) +                          \
Packit 631bab
       (((tbl->num_items & ((tbl->num_buckets*2U)-1U)) != 0U) ? 1U : 0U);        \
Packit 631bab
    tbl->nonideal_items = 0;                                                     \
Packit 631bab
    for(_he_bkt_i = 0; _he_bkt_i < tbl->num_buckets; _he_bkt_i++)                \
Packit 631bab
    {                                                                            \
Packit 631bab
        _he_thh = tbl->buckets[ _he_bkt_i ].hh_head;                             \
Packit 631bab
        while (_he_thh != NULL) {                                                \
Packit 631bab
           _he_hh_nxt = _he_thh->hh_next;                                        \
Packit 631bab
           HASH_TO_BKT( _he_thh->hashv, tbl->num_buckets*2U, _he_bkt);           \
Packit 631bab
           _he_newbkt = &(_he_new_buckets[ _he_bkt ]);                           \
Packit 631bab
           if (++(_he_newbkt->count) > tbl->ideal_chain_maxlen) {                \
Packit 631bab
             tbl->nonideal_items++;                                              \
Packit 631bab
             _he_newbkt->expand_mult = _he_newbkt->count /                       \
Packit 631bab
                                        tbl->ideal_chain_maxlen;                 \
Packit 631bab
           }                                                                     \
Packit 631bab
           _he_thh->hh_prev = NULL;                                              \
Packit 631bab
           _he_thh->hh_next = _he_newbkt->hh_head;                               \
Packit 631bab
           if (_he_newbkt->hh_head != NULL) { _he_newbkt->hh_head->hh_prev =     \
Packit 631bab
                _he_thh; }                                                       \
Packit 631bab
           _he_newbkt->hh_head = _he_thh;                                        \
Packit 631bab
           _he_thh = _he_hh_nxt;                                                 \
Packit 631bab
        }                                                                        \
Packit 631bab
    }                                                                            \
Packit 631bab
    uthash_free( tbl->buckets, tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \
Packit 631bab
    tbl->num_buckets *= 2U;                                                      \
Packit 631bab
    tbl->log2_num_buckets++;                                                     \
Packit 631bab
    tbl->buckets = _he_new_buckets;                                              \
Packit 631bab
    tbl->ineff_expands = (tbl->nonideal_items > (tbl->num_items >> 1)) ?         \
Packit 631bab
        (tbl->ineff_expands+1U) : 0U;                                            \
Packit 631bab
    if (tbl->ineff_expands > 1U) {                                               \
Packit 631bab
        tbl->noexpand=1;                                                         \
Packit 631bab
        uthash_noexpand_fyi(tbl);                                                \
Packit 631bab
    }                                                                            \
Packit 631bab
    uthash_expand_fyi(tbl);                                                      \
Packit 631bab
} while (0)
Packit 631bab
Packit 631bab
Packit 631bab
/* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */
Packit 631bab
/* Note that HASH_SORT assumes the hash handle name to be hh.
Packit 631bab
 * HASH_SRT was added to allow the hash handle name to be passed in. */
Packit 631bab
#define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn)
Packit 631bab
#define HASH_SRT(hh,head,cmpfcn)                                                 \
Packit 631bab
do {                                                                             \
Packit 631bab
  unsigned _hs_i;                                                                \
Packit 631bab
  unsigned _hs_looping,_hs_nmerges,_hs_insize,_hs_psize,_hs_qsize;               \
Packit 631bab
  struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail;            \
Packit 631bab
  if (head != NULL) {                                                            \
Packit 631bab
      _hs_insize = 1;                                                            \
Packit 631bab
      _hs_looping = 1;                                                           \
Packit 631bab
      _hs_list = &((head)->hh);                                                  \
Packit 631bab
      while (_hs_looping != 0U) {                                                \
Packit 631bab
          _hs_p = _hs_list;                                                      \
Packit 631bab
          _hs_list = NULL;                                                       \
Packit 631bab
          _hs_tail = NULL;                                                       \
Packit 631bab
          _hs_nmerges = 0;                                                       \
Packit 631bab
          while (_hs_p != NULL) {                                                \
Packit 631bab
              _hs_nmerges++;                                                     \
Packit 631bab
              _hs_q = _hs_p;                                                     \
Packit 631bab
              _hs_psize = 0;                                                     \
Packit 631bab
              for ( _hs_i = 0; _hs_i  < _hs_insize; _hs_i++ ) {                  \
Packit 631bab
                  _hs_psize++;                                                   \
Packit 631bab
                  _hs_q = (UT_hash_handle*)((_hs_q->next != NULL) ?              \
Packit 631bab
                          ((void*)((char*)(_hs_q->next) +                        \
Packit 631bab
                          (head)->hh.tbl->hho)) : NULL);                         \
Packit 631bab
                  if (! (_hs_q) ) { break; }                                     \
Packit 631bab
              }                                                                  \
Packit 631bab
              _hs_qsize = _hs_insize;                                            \
Packit 631bab
              while ((_hs_psize > 0U) || ((_hs_qsize > 0U) && (_hs_q != NULL))) {\
Packit 631bab
                  if (_hs_psize == 0U) {                                         \
Packit 631bab
                      _hs_e = _hs_q;                                             \
Packit 631bab
                      _hs_q = (UT_hash_handle*)((_hs_q->next != NULL) ?          \
Packit 631bab
                              ((void*)((char*)(_hs_q->next) +                    \
Packit 631bab
                              (head)->hh.tbl->hho)) : NULL);                     \
Packit 631bab
                      _hs_qsize--;                                               \
Packit 631bab
                  } else if ( (_hs_qsize == 0U) || (_hs_q == NULL) ) {           \
Packit 631bab
                      _hs_e = _hs_p;                                             \
Packit 631bab
                      if (_hs_p != NULL){                                        \
Packit 631bab
                        _hs_p = (UT_hash_handle*)((_hs_p->next != NULL) ?        \
Packit 631bab
                                ((void*)((char*)(_hs_p->next) +                  \
Packit 631bab
                                (head)->hh.tbl->hho)) : NULL);                   \
Packit 631bab
                       }                                                         \
Packit 631bab
                      _hs_psize--;                                               \
Packit 631bab
                  } else if ((                                                   \
Packit 631bab
                      cmpfcn(DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_p)), \
Packit 631bab
                             DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_q))) \
Packit 631bab
                             ) <= 0) {                                           \
Packit 631bab
                      _hs_e = _hs_p;                                             \
Packit 631bab
                      if (_hs_p != NULL){                                        \
Packit 631bab
                        _hs_p = (UT_hash_handle*)((_hs_p->next != NULL) ?        \
Packit 631bab
                               ((void*)((char*)(_hs_p->next) +                   \
Packit 631bab
                               (head)->hh.tbl->hho)) : NULL);                    \
Packit 631bab
                       }                                                         \
Packit 631bab
                      _hs_psize--;                                               \
Packit 631bab
                  } else {                                                       \
Packit 631bab
                      _hs_e = _hs_q;                                             \
Packit 631bab
                      _hs_q = (UT_hash_handle*)((_hs_q->next != NULL) ?          \
Packit 631bab
                              ((void*)((char*)(_hs_q->next) +                    \
Packit 631bab
                              (head)->hh.tbl->hho)) : NULL);                     \
Packit 631bab
                      _hs_qsize--;                                               \
Packit 631bab
                  }                                                              \
Packit 631bab
                  if ( _hs_tail != NULL ) {                                      \
Packit 631bab
                      _hs_tail->next = ((_hs_e != NULL) ?                        \
Packit 631bab
                            ELMT_FROM_HH((head)->hh.tbl,_hs_e) : NULL);          \
Packit 631bab
                  } else {                                                       \
Packit 631bab
                      _hs_list = _hs_e;                                          \
Packit 631bab
                  }                                                              \
Packit 631bab
                  if (_hs_e != NULL) {                                           \
Packit 631bab
                  _hs_e->prev = ((_hs_tail != NULL) ?                            \
Packit 631bab
                     ELMT_FROM_HH((head)->hh.tbl,_hs_tail) : NULL);              \
Packit 631bab
                  }                                                              \
Packit 631bab
                  _hs_tail = _hs_e;                                              \
Packit 631bab
              }                                                                  \
Packit 631bab
              _hs_p = _hs_q;                                                     \
Packit 631bab
          }                                                                      \
Packit 631bab
          if (_hs_tail != NULL){                                                 \
Packit 631bab
            _hs_tail->next = NULL;                                               \
Packit 631bab
          }                                                                      \
Packit 631bab
          if ( _hs_nmerges <= 1U ) {                                             \
Packit 631bab
              _hs_looping=0;                                                     \
Packit 631bab
              (head)->hh.tbl->tail = _hs_tail;                                   \
Packit 631bab
              DECLTYPE_ASSIGN(head,ELMT_FROM_HH((head)->hh.tbl, _hs_list));      \
Packit 631bab
          }                                                                      \
Packit 631bab
          _hs_insize *= 2U;                                                      \
Packit 631bab
      }                                                                          \
Packit 631bab
      HASH_FSCK(hh,head);                                                        \
Packit 631bab
 }                                                                               \
Packit 631bab
} while (0)
Packit 631bab
Packit 631bab
/* This function selects items from one hash into another hash.
Packit 631bab
 * The end result is that the selected items have dual presence
Packit 631bab
 * in both hashes. There is no copy of the items made; rather
Packit 631bab
 * they are added into the new hash through a secondary hash
Packit 631bab
 * hash handle that must be present in the structure. */
Packit 631bab
#define HASH_SELECT(hh_dst, dst, hh_src, src, cond)                              \
Packit 631bab
do {                                                                             \
Packit 631bab
  unsigned _src_bkt, _dst_bkt;                                                   \
Packit 631bab
  void *_last_elt=NULL, *_elt;                                                   \
Packit 631bab
  UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL;                         \
Packit 631bab
  ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst));                 \
Packit 631bab
  if (src != NULL) {                                                             \
Packit 631bab
    for(_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) {     \
Packit 631bab
      for(_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head;                \
Packit 631bab
          _src_hh != NULL;                                                       \
Packit 631bab
          _src_hh = _src_hh->hh_next) {                                          \
Packit 631bab
          _elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh);                       \
Packit 631bab
          if (cond(_elt)) {                                                      \
Packit 631bab
            _dst_hh = (UT_hash_handle*)(((char*)_elt) + _dst_hho);               \
Packit 631bab
            _dst_hh->key = _src_hh->key;                                         \
Packit 631bab
            _dst_hh->keylen = _src_hh->keylen;                                   \
Packit 631bab
            _dst_hh->hashv = _src_hh->hashv;                                     \
Packit 631bab
            _dst_hh->prev = _last_elt;                                           \
Packit 631bab
            _dst_hh->next = NULL;                                                \
Packit 631bab
            if (_last_elt_hh != NULL) { _last_elt_hh->next = _elt; }             \
Packit 631bab
            if (dst == NULL) {                                                   \
Packit 631bab
              DECLTYPE_ASSIGN(dst,_elt);                                         \
Packit 631bab
              HASH_MAKE_TABLE(hh_dst,dst);                                       \
Packit 631bab
            } else {                                                             \
Packit 631bab
              _dst_hh->tbl = (dst)->hh_dst.tbl;                                  \
Packit 631bab
            }                                                                    \
Packit 631bab
            HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt);    \
Packit 631bab
            HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt],_dst_hh);            \
Packit 631bab
            (dst)->hh_dst.tbl->num_items++;                                      \
Packit 631bab
            _last_elt = _elt;                                                    \
Packit 631bab
            _last_elt_hh = _dst_hh;                                              \
Packit 631bab
          }                                                                      \
Packit 631bab
      }                                                                          \
Packit 631bab
    }                                                                            \
Packit 631bab
  }                                                                              \
Packit 631bab
  HASH_FSCK(hh_dst,dst);                                                         \
Packit 631bab
} while (0)
Packit 631bab
Packit 631bab
#define HASH_CLEAR(hh,head)                                                      \
Packit 631bab
do {                                                                             \
Packit 631bab
  if (head != NULL) {                                                            \
Packit 631bab
    uthash_free((head)->hh.tbl->buckets,                                         \
Packit 631bab
                (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket));      \
Packit 631bab
    HASH_BLOOM_FREE((head)->hh.tbl);                                             \
Packit 631bab
    uthash_free((head)->hh.tbl, sizeof(UT_hash_table));                          \
Packit 631bab
    (head)=NULL;                                                                 \
Packit 631bab
  }                                                                              \
Packit 631bab
} while (0)
Packit 631bab
Packit 631bab
#define HASH_OVERHEAD(hh,head)                                                   \
Packit 631bab
 ((head != NULL) ? (                                                             \
Packit 631bab
 (size_t)(((head)->hh.tbl->num_items   * sizeof(UT_hash_handle))   +             \
Packit 631bab
          ((head)->hh.tbl->num_buckets * sizeof(UT_hash_bucket))   +             \
Packit 631bab
           sizeof(UT_hash_table)                                   +             \
Packit 631bab
           (HASH_BLOOM_BYTELEN))) : 0U)
Packit 631bab
Packit 631bab
#ifdef NO_DECLTYPE
Packit 631bab
#define HASH_ITER(hh,head,el,tmp)                                                \
Packit 631bab
for(((el)=(head)), ((*(char**)(&(tmp)))=(char*)((head!=NULL)?(head)->hh.next:NULL)); \
Packit 631bab
  (el) != NULL; ((el)=(tmp)), ((*(char**)(&(tmp)))=(char*)((tmp!=NULL)?(tmp)->hh.next:NULL)))
Packit 631bab
#else
Packit 631bab
#define HASH_ITER(hh,head,el,tmp)                                                \
Packit 631bab
for(((el)=(head)), ((tmp)=DECLTYPE(el)((head!=NULL)?(head)->hh.next:NULL));      \
Packit 631bab
  (el) != NULL; ((el)=(tmp)), ((tmp)=DECLTYPE(el)((tmp!=NULL)?(tmp)->hh.next:NULL)))
Packit 631bab
#endif
Packit 631bab
Packit 631bab
/* obtain a count of items in the hash */
Packit 631bab
#define HASH_COUNT(head) HASH_CNT(hh,head)
Packit 631bab
#define HASH_CNT(hh,head) ((head != NULL)?((head)->hh.tbl->num_items):0U)
Packit 631bab
Packit 631bab
typedef struct UT_hash_bucket {
Packit 631bab
   struct UT_hash_handle *hh_head;
Packit 631bab
   unsigned count;
Packit 631bab
Packit 631bab
   /* expand_mult is normally set to 0. In this situation, the max chain length
Packit 631bab
    * threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If
Packit 631bab
    * the bucket's chain exceeds this length, bucket expansion is triggered).
Packit 631bab
    * However, setting expand_mult to a non-zero value delays bucket expansion
Packit 631bab
    * (that would be triggered by additions to this particular bucket)
Packit 631bab
    * until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH.
Packit 631bab
    * (The multiplier is simply expand_mult+1). The whole idea of this
Packit 631bab
    * multiplier is to reduce bucket expansions, since they are expensive, in
Packit 631bab
    * situations where we know that a particular bucket tends to be overused.
Packit 631bab
    * It is better to let its chain length grow to a longer yet-still-bounded
Packit 631bab
    * value, than to do an O(n) bucket expansion too often.
Packit 631bab
    */
Packit 631bab
   unsigned expand_mult;
Packit 631bab
Packit 631bab
} UT_hash_bucket;
Packit 631bab
Packit 631bab
/* random signature used only to find hash tables in external analysis */
Packit 631bab
#define HASH_SIGNATURE 0xa0111fe1u
Packit 631bab
#define HASH_BLOOM_SIGNATURE 0xb12220f2u
Packit 631bab
Packit 631bab
typedef struct UT_hash_table {
Packit 631bab
   UT_hash_bucket *buckets;
Packit 631bab
   unsigned num_buckets, log2_num_buckets;
Packit 631bab
   unsigned num_items;
Packit 631bab
   struct UT_hash_handle *tail; /* tail hh in app order, for fast append    */
Packit 631bab
   ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */
Packit 631bab
Packit 631bab
   /* in an ideal situation (all buckets used equally), no bucket would have
Packit 631bab
    * more than ceil(#items/#buckets) items. that's the ideal chain length. */
Packit 631bab
   unsigned ideal_chain_maxlen;
Packit 631bab
Packit 631bab
   /* nonideal_items is the number of items in the hash whose chain position
Packit 631bab
    * exceeds the ideal chain maxlen. these items pay the penalty for an uneven
Packit 631bab
    * hash distribution; reaching them in a chain traversal takes >ideal steps */
Packit 631bab
   unsigned nonideal_items;
Packit 631bab
Packit 631bab
   /* ineffective expands occur when a bucket doubling was performed, but
Packit 631bab
    * afterward, more than half the items in the hash had nonideal chain
Packit 631bab
    * positions. If this happens on two consecutive expansions we inhibit any
Packit 631bab
    * further expansion, as it's not helping; this happens when the hash
Packit 631bab
    * function isn't a good fit for the key domain. When expansion is inhibited
Packit 631bab
    * the hash will still work, albeit no longer in constant time. */
Packit 631bab
   unsigned ineff_expands, noexpand;
Packit 631bab
Packit 631bab
   uint32_t signature; /* used only to find hash tables in external analysis */
Packit 631bab
#ifdef HASH_BLOOM
Packit 631bab
   uint32_t bloom_sig; /* used only to test bloom exists in external analysis */
Packit 631bab
   uint8_t *bloom_bv;
Packit 631bab
   uint8_t bloom_nbits;
Packit 631bab
#endif
Packit 631bab
Packit 631bab
} UT_hash_table;
Packit 631bab
Packit 631bab
typedef struct UT_hash_handle {
Packit 631bab
   struct UT_hash_table *tbl;
Packit 631bab
   void *prev;                       /* prev element in app order      */
Packit 631bab
   void *next;                       /* next element in app order      */
Packit 631bab
   struct UT_hash_handle *hh_prev;   /* previous hh in bucket order    */
Packit 631bab
   struct UT_hash_handle *hh_next;   /* next hh in bucket order        */
Packit 631bab
   void *key;                        /* ptr to enclosing struct's key  */
Packit 631bab
   unsigned keylen;                  /* enclosing struct's key len     */
Packit 631bab
   unsigned hashv;                   /* result of hash-fcn(key)        */
Packit 631bab
} UT_hash_handle;
Packit 631bab
Packit 631bab
#endif /* UTHASH_H */