mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-29 13:38:26 +00:00
Merge branch 'each-cleanup-dns_rbt' into 'main'
clean up dns_rbt See merge request isc-projects/bind9!8715
This commit is contained in:
commit
9279a1038b
@ -30,7 +30,7 @@ ISC_LANG_BEGINDECLS
|
||||
|
||||
/*@{*/
|
||||
/*%
|
||||
* Option values for dns_rbt_findnode() and dns_rbt_findname().
|
||||
* Option values for dns_rbt_findnode().
|
||||
* These are used to form a bitmask.
|
||||
*/
|
||||
#define DNS_RBTFIND_NOOPTIONS 0x00
|
||||
@ -144,13 +144,6 @@ typedef isc_result_t (*dns_rbtfindcallback_t)(dns_rbtnode_t *node,
|
||||
dns_name_t *name,
|
||||
void *callback_arg DNS__DB_FLARG);
|
||||
|
||||
typedef isc_result_t (*dns_rbtdatawriter_t)(FILE *file, unsigned char *data,
|
||||
void *arg, uint64_t *crc);
|
||||
|
||||
typedef isc_result_t (*dns_rbtdatafixer_t)(dns_rbtnode_t *rbtnode, void *base,
|
||||
size_t offset, void *arg,
|
||||
uint64_t *crc);
|
||||
|
||||
typedef void (*dns_rbtdeleter_t)(void *, void *);
|
||||
|
||||
/*****
|
||||
@ -276,54 +269,15 @@ dns_rbt_create(isc_mem_t *mctx, dns_rbtdeleter_t deleter, void *deleter_arg,
|
||||
*
|
||||
* Returns:
|
||||
*\li #ISC_R_SUCCESS Success
|
||||
*\li #ISC_R_NOMEMORY Resource limit: Out of Memory
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_rbt_addname(dns_rbt_t *rbt, const dns_name_t *name, void *data);
|
||||
/*%<
|
||||
* Add 'name' to the tree of trees, associated with 'data'.
|
||||
*
|
||||
* Notes:
|
||||
*\li 'data' is never required to be non-NULL, but specifying it
|
||||
* when the name is added is faster than searching for 'name'
|
||||
* again and then setting the data pointer. The lack of a data pointer
|
||||
* for a node also has other ramifications regarding whether
|
||||
* dns_rbt_findname considers a node to exist, or dns_rbt_deletename
|
||||
* joins nodes.
|
||||
*
|
||||
* Requires:
|
||||
*\li rbt is a valid rbt manager.
|
||||
*\li dns_name_isabsolute(name) == TRUE
|
||||
*
|
||||
* Ensures:
|
||||
*\li 'name' is not altered in any way.
|
||||
*
|
||||
*\li Any external references to nodes in the tree are unaffected by
|
||||
* node splits that are necessary to insert the new name.
|
||||
*
|
||||
*\li If result is #ISC_R_SUCCESS:
|
||||
* 'name' is findable in the red/black tree of trees in O(log N).
|
||||
* The data pointer of the node for 'name' is set to 'data'.
|
||||
*
|
||||
*\li If result is #ISC_R_EXISTS or #ISC_R_NOSPACE:
|
||||
* The tree of trees is unaltered.
|
||||
*
|
||||
*\li If result is #ISC_R_NOMEMORY:
|
||||
* No guarantees.
|
||||
*
|
||||
* Returns:
|
||||
*\li #ISC_R_SUCCESS Success
|
||||
*\li #ISC_R_EXISTS The name already exists with associated data.
|
||||
*\li #ISC_R_NOSPACE The name had more logical labels than are allowed.
|
||||
*\li #ISC_R_NOMEMORY Resource Limit: Out of Memory
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_rbt_addnode(dns_rbt_t *rbt, const dns_name_t *name, dns_rbtnode_t **nodep);
|
||||
|
||||
/*%<
|
||||
* Just like dns_rbt_addname, but returns the address of the node.
|
||||
* Add 'name' to the tree of trees. On success, return the address of
|
||||
* the newly added node. If 'name' already existed, return ISC_R_EXISTS
|
||||
* and the address of the pre-existing node.
|
||||
*
|
||||
* Requires:
|
||||
*\li rbt is a valid rbt structure.
|
||||
@ -344,61 +298,16 @@ dns_rbt_addnode(dns_rbt_t *rbt, const dns_name_t *name, dns_rbtnode_t **nodep);
|
||||
* The tree of trees is unaltered.
|
||||
* *nodep is the existing node for 'name'.
|
||||
*
|
||||
*\li If result is ISC_R_NOMEMORY:
|
||||
* No guarantees.
|
||||
*
|
||||
* Returns:
|
||||
*\li #ISC_R_SUCCESS Success
|
||||
*\li #ISC_R_EXISTS The name already exists, possibly without data.
|
||||
*\li #ISC_R_NOMEMORY Resource Limit: Out of Memory
|
||||
*/
|
||||
|
||||
#define dns_rbt_findname(rbt, name, options, foundname, data) \
|
||||
dns__rbt_findname(rbt, name, options, foundname, data DNS__DB_FILELINE)
|
||||
isc_result_t
|
||||
dns__rbt_findname(dns_rbt_t *rbt, const dns_name_t *name, unsigned int options,
|
||||
dns_name_t *foundname, void **data DNS__DB_FLARG);
|
||||
/*%<
|
||||
* Get the data pointer associated with 'name'.
|
||||
*
|
||||
* Notes:
|
||||
*\li When #DNS_RBTFIND_NOEXACT is set, the closest matching superdomain is
|
||||
* returned (also subject to #DNS_RBTFIND_EMPTYDATA), even when there is
|
||||
* an exact match in the tree.
|
||||
*
|
||||
*\li A node that has no data is considered not to exist for this function,
|
||||
* unless the #DNS_RBTFIND_EMPTYDATA option is set.
|
||||
*
|
||||
* Requires:
|
||||
*\li rbt is a valid rbt manager.
|
||||
*\li dns_name_isabsolute(name) == TRUE
|
||||
*\li data != NULL && *data == NULL
|
||||
*
|
||||
* Ensures:
|
||||
*\li 'name' and the tree are not altered in any way.
|
||||
*
|
||||
*\li If result is ISC_R_SUCCESS:
|
||||
* *data is the data associated with 'name'.
|
||||
*
|
||||
*\li If result is DNS_R_PARTIALMATCH:
|
||||
* *data is the data associated with the deepest superdomain
|
||||
* of 'name' which has data.
|
||||
*
|
||||
*\li If result is ISC_R_NOTFOUND:
|
||||
* Neither the name nor a superdomain was found with data.
|
||||
*
|
||||
* Returns:
|
||||
*\li #ISC_R_SUCCESS Success
|
||||
*\li #DNS_R_PARTIALMATCH Superdomain found with data
|
||||
*\li #ISC_R_NOTFOUND No match
|
||||
*\li #ISC_R_NOSPACE Concatenating nodes to form foundname failed
|
||||
*\li #ISC_R_NOSPACE The name had more logical labels than are allowed.
|
||||
*/
|
||||
|
||||
#define dns_rbt_findnode(rbt, name, foundname, node, chain, options, callback, \
|
||||
callback_arg) \
|
||||
dns__rbt_findnode(rbt, name, foundname, node, chain, options, \
|
||||
callback, callback_arg DNS__DB_FILELINE)
|
||||
|
||||
isc_result_t
|
||||
dns__rbt_findnode(dns_rbt_t *rbt, const dns_name_t *name, dns_name_t *foundname,
|
||||
dns_rbtnode_t **node, dns_rbtnodechain_t *chain,
|
||||
@ -504,52 +413,6 @@ dns__rbt_findnode(dns_rbt_t *rbt, const dns_name_t *name, dns_name_t *foundname,
|
||||
*\li #ISC_R_NOSPACE Concatenating nodes to form foundname failed
|
||||
*/
|
||||
|
||||
#define dns_rbt_deletename(rbt, name, recurse) \
|
||||
dns__rbt_deletename(rbt, name, recurse DNS__DB_FILELINE)
|
||||
isc_result_t
|
||||
dns__rbt_deletename(dns_rbt_t *rbt, const dns_name_t *name,
|
||||
bool recurse DNS__DB_FLARG);
|
||||
/*%<
|
||||
* Delete 'name' from the tree of trees.
|
||||
*
|
||||
* Notes:
|
||||
*\li When 'name' is removed, if recurse is true then all of its
|
||||
* subnames are removed too.
|
||||
*
|
||||
* Requires:
|
||||
*\li rbt is a valid rbt manager.
|
||||
*\li dns_name_isabsolute(name) == TRUE
|
||||
*
|
||||
* Ensures:
|
||||
*\li 'name' is not altered in any way.
|
||||
*
|
||||
*\li Does NOT ensure that any external references to nodes in the tree
|
||||
* are unaffected by node joins.
|
||||
*
|
||||
*\li If result is ISC_R_SUCCESS:
|
||||
* 'name' does not appear in the tree with data; however,
|
||||
* the node for the name might still exist which can be
|
||||
* found with dns_rbt_findnode (but not dns_rbt_findname).
|
||||
*
|
||||
*\li If result is ISC_R_NOTFOUND:
|
||||
* 'name' does not appear in the tree with data, because
|
||||
* it did not appear in the tree before the function was called.
|
||||
*
|
||||
*\li If result is something else:
|
||||
* See result codes for dns_rbt_findnode (if it fails, the
|
||||
* node is not deleted) or dns_rbt_deletenode (if it fails,
|
||||
* the node is deleted, but the tree is not optimized when
|
||||
* it could have been).
|
||||
*
|
||||
* Returns:
|
||||
*\li #ISC_R_SUCCESS Success
|
||||
*\li #ISC_R_NOTFOUND No match
|
||||
*\li something_else Any return code from dns_rbt_findnode except
|
||||
* DNS_R_PARTIALMATCH (which causes ISC_R_NOTFOUND
|
||||
* to be returned instead), and any code from
|
||||
* dns_rbt_deletenode.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_rbt_deletenode(dns_rbt_t *rbt, dns_rbtnode_t *node, bool recurse);
|
||||
/*%<
|
||||
@ -574,13 +437,12 @@ dns_rbt_deletenode(dns_rbt_t *rbt, dns_rbtnode_t *node, bool recurse);
|
||||
* the node could can be found with dns_rbt_findnode when
|
||||
* that function's empty_data_ok parameter is true.
|
||||
*
|
||||
*\li If result is ISC_R_NOMEMORY or ISC_R_NOSPACE:
|
||||
*\li If result is ISC_R_NOSPACE:
|
||||
* The node was deleted, but the tree structure was not
|
||||
* optimized.
|
||||
*
|
||||
* Returns:
|
||||
*\li #ISC_R_SUCCESS Success
|
||||
*\li #ISC_R_NOMEMORY Resource Limit: Out of Memory when joining nodes.
|
||||
*\li #ISC_R_NOSPACE dns_name_concatenate failed when joining nodes.
|
||||
*/
|
||||
|
||||
@ -664,10 +526,8 @@ dns_rbt_hashsize(dns_rbt_t *rbt);
|
||||
* \li rbt is a valid rbt manager.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_rbt_destroy(dns_rbt_t **rbtp);
|
||||
isc_result_t
|
||||
dns_rbt_destroy2(dns_rbt_t **rbtp, unsigned int quantum);
|
||||
dns_rbt_destroy(dns_rbt_t **rbtp, unsigned int quantum);
|
||||
/*%<
|
||||
* Stop working with a red-black tree of trees.
|
||||
* If 'quantum' is zero then the entire tree will be destroyed.
|
||||
@ -902,7 +762,6 @@ dns_rbtnodechain_last(dns_rbtnodechain_t *chain, dns_rbt_t *rbt,
|
||||
*
|
||||
* Returns:
|
||||
*\li #DNS_R_NEWORIGIN The name & origin were successfully set.
|
||||
*\li #ISC_R_NOMEMORY Resource Limit: Out of Memory building chain.
|
||||
*\li <something_else> Any error result from dns_name_concatenate.
|
||||
*/
|
||||
|
||||
|
151
lib/dns/rbt.c
151
lib/dns/rbt.c
@ -178,8 +178,8 @@ dns__rbtnode_getdistance(dns_rbtnode_t *node) {
|
||||
/*
|
||||
* Forward declarations.
|
||||
*/
|
||||
static isc_result_t
|
||||
create_node(isc_mem_t *mctx, const dns_name_t *name, dns_rbtnode_t **nodep);
|
||||
static dns_rbtnode_t *
|
||||
rbtnode_new(isc_mem_t *mctx, const dns_name_t *name);
|
||||
|
||||
static void
|
||||
hashtable_new(dns_rbt_t *rbt, uint8_t index, uint8_t bits);
|
||||
@ -291,13 +291,8 @@ dns_rbt_create(isc_mem_t *mctx, dns_rbtdeleter_t deleter, void *deleter_arg,
|
||||
/*
|
||||
* Deallocate a red/black tree of trees.
|
||||
*/
|
||||
void
|
||||
dns_rbt_destroy(dns_rbt_t **rbtp) {
|
||||
RUNTIME_CHECK(dns_rbt_destroy2(rbtp, 0) == ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_rbt_destroy2(dns_rbt_t **rbtp, unsigned int quantum) {
|
||||
dns_rbt_destroy(dns_rbt_t **rbtp, unsigned int quantum) {
|
||||
dns_rbt_t *rbt;
|
||||
|
||||
REQUIRE(rbtp != NULL && VALID_RBT(*rbtp));
|
||||
@ -459,18 +454,14 @@ dns_rbt_addnode(dns_rbt_t *rbt, const dns_name_t *name, dns_rbtnode_t **nodep) {
|
||||
dns_name_clone(name, add_name);
|
||||
|
||||
if (rbt->root == NULL) {
|
||||
result = create_node(rbt->mctx, add_name, &new_current);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
new_current = rbtnode_new(rbt->mctx, add_name);
|
||||
rbt->nodecount++;
|
||||
new_current->is_root = 1;
|
||||
|
||||
new_current->uppernode = NULL;
|
||||
|
||||
rbt->root = new_current;
|
||||
*nodep = new_current;
|
||||
hash_node(rbt, new_current, name);
|
||||
}
|
||||
return (result);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
level_count = 0;
|
||||
@ -583,12 +574,7 @@ dns_rbt_addnode(dns_rbt_t *rbt, const dns_name_t *name, dns_rbtnode_t **nodep) {
|
||||
*/
|
||||
dns_name_split(¤t_name, common_labels,
|
||||
prefix, suffix);
|
||||
result = create_node(rbt->mctx, suffix,
|
||||
&new_current);
|
||||
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
new_current = rbtnode_new(rbt->mctx, suffix);
|
||||
|
||||
/*
|
||||
* Reproduce the tree attributes of the
|
||||
@ -672,20 +658,16 @@ dns_rbt_addnode(dns_rbt_t *rbt, const dns_name_t *name, dns_rbtnode_t **nodep) {
|
||||
* The current node has no data,
|
||||
* because it is just a placeholder.
|
||||
* Its data pointer is already NULL
|
||||
* from create_node()), so there's
|
||||
* from rbtnode_new()), so there's
|
||||
* nothing more to do to it.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* The not-in-common parts of the new
|
||||
* name will be inserted into the new
|
||||
* level following this loop (unless
|
||||
* result != ISC_R_SUCCESS, which
|
||||
* is tested after the loop ends).
|
||||
* level following this loop.
|
||||
*/
|
||||
dns_name_split(add_name, common_labels,
|
||||
add_name, NULL);
|
||||
|
||||
result = ISC_R_SUCCESS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -693,7 +675,7 @@ dns_rbt_addnode(dns_rbt_t *rbt, const dns_name_t *name, dns_rbtnode_t **nodep) {
|
||||
} while (child != NULL);
|
||||
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
result = create_node(rbt->mctx, add_name, &new_current);
|
||||
new_current = rbtnode_new(rbt->mctx, add_name);
|
||||
}
|
||||
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
@ -712,37 +694,6 @@ dns_rbt_addnode(dns_rbt_t *rbt, const dns_name_t *name, dns_rbtnode_t **nodep) {
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a name to the tree of trees, associating it with some data.
|
||||
*/
|
||||
isc_result_t
|
||||
dns_rbt_addname(dns_rbt_t *rbt, const dns_name_t *name, void *data) {
|
||||
isc_result_t result;
|
||||
dns_rbtnode_t *node;
|
||||
|
||||
REQUIRE(VALID_RBT(rbt));
|
||||
REQUIRE(dns_name_isabsolute(name));
|
||||
|
||||
node = NULL;
|
||||
|
||||
result = dns_rbt_addnode(rbt, name, &node);
|
||||
|
||||
/*
|
||||
* dns_rbt_addnode will report the node exists even when
|
||||
* it does not have data associated with it, but the
|
||||
* dns_rbt_*name functions all behave depending on whether
|
||||
* there is data associated with a node.
|
||||
*/
|
||||
if (result == ISC_R_SUCCESS ||
|
||||
(result == ISC_R_EXISTS && node != NULL && node->data == NULL))
|
||||
{
|
||||
node->data = data;
|
||||
result = ISC_R_SUCCESS;
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the node for "name" in the tree of trees.
|
||||
*/
|
||||
@ -1274,72 +1225,6 @@ dns__rbt_findnode(dns_rbt_t *rbt, const dns_name_t *name, dns_name_t *foundname,
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the data pointer associated with 'name'.
|
||||
*/
|
||||
isc_result_t
|
||||
dns__rbt_findname(dns_rbt_t *rbt, const dns_name_t *name, unsigned int options,
|
||||
dns_name_t *foundname, void **data DNS__DB_FLARG) {
|
||||
dns_rbtnode_t *node = NULL;
|
||||
isc_result_t result;
|
||||
|
||||
REQUIRE(data != NULL && *data == NULL);
|
||||
|
||||
result = dns__rbt_findnode(rbt, name, foundname, &node, NULL, options,
|
||||
NULL, NULL DNS__DB_FLARG_PASS);
|
||||
|
||||
if (node != NULL && WANTEMPTYDATA_OR_DATA(options, node)) {
|
||||
*data = node->data;
|
||||
} else {
|
||||
result = ISC_R_NOTFOUND;
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete a name from the tree of trees.
|
||||
*/
|
||||
isc_result_t
|
||||
dns__rbt_deletename(dns_rbt_t *rbt, const dns_name_t *name,
|
||||
bool recurse DNS__DB_FLARG) {
|
||||
dns_rbtnode_t *node = NULL;
|
||||
isc_result_t result;
|
||||
|
||||
REQUIRE(VALID_RBT(rbt));
|
||||
REQUIRE(dns_name_isabsolute(name));
|
||||
|
||||
/*
|
||||
* First, find the node.
|
||||
*
|
||||
* When searching, the name might not have an exact match:
|
||||
* consider a.b.a.com, b.b.a.com and c.b.a.com as the only
|
||||
* elements of a tree, which would make layer 1 a single
|
||||
* node tree of "b.a.com" and layer 2 a three node tree of
|
||||
* a, b, and c. Deleting a.com would find only a partial depth
|
||||
* match in the first layer. Should it be a requirement that
|
||||
* that the name to be deleted have data? For now, it is.
|
||||
*
|
||||
* ->dirty, ->locknum and ->references are ignored; they are
|
||||
* solely the province of rbtdb.c.
|
||||
*/
|
||||
result = dns__rbt_findnode(rbt, name, NULL, &node, NULL,
|
||||
DNS_RBTFIND_NOOPTIONS, NULL,
|
||||
NULL DNS__DB_FLARG_PASS);
|
||||
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
if (node->data != NULL) {
|
||||
result = dns_rbt_deletenode(rbt, node, recurse);
|
||||
} else {
|
||||
result = ISC_R_NOTFOUND;
|
||||
}
|
||||
} else if (result == DNS_R_PARTIALMATCH) {
|
||||
result = ISC_R_NOTFOUND;
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove a node from the tree of trees.
|
||||
*
|
||||
@ -1497,9 +1382,9 @@ dns_rbt_formatnodename(dns_rbtnode_t *node, char *printname,
|
||||
return (printname);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
create_node(isc_mem_t *mctx, const dns_name_t *name, dns_rbtnode_t **nodep) {
|
||||
dns_rbtnode_t *node;
|
||||
static dns_rbtnode_t *
|
||||
rbtnode_new(isc_mem_t *mctx, const dns_name_t *name) {
|
||||
dns_rbtnode_t *node = NULL;
|
||||
isc_region_t region;
|
||||
unsigned int labels;
|
||||
size_t nodelen;
|
||||
@ -1548,9 +1433,7 @@ create_node(isc_mem_t *mctx, const dns_name_t *name, dns_rbtnode_t **nodep) {
|
||||
#if DNS_RBT_USEMAGIC
|
||||
node->magic = DNS_RBTNODE_MAGIC;
|
||||
#endif /* if DNS_RBT_USEMAGIC */
|
||||
*nodep = node;
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
return (node);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2565,9 +2448,7 @@ dns_rbtnodechain_current(dns_rbtnodechain_t *chain, dns_name_t *name,
|
||||
|
||||
REQUIRE(VALID_CHAIN(chain));
|
||||
|
||||
if (node != NULL) {
|
||||
*node = chain->end;
|
||||
}
|
||||
SET_IF_NOT_NULL(node, chain->end);
|
||||
|
||||
if (chain->end == NULL) {
|
||||
return (ISC_R_NOTFOUND);
|
||||
|
@ -516,7 +516,7 @@ free_rbtdb(dns_rbtdb_t *rbtdb, bool log) {
|
||||
}
|
||||
|
||||
start = isc_time_now();
|
||||
result = dns_rbt_destroy2(treep, rbtdb->quantum);
|
||||
result = dns_rbt_destroy(treep, rbtdb->quantum);
|
||||
if (result == ISC_R_QUOTA) {
|
||||
INSIST(rbtdb->loop != NULL);
|
||||
if (rbtdb->quantum != 0) {
|
||||
|
@ -311,15 +311,30 @@ new_rbt(isc_mem_t *mem) {
|
||||
|
||||
static isc_result_t
|
||||
add_rbt(void *rbt, size_t count) {
|
||||
isc_result_t result = dns_rbt_addname(rbt, &item[count].fixed.name,
|
||||
&item[count]);
|
||||
isc_result_t result;
|
||||
dns_rbtnode_t *node = NULL;
|
||||
|
||||
result = dns_rbt_addnode(rbt, &item[count].fixed.name, &node);
|
||||
if (result == ISC_R_SUCCESS ||
|
||||
(result == ISC_R_EXISTS && node->data == NULL))
|
||||
{
|
||||
node->data = &item[count];
|
||||
result = ISC_R_SUCCESS;
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
get_rbt(void *rbt, size_t count, void **pval) {
|
||||
isc_result_t result = dns_rbt_findname(rbt, &item[count].fixed.name, 0,
|
||||
NULL, pval);
|
||||
isc_result_t result;
|
||||
dns_rbtnode_t *node = NULL;
|
||||
|
||||
result = dns_rbt_findnode(rbt, &item[count].fixed.name, NULL, &node,
|
||||
NULL, 0, NULL, NULL);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
*pval = node->data;
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
|
@ -150,7 +150,8 @@ test_context_setup(void) {
|
||||
for (i = 0; i < domain_names_count; i++) {
|
||||
size_t *n;
|
||||
dns_fixedname_t fname;
|
||||
dns_name_t *name;
|
||||
dns_name_t *name = NULL;
|
||||
dns_rbtnode_t *node = NULL;
|
||||
|
||||
dns_test_namefromstring(domain_names[i], &fname);
|
||||
|
||||
@ -159,13 +160,16 @@ test_context_setup(void) {
|
||||
n = isc_mem_get(mctx, sizeof(size_t));
|
||||
assert_non_null(n);
|
||||
*n = i + 1;
|
||||
result = dns_rbt_addname(ctx->rbt, name, n);
|
||||
result = dns_rbt_addnode(ctx->rbt, name, &node);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
node->data = n;
|
||||
|
||||
node = NULL;
|
||||
n = isc_mem_get(mctx, sizeof(size_t));
|
||||
assert_non_null(n);
|
||||
*n = node_distances[i];
|
||||
result = dns_rbt_addname(ctx->rbt_distances, name, n);
|
||||
result = dns_rbt_addnode(ctx->rbt_distances, name, &node);
|
||||
node->data = n;
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
@ -174,8 +178,8 @@ test_context_setup(void) {
|
||||
|
||||
static void
|
||||
test_context_teardown(test_context_t *ctx) {
|
||||
dns_rbt_destroy(&ctx->rbt);
|
||||
dns_rbt_destroy(&ctx->rbt_distances);
|
||||
dns_rbt_destroy(&ctx->rbt, 0);
|
||||
dns_rbt_destroy(&ctx->rbt_distances, 0);
|
||||
|
||||
isc_mem_put(mctx, ctx, sizeof(*ctx));
|
||||
}
|
||||
@ -194,15 +198,18 @@ check_test_data(dns_rbt_t *rbt) {
|
||||
|
||||
for (i = 0; i < domain_names_count; i++) {
|
||||
dns_fixedname_t fname;
|
||||
dns_name_t *name;
|
||||
size_t *n;
|
||||
dns_rbtnode_t *node = NULL;
|
||||
dns_name_t *name = NULL;
|
||||
size_t *n = NULL;
|
||||
|
||||
dns_test_namefromstring(domain_names[i], &fname);
|
||||
|
||||
name = dns_fixedname_name(&fname);
|
||||
n = NULL;
|
||||
result = dns_rbt_findname(rbt, name, 0, foundname, (void *)&n);
|
||||
result = dns_rbt_findnode(rbt, name, foundname, &node, NULL, 0,
|
||||
NULL, NULL);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
n = node->data;
|
||||
assert_int_equal(*n, i + 1);
|
||||
}
|
||||
}
|
||||
@ -311,7 +318,7 @@ ISC_RUN_TEST_IMPL(rbt_check_distance_random) {
|
||||
* yueojmhyffslpvfmgyfwioxegfhepnqq.
|
||||
*/
|
||||
for (i = 0; i < (1 << log_num_nodes); i++) {
|
||||
size_t *n;
|
||||
size_t *n = NULL;
|
||||
char namebuf[34];
|
||||
|
||||
n = isc_mem_get(mctx, sizeof(size_t));
|
||||
@ -321,7 +328,8 @@ ISC_RUN_TEST_IMPL(rbt_check_distance_random) {
|
||||
while (1) {
|
||||
int j;
|
||||
dns_fixedname_t fname;
|
||||
dns_name_t *name;
|
||||
dns_rbtnode_t *node = NULL;
|
||||
dns_name_t *name = NULL;
|
||||
|
||||
for (j = 0; j < 32; j++) {
|
||||
uint32_t v = isc_random_uniform(26);
|
||||
@ -333,7 +341,8 @@ ISC_RUN_TEST_IMPL(rbt_check_distance_random) {
|
||||
dns_test_namefromstring(namebuf, &fname);
|
||||
name = dns_fixedname_name(&fname);
|
||||
|
||||
result = dns_rbt_addname(mytree, name, n);
|
||||
result = dns_rbt_addnode(mytree, name, &node);
|
||||
node->data = n;
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
@ -352,7 +361,7 @@ ISC_RUN_TEST_IMPL(rbt_check_distance_random) {
|
||||
tree_ok = dns__rbt_checkproperties(mytree);
|
||||
assert_true(tree_ok);
|
||||
|
||||
dns_rbt_destroy(&mytree);
|
||||
dns_rbt_destroy(&mytree, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -389,7 +398,8 @@ ISC_RUN_TEST_IMPL(rbt_check_distance_ordered) {
|
||||
size_t *n;
|
||||
char namebuf[14];
|
||||
dns_fixedname_t fname;
|
||||
dns_name_t *name;
|
||||
dns_name_t *name = NULL;
|
||||
dns_rbtnode_t *node = NULL;
|
||||
|
||||
n = isc_mem_get(mctx, sizeof(size_t));
|
||||
assert_non_null(n);
|
||||
@ -399,8 +409,9 @@ ISC_RUN_TEST_IMPL(rbt_check_distance_ordered) {
|
||||
dns_test_namefromstring(namebuf, &fname);
|
||||
name = dns_fixedname_name(&fname);
|
||||
|
||||
result = dns_rbt_addname(mytree, name, n);
|
||||
result = dns_rbt_addnode(mytree, name, &node);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
node->data = n;
|
||||
}
|
||||
|
||||
/* 1 (root . node) + (1 << log_num_nodes) */
|
||||
@ -415,7 +426,7 @@ ISC_RUN_TEST_IMPL(rbt_check_distance_ordered) {
|
||||
tree_ok = dns__rbt_checkproperties(mytree);
|
||||
assert_true(tree_ok);
|
||||
|
||||
dns_rbt_destroy(&mytree);
|
||||
dns_rbt_destroy(&mytree, 0);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
@ -610,6 +621,26 @@ ISC_RUN_TEST_IMPL(rbt_insert) {
|
||||
* as a red-black tree. This test checks node deletion when upper nodes
|
||||
* have data.
|
||||
*/
|
||||
static isc_result_t
|
||||
deletename(dns_rbt_t *mytree, const dns_name_t *name) {
|
||||
isc_result_t result;
|
||||
dns_rbtnode_t *node = NULL;
|
||||
|
||||
result = dns_rbt_findnode(mytree, name, NULL, &node, NULL, 0, NULL,
|
||||
NULL);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
if (node->data != NULL) {
|
||||
result = dns_rbt_deletenode(mytree, node, false);
|
||||
} else {
|
||||
result = ISC_R_NOTFOUND;
|
||||
}
|
||||
} else if (result == DNS_R_PARTIALMATCH) {
|
||||
result = ISC_R_NOTFOUND;
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
ISC_RUN_TEST_IMPL(rbt_remove) {
|
||||
isc_result_t result;
|
||||
size_t j;
|
||||
@ -673,7 +704,7 @@ ISC_RUN_TEST_IMPL(rbt_remove) {
|
||||
|
||||
name = dns_fixedname_name(&fname);
|
||||
|
||||
result = dns_rbt_deletename(mytree, name, false);
|
||||
result = deletename(mytree, name);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
@ -783,7 +814,7 @@ ISC_RUN_TEST_IMPL(rbt_remove) {
|
||||
/* We should have reached the end of the tree. */
|
||||
assert_null(node);
|
||||
|
||||
dns_rbt_destroy(&mytree);
|
||||
dns_rbt_destroy(&mytree, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -840,22 +871,22 @@ remove_nodes(dns_rbt_t *mytree, char **names, size_t *names_count,
|
||||
UNUSED(mytree);
|
||||
|
||||
for (i = 0; i < num_names; i++) {
|
||||
uint32_t node;
|
||||
dns_fixedname_t fname;
|
||||
dns_name_t *name;
|
||||
isc_result_t result;
|
||||
dns_fixedname_t fname;
|
||||
dns_name_t *name = NULL;
|
||||
uint32_t num;
|
||||
|
||||
node = isc_random_uniform(*names_count);
|
||||
num = isc_random_uniform(*names_count);
|
||||
|
||||
dns_test_namefromstring(names[node], &fname);
|
||||
dns_test_namefromstring(names[num], &fname);
|
||||
name = dns_fixedname_name(&fname);
|
||||
|
||||
result = dns_rbt_deletename(mytree, name, false);
|
||||
result = deletename(mytree, name);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
isc_mem_free(mctx, names[node]);
|
||||
isc_mem_free(mctx, names[num]);
|
||||
if (*names_count > 0) {
|
||||
names[node] = names[*names_count - 1];
|
||||
names[num] = names[*names_count - 1];
|
||||
names[*names_count - 1] = NULL;
|
||||
*names_count -= 1;
|
||||
}
|
||||
@ -901,7 +932,8 @@ check_tree(dns_rbt_t *mytree, char **names, size_t names_count) {
|
||||
ISC_RUN_TEST_IMPL(rbt_insert_and_remove) {
|
||||
isc_result_t result;
|
||||
dns_rbt_t *mytree = NULL;
|
||||
size_t *n;
|
||||
size_t *n = NULL;
|
||||
dns_rbtnode_t *node = NULL;
|
||||
char *names[1024];
|
||||
size_t names_count;
|
||||
int i;
|
||||
@ -913,8 +945,9 @@ ISC_RUN_TEST_IMPL(rbt_insert_and_remove) {
|
||||
|
||||
n = isc_mem_get(mctx, sizeof(size_t));
|
||||
assert_non_null(n);
|
||||
result = dns_rbt_addname(mytree, dns_rootname, n);
|
||||
result = dns_rbt_addnode(mytree, dns_rootname, &node);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
node->data = n;
|
||||
|
||||
memset(names, 0, sizeof(names));
|
||||
names_count = 0;
|
||||
@ -954,116 +987,11 @@ ISC_RUN_TEST_IMPL(rbt_insert_and_remove) {
|
||||
}
|
||||
}
|
||||
|
||||
result = dns_rbt_deletename(mytree, dns_rootname, false);
|
||||
result = deletename(mytree, dns_rootname);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
assert_int_equal(dns_rbt_nodecount(mytree), 0);
|
||||
|
||||
dns_rbt_destroy(&mytree);
|
||||
}
|
||||
|
||||
/* Test findname return values */
|
||||
ISC_RUN_TEST_IMPL(rbt_findname) {
|
||||
isc_result_t result;
|
||||
test_context_t *ctx = NULL;
|
||||
dns_fixedname_t fname, found;
|
||||
dns_name_t *name = NULL, *foundname = NULL;
|
||||
size_t *n = NULL;
|
||||
|
||||
isc_mem_debugging = ISC_MEM_DEBUGRECORD;
|
||||
|
||||
ctx = test_context_setup();
|
||||
|
||||
/* Try to find a name that exists. */
|
||||
dns_test_namefromstring("d.e.f.", &fname);
|
||||
name = dns_fixedname_name(&fname);
|
||||
|
||||
foundname = dns_fixedname_initname(&found);
|
||||
|
||||
result = dns_rbt_findname(ctx->rbt, name, DNS_RBTFIND_EMPTYDATA,
|
||||
foundname, (void *)&n);
|
||||
assert_true(dns_name_equal(foundname, name));
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
/* Now without EMPTYDATA */
|
||||
result = dns_rbt_findname(ctx->rbt, name, 0, foundname, (void *)&n);
|
||||
assert_int_equal(result, ISC_R_NOTFOUND);
|
||||
|
||||
/* Now one that partially matches */
|
||||
dns_test_namefromstring("d.e.f.g.h.i.j.", &fname);
|
||||
name = dns_fixedname_name(&fname);
|
||||
result = dns_rbt_findname(ctx->rbt, name, DNS_RBTFIND_EMPTYDATA,
|
||||
foundname, (void *)&n);
|
||||
assert_int_equal(result, DNS_R_PARTIALMATCH);
|
||||
|
||||
/* Now one that doesn't match */
|
||||
dns_test_namefromstring("1.2.", &fname);
|
||||
name = dns_fixedname_name(&fname);
|
||||
result = dns_rbt_findname(ctx->rbt, name, DNS_RBTFIND_EMPTYDATA,
|
||||
foundname, (void *)&n);
|
||||
assert_int_equal(result, DNS_R_PARTIALMATCH);
|
||||
assert_true(dns_name_equal(foundname, dns_rootname));
|
||||
|
||||
test_context_teardown(ctx);
|
||||
}
|
||||
|
||||
/* Test addname return values */
|
||||
ISC_RUN_TEST_IMPL(rbt_addname) {
|
||||
isc_result_t result;
|
||||
test_context_t *ctx = NULL;
|
||||
dns_fixedname_t fname;
|
||||
dns_name_t *name = NULL;
|
||||
size_t *n;
|
||||
|
||||
isc_mem_debugging = ISC_MEM_DEBUGRECORD;
|
||||
|
||||
ctx = test_context_setup();
|
||||
|
||||
n = isc_mem_get(mctx, sizeof(size_t));
|
||||
assert_non_null(n);
|
||||
*n = 1;
|
||||
|
||||
dns_test_namefromstring("d.e.f.g.h.i.j.k.", &fname);
|
||||
name = dns_fixedname_name(&fname);
|
||||
|
||||
/* Add a name that doesn't exist */
|
||||
result = dns_rbt_addname(ctx->rbt, name, n);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
/* Now add again, should get ISC_R_EXISTS */
|
||||
n = isc_mem_get(mctx, sizeof(size_t));
|
||||
assert_non_null(n);
|
||||
*n = 2;
|
||||
result = dns_rbt_addname(ctx->rbt, name, n);
|
||||
assert_int_equal(result, ISC_R_EXISTS);
|
||||
isc_mem_put(mctx, n, sizeof(size_t));
|
||||
|
||||
test_context_teardown(ctx);
|
||||
}
|
||||
|
||||
/* Test deletename return values */
|
||||
ISC_RUN_TEST_IMPL(rbt_deletename) {
|
||||
isc_result_t result;
|
||||
test_context_t *ctx = NULL;
|
||||
dns_fixedname_t fname;
|
||||
dns_name_t *name = NULL;
|
||||
|
||||
isc_mem_debugging = ISC_MEM_DEBUGRECORD;
|
||||
|
||||
ctx = test_context_setup();
|
||||
|
||||
/* Delete a name that doesn't exist */
|
||||
dns_test_namefromstring("z.x.y.w.", &fname);
|
||||
name = dns_fixedname_name(&fname);
|
||||
result = dns_rbt_deletename(ctx->rbt, name, false);
|
||||
assert_int_equal(result, ISC_R_NOTFOUND);
|
||||
|
||||
/* Now one that does */
|
||||
dns_test_namefromstring("d.e.f.", &fname);
|
||||
name = dns_fixedname_name(&fname);
|
||||
result = dns_rbt_deletename(ctx->rbt, name, false);
|
||||
assert_int_equal(result, ISC_R_NOTFOUND);
|
||||
|
||||
test_context_teardown(ctx);
|
||||
dns_rbt_destroy(&mytree, 0);
|
||||
}
|
||||
|
||||
/* Test nodechain */
|
||||
@ -1124,7 +1052,7 @@ ISC_RUN_TEST_IMPL(rbt_nodechain) {
|
||||
test_context_teardown(ctx);
|
||||
}
|
||||
|
||||
/* Test addname return values */
|
||||
/* Test name lengths */
|
||||
ISC_RUN_TEST_IMPL(rbtnode_namelen) {
|
||||
isc_result_t result;
|
||||
test_context_t *ctx = NULL;
|
||||
@ -1270,7 +1198,7 @@ ISC_RUN_TEST_IMPL(benchmark) {
|
||||
free(names);
|
||||
free(fnames);
|
||||
|
||||
dns_rbt_destroy(&mytree);
|
||||
dns_rbt_destroy(&mytree, 0);
|
||||
}
|
||||
#endif /* defined(DNS_BENCHMARK_TESTS) && !defined(__SANITIZE_THREAD__) */
|
||||
|
||||
@ -1283,9 +1211,6 @@ ISC_TEST_ENTRY(rbt_check_distance_ordered)
|
||||
ISC_TEST_ENTRY(rbt_insert)
|
||||
ISC_TEST_ENTRY(rbt_remove)
|
||||
ISC_TEST_ENTRY(rbt_insert_and_remove)
|
||||
ISC_TEST_ENTRY(rbt_findname)
|
||||
ISC_TEST_ENTRY(rbt_addname)
|
||||
ISC_TEST_ENTRY(rbt_deletename)
|
||||
ISC_TEST_ENTRY(rbt_nodechain)
|
||||
ISC_TEST_ENTRY(rbtnode_namelen)
|
||||
#if defined(DNS_BENCHMARK_TESTS) && !defined(__SANITIZE_THREAD__)
|
||||
|
Loading…
x
Reference in New Issue
Block a user