Revised dns_rbt_findname and dns_rbt_findnode to find the closest match

when an exact match cannot be found.  This changed the calling interface,
which necessitated changes to rbtdb.c and compress.c.
This commit is contained in:
David Lawrence
1999-03-04 21:03:29 +00:00
parent f85b8869df
commit 587fc7b519
4 changed files with 68 additions and 33 deletions
+11 -6
View File
@@ -15,7 +15,7 @@
* SOFTWARE.
*/
/* $Id: compress.c,v 1.4 1999/02/26 00:25:12 marka Exp $ */
/* $Id: compress.c,v 1.5 1999/03/04 21:03:29 tale Exp $ */
#include <config.h>
@@ -436,7 +436,6 @@ compress_find(dns_rbt_t *root, dns_name_t *name, dns_name_t *prefix,
labels = count = dns_name_countlabels(name);
start = 0;
data = NULL;
bits = 0;
dns_name_init(&tmpname, NULL);
@@ -445,8 +444,12 @@ compress_find(dns_rbt_t *root, dns_name_t *name, dns_name_t *prefix,
/* Don't look for the root label (count == 1). */
while (count > 1) {
dns_name_getlabelsequence(name, start, count, &tmpname);
data = dns_rbt_findname(root, &tmpname);
if (data != NULL)
data = NULL;
result = dns_rbt_findname(root, &tmpname, (void *)&data);
/* XXX @@@ is this right, Mark?
note that for data to be non-null, then result can
be DNS_R_SUCCESS or DNS_R_PARTIALMATCH */
if (result == DNS_R_SUCCESS && data != NULL)
break;
count--;
start++;
@@ -476,8 +479,10 @@ compress_find(dns_rbt_t *root, dns_name_t *name, dns_name_t *prefix,
&tmpname, workspace);
if (result != DNS_R_SUCCESS)
continue;
data = dns_rbt_findname(root, &tmpname);
if (data != NULL)
data = NULL;
result = dns_rbt_findname(root, &tmpname, (void *)&data);
/* XXX @@@ is this right, Mark? */
if (result == DNS_R_SUCCESS && data != NULL)
break;
if (bits == 1)
bits = 0;
+8 -7
View File
@@ -42,10 +42,10 @@ typedef struct dns_rbt dns_rbt_t;
#define DNS_RBT_LOCKLENGTH 11
#define DNS_RBT_REFLENGTH 20
typedef struct dns_rbt_node {
struct dns_rbt_node *left;
struct dns_rbt_node *right;
struct dns_rbt_node *down;
typedef struct dns_rbtnode {
struct dns_rbtnode *left;
struct dns_rbtnode *right;
struct dns_rbtnode *down;
/*
* We'd like to find a better place for the single bit of color
* information. We can't pack it into the bitfield below, however,
@@ -138,8 +138,9 @@ void dns_rbt_namefromnode(dns_rbtnode_t *node, dns_name_t *name);
*
*/
dns_rbtnode_t *dns_rbt_findnode(dns_rbt_t *rbt, dns_name_t *name,
dns_rbtnodechain_t *chain);
dns_result_t dns_rbt_findnode(dns_rbt_t *rbt, dns_name_t *name,
dns_rbtnode_t **node,
dns_rbtnodechain_t *chain);
/*
* Find the node for 'name'.
*
@@ -148,7 +149,7 @@ dns_rbtnode_t *dns_rbt_findnode(dns_rbt_t *rbt, dns_name_t *name,
* has a non-NULL data pointer.
*/
void *dns_rbt_findname(dns_rbt_t *rbt, dns_name_t *name);
dns_result_t dns_rbt_findname(dns_rbt_t *rbt, dns_name_t *name, void **data);
/*
* Return the data pointer associated with 'name'.
*
+45 -17
View File
@@ -240,8 +240,9 @@ dns_rbt_addnode(dns_rbt_t *rbt, dns_name_t *name, dns_rbtnode_t **nodep) {
dns_result_t result;
dns_rbtnodechain_t chain;
isc_region_t r;
int add_labels, current_labels, keep_labels, start_label, order;
unsigned int add_labels, current_labels, keep_labels, start_label;
unsigned int common_labels, common_bits;
int order;
REQUIRE(VALID_RBT(rbt));
REQUIRE(FAST_ISABSOLUTE(name));
@@ -315,6 +316,8 @@ dns_rbt_addnode(dns_rbt_t *rbt, dns_name_t *name, dns_rbtnode_t **nodep) {
}
} else {
/* @@@ handle bitstrings */
/*
* This name has some suffix in common with the
* name at the current node. If the name at
@@ -538,21 +541,25 @@ dns_rbt_addname(dns_rbt_t *rbt, dns_name_t *name, void *data) {
* If second argument "up" is non-NULL, set it to the node that has
* the down pointer for the found node.
*/
dns_rbtnode_t *
dns_rbt_findnode(dns_rbt_t *rbt, dns_name_t *name, dns_rbtnodechain_t *chain) {
dns_result_t
dns_rbt_findnode(dns_rbt_t *rbt, dns_name_t *name, dns_rbtnode_t **node,
dns_rbtnodechain_t *chain)
{
dns_rbtnode_t *current;
dns_name_t *search_name, *new_search_name, *current_name;
dns_name_t holder1, holder2;
dns_namereln_t compared;
dns_result_t result;
dns_offsets_t holder1_offsets, holder2_offsets;
int current_labels, keep_labels, order;
unsigned int common_labels, common_bits;
isc_region_t r;
unsigned int current_labels, keep_labels, common_labels, common_bits;
int order;
/* @@@ optimize skipping the root node? */
REQUIRE(VALID_RBT(rbt));
REQUIRE(FAST_ISABSOLUTE(name));
REQUIRE(node != NULL && *node == NULL);
dns_name_init(&holder1, holder1_offsets);
dns_name_init(&holder2, holder2_offsets);
@@ -576,7 +583,7 @@ dns_rbt_findnode(dns_rbt_t *rbt, dns_name_t *name, dns_rbtnodechain_t *chain) {
chain->level_count = 0;
if (get_ancestor_mem(rbt->mctx, chain) != DNS_R_SUCCESS)
return (NULL);
return (DNS_R_NOMEMORY);
ADD_ANCESTOR(chain, NULL);
}
@@ -596,7 +603,7 @@ dns_rbt_findnode(dns_rbt_t *rbt, dns_name_t *name, dns_rbtnodechain_t *chain) {
if (chain != NULL &&
chain->ancestor_count == chain->ancestor_maxitems &&
get_ancestor_mem(rbt->mctx, chain) != DNS_R_SUCCESS)
return (NULL);
return (DNS_R_NOMEMORY);
/*
* Standard binary search tree movement.
@@ -654,36 +661,55 @@ dns_rbt_findnode(dns_rbt_t *rbt, dns_name_t *name, dns_rbtnodechain_t *chain) {
ADD_LEVEL(chain, current);
}
/*
* This might be the closest enclosing name.
*/
*node = current;
/*
* Search in the next tree level.
*/
current = DOWN(current);
} else
} else {
/*
* Though there is a suffix in common, it
* has no down pointer, so the name does
* not exist.
*/
current = NULL;
}
}
}
return (current);
if (current != NULL) {
*node = current;
result = DNS_R_SUCCESS;
} else if (*node != NULL) {
result = DNS_R_PARTIALMATCH;
} else {
result = DNS_R_NOTFOUND;
}
return (result);
}
void *
dns_rbt_findname(dns_rbt_t *rbt, dns_name_t *name) {
dns_rbtnode_t *node;
dns_result_t
dns_rbt_findname(dns_rbt_t *rbt, dns_name_t *name, void **data) {
dns_rbtnode_t *node = NULL;
dns_result_t result;
REQUIRE(VALID_RBT(rbt));
REQUIRE(data != NULL && *data == NULL);
node = dns_rbt_findnode(rbt, name, NULL);
result = dns_rbt_findnode(rbt, name, &node, NULL);
if (node != NULL && DATA(node) != NULL)
return(DATA(node));
*data = DATA(node);
else
return(NULL);
result = DNS_R_NOTFOUND;
return (result);
}
/*
@@ -691,7 +717,7 @@ dns_rbt_findname(dns_rbt_t *rbt, dns_name_t *name) {
*/
dns_result_t
dns_rbt_deletename(dns_rbt_t *rbt, dns_name_t *name, isc_boolean_t recurse) {
dns_rbtnode_t *node;
dns_rbtnode_t *node = NULL;
dns_result_t result;
dns_rbtnodechain_t chain;
@@ -711,8 +737,10 @@ dns_rbt_deletename(dns_rbt_t *rbt, dns_name_t *name, isc_boolean_t recurse) {
*
* @@@ how to ->dirty, ->locknum and ->references figure in?
*/
result = dns_rbt_findnode(rbt, name, &node, &chain);
node = dns_rbt_findnode(rbt, name, &chain);
if (result != DNS_R_SUCCESS)
return (DNS_R_NOTFOUND);
/*
* The guts of this routine are in a separate function (which
+4 -3
View File
@@ -669,7 +669,8 @@ closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) {
static dns_result_t
findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
dns_dbnode_t **nodep) {
dns_dbnode_t **nodep)
{
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
dns_rbtnode_t *node = NULL;
dns_name_t foundname;
@@ -681,9 +682,9 @@ findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
dns_name_init(&foundname, NULL);
RWLOCK(&rbtdb->tree_lock, locktype);
node = dns_rbt_findnode(rbtdb->tree, name, NULL);
result = dns_rbt_findnode(rbtdb->tree, name, &node, NULL);
again:
if (node != NULL) {
if (result == DNS_R_SUCCESS) {
locknum = node->locknum;
LOCK(&rbtdb->node_locks[locknum].lock);
if (node->references == 0)