Blame intel/uthash.h

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