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:
139
lib/isc/hash.c
139
lib/isc/hash.c
@@ -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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user