mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
Merge branch 'each-consolidate-fibonacci-hashing' into 'main'
consolidate fibonacci hashing and support case-insensitive hash tables See merge request isc-projects/bind9!6035
This commit is contained in:
commit
bb61a3a90a
15 changed files with 120 additions and 154 deletions
|
|
@ -347,7 +347,7 @@ plugin_register(const char *parameters, const void *cfg, const char *cfg_file,
|
|||
cfg_line, mctx, lctx, actx));
|
||||
}
|
||||
|
||||
isc_ht_init(&inst->ht, mctx, 16);
|
||||
isc_ht_init(&inst->ht, mctx, 1, ISC_HT_CASE_SENSITIVE);
|
||||
isc_mutex_init(&inst->hlock);
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -350,7 +350,7 @@ plugin_register(const char *parameters, const void *cfg, const char *cfg_file,
|
|||
cfg_line, mctx, lctx, actx));
|
||||
}
|
||||
|
||||
isc_ht_init(&inst->ht, mctx, 16);
|
||||
isc_ht_init(&inst->ht, mctx, 1, ISC_HT_CASE_SENSITIVE);
|
||||
isc_mutex_init(&inst->hlock);
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ plugin_register(const char *parameters, const void *cfg, const char *cfg_file,
|
|||
*inst = (async_instance_t){ .mctx = NULL };
|
||||
isc_mem_attach(mctx, &inst->mctx);
|
||||
|
||||
isc_ht_init(&inst->ht, mctx, 16);
|
||||
isc_ht_init(&inst->ht, mctx, 1, ISC_HT_CASE_SENSITIVE);
|
||||
isc_mutex_init(&inst->hlock);
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -392,9 +392,9 @@ dns_catz_zones_merge(dns_catz_zone_t *target, dns_catz_zone_t *newzone) {
|
|||
|
||||
dns_name_format(&target->name, czname, DNS_NAME_FORMATSIZE);
|
||||
|
||||
isc_ht_init(&toadd, target->catzs->mctx, 16);
|
||||
isc_ht_init(&toadd, target->catzs->mctx, 1, ISC_HT_CASE_SENSITIVE);
|
||||
|
||||
isc_ht_init(&tomod, target->catzs->mctx, 16);
|
||||
isc_ht_init(&tomod, target->catzs->mctx, 1, ISC_HT_CASE_SENSITIVE);
|
||||
|
||||
isc_ht_iter_create(newzone->entries, &iter1);
|
||||
|
||||
|
|
@ -579,7 +579,7 @@ dns_catz_new_zones(dns_catz_zones_t **catzsp, dns_catz_zonemodmethods_t *zmm,
|
|||
|
||||
isc_refcount_init(&new_zones->refs, 1);
|
||||
|
||||
isc_ht_init(&new_zones->zones, mctx, 4);
|
||||
isc_ht_init(&new_zones->zones, mctx, 4, ISC_HT_CASE_SENSITIVE);
|
||||
|
||||
isc_mem_attach(mctx, &new_zones->mctx);
|
||||
new_zones->zmm = zmm;
|
||||
|
|
@ -630,7 +630,7 @@ dns_catz_new_zone(dns_catz_zones_t *catzs, dns_catz_zone_t **zonep,
|
|||
dns_name_init(&new_zone->name, NULL);
|
||||
dns_name_dup(name, catzs->mctx, &new_zone->name);
|
||||
|
||||
isc_ht_init(&new_zone->entries, catzs->mctx, 4);
|
||||
isc_ht_init(&new_zone->entries, catzs->mctx, 4, ISC_HT_CASE_SENSITIVE);
|
||||
|
||||
new_zone->updatetimer = NULL;
|
||||
isc_timer_create(catzs->timermgr, catzs->updater,
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -60,24 +61,8 @@
|
|||
#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];
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -211,22 +212,8 @@
|
|||
#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;
|
||||
|
|
|
|||
|
|
@ -1530,7 +1530,7 @@ dns_rpz_new_zone(dns_rpz_zones_t *rpzs, dns_rpz_zone_t **rpzp) {
|
|||
* simplifies update_from_db
|
||||
*/
|
||||
|
||||
isc_ht_init(&zone->nodes, rpzs->mctx, 1);
|
||||
isc_ht_init(&zone->nodes, rpzs->mctx, 1, ISC_HT_CASE_SENSITIVE);
|
||||
|
||||
dns_name_init(&zone->origin, NULL);
|
||||
dns_name_init(&zone->client_ip, NULL);
|
||||
|
|
@ -1676,30 +1676,12 @@ static isc_result_t
|
|||
setup_update(dns_rpz_zone_t *rpz) {
|
||||
isc_result_t result;
|
||||
char domain[DNS_NAME_FORMATSIZE];
|
||||
unsigned int nodecount;
|
||||
uint32_t hashsize;
|
||||
|
||||
dns_name_format(&rpz->origin, domain, DNS_NAME_FORMATSIZE);
|
||||
isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_MASTER,
|
||||
ISC_LOG_INFO, "rpz: %s: reload start", domain);
|
||||
|
||||
nodecount = dns_db_nodecount(rpz->updb, dns_dbtree_main);
|
||||
hashsize = 1;
|
||||
while (nodecount != 0 &&
|
||||
hashsize <= (DNS_RPZ_HTSIZE_MAX + DNS_RPZ_HTSIZE_DIV)) {
|
||||
hashsize++;
|
||||
nodecount >>= 1;
|
||||
}
|
||||
|
||||
if (hashsize > DNS_RPZ_HTSIZE_DIV) {
|
||||
hashsize -= DNS_RPZ_HTSIZE_DIV;
|
||||
}
|
||||
|
||||
isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_MASTER,
|
||||
ISC_LOG_DEBUG(1), "rpz: %s: using hashtable size %d",
|
||||
domain, hashsize);
|
||||
|
||||
isc_ht_init(&rpz->newnodes, rpz->rpzs->mctx, hashsize);
|
||||
isc_ht_init(&rpz->newnodes, rpz->rpzs->mctx, 1, ISC_HT_CASE_SENSITIVE);
|
||||
|
||||
result = dns_db_createiterator(rpz->updb, DNS_DB_NONSEC3, &rpz->updbit);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
15
lib/isc/ht.c
15
lib/isc/ht.c
|
|
@ -51,6 +51,7 @@ struct isc_ht {
|
|||
unsigned int magic;
|
||||
isc_mem_t *mctx;
|
||||
size_t count;
|
||||
bool case_sensitive;
|
||||
size_t size[2];
|
||||
uint8_t hashbits[2];
|
||||
isc_ht_node_t **table[2];
|
||||
|
|
@ -234,15 +235,19 @@ hashtable_free(isc_ht_t *ht, const uint8_t idx) {
|
|||
}
|
||||
|
||||
void
|
||||
isc_ht_init(isc_ht_t **htp, isc_mem_t *mctx, uint8_t bits) {
|
||||
isc_ht_init(isc_ht_t **htp, isc_mem_t *mctx, uint8_t bits,
|
||||
unsigned int options) {
|
||||
isc_ht_t *ht = NULL;
|
||||
bool case_sensitive = ((options & ISC_HT_CASE_INSENSITIVE) == 0);
|
||||
|
||||
REQUIRE(htp != NULL && *htp == NULL);
|
||||
REQUIRE(mctx != NULL);
|
||||
REQUIRE(bits >= 1 && bits <= HT_MAX_BITS);
|
||||
|
||||
ht = isc_mem_get(mctx, sizeof(*ht));
|
||||
*ht = (isc_ht_t){ 0 };
|
||||
*ht = (isc_ht_t){
|
||||
.case_sensitive = case_sensitive,
|
||||
};
|
||||
|
||||
isc_mem_attach(mctx, &ht->mctx);
|
||||
|
||||
|
|
@ -313,7 +318,7 @@ isc_ht_add(isc_ht_t *ht, const unsigned char *key, const uint32_t keysize,
|
|||
maybe_rehash(ht, ht->count);
|
||||
}
|
||||
|
||||
hashval = isc_hash32(key, keysize, true);
|
||||
hashval = isc_hash32(key, keysize, ht->case_sensitive);
|
||||
|
||||
if (isc__ht_find(ht, key, keysize, hashval, ht->hindex) != NULL) {
|
||||
return (ISC_R_EXISTS);
|
||||
|
|
@ -361,7 +366,7 @@ isc_ht_find(const isc_ht_t *ht, const unsigned char *key,
|
|||
REQUIRE(key != NULL && keysize > 0);
|
||||
REQUIRE(valuep == NULL || *valuep == NULL);
|
||||
|
||||
hashval = isc_hash32(key, keysize, true);
|
||||
hashval = isc_hash32(key, keysize, ht->case_sensitive);
|
||||
|
||||
node = isc__ht_find(ht, key, keysize, hashval, ht->hindex);
|
||||
if (node == NULL) {
|
||||
|
|
@ -417,7 +422,7 @@ isc_ht_delete(isc_ht_t *ht, const unsigned char *key, const uint32_t keysize) {
|
|||
}
|
||||
|
||||
hindex = ht->hindex;
|
||||
hashval = isc_hash32(key, keysize, true);
|
||||
hashval = isc_hash32(key, keysize, ht->case_sensitive);
|
||||
nexttable:
|
||||
result = isc__ht_delete(ht, key, keysize, hashval, hindex);
|
||||
|
||||
|
|
|
|||
|
|
@ -16,8 +16,14 @@
|
|||
#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
|
||||
|
|
|
|||
|
|
@ -24,9 +24,15 @@
|
|||
typedef struct isc_ht isc_ht_t;
|
||||
typedef struct isc_ht_iter isc_ht_iter_t;
|
||||
|
||||
enum { ISC_HT_CASE_SENSITIVE = 0x00, ISC_HT_CASE_INSENSITIVE = 0x01 };
|
||||
|
||||
/*%
|
||||
* Initialize hashtable at *htp, using memory context and size of (1<<bits)
|
||||
*
|
||||
* If 'options' contains ISC_HT_CASE_INSENSITIVE, then upper- and lower-case
|
||||
* letters in key values will generate the same hash values; this can be used
|
||||
* when the key for a hash table is a DNS name.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'htp' is not NULL and '*htp' is NULL.
|
||||
*\li 'mctx' is a valid memory context.
|
||||
|
|
@ -34,7 +40,8 @@ typedef struct isc_ht_iter isc_ht_iter_t;
|
|||
*
|
||||
*/
|
||||
void
|
||||
isc_ht_init(isc_ht_t **htp, isc_mem_t *mctx, uint8_t bits);
|
||||
isc_ht_init(isc_ht_t **htp, isc_mem_t *mctx, uint8_t bits,
|
||||
unsigned int options);
|
||||
|
||||
/*%
|
||||
* Destroy hashtable, freeing everything
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ test_ht_full(uint8_t init_bits, uint8_t finish_bits, uintptr_t count) {
|
|||
isc_result_t result;
|
||||
uintptr_t i;
|
||||
|
||||
isc_ht_init(&ht, test_mctx, init_bits);
|
||||
isc_ht_init(&ht, test_mctx, init_bits, ISC_HT_CASE_SENSITIVE);
|
||||
assert_non_null(ht);
|
||||
|
||||
for (i = 1; i < count; i++) {
|
||||
|
|
@ -212,7 +212,7 @@ test_ht_iterator(void) {
|
|||
unsigned char key[16];
|
||||
size_t tksize;
|
||||
|
||||
isc_ht_init(&ht, test_mctx, HT_MIN_BITS);
|
||||
isc_ht_init(&ht, test_mctx, HT_MIN_BITS, ISC_HT_CASE_SENSITIVE);
|
||||
assert_non_null(ht);
|
||||
for (i = 1; i <= count; i++) {
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -1109,7 +1109,7 @@ isc_tlsctx_cache_new(isc_mem_t *mctx) {
|
|||
isc_refcount_init(&nc->references, 1);
|
||||
isc_mem_attach(mctx, &nc->mctx);
|
||||
|
||||
isc_ht_init(&nc->data, mctx, 5);
|
||||
isc_ht_init(&nc->data, mctx, 5, ISC_HT_CASE_SENSITIVE);
|
||||
isc_rwlock_init(&nc->rwlock, 0, 0);
|
||||
|
||||
return (nc);
|
||||
|
|
|
|||
Loading…
Reference in a new issue