]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
consolidate fibonacci hashing in one place
authorEvan Hunt <each@isc.org>
Wed, 16 Mar 2022 20:23:02 +0000 (13:23 -0700)
committerEvan Hunt <each@isc.org>
Mon, 28 Mar 2022 21:44:21 +0000 (14:44 -0700)
Fibonacci hashing was implemented in four separate places (rbt.c,
rbtdb.c, resolver.c, zone.c). This commit combines them into a single
implementation. The hash_32() function is now replaced with
isc_hash_bits32().

lib/dns/name.c
lib/dns/rbt.c
lib/dns/rbtdb.c
lib/dns/resolver.c
lib/dns/zone.c
lib/isc/include/isc/hash.h

index f1939d27d10ef54cb53297d7bfa44b3d63107b4c..58cdc100a5de9c76c46c798a9b91d92cdf58d0b2 100644 (file)
@@ -466,7 +466,6 @@ dns_name_hash(const dns_name_t *name, bool case_sensitive) {
                length = 16;
        }
 
-       /* High bits are more random. */
        return (isc_hash32(name->ndata, length, case_sensitive));
 }
 
@@ -481,7 +480,6 @@ dns_name_fullhash(const dns_name_t *name, bool case_sensitive) {
                return (0);
        }
 
-       /* High bits are more random. */
        return (isc_hash32(name->ndata, name->length, case_sensitive));
 }
 
index 0bdaaf8a8aa2994710321a2dc8e654e5ade5a6a2..8cc2e3b1d86eb5aad8caa56ba88aef6b108a4b31 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <isc/crc64.h>
 #include <isc/file.h>
+#include <isc/hash.h>
 #include <isc/hex.h>
 #include <isc/mem.h>
 #include <isc/once.h>
 #define CHAIN_MAGIC       ISC_MAGIC('0', '-', '0', '-')
 #define VALID_CHAIN(chain) ISC_MAGIC_VALID(chain, CHAIN_MAGIC)
 
-#define RBT_HASH_NO_BITS    0
-#define RBT_HASH_MIN_BITS   4
-#define RBT_HASH_MAX_BITS   32
-#define RBT_HASH_OVERCOMMIT 3
-
 #define RBT_HASH_NEXTTABLE(hindex) ((hindex == 0) ? 1 : 0)
 
-#define GOLDEN_RATIO_32 0x61C88647
-
-#define HASHSIZE(bits) (UINT64_C(1) << (bits))
-
-static uint32_t
-hash_32(uint32_t val, unsigned int bits) {
-       REQUIRE(bits <= RBT_HASH_MAX_BITS);
-       /* High bits are more random. */
-       return (val * GOLDEN_RATIO_32 >> (32 - bits));
-}
-
 struct dns_rbt {
        unsigned int magic;
        isc_mem_t *mctx;
@@ -322,7 +307,7 @@ dns_rbt_create(isc_mem_t *mctx, dns_rbtdeleter_t deleter, void *deleter_arg,
 
        isc_mem_attach(mctx, &rbt->mctx);
 
-       hashtable_new(rbt, 0, RBT_HASH_MIN_BITS);
+       hashtable_new(rbt, 0, ISC_HASH_MIN_BITS);
 
        rbt->magic = RBT_MAGIC;
 
@@ -932,7 +917,7 @@ dns_rbt_findnode(dns_rbt_t *rbt, const dns_name_t *name, dns_name_t *foundname,
                         * by the computed hash value.
                         */
 
-                       hash = hash_32(hashval, rbt->hashbits[hindex]);
+                       hash = isc_hash_bits32(hashval, rbt->hashbits[hindex]);
 
                        for (hnode = rbt->hashtable[hindex][hash];
                             hnode != NULL; hnode = HASHNEXT(hnode))
@@ -1616,7 +1601,7 @@ hash_add_node(dns_rbt_t *rbt, dns_rbtnode_t *node, const dns_name_t *name) {
 
        HASHVAL(node) = dns_name_fullhash(name, false);
 
-       hash = hash_32(HASHVAL(node), rbt->hashbits[rbt->hindex]);
+       hash = isc_hash_bits32(HASHVAL(node), rbt->hashbits[rbt->hindex]);
        HASHNEXT(node) = rbt->hashtable[rbt->hindex][hash];
 
        rbt->hashtable[rbt->hindex][hash] = node;
@@ -1629,24 +1614,25 @@ static void
 hashtable_new(dns_rbt_t *rbt, uint8_t index, uint8_t bits) {
        size_t size;
 
-       REQUIRE(rbt->hashbits[index] == RBT_HASH_NO_BITS);
+       REQUIRE(rbt->hashbits[index] == 0U);
        REQUIRE(rbt->hashtable[index] == NULL);
-       REQUIRE(bits >= RBT_HASH_MIN_BITS);
-       REQUIRE(bits < RBT_HASH_MAX_BITS);
+       REQUIRE(bits >= ISC_HASH_MIN_BITS);
+       REQUIRE(bits < ISC_HASH_MAX_BITS);
 
        rbt->hashbits[index] = bits;
 
-       size = HASHSIZE(rbt->hashbits[index]) * sizeof(dns_rbtnode_t *);
+       size = ISC_HASHSIZE(rbt->hashbits[index]) * sizeof(dns_rbtnode_t *);
        rbt->hashtable[index] = isc_mem_get(rbt->mctx, size);
        memset(rbt->hashtable[index], 0, size);
 }
 
 static void
 hashtable_free(dns_rbt_t *rbt, uint8_t index) {
-       size_t size = HASHSIZE(rbt->hashbits[index]) * sizeof(dns_rbtnode_t *);
+       size_t size = ISC_HASHSIZE(rbt->hashbits[index]) *
+                     sizeof(dns_rbtnode_t *);
        isc_mem_put(rbt->mctx, rbt->hashtable[index], size);
 
-       rbt->hashbits[index] = RBT_HASH_NO_BITS;
+       rbt->hashbits[index] = 0U;
        rbt->hashtable[index] = NULL;
 }
 
@@ -1654,7 +1640,8 @@ static uint32_t
 rehash_bits(dns_rbt_t *rbt, size_t newcount) {
        uint32_t newbits = rbt->hashbits[rbt->hindex];
 
-       while (newcount >= HASHSIZE(newbits) && newbits < RBT_HASH_MAX_BITS) {
+       while (newcount >= ISC_HASHSIZE(newbits) && newbits < ISC_HASH_MAX_BITS)
+       {
                newbits += 1;
        }
 
@@ -1670,12 +1657,12 @@ hashtable_rehash(dns_rbt_t *rbt, uint32_t newbits) {
        uint32_t oldbits = rbt->hashbits[oldindex];
        uint8_t newindex = RBT_HASH_NEXTTABLE(oldindex);
 
-       REQUIRE(rbt->hashbits[oldindex] >= RBT_HASH_MIN_BITS);
-       REQUIRE(rbt->hashbits[oldindex] <= RBT_HASH_MAX_BITS);
+       REQUIRE(rbt->hashbits[oldindex] >= ISC_HASH_MIN_BITS);
+       REQUIRE(rbt->hashbits[oldindex] <= ISC_HASH_MAX_BITS);
        REQUIRE(rbt->hashtable[oldindex] != NULL);
 
-       REQUIRE(newbits <= RBT_HASH_MAX_BITS);
-       REQUIRE(rbt->hashbits[newindex] == RBT_HASH_NO_BITS);
+       REQUIRE(newbits <= ISC_HASH_MAX_BITS);
+       REQUIRE(rbt->hashbits[newindex] == 0U);
        REQUIRE(rbt->hashtable[newindex] == NULL);
 
        REQUIRE(newbits > oldbits);
@@ -1691,7 +1678,7 @@ static void
 hashtable_rehash_one(dns_rbt_t *rbt) {
        dns_rbtnode_t **newtable = rbt->hashtable[rbt->hindex];
        uint32_t oldsize =
-               HASHSIZE(rbt->hashbits[RBT_HASH_NEXTTABLE(rbt->hindex)]);
+               ISC_HASHSIZE(rbt->hashbits[RBT_HASH_NEXTTABLE(rbt->hindex)]);
        dns_rbtnode_t **oldtable =
                rbt->hashtable[RBT_HASH_NEXTTABLE(rbt->hindex)];
        dns_rbtnode_t *node = NULL;
@@ -1711,8 +1698,8 @@ hashtable_rehash_one(dns_rbt_t *rbt) {
 
        /* Move the first non-empty node from old hashtable to new hashtable */
        for (node = oldtable[rbt->hiter]; node != NULL; node = nextnode) {
-               uint32_t hash = hash_32(HASHVAL(node),
-                                       rbt->hashbits[rbt->hindex]);
+               uint32_t hash = isc_hash_bits32(HASHVAL(node),
+                                               rbt->hashbits[rbt->hindex]);
                nextnode = HASHNEXT(node);
                HASHNEXT(node) = newtable[hash];
                newtable[hash] = node;
@@ -1728,7 +1715,7 @@ maybe_rehash(dns_rbt_t *rbt, size_t newcount) {
        uint32_t newbits = rehash_bits(rbt, newcount);
 
        if (rbt->hashbits[rbt->hindex] < newbits &&
-           newbits <= RBT_HASH_MAX_BITS) {
+           newbits <= ISC_HASH_MAX_BITS) {
                hashtable_rehash(rbt, newbits);
        }
 }
@@ -1740,8 +1727,8 @@ rehashing_in_progress(dns_rbt_t *rbt) {
 
 static bool
 hashtable_is_overcommited(dns_rbt_t *rbt) {
-       return (rbt->nodecount >=
-               (HASHSIZE(rbt->hashbits[rbt->hindex]) * RBT_HASH_OVERCOMMIT));
+       return (rbt->nodecount >= (ISC_HASHSIZE(rbt->hashbits[rbt->hindex]) *
+                                  ISC_HASH_OVERCOMMIT));
 }
 
 /*
@@ -1781,7 +1768,7 @@ unhash_node(dns_rbt_t *rbt, dns_rbtnode_t *dnode) {
         *  c) other table: the node hasn't been moved yet.
         */
 nexttable:
-       hash = hash_32(HASHVAL(dnode), rbt->hashbits[hindex]);
+       hash = isc_hash_bits32(HASHVAL(dnode), rbt->hashbits[hindex]);
 
        hnode = rbt->hashtable[hindex][hash];
 
index 29dce2ed0213c8501920633f7fa94863d406bfb0..a4c9aec6a88efc4d8ac3944510bdf9936a4467ec 100644 (file)
@@ -309,20 +309,7 @@ typedef ISC_LIST(dns_rbtnode_t) rbtnodelist_t;
        (((header)->rdh_ttl > (now)) || \
         ((header)->rdh_ttl == (now) && ZEROTTL(header)))
 
-#define DEFAULT_NODE_LOCK_COUNT            7 /*%< Should be prime. */
-#define RBTDB_GLUE_TABLE_INIT_BITS  2U
-#define RBTDB_GLUE_TABLE_MAX_BITS   32U
-#define RBTDB_GLUE_TABLE_OVERCOMMIT 3
-
-#define GOLDEN_RATIO_32 0x61C88647
-#define HASHSIZE(bits) (UINT64_C(1) << (bits))
-
-static uint32_t
-hash_32(uint32_t val, unsigned int bits) {
-       REQUIRE(bits <= RBTDB_GLUE_TABLE_MAX_BITS);
-       /* High bits are more random. */
-       return (val * GOLDEN_RATIO_32 >> (32 - bits));
-}
+#define DEFAULT_NODE_LOCK_COUNT 7 /*%< Should be prime. */
 
 /*%
  * Number of buckets for cache DB entries (locks, LRU lists, TTL heaps).
@@ -1252,10 +1239,10 @@ allocate_version(isc_mem_t *mctx, rbtdb_serial_t serial,
        isc_refcount_init(&version->references, references);
        isc_rwlock_init(&version->glue_rwlock, 0, 0);
 
-       version->glue_table_bits = RBTDB_GLUE_TABLE_INIT_BITS;
+       version->glue_table_bits = ISC_HASH_MIN_BITS;
        version->glue_table_nodecount = 0U;
 
-       size = HASHSIZE(version->glue_table_bits) *
+       size = ISC_HASHSIZE(version->glue_table_bits) *
               sizeof(version->glue_table[0]);
        version->glue_table = isc_mem_get(mctx, size);
        memset(version->glue_table, 0, size);
@@ -9494,7 +9481,7 @@ free_gluetable(rbtdb_version_t *version) {
 
        rbtdb = version->rbtdb;
 
-       for (i = 0; i < HASHSIZE(version->glue_table_bits); i++) {
+       for (i = 0; i < ISC_HASHSIZE(version->glue_table_bits); i++) {
                rbtdb_glue_table_node_t *cur, *cur_next;
 
                cur = version->glue_table[i];
@@ -9510,7 +9497,7 @@ free_gluetable(rbtdb_version_t *version) {
                version->glue_table[i] = NULL;
        }
 
-       size = HASHSIZE(version->glue_table_bits) *
+       size = ISC_HASHSIZE(version->glue_table_bits) *
               sizeof(*version->glue_table);
        isc_mem_put(rbtdb->common.mctx, version->glue_table, size);
 
@@ -9522,8 +9509,8 @@ rehash_bits(rbtdb_version_t *version, size_t newcount) {
        uint32_t oldbits = version->glue_table_bits;
        uint32_t newbits = oldbits;
 
-       while (newcount >= HASHSIZE(newbits) &&
-              newbits <= RBTDB_GLUE_TABLE_MAX_BITS) {
+       while (newcount >= ISC_HASHSIZE(newbits) &&
+              newbits <= ISC_HASH_MAX_BITS) {
                newbits += 1;
        }
 
@@ -9540,11 +9527,11 @@ rehash_gluetable(rbtdb_version_t *version) {
        rbtdb_glue_table_node_t **oldtable;
 
        oldbits = version->glue_table_bits;
-       oldcount = HASHSIZE(oldbits);
+       oldcount = ISC_HASHSIZE(oldbits);
        oldtable = version->glue_table;
 
        newbits = rehash_bits(version, version->glue_table_nodecount);
-       newsize = HASHSIZE(newbits) * sizeof(version->glue_table[0]);
+       newsize = ISC_HASHSIZE(newbits) * sizeof(version->glue_table[0]);
 
        version->glue_table = isc_mem_get(version->rbtdb->common.mctx, newsize);
        version->glue_table_bits = newbits;
@@ -9557,7 +9544,7 @@ rehash_gluetable(rbtdb_version_t *version) {
                     gluenode = nextgluenode) {
                        uint32_t hash = isc_hash32(
                                &gluenode->node, sizeof(gluenode->node), true);
-                       uint32_t idx = hash_32(hash, newbits);
+                       uint32_t idx = isc_hash_bits32(hash, newbits);
                        nextgluenode = gluenode->next;
                        gluenode->next = version->glue_table[idx];
                        version->glue_table[idx] = gluenode;
@@ -9577,8 +9564,8 @@ rehash_gluetable(rbtdb_version_t *version) {
 
 static void
 maybe_rehash_gluetable(rbtdb_version_t *version) {
-       size_t overcommit = HASHSIZE(version->glue_table_bits) *
-                           RBTDB_GLUE_TABLE_OVERCOMMIT;
+       size_t overcommit = ISC_HASHSIZE(version->glue_table_bits) *
+                           ISC_HASH_OVERCOMMIT;
        if (version->glue_table_nodecount < overcommit) {
                return;
        }
@@ -9740,7 +9727,7 @@ restart:
         */
        RWLOCK(&rbtversion->glue_rwlock, isc_rwlocktype_read);
 
-       idx = hash_32(hash, rbtversion->glue_table_bits);
+       idx = isc_hash_bits32(hash, rbtversion->glue_table_bits);
 
        for (cur = rbtversion->glue_table[idx]; cur != NULL; cur = cur->next) {
                if (cur->node == node) {
@@ -9901,7 +9888,7 @@ no_glue:
        RWLOCK(&rbtversion->glue_rwlock, isc_rwlocktype_write);
 
        maybe_rehash_gluetable(rbtversion);
-       idx = hash_32(hash, rbtversion->glue_table_bits);
+       idx = isc_hash_bits32(hash, rbtversion->glue_table_bits);
 
        (void)dns_rdataset_additionaldata(rdataset, dns_rootname,
                                          glue_nsdname_cb, &ctx);
index 686eb0a489d77564f4f52625f7d01160947e807e..53f3c2fa92cac78f7dba689f1ed4fb4ed15b0264 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <isc/atomic.h>
 #include <isc/counter.h>
+#include <isc/hash.h>
 #include <isc/log.h>
 #include <isc/print.h>
 #include <isc/random.h>
 #endif /* ifndef RES_DOMAIN_HASH_BITS */
 #define RES_NOBUCKET 0xffffffff
 
-#define GOLDEN_RATIO_32 0x61C88647
-
-#define HASHSIZE(bits) (UINT64_C(1) << (bits))
-
-#define RES_DOMAIN_MAX_BITS   32
-#define RES_DOMAIN_OVERCOMMIT 3
-
 #define RES_DOMAIN_NEXTTABLE(hindex) ((hindex == 0) ? 1 : 0)
 
-static uint32_t
-hash_32(uint32_t val, unsigned int bits) {
-       REQUIRE(bits <= RES_DOMAIN_MAX_BITS);
-       /* High bits are more random. */
-       return (val * GOLDEN_RATIO_32 >> (32 - bits));
-}
-
 /*%
  * Maximum EDNS0 input packet size.
  */
@@ -1578,7 +1565,7 @@ fcount_incr(fetchctx_t *fctx, bool force) {
 
        INSIST(fctx->dbucketnum == RES_NOBUCKET);
        hashval = dns_name_fullhash(fctx->domain, false);
-       dbucketnum = hash_32(hashval, fctx->res->dhashbits);
+       dbucketnum = isc_hash_bits32(hashval, fctx->res->dhashbits);
 
        dbucket = &fctx->res->dbuckets[dbucketnum];
 
@@ -10108,12 +10095,12 @@ destroy(dns_resolver_t *res) {
        }
        isc_mem_put(res->mctx, res->buckets,
                    res->nbuckets * sizeof(fctxbucket_t));
-       for (i = 0; i < HASHSIZE(res->dhashbits); i++) {
+       for (i = 0; i < ISC_HASHSIZE(res->dhashbits); i++) {
                INSIST(ISC_LIST_EMPTY(res->dbuckets[i].list));
                isc_mutex_destroy(&res->dbuckets[i].lock);
        }
        isc_mem_put(res->mctx, res->dbuckets,
-                   HASHSIZE(res->dhashbits) * sizeof(zonebucket_t));
+                   ISC_HASHSIZE(res->dhashbits) * sizeof(zonebucket_t));
        if (res->dispatches4 != NULL) {
                dns_dispatchset_destroy(&res->dispatches4);
        }
@@ -10285,9 +10272,9 @@ dns_resolver_create(dns_view_t *view, isc_taskmgr_t *taskmgr,
        }
 
        res->dbuckets = isc_mem_get(view->mctx,
-                                   HASHSIZE(res->dhashbits) *
+                                   ISC_HASHSIZE(res->dhashbits) *
                                            sizeof(res->dbuckets[0]));
-       for (size_t i = 0; i < HASHSIZE(res->dhashbits); i++) {
+       for (size_t i = 0; i < ISC_HASHSIZE(res->dhashbits); i++) {
                res->dbuckets[i] = (zonebucket_t){ .list = { 0 } };
                ISC_LIST_INIT(res->dbuckets[i].list);
                isc_mutex_init(&res->dbuckets[i].lock);
@@ -10333,11 +10320,11 @@ cleanup_primelock:
                dns_dispatchset_destroy(&res->dispatches4);
        }
 
-       for (size_t i = 0; i < HASHSIZE(res->dhashbits); i++) {
+       for (size_t i = 0; i < ISC_HASHSIZE(res->dhashbits); i++) {
                isc_mutex_destroy(&res->dbuckets[i].lock);
        }
        isc_mem_put(view->mctx, res->dbuckets,
-                   HASHSIZE(res->dhashbits) * sizeof(zonebucket_t));
+                   ISC_HASHSIZE(res->dhashbits) * sizeof(zonebucket_t));
 
 cleanup_buckets:
        for (size_t i = 0; i < ntasks; i++) {
@@ -11518,7 +11505,7 @@ dns_resolver_dumpfetches(dns_resolver_t *resolver, isc_statsformat_t format,
        REQUIRE(fp != NULL);
        REQUIRE(format == isc_statsformat_file);
 
-       for (size_t i = 0; i < HASHSIZE(resolver->dhashbits); i++) {
+       for (size_t i = 0; i < ISC_HASHSIZE(resolver->dhashbits); i++) {
                fctxcount_t *fc;
                LOCK(&resolver->dbuckets[i].lock);
                for (fc = ISC_LIST_HEAD(resolver->dbuckets[i].list); fc != NULL;
index baa4b0abe2b0619d8361c2aaea8d3df501636f34..31443d68157bc8dd59e9c4e5be96c28534612e05 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <isc/atomic.h>
 #include <isc/file.h>
+#include <isc/hash.h>
 #include <isc/hex.h>
 #include <isc/md.h>
 #include <isc/mutex.h>
@@ -18504,26 +18505,10 @@ dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first) {
  ***   Zone manager.
  ***/
 
-#define KEYMGMT_OVERCOMMIT 3
-#define KEYMGMT_BITS_MIN   2U
-#define KEYMGMT_BITS_MAX   32U
-
-/*
- * WMM: Static hash functions copied from lib/dns/rbtdb.c. Should be moved to
- * lib/isc/hash.c when we refactor the hash table code.
- */
-#define GOLDEN_RATIO_32 0x61C88647
-#define HASHSIZE(bits) (UINT64_C(1) << (bits))
-
-static uint32_t
-hash_index(uint32_t val, uint32_t bits) {
-       return (val * GOLDEN_RATIO_32 >> (32 - bits));
-}
-
 static uint32_t
 hash_bits_grow(uint32_t bits, uint32_t count) {
        uint32_t newbits = bits;
-       while (count >= HASHSIZE(newbits) && newbits < KEYMGMT_BITS_MAX) {
+       while (count >= ISC_HASHSIZE(newbits) && newbits < ISC_HASH_MAX_BITS) {
                newbits++;
        }
        return (newbits);
@@ -18532,7 +18517,7 @@ hash_bits_grow(uint32_t bits, uint32_t count) {
 static uint32_t
 hash_bits_shrink(uint32_t bits, uint32_t count) {
        uint32_t newbits = bits;
-       while (count <= HASHSIZE(newbits) && newbits > KEYMGMT_BITS_MIN) {
+       while (count <= ISC_HASHSIZE(newbits) && newbits > ISC_HASH_MIN_BITS) {
                newbits--;
        }
        return (newbits);
@@ -18544,12 +18529,12 @@ zonemgr_keymgmt_init(dns_zonemgr_t *zmgr) {
        uint32_t size;
 
        *mgmt = (dns_keymgmt_t){
-               .bits = KEYMGMT_BITS_MIN,
+               .bits = ISC_HASH_MIN_BITS,
        };
        isc_mem_attach(zmgr->mctx, &mgmt->mctx);
        isc_rwlock_init(&mgmt->lock, 0, 0);
 
-       size = HASHSIZE(mgmt->bits);
+       size = ISC_HASHSIZE(mgmt->bits);
        mgmt->table = isc_mem_get(mgmt->mctx, sizeof(*mgmt->table) * size);
        memset(mgmt->table, 0, size * sizeof(mgmt->table[0]));
 
@@ -18568,7 +18553,7 @@ zonemgr_keymgmt_destroy(dns_zonemgr_t *zmgr) {
        REQUIRE(DNS_KEYMGMT_VALID(mgmt));
 
        RWLOCK(&mgmt->lock, isc_rwlocktype_write);
-       size = HASHSIZE(mgmt->bits);
+       size = ISC_HASHSIZE(mgmt->bits);
        for (unsigned int i = 0;
             atomic_load_relaxed(&mgmt->count) > 0 && i < size; i++) {
                for (curr = mgmt->table[i]; curr != NULL; curr = next) {
@@ -18601,10 +18586,10 @@ zonemgr_keymgmt_resize(dns_zonemgr_t *zmgr) {
        bits = mgmt->bits;
        RWUNLOCK(&mgmt->lock, isc_rwlocktype_read);
 
-       size = HASHSIZE(bits);
+       size = ISC_HASHSIZE(bits);
        INSIST(size > 0);
 
-       if (count >= (size * KEYMGMT_OVERCOMMIT)) {
+       if (count >= (size * ISC_HASH_OVERCOMMIT)) {
                grow = true;
        } else if (count < (size / 2)) {
                grow = false;
@@ -18627,7 +18612,7 @@ zonemgr_keymgmt_resize(dns_zonemgr_t *zmgr) {
                return;
        }
 
-       newsize = HASHSIZE(newbits);
+       newsize = ISC_HASHSIZE(newbits);
        INSIST(newsize > 0);
 
        RWLOCK(&mgmt->lock, isc_rwlocktype_write);
@@ -18638,7 +18623,7 @@ zonemgr_keymgmt_resize(dns_zonemgr_t *zmgr) {
        for (unsigned int i = 0; i < size; i++) {
                dns_keyfileio_t *kfio, *next;
                for (kfio = mgmt->table[i]; kfio != NULL; kfio = next) {
-                       uint32_t hash = hash_index(kfio->hashval, newbits);
+                       uint32_t hash = isc_hash_bits32(kfio->hashval, newbits);
                        next = kfio->next;
                        kfio->next = newtable[hash];
                        newtable[hash] = kfio;
@@ -18665,7 +18650,7 @@ zonemgr_keymgmt_add(dns_zonemgr_t *zmgr, dns_zone_t *zone,
        RWLOCK(&mgmt->lock, isc_rwlocktype_write);
 
        hashval = dns_name_hash(&zone->origin, false);
-       hash = hash_index(hashval, mgmt->bits);
+       hash = isc_hash_bits32(hashval, mgmt->bits);
 
        for (kfio = mgmt->table[hash]; kfio != NULL; kfio = next) {
                next = kfio->next;
@@ -18718,7 +18703,7 @@ zonemgr_keymgmt_delete(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
        RWLOCK(&mgmt->lock, isc_rwlocktype_write);
 
        hashval = dns_name_hash(&zone->origin, false);
-       hash = hash_index(hashval, mgmt->bits);
+       hash = isc_hash_bits32(hashval, mgmt->bits);
 
        prev = NULL;
        for (kfio = mgmt->table[hash]; kfio != NULL; kfio = next) {
@@ -18776,7 +18761,7 @@ zonemgr_keymgmt_find(dns_zonemgr_t *zmgr, dns_zone_t *zone,
        }
 
        hashval = dns_name_hash(&zone->origin, false);
-       hash = hash_index(hashval, mgmt->bits);
+       hash = isc_hash_bits32(hashval, mgmt->bits);
 
        for (kfio = mgmt->table[hash]; kfio != NULL; kfio = next) {
                next = kfio->next;
index ee9e74f2d919ac145a0c7ec2d109fb37ea019746..80e50da83d7754fe719ad31c1ee03333833a3ab3 100644 (file)
 #include <inttypes.h>
 #include <stdbool.h>
 
-#include "isc/lang.h"
-#include "isc/types.h"
+#include <isc/assertions.h>
+#include <isc/lang.h>
+#include <isc/types.h>
+
+#define ISC_HASHSIZE(bits)  (UINT64_C(1) << (bits))
+#define ISC_HASH_OVERCOMMIT 3
+#define ISC_HASH_MIN_BITS   2U
+#define ISC_HASH_MAX_BITS   32U
 
 /***
  *** Functions
@@ -60,4 +66,26 @@ isc_hash64(const void *data, const size_t length, const bool case_sensitive);
  * \li 32 or 64-bit hash value
  */
 
+/*!
+ * \brief Return a hash value of a specified number of bits
+ *
+ * This function uses Fibonacci Hashing to convert a 32 bit hash value
+ * 'val' into a smaller hash value of up to 'bits' bits. This results
+ * in better hash table distribution than the use of modulo.
+ *
+ * Requires:
+ * \li 'bits' is less than 32.
+ *
+ * Returns:
+ * \li a hash value of length 'bits'.
+ */
+#define ISC_HASH_GOLDENRATIO_32 0x61C88647
+#define isc_hash_bits32(val, bits)                                      \
+       ({                                                              \
+               REQUIRE(bits <= 32U);                                   \
+               uint32_t __v = (val & 0xffff);                          \
+               __v = ((__v * ISC_HASH_GOLDENRATIO_32) >> (32 - bits)); \
+               __v;                                                    \
+       })
+
 ISC_LANG_ENDDECLS