2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 06:25:31 +00:00

Improve performance of RBT (#41165)

This commit is contained in:
Mukund Sivaraman
2015-12-09 19:07:20 +05:30
parent aeb7b6e145
commit 5d79b60fc5
17 changed files with 555 additions and 237 deletions

View File

@@ -403,3 +403,142 @@ isc__hash_setvec(const isc_uint16_t *vec) {
p[i] = vec[i];
}
}
static unsigned int fnv_offset_basis;
static isc_once_t fnv_once = ISC_ONCE_INIT;
static void
fnv_initialize(void) {
/*
* This function should not leave fnv_offset_basis set to
* 0. Also, after this function has been called, if it is called
* again, it should not change fnv_offset_basis.
*/
while (fnv_offset_basis == 0) {
isc_random_get(&fnv_offset_basis);
}
}
unsigned int
isc_hash_function(const void *data, size_t length,
isc_boolean_t case_sensitive,
unsigned int *previous_hashp)
{
unsigned int hval;
const unsigned char *bp;
const unsigned char *be;
RUNTIME_CHECK(isc_once_do(&fnv_once, fnv_initialize) == ISC_R_SUCCESS);
hval = previous_hashp != NULL ? *previous_hashp : fnv_offset_basis;
bp = (const unsigned char *) data;
be = bp + length;
/*
* Fowler-Noll-Vo FNV-1a hash function.
*
* NOTE: A random fnv_offset_basis is used by default to avoid
* collision attacks as the hash function is reversible. This
* makes the mapping non-deterministic, but the distribution in
* the domain is still uniform.
*/
if (case_sensitive) {
while (bp < be - 4) {
hval ^= (unsigned int) bp[0];
hval *= 16777619;
hval ^= (unsigned int) bp[1];
hval *= 16777619;
hval ^= (unsigned int) bp[2];
hval *= 16777619;
hval ^= (unsigned int) bp[3];
hval *= 16777619;
bp += 4;
}
while (bp < be) {
hval ^= (unsigned int) *bp++;
hval *= 16777619;
}
} else {
while (bp < be - 4) {
hval ^= (unsigned int) maptolower[bp[0]];
hval *= 16777619;
hval ^= (unsigned int) maptolower[bp[1]];
hval *= 16777619;
hval ^= (unsigned int) maptolower[bp[2]];
hval *= 16777619;
hval ^= (unsigned int) maptolower[bp[3]];
hval *= 16777619;
bp += 4;
}
while (bp < be) {
hval ^= (unsigned int) maptolower[*bp++];
hval *= 16777619;
}
}
return (hval);
}
unsigned int
isc_hash_function_reverse(const void *data, size_t length,
isc_boolean_t case_sensitive,
unsigned int *previous_hashp)
{
unsigned int hval;
const unsigned char *bp;
const unsigned char *be;
RUNTIME_CHECK(isc_once_do(&fnv_once, fnv_initialize) == ISC_R_SUCCESS);
hval = previous_hashp != NULL ? *previous_hashp : fnv_offset_basis;
bp = (const unsigned char *) data;
be = bp + length;
/*
* Fowler-Noll-Vo FNV-1a hash function.
*
* NOTE: A random fnv_offset_basis is used by default to avoid
* collision attacks as the hash function is reversible. This
* makes the mapping non-deterministic, but the distribution in
* the domain is still uniform.
*/
if (case_sensitive) {
while (be >= bp + 4) {
be -= 4;
hval ^= (unsigned int) be[3];
hval *= 16777619;
hval ^= (unsigned int) be[2];
hval *= 16777619;
hval ^= (unsigned int) be[1];
hval *= 16777619;
hval ^= (unsigned int) be[0];
hval *= 16777619;
}
while (--be >= bp) {
hval ^= (unsigned int) *be;
hval *= 16777619;
}
} else {
while (be >= bp + 4) {
be -= 4;
hval ^= (unsigned int) maptolower[be[3]];
hval *= 16777619;
hval ^= (unsigned int) maptolower[be[2]];
hval *= 16777619;
hval ^= (unsigned int) maptolower[be[1]];
hval *= 16777619;
hval ^= (unsigned int) maptolower[be[0]];
hval *= 16777619;
}
while (--be >= bp) {
hval ^= (unsigned int) maptolower[*be];
hval *= 16777619;
}
}
return (hval);
}