diff --git a/lib/dns/include/dns/name.h b/lib/dns/include/dns/name.h index d524e8c7b1..d1c610f66d 100644 --- a/lib/dns/include/dns/name.h +++ b/lib/dns/include/dns/name.h @@ -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 ***/ diff --git a/lib/dns/name.c b/lib/dns/name.c index 98d9d352d6..ff668ab84a 100644 --- a/lib/dns/name.c +++ b/lib/dns/name.c @@ -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 @@ -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, diff --git a/lib/dns/rbt.c b/lib/dns/rbt.c index b06ef460c2..5a44b5d9bb 100644 --- a/lib/dns/rbt.c +++ b/lib/dns/rbt.c @@ -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;