|
@@ -103,31 +103,12 @@ typedef unsigned char uint8_t;
|
|
/* calculate the element whose hash handle address is hhe */
|
|
/* calculate the element whose hash handle address is hhe */
|
|
#define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho)))
|
|
#define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho)))
|
|
|
|
|
|
-#define HASH_VALUE(keyptr,keylen,hashv) \
|
|
|
|
-do { \
|
|
|
|
- HASH_FCN(keyptr, keylen, hashv); \
|
|
|
|
-} while (0)
|
|
|
|
-
|
|
|
|
#define HASH_FIND(hh,head,keyptr,keylen,out) \
|
|
#define HASH_FIND(hh,head,keyptr,keylen,out) \
|
|
do { \
|
|
do { \
|
|
out=NULL; \
|
|
out=NULL; \
|
|
if (head != NULL) { \
|
|
if (head != NULL) { \
|
|
unsigned _hf_bkt,_hf_hashv; \
|
|
unsigned _hf_bkt,_hf_hashv; \
|
|
- HASH_FCN(keyptr, keylen, _hf_hashv); \
|
|
|
|
- HASH_TO_BKT(_hf_hashv, (head)->hh.tbl->num_buckets, _hf_bkt); \
|
|
|
|
- if (HASH_BLOOM_TEST((head)->hh.tbl, _hf_hashv) != 0) { \
|
|
|
|
- HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], \
|
|
|
|
- keyptr,keylen,out); \
|
|
|
|
- } \
|
|
|
|
- } \
|
|
|
|
-} while (0)
|
|
|
|
-
|
|
|
|
-#define HASH_FIND_BY_HASH_VALUE(hh,head,keyptr,keylen,_hf_hashv,out) \
|
|
|
|
-do { \
|
|
|
|
- out=NULL; \
|
|
|
|
- if (head != NULL) { \
|
|
|
|
- unsigned _hf_bkt; \
|
|
|
|
- HASH_TO_BKT(_hf_hashv, (head)->hh.tbl->num_buckets, _hf_bkt); \
|
|
|
|
|
|
+ HASH_FCN(keyptr,keylen, (head)->hh.tbl->num_buckets, _hf_hashv, _hf_bkt); \
|
|
if (HASH_BLOOM_TEST((head)->hh.tbl, _hf_hashv) != 0) { \
|
|
if (HASH_BLOOM_TEST((head)->hh.tbl, _hf_hashv) != 0) { \
|
|
HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], \
|
|
HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], \
|
|
keyptr,keylen,out); \
|
|
keyptr,keylen,out); \
|
|
@@ -191,24 +172,14 @@ do {
|
|
#define HASH_ADD(hh,head,fieldname,keylen_in,add) \
|
|
#define HASH_ADD(hh,head,fieldname,keylen_in,add) \
|
|
HASH_ADD_KEYPTR(hh,head,&((add)->fieldname),keylen_in,add)
|
|
HASH_ADD_KEYPTR(hh,head,&((add)->fieldname),keylen_in,add)
|
|
|
|
|
|
-#define HASH_ADD_BY_HASH_VALUE(hh,head,fieldname,keylen_in,hashval,add) \
|
|
|
|
- HASH_ADD_KEYPTR_BY_HASH_VALUE(hh,head,&((add)->fieldname),keylen_in,hashval,add)
|
|
|
|
-
|
|
|
|
#define HASH_REPLACE(hh,head,fieldname,keylen_in,add,replaced) \
|
|
#define HASH_REPLACE(hh,head,fieldname,keylen_in,add,replaced) \
|
|
-do { \
|
|
|
|
- unsigned _hr_hashv; \
|
|
|
|
- HASH_VALUE(&((add)->fieldname), keylen_in, _hr_hashv); \
|
|
|
|
- HASH_REPLACE_BY_HASH_VALUE(hh,head,fieldname,keylen_in,_hr_hashv,add,replaced);\
|
|
|
|
-} while(0)
|
|
|
|
-
|
|
|
|
-#define HASH_REPLACE_BY_HASH_VALUE(hh,head,fieldname,keylen_in,hashval,add,replaced) \
|
|
|
|
do { \
|
|
do { \
|
|
replaced=NULL; \
|
|
replaced=NULL; \
|
|
- HASH_FIND_BY_HASH_VALUE(hh,head,&((add)->fieldname),keylen_in,hashval,replaced); \
|
|
|
|
|
|
+ HASH_FIND(hh,head,&((add)->fieldname),keylen_in,replaced); \
|
|
if (replaced!=NULL) { \
|
|
if (replaced!=NULL) { \
|
|
HASH_DELETE(hh,head,replaced); \
|
|
HASH_DELETE(hh,head,replaced); \
|
|
} \
|
|
} \
|
|
- HASH_ADD_BY_HASH_VALUE(hh,head,fieldname,keylen_in,hashval,add); \
|
|
|
|
|
|
+ HASH_ADD(hh,head,fieldname,keylen_in,add); \
|
|
} while(0)
|
|
} while(0)
|
|
|
|
|
|
#define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add) \
|
|
#define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add) \
|
|
@@ -228,39 +199,14 @@ do {
|
|
} \
|
|
} \
|
|
(head)->hh.tbl->num_items++; \
|
|
(head)->hh.tbl->num_items++; \
|
|
(add)->hh.tbl = (head)->hh.tbl; \
|
|
(add)->hh.tbl = (head)->hh.tbl; \
|
|
- HASH_FCN(keyptr, keylen_in, (add)->hh.hashv); \
|
|
|
|
- HASH_TO_BKT((add)->hh.hashv, (head)->hh.tbl->num_buckets, _ha_bkt); \
|
|
|
|
|
|
+ HASH_FCN(keyptr,keylen_in, (head)->hh.tbl->num_buckets, \
|
|
|
|
+ (add)->hh.hashv, _ha_bkt); \
|
|
HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt],&(add)->hh); \
|
|
HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt],&(add)->hh); \
|
|
HASH_BLOOM_ADD((head)->hh.tbl,(add)->hh.hashv); \
|
|
HASH_BLOOM_ADD((head)->hh.tbl,(add)->hh.hashv); \
|
|
HASH_EMIT_KEY(hh,head,keyptr,keylen_in); \
|
|
HASH_EMIT_KEY(hh,head,keyptr,keylen_in); \
|
|
HASH_FSCK(hh,head); \
|
|
HASH_FSCK(hh,head); \
|
|
} while(0)
|
|
} while(0)
|
|
|
|
|
|
-#define HASH_ADD_KEYPTR_BY_HASH_VALUE(hh,head,keyptr,keylen_in,hashval,add) \
|
|
|
|
-do { \
|
|
|
|
- unsigned _ha_bkt; \
|
|
|
|
- (add)->hh.next = NULL; \
|
|
|
|
- (add)->hh.key = (char*)(keyptr); \
|
|
|
|
- (add)->hh.keylen = (unsigned)(keylen_in); \
|
|
|
|
- if (!(head)) { \
|
|
|
|
- head = (add); \
|
|
|
|
- (head)->hh.prev = NULL; \
|
|
|
|
- HASH_MAKE_TABLE(hh,head); \
|
|
|
|
- } else { \
|
|
|
|
- (head)->hh.tbl->tail->next = (add); \
|
|
|
|
- (add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail); \
|
|
|
|
- (head)->hh.tbl->tail = &((add)->hh); \
|
|
|
|
- } \
|
|
|
|
- (head)->hh.tbl->num_items++; \
|
|
|
|
- (add)->hh.tbl = (head)->hh.tbl; \
|
|
|
|
- (add)->hh.hashv = hashval; \
|
|
|
|
- HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _ha_bkt); \
|
|
|
|
- HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt],&(add)->hh); \
|
|
|
|
- HASH_BLOOM_ADD((head)->hh.tbl,hashval); \
|
|
|
|
- HASH_EMIT_KEY(hh,head,keyptr,keylen_in); \
|
|
|
|
- HASH_FSCK(hh,head); \
|
|
|
|
-} while(0)
|
|
|
|
-
|
|
|
|
#define HASH_TO_BKT( hashv, num_bkts, bkt ) \
|
|
#define HASH_TO_BKT( hashv, num_bkts, bkt ) \
|
|
do { \
|
|
do { \
|
|
bkt = ((hashv) & ((num_bkts) - 1U)); \
|
|
bkt = ((hashv) & ((num_bkts) - 1U)); \
|
|
@@ -418,7 +364,7 @@ do {
|
|
#endif
|
|
#endif
|
|
|
|
|
|
/* The Bernstein hash function, used in Perl prior to v5.6. Note (x<<5+x)=x*33. */
|
|
/* The Bernstein hash function, used in Perl prior to v5.6. Note (x<<5+x)=x*33. */
|
|
-#define HASH_BER(key,keylen,hashv) \
|
|
|
|
|
|
+#define HASH_BER(key,keylen,num_bkts,hashv,bkt) \
|
|
do { \
|
|
do { \
|
|
unsigned _hb_keylen=(unsigned)keylen; \
|
|
unsigned _hb_keylen=(unsigned)keylen; \
|
|
const unsigned char *_hb_key=(const unsigned char*)(key); \
|
|
const unsigned char *_hb_key=(const unsigned char*)(key); \
|
|
@@ -426,12 +372,13 @@ do {
|
|
while (_hb_keylen-- != 0U) { \
|
|
while (_hb_keylen-- != 0U) { \
|
|
(hashv) = (((hashv) << 5) + (hashv)) + *_hb_key++; \
|
|
(hashv) = (((hashv) << 5) + (hashv)) + *_hb_key++; \
|
|
} \
|
|
} \
|
|
|
|
+ bkt = (hashv) & (num_bkts-1U); \
|
|
} while (0)
|
|
} while (0)
|
|
|
|
|
|
|
|
|
|
/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at
|
|
/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at
|
|
* http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */
|
|
* http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */
|
|
-#define HASH_SAX(key,keylen,hashv) \
|
|
|
|
|
|
+#define HASH_SAX(key,keylen,num_bkts,hashv,bkt) \
|
|
do { \
|
|
do { \
|
|
unsigned _sx_i; \
|
|
unsigned _sx_i; \
|
|
const unsigned char *_hs_key=(const unsigned char*)(key); \
|
|
const unsigned char *_hs_key=(const unsigned char*)(key); \
|
|
@@ -439,9 +386,10 @@ do {
|
|
for(_sx_i=0; _sx_i < keylen; _sx_i++) { \
|
|
for(_sx_i=0; _sx_i < keylen; _sx_i++) { \
|
|
hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i]; \
|
|
hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i]; \
|
|
} \
|
|
} \
|
|
|
|
+ bkt = hashv & (num_bkts-1U); \
|
|
} while (0)
|
|
} while (0)
|
|
/* FNV-1a variation */
|
|
/* FNV-1a variation */
|
|
-#define HASH_FNV(key,keylen,hashv) \
|
|
|
|
|
|
+#define HASH_FNV(key,keylen,num_bkts,hashv,bkt) \
|
|
do { \
|
|
do { \
|
|
unsigned _fn_i; \
|
|
unsigned _fn_i; \
|
|
const unsigned char *_hf_key=(const unsigned char*)(key); \
|
|
const unsigned char *_hf_key=(const unsigned char*)(key); \
|
|
@@ -450,9 +398,10 @@ do {
|
|
hashv = hashv ^ _hf_key[_fn_i]; \
|
|
hashv = hashv ^ _hf_key[_fn_i]; \
|
|
hashv = hashv * 16777619U; \
|
|
hashv = hashv * 16777619U; \
|
|
} \
|
|
} \
|
|
|
|
+ bkt = hashv & (num_bkts-1U); \
|
|
} while(0)
|
|
} while(0)
|
|
|
|
|
|
-#define HASH_OAT(key,keylen,hashv) \
|
|
|
|
|
|
+#define HASH_OAT(key,keylen,num_bkts,hashv,bkt) \
|
|
do { \
|
|
do { \
|
|
unsigned _ho_i; \
|
|
unsigned _ho_i; \
|
|
const unsigned char *_ho_key=(const unsigned char*)(key); \
|
|
const unsigned char *_ho_key=(const unsigned char*)(key); \
|
|
@@ -465,6 +414,7 @@ do {
|
|
hashv += (hashv << 3); \
|
|
hashv += (hashv << 3); \
|
|
hashv ^= (hashv >> 11); \
|
|
hashv ^= (hashv >> 11); \
|
|
hashv += (hashv << 15); \
|
|
hashv += (hashv << 15); \
|
|
|
|
+ bkt = hashv & (num_bkts-1U); \
|
|
} while(0)
|
|
} while(0)
|
|
|
|
|
|
#define HASH_JEN_MIX(a,b,c) \
|
|
#define HASH_JEN_MIX(a,b,c) \
|
|
@@ -480,7 +430,7 @@ do {
|
|
c -= a; c -= b; c ^= ( b >> 15 ); \
|
|
c -= a; c -= b; c ^= ( b >> 15 ); \
|
|
} while (0)
|
|
} while (0)
|
|
|
|
|
|
-#define HASH_JEN(key,keylen,hashv) \
|
|
|
|
|
|
+#define HASH_JEN(key,keylen,num_bkts,hashv,bkt) \
|
|
do { \
|
|
do { \
|
|
unsigned _hj_i,_hj_j,_hj_k; \
|
|
unsigned _hj_i,_hj_j,_hj_k; \
|
|
unsigned const char *_hj_key=(unsigned const char*)(key); \
|
|
unsigned const char *_hj_key=(unsigned const char*)(key); \
|
|
@@ -518,6 +468,7 @@ do {
|
|
case 1: _hj_i += _hj_key[0]; \
|
|
case 1: _hj_i += _hj_key[0]; \
|
|
} \
|
|
} \
|
|
HASH_JEN_MIX(_hj_i, _hj_j, hashv); \
|
|
HASH_JEN_MIX(_hj_i, _hj_j, hashv); \
|
|
|
|
+ bkt = hashv & (num_bkts-1U); \
|
|
} while(0)
|
|
} while(0)
|
|
|
|
|
|
/* The Paul Hsieh hash function */
|
|
/* The Paul Hsieh hash function */
|
|
@@ -531,7 +482,7 @@ do {
|
|
#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) \
|
|
#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) \
|
|
+(uint32_t)(((const uint8_t *)(d))[0]) )
|
|
+(uint32_t)(((const uint8_t *)(d))[0]) )
|
|
#endif
|
|
#endif
|
|
-#define HASH_SFH(key,keylen,hashv) \
|
|
|
|
|
|
+#define HASH_SFH(key,keylen,num_bkts,hashv,bkt) \
|
|
do { \
|
|
do { \
|
|
unsigned const char *_sfh_key=(unsigned const char*)(key); \
|
|
unsigned const char *_sfh_key=(unsigned const char*)(key); \
|
|
uint32_t _sfh_tmp, _sfh_len = (uint32_t)keylen; \
|
|
uint32_t _sfh_tmp, _sfh_len = (uint32_t)keylen; \
|
|
@@ -572,6 +523,7 @@ do {
|
|
hashv += hashv >> 17; \
|
|
hashv += hashv >> 17; \
|
|
hashv ^= hashv << 25; \
|
|
hashv ^= hashv << 25; \
|
|
hashv += hashv >> 6; \
|
|
hashv += hashv >> 6; \
|
|
|
|
+ bkt = hashv & (num_bkts-1U); \
|
|
} while(0)
|
|
} while(0)
|
|
|
|
|
|
#ifdef HASH_USING_NO_STRICT_ALIASING
|
|
#ifdef HASH_USING_NO_STRICT_ALIASING
|
|
@@ -616,7 +568,7 @@ do { \
|
|
_h ^= _h >> 16; \
|
|
_h ^= _h >> 16; \
|
|
} while(0)
|
|
} while(0)
|
|
|
|
|
|
-#define HASH_MUR(key,keylen,hashv) \
|
|
|
|
|
|
+#define HASH_MUR(key,keylen,num_bkts,hashv,bkt) \
|
|
do { \
|
|
do { \
|
|
const uint8_t *_mur_data = (const uint8_t*)(key); \
|
|
const uint8_t *_mur_data = (const uint8_t*)(key); \
|
|
const int _mur_nblocks = (int)(keylen) / 4; \
|
|
const int _mur_nblocks = (int)(keylen) / 4; \
|
|
@@ -651,6 +603,7 @@ do { \
|
|
_mur_h1 ^= (uint32_t)(keylen); \
|
|
_mur_h1 ^= (uint32_t)(keylen); \
|
|
MUR_FMIX(_mur_h1); \
|
|
MUR_FMIX(_mur_h1); \
|
|
hashv = _mur_h1; \
|
|
hashv = _mur_h1; \
|
|
|
|
+ bkt = hashv & (num_bkts-1U); \
|
|
} while(0)
|
|
} while(0)
|
|
#endif /* HASH_USING_NO_STRICT_ALIASING */
|
|
#endif /* HASH_USING_NO_STRICT_ALIASING */
|
|
|
|
|