2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-29 05:28:00 +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:
Evan Hunt 2024-02-14 09:45:58 +00:00
commit 9279a1038b
5 changed files with 113 additions and 433 deletions

View File

@ -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 &lt;something_else> Any error result from dns_name_concatenate.
*/

View File

@ -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) {
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);
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 (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(&current_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);

View File

@ -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) {

View File

@ -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);
}

View File

@ -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__)