add dns_name_hashbylabel() and make the rbt use it.

This commit is contained in:
Brian Wellington
2001-12-04 01:32:44 +00:00
parent 4de7f30751
commit 41e50ece38
3 changed files with 71 additions and 35 deletions

View File

@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: name.h,v 1.96 2001/11/19 03:08:15 mayer Exp $ */
/* $Id: name.h,v 1.97 2001/12/04 01:32:44 bwelling Exp $ */
#ifndef DNS_NAME_H
#define DNS_NAME_H 1
@@ -389,6 +389,22 @@ dns_name_hash(dns_name_t *name, isc_boolean_t case_sensitive);
* A hash value
*/
unsigned int
dns_name_hashbylabel(dns_name_t *name, isc_boolean_t case_sensitive);
/*
* Provide a hash value for 'name', where the hash value is the sum
* of the hash values of each label.
*
* Note: if 'case_sensitive' is ISC_FALSE, then names which differ only in
* case will have the same hash value.
*
* Requires:
* 'name' is a valid name
*
* Returns:
* A hash value
*/
/***
*** Comparisons
***/

View File

@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: name.c,v 1.129 2001/11/19 03:08:11 mayer Exp $ */
/* $Id: name.c,v 1.130 2001/12/04 01:32:41 bwelling Exp $ */
#include <config.h>
@@ -420,20 +420,13 @@ dns_name_requiresedns(const dns_name_t *name) {
return (requiresedns);
}
unsigned int
dns_name_hash(dns_name_t *name, isc_boolean_t case_sensitive) {
static inline unsigned int
name_hash(dns_name_t *name, isc_boolean_t case_sensitive) {
unsigned int length;
const unsigned char *s;
unsigned int h = 0;
unsigned char c;
/*
* Provide a hash value for 'name'.
*/
REQUIRE(VALID_NAME(name));
if (name->labels == 0)
return (0);
length = name->length;
if (length > 16)
length = 16;
@@ -461,6 +454,53 @@ dns_name_hash(dns_name_t *name, isc_boolean_t case_sensitive) {
return (h);
}
unsigned int
dns_name_hash(dns_name_t *name, isc_boolean_t case_sensitive) {
/*
* Provide a hash value for 'name'.
*/
REQUIRE(VALID_NAME(name));
if (name->labels == 0)
return (0);
return (name_hash(name, case_sensitive));
}
unsigned int
dns_name_hashbylabel(dns_name_t *name, isc_boolean_t case_sensitive) {
unsigned char *offsets;
dns_offsets_t odata;
dns_name_t tname;
unsigned int h = 0;
unsigned int i;
/*
* Provide a hash value for 'name'.
*/
REQUIRE(VALID_NAME(name));
if (name->labels == 0)
return (0);
else if (name->labels == 1)
return (name_hash(name, case_sensitive));
SETUP_OFFSETS(name, offsets, odata);
DNS_NAME_INIT(&tname, NULL);
tname.labels = 1;
h = 0;
for (i = 0; i < name->labels; i++) {
tname.ndata = name->ndata + offsets[i];
if (i == name->labels - 1)
tname.length = name->length - offsets[i];
else
tname.length = offsets[i + 1] - offsets[i];
h += name_hash(&tname, case_sensitive);
}
return (h);
}
dns_namereln_t
dns_name_fullcompare(const dns_name_t *name1, const dns_name_t *name2,
int *orderp,

View File

@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: rbt.c,v 1.121 2001/12/03 19:44:07 gson Exp $ */
/* $Id: rbt.c,v 1.122 2001/12/04 01:32:43 bwelling Exp $ */
/* Principal Authors: DCL */
@@ -173,27 +173,6 @@ find_up(dns_rbtnode_t *node) {
return (PARENT(root));
}
static inline unsigned int
name_hash(dns_name_t *name) {
unsigned int nlabels;
unsigned int hash;
dns_name_t tname;
if (dns_name_countlabels(name) == 1)
return (dns_name_hash(name, ISC_FALSE));
dns_name_init(&tname, NULL);
nlabels = dns_name_countlabels(name);
hash = 0;
for (; nlabels > 0; nlabels--) {
dns_name_getlabelsequence(name, nlabels - 1, 1, &tname);
hash += dns_name_hash(&tname, ISC_FALSE);
}
return (hash);
}
#ifdef DNS_RBT_USEHASH
static inline void
compute_node_hash(dns_rbtnode_t *node) {
@@ -203,7 +182,7 @@ compute_node_hash(dns_rbtnode_t *node) {
dns_name_init(&name, NULL);
NODENAME(node, &name);
hash = name_hash(&name);
hash = dns_name_hashbylabel(&name, ISC_FALSE);
up_node = find_up(node);
if (up_node != NULL)
@@ -886,7 +865,8 @@ dns_rbt_findnode(dns_rbt_t *rbt, dns_name_t *name, dns_name_t *foundname,
dns_name_getlabelsequence(search_name,
nlabels - tlabels,
tlabels, &hash_name);
hash = HASHVAL(up_current) + name_hash(&hash_name);
hash = HASHVAL(up_current) +
dns_name_hashbylabel(&hash_name, ISC_FALSE);
for (hnode = rbt->hashtable[hash % rbt->hashsize];
hnode != NULL;