Переглянути джерело

Revert "Add HASH_VALUE and HASH_FIND_BY_HASH_VALUE primitives; breaking change to HASH_FCN"

Troy D. Hanson 9 роки тому
батько
коміт
f866eaf886
2 змінених файлів з 31 додано та 88 видалено
  1. 12 22
      doc/userguide.txt
  2. 19 66
      src/uthash.h

+ 12 - 22
doc/userguide.txt

@@ -1712,23 +1712,18 @@ than `hh`, or if your key's data type isn't `int` or `char[]`.
 .General macros
 [width="90%",cols="10m,30m",grid="none",options="header"]
 |===============================================================================
-|macro                        | arguments
-|HASH_ADD                     | (hh_name, head, keyfield_name, key_len, item_ptr)
-|HASH_ADD_BY_HASH_VALUE       | (hh_name, head, keyfield_name, key_len, key_hash, item_ptr)
-|HASH_ADD_KEYPTR              | (hh_name, head, key_ptr, key_len, item_ptr)
-|HASH_ADD_KEYPTR_BY_HASH_VALUE| (hh_name, head, key_ptr, key_len, key_hash, item_ptr)
-|HASH_REPLACE                 | (hh_name, head, keyfield_name, key_len, item_ptr, replaced_item_ptr)
-|HASH_REPLACE_BY_HASH_VALUE   | (hh_name, head, keyfield_name, key_len, key_hash, item_ptr, replaced_item_ptr)
-|HASH_FIND                    | (hh_name, head, key_ptr, key_len, item_ptr)
-|HASH_FIND_BY_HASH_VALUE      | (hh_name, head, key_ptr, key_len, key_hash, item_ptr)
-|HASH_DELETE                  | (hh_name, head, item_ptr)
-|HASH_VALUE                   | (key_ptr, key_len, key_hash)
-|HASH_SRT                     | (hh_name, head, cmp)
-|HASH_CNT                     | (hh_name, head)
-|HASH_CLEAR                   | (hh_name, head)
-|HASH_SELECT                  | (dst_hh_name, dst_head, src_hh_name, src_head, condition)
-|HASH_ITER                    | (hh_name, head, item_ptr, tmp_item_ptr)
-|HASH_OVERHEAD                | (hh_name, head)
+|macro          | arguments
+|HASH_ADD       | (hh_name, head, keyfield_name, key_len, item_ptr)
+|HASH_ADD_KEYPTR| (hh_name, head, key_ptr, key_len, item_ptr)
+|HASH_REPLACE   | (hh_name, head, keyfield_name, key_len, item_ptr, replaced_item_ptr)
+|HASH_FIND      | (hh_name, head, key_ptr, key_len, item_ptr)
+|HASH_DELETE    | (hh_name, head, item_ptr)
+|HASH_SRT       | (hh_name, head, cmp)
+|HASH_CNT       | (hh_name, head)
+|HASH_CLEAR     | (hh_name, head)
+|HASH_SELECT    | (dst_hh_name, dst_head, src_hh_name, src_head, condition)
+|HASH_ITER      | (hh_name, head, item_ptr, tmp_item_ptr)
+|HASH_OVERHEAD  | (hh_name, head)
 |===============================================================================
 
 [NOTE]
@@ -1757,11 +1752,6 @@ key_ptr::
     for `HASH_FIND`, this is a pointer to the key to look up in the hash
     (since it's a pointer, you can't directly pass a literal value here). For
     `HASH_ADD_KEYPTR`, this is the address of the key of the item being added.
-key_hash::
-    the hash value of the provided key. This is an input parameter for the
-    `..._BY_HASH_VALUE` macros, and an output parameter for `HASH_VALUE`.
-    Reusing a cached hash value can be a performance optimization if
-    you're going to do repeated lookups for the same key.
 item_ptr::
     pointer to the structure being added, deleted, or looked up, or the current
     pointer during iteration. This is an input parameter for `HASH_ADD` and

+ 19 - 66
src/uthash.h

@@ -103,31 +103,12 @@ typedef unsigned char uint8_t;
 /* calculate the element whose hash handle address is hhe */
 #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)                                     \
 do {                                                                             \
   out=NULL;                                                                      \
   if (head != NULL) {                                                            \
      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) {                      \
        HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ],  \
                         keyptr,keylen,out);                                      \
@@ -191,24 +172,14 @@ do {
 #define HASH_ADD(hh,head,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)                   \
-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 {                                                                             \
   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) {                                                          \
      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)
 
 #define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add)                            \
@@ -228,39 +199,14 @@ do {
  }                                                                               \
  (head)->hh.tbl->num_items++;                                                    \
  (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_BLOOM_ADD((head)->hh.tbl,(add)->hh.hashv);                                 \
  HASH_EMIT_KEY(hh,head,keyptr,keylen_in);                                        \
  HASH_FSCK(hh,head);                                                             \
 } 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 )                                      \
 do {                                                                             \
   bkt = ((hashv) & ((num_bkts) - 1U));                                           \
@@ -418,7 +364,7 @@ do {
 #endif
 
 /* 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 {                                                                             \
   unsigned _hb_keylen=(unsigned)keylen;                                          \
   const unsigned char *_hb_key=(const unsigned char*)(key);                      \
@@ -426,12 +372,13 @@ do {
   while (_hb_keylen-- != 0U) {                                                   \
       (hashv) = (((hashv) << 5) + (hashv)) + *_hb_key++;                         \
   }                                                                              \
+  bkt = (hashv) & (num_bkts-1U);                                                 \
 } while (0)
 
 
 /* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at
  * 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 {                                                                             \
   unsigned _sx_i;                                                                \
   const unsigned char *_hs_key=(const unsigned char*)(key);                      \
@@ -439,9 +386,10 @@ do {
   for(_sx_i=0; _sx_i < keylen; _sx_i++) {                                        \
       hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i];                     \
   }                                                                              \
+  bkt = hashv & (num_bkts-1U);                                                   \
 } while (0)
 /* FNV-1a variation */
-#define HASH_FNV(key,keylen,hashv)                                               \
+#define HASH_FNV(key,keylen,num_bkts,hashv,bkt)                                  \
 do {                                                                             \
   unsigned _fn_i;                                                                \
   const unsigned char *_hf_key=(const unsigned char*)(key);                      \
@@ -450,9 +398,10 @@ do {
       hashv = hashv ^ _hf_key[_fn_i];                                            \
       hashv = hashv * 16777619U;                                                 \
   }                                                                              \
+  bkt = hashv & (num_bkts-1U);                                                   \
 } while(0)
 
-#define HASH_OAT(key,keylen,hashv)                                               \
+#define HASH_OAT(key,keylen,num_bkts,hashv,bkt)                                  \
 do {                                                                             \
   unsigned _ho_i;                                                                \
   const unsigned char *_ho_key=(const unsigned char*)(key);                      \
@@ -465,6 +414,7 @@ do {
   hashv += (hashv << 3);                                                         \
   hashv ^= (hashv >> 11);                                                        \
   hashv += (hashv << 15);                                                        \
+  bkt = hashv & (num_bkts-1U);                                                   \
 } while(0)
 
 #define HASH_JEN_MIX(a,b,c)                                                      \
@@ -480,7 +430,7 @@ do {
   c -= a; c -= b; c ^= ( b >> 15 );                                              \
 } while (0)
 
-#define HASH_JEN(key,keylen,hashv)                                               \
+#define HASH_JEN(key,keylen,num_bkts,hashv,bkt)                                  \
 do {                                                                             \
   unsigned _hj_i,_hj_j,_hj_k;                                                    \
   unsigned const char *_hj_key=(unsigned const char*)(key);                      \
@@ -518,6 +468,7 @@ do {
      case 1:  _hj_i += _hj_key[0];                                               \
   }                                                                              \
   HASH_JEN_MIX(_hj_i, _hj_j, hashv);                                             \
+  bkt = hashv & (num_bkts-1U);                                                   \
 } while(0)
 
 /* The Paul Hsieh hash function */
@@ -531,7 +482,7 @@ do {
 #define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)             \
                        +(uint32_t)(((const uint8_t *)(d))[0]) )
 #endif
-#define HASH_SFH(key,keylen,hashv)                                               \
+#define HASH_SFH(key,keylen,num_bkts,hashv,bkt)                                  \
 do {                                                                             \
   unsigned const char *_sfh_key=(unsigned const char*)(key);                     \
   uint32_t _sfh_tmp, _sfh_len = (uint32_t)keylen;                                \
@@ -572,6 +523,7 @@ do {
     hashv += hashv >> 17;                                                        \
     hashv ^= hashv << 25;                                                        \
     hashv += hashv >> 6;                                                         \
+    bkt = hashv & (num_bkts-1U);                                                 \
 } while(0)
 
 #ifdef HASH_USING_NO_STRICT_ALIASING
@@ -616,7 +568,7 @@ do {                 \
   _h ^= _h >> 16;    \
 } while(0)
 
-#define HASH_MUR(key,keylen,hashv)                                     \
+#define HASH_MUR(key,keylen,num_bkts,hashv,bkt)                        \
 do {                                                                   \
   const uint8_t *_mur_data = (const uint8_t*)(key);                    \
   const int _mur_nblocks = (int)(keylen) / 4;                          \
@@ -651,6 +603,7 @@ do {                                                                   \
   _mur_h1 ^= (uint32_t)(keylen);                                       \
   MUR_FMIX(_mur_h1);                                                   \
   hashv = _mur_h1;                                                     \
+  bkt = hashv & (num_bkts-1U);                                         \
 } while(0)
 #endif  /* HASH_USING_NO_STRICT_ALIASING */