mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-30 05:57:52 +00:00
performance enhancements, deleter arg
This commit is contained in:
parent
c5839c39bd
commit
1630fce031
@ -24,14 +24,9 @@
|
||||
/*
|
||||
* This is the structure that is used for each node in the red/black
|
||||
* tree of trees. NOTE WELL: the implementation manages this as a variable
|
||||
* length structure, with the actual wire-format name being stored as
|
||||
* a sequence of "name_length" bytes appended to this structure. Allocating
|
||||
* a contiguous block of memory for multiple dns_rbt_node structures is
|
||||
* pretty much guaranteed to be useless.
|
||||
*
|
||||
* Note that the name_length variable will indicate how long just the length
|
||||
* of the label(s) associated with this tree, not the length of the entire
|
||||
* name the node is part of.
|
||||
* length structure, with the actual wire-format name and other data appended
|
||||
* appended to this structure. Allocating a contiguous block of memory for
|
||||
* multiple dns_rbt_node structures will not work.
|
||||
*/
|
||||
|
||||
typedef struct dns_rbt dns_rbt_t;
|
||||
@ -52,7 +47,7 @@ typedef struct dns_rbt_node {
|
||||
unsigned int references:DNS_RBT_REFLENGTH;
|
||||
} dns_rbtnode_t;
|
||||
|
||||
typedef struct node_chain node_chain_t;
|
||||
typedef struct dns_rbtnodechain dns_rbtnodechain_t;
|
||||
|
||||
dns_result_t dns_rbt_addname(dns_rbt_t *rbt, dns_name_t *name, void *data);
|
||||
/*
|
||||
@ -126,7 +121,7 @@ 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,
|
||||
node_chain_t *chain);
|
||||
dns_rbtnodechain_t *chain);
|
||||
/*
|
||||
* Find the node for 'name'.
|
||||
*
|
||||
@ -149,6 +144,6 @@ void dns_rbt_printnodename(dns_rbtnode_t *node);
|
||||
void dns_rbt_printtree(dns_rbtnode_t *root, dns_rbtnode_t *parent, int depth);
|
||||
void dns_rbt_printall(dns_rbt_t *rbt);
|
||||
|
||||
dns_result_t dns_rbt_create(isc_mem_t *mctx, void (*deleter)(void *),
|
||||
dns_rbt_t **rbtp);
|
||||
dns_result_t dns_rbt_create(isc_mem_t *mctx, void (*deleter)(void *, void *),
|
||||
void *arg, dns_rbt_t **rbtp);
|
||||
void dns_rbt_destroy(dns_rbt_t **rbtp);
|
||||
|
225
lib/dns/rbt.c
225
lib/dns/rbt.c
@ -37,10 +37,11 @@ struct dns_rbt {
|
||||
unsigned int magic;
|
||||
isc_mem_t * mctx;
|
||||
dns_rbtnode_t * root;
|
||||
void (*data_deleter)(void *);
|
||||
void (*data_deleter)(void *, void *);
|
||||
void * deleter_arg;
|
||||
};
|
||||
|
||||
struct node_chain {
|
||||
struct dns_rbtnodechain {
|
||||
dns_rbtnode_t ** ancestors;
|
||||
int ancestor_count;
|
||||
int ancestor_maxitems;
|
||||
@ -63,8 +64,9 @@ struct node_chain {
|
||||
#define LEFT(node) ((node)->left)
|
||||
#define RIGHT(node) ((node)->right)
|
||||
#define DOWN(node) ((node)->down)
|
||||
#define NAMELEN(node) (*(unsigned char *)((node) + 1))
|
||||
#define NAME(node) ((void *)((char *)(node) + sizeof(*node) + 1))
|
||||
#define NAMELEN(node) (((unsigned char *)((node) + 1))[0])
|
||||
#define OFFSETLEN(node) (((unsigned char *)((node) + 1))[1])
|
||||
#define NAME(node) (&((unsigned char *)((node) + 1))[3])
|
||||
#define DATA(node) ((node)->data)
|
||||
#define COLOR(node) ((node)->color)
|
||||
#define DIRTY(node) ((node)->dirty)
|
||||
@ -76,7 +78,43 @@ struct node_chain {
|
||||
#define MAKE_RED(node) ((node)->color = RED)
|
||||
#define MAKE_BLACK(node) ((node)->color = BLACK)
|
||||
|
||||
#define NODE_SIZE(node) (sizeof(*node) + 1 + NAMELEN(node))
|
||||
#define NODE_SIZE(node) (sizeof(*node) + 3 + NAMELEN(node) + OFFSETLEN(node))
|
||||
|
||||
/*
|
||||
* The following macros directly access normally private name variables.
|
||||
* These macros are used to avoid a lot of function calls in the critical
|
||||
* path of the tree traversal code.
|
||||
*/
|
||||
|
||||
#define NODENAME(node, name) \
|
||||
do { \
|
||||
unsigned char *__current; \
|
||||
(name)->attributes = DNS_NAMEATTR_READONLY; \
|
||||
__current = (unsigned char *)&(node)[1]; \
|
||||
(name)->length = *__current++; \
|
||||
(name)->labels = *__current++; \
|
||||
if (*__current++ == 1) \
|
||||
(name)->attributes |= DNS_NAMEATTR_ABSOLUTE; \
|
||||
(name)->ndata = __current; \
|
||||
__current += (name)->length; \
|
||||
(name)->offsets = __current; \
|
||||
} while (0)
|
||||
|
||||
#define FAST_GETLABEL(name, n, label) \
|
||||
do { \
|
||||
(label)->base = &((name)->ndata[(name)->offsets[(n)]]); \
|
||||
if ((unsigned int)(n) == (name)->labels - 1) \
|
||||
(label)->length = (name)->length - (name)->offsets[(n)]; \
|
||||
else \
|
||||
(label)->length = (name)->offsets[(n) + 1] - \
|
||||
(name)->offsets[(n)]; \
|
||||
} while (0)
|
||||
|
||||
#define FAST_ISABSOLUTE(name) \
|
||||
(((name)->attributes & DNS_NAMEATTR_ABSOLUTE) ? ISC_TRUE : ISC_FALSE)
|
||||
|
||||
#define FAST_COUNTLABELS(name) \
|
||||
((name)->labels)
|
||||
|
||||
/*
|
||||
* For the return value of cmp_names_for_depth().
|
||||
@ -127,7 +165,7 @@ static dns_result_t join_nodes(dns_rbt_t *rbt,
|
||||
dns_rbtnode_t **rootp);
|
||||
|
||||
static inline dns_result_t get_ancestor_mem(isc_mem_t *mctx,
|
||||
node_chain_t *chain);
|
||||
dns_rbtnodechain_t *chain);
|
||||
|
||||
static int cmp_label(dns_label_t *a, dns_label_t *b);
|
||||
static inline int cmp_names_on_level(dns_name_t *a, dns_name_t *b);
|
||||
@ -141,22 +179,24 @@ static inline void rotate_right(dns_rbtnode_t *node, dns_rbtnode_t *parent,
|
||||
static dns_result_t dns_rbt_addonlevel(dns_rbt_t *rbt,
|
||||
dns_rbtnode_t *node,
|
||||
dns_rbtnode_t **rootp,
|
||||
node_chain_t *chain);
|
||||
dns_rbtnodechain_t *chain);
|
||||
static void dns_rbt_deletefromlevel(dns_rbt_t *rbt,
|
||||
dns_rbtnode_t *delete,
|
||||
node_chain_t *chain);
|
||||
dns_rbtnodechain_t *chain);
|
||||
static void dns_rbt_deletetree(dns_rbt_t *rbt, dns_rbtnode_t *node);
|
||||
|
||||
static dns_result_t zapnode_and_fixlevels(dns_rbt_t *rbt,
|
||||
dns_rbtnode_t *node,
|
||||
isc_boolean_t recurse,
|
||||
node_chain_t *chain);
|
||||
dns_rbtnodechain_t *chain);
|
||||
|
||||
/*
|
||||
* Initialize a red/black tree of trees.
|
||||
*/
|
||||
dns_result_t
|
||||
dns_rbt_create(isc_mem_t *mctx, void (*deleter)(void *), dns_rbt_t **rbtp) {
|
||||
dns_rbt_create(isc_mem_t *mctx, void (*deleter)(void *, void *), void *arg,
|
||||
dns_rbt_t **rbtp)
|
||||
{
|
||||
dns_rbt_t *rbt;
|
||||
|
||||
REQUIRE(mctx != NULL);
|
||||
@ -168,6 +208,7 @@ dns_rbt_create(isc_mem_t *mctx, void (*deleter)(void *), dns_rbt_t **rbtp) {
|
||||
|
||||
rbt->mctx = mctx;
|
||||
rbt->data_deleter = deleter;
|
||||
rbt->deleter_arg = arg;
|
||||
rbt->root = NULL;
|
||||
rbt->magic = RBT_MAGIC;
|
||||
|
||||
@ -211,17 +252,21 @@ dns_rbt_addnode(dns_rbt_t *rbt, dns_name_t *name, dns_rbtnode_t **nodep) {
|
||||
dns_name_t add_name, current_name, new_name, tmp_name;
|
||||
int compared, add_labels, current_labels, keep_labels, start_label;
|
||||
dns_result_t result;
|
||||
node_chain_t chain;
|
||||
dns_rbtnodechain_t chain;
|
||||
dns_offsets_t o1, o2;
|
||||
isc_region_t r;
|
||||
|
||||
REQUIRE(VALID_RBT(rbt));
|
||||
REQUIRE(dns_name_isabsolute(name));
|
||||
REQUIRE(FAST_ISABSOLUTE(name));
|
||||
REQUIRE(nodep != NULL && *nodep == NULL);
|
||||
|
||||
/*
|
||||
* Create a copy of the name so the original name structure is
|
||||
* not modified.
|
||||
*/
|
||||
memcpy(&add_name, name, sizeof(add_name));
|
||||
dns_name_init(&add_name, o1);
|
||||
dns_name_toregion(name, &r);
|
||||
dns_name_fromregion(&add_name, &r);
|
||||
|
||||
if (rbt->root == NULL) {
|
||||
result = create_node(rbt->mctx, &add_name, &new_node);
|
||||
@ -239,7 +284,7 @@ dns_rbt_addnode(dns_rbt_t *rbt, dns_name_t *name, dns_rbtnode_t **nodep) {
|
||||
do {
|
||||
current = child;
|
||||
|
||||
dns_rbt_namefromnode(current, ¤t_name);
|
||||
NODENAME(current, ¤t_name);
|
||||
compared = cmp_names_for_depth(&add_name, ¤t_name);
|
||||
|
||||
if (compared == BOTH_ARE_EQUAL) {
|
||||
@ -268,8 +313,8 @@ dns_rbt_addnode(dns_rbt_t *rbt, dns_name_t *name, dns_rbtnode_t **nodep) {
|
||||
* the non-common parts of these two names should
|
||||
* start a new tree.
|
||||
*/
|
||||
add_labels = dns_name_countlabels(&add_name);
|
||||
current_labels = dns_name_countlabels(¤t_name);
|
||||
add_labels = FAST_COUNTLABELS(&add_name);
|
||||
current_labels = FAST_COUNTLABELS(¤t_name);
|
||||
|
||||
/*
|
||||
* When *root == rbt->root, the current tree level is
|
||||
@ -323,7 +368,7 @@ dns_rbt_addnode(dns_rbt_t *rbt, dns_name_t *name, dns_rbtnode_t **nodep) {
|
||||
start_label = current_labels - compared;
|
||||
keep_labels = compared + (*root == rbt->root);
|
||||
|
||||
dns_name_init(&tmp_name, NULL);
|
||||
dns_name_init(&tmp_name, o2);
|
||||
dns_name_getlabelsequence(¤t_name,
|
||||
start_label,
|
||||
keep_labels,
|
||||
@ -385,7 +430,7 @@ dns_rbt_addnode(dns_rbt_t *rbt, dns_name_t *name, dns_rbtnode_t **nodep) {
|
||||
|
||||
/*
|
||||
* Now that the old name in the existing
|
||||
* node has been disected into two new
|
||||
* node has been dissected into two new
|
||||
* nodes, the old node can be freed.
|
||||
*/
|
||||
isc_mem_put(rbt->mctx, current,
|
||||
@ -444,6 +489,7 @@ dns_rbt_addnode(dns_rbt_t *rbt, dns_name_t *name, dns_rbtnode_t **nodep) {
|
||||
result = dns_rbt_addonlevel(rbt, new_node, root, &chain);
|
||||
/* XXXRTH Free node if add fails? */
|
||||
/* XXXRTH Is it true that result should never be DNS_R_EXISTS? */
|
||||
INSIST(result != DNS_R_EXISTS);
|
||||
|
||||
if (chain.ancestor_maxitems > 0)
|
||||
isc_mem_put(rbt->mctx, chain.ancestors,
|
||||
@ -461,7 +507,7 @@ dns_rbt_addname(dns_rbt_t *rbt, dns_name_t *name, void *data) {
|
||||
dns_rbtnode_t *node;
|
||||
|
||||
REQUIRE(VALID_RBT(rbt));
|
||||
REQUIRE(dns_name_isabsolute(name));
|
||||
REQUIRE(FAST_ISABSOLUTE(name));
|
||||
|
||||
node = NULL;
|
||||
|
||||
@ -483,25 +529,30 @@ dns_rbt_addname(dns_rbt_t *rbt, dns_name_t *name, void *data) {
|
||||
* the down pointer for the found node.
|
||||
*/
|
||||
dns_rbtnode_t *
|
||||
dns_rbt_findnode(dns_rbt_t *rbt, dns_name_t *name, node_chain_t *chain) {
|
||||
dns_rbt_findnode(dns_rbt_t *rbt, dns_name_t *name, dns_rbtnodechain_t *chain) {
|
||||
dns_rbtnode_t *current;
|
||||
dns_name_t *search_name, *new_search_name, *current_name;
|
||||
dns_name_t holder1, holder2;
|
||||
dns_name_t holder1, holder2, orig;
|
||||
int compared, current_labels, keep_labels, dont_count_root_label;
|
||||
dns_offsets_t o1, o2, o3, o4;
|
||||
isc_region_t r;
|
||||
|
||||
REQUIRE(VALID_RBT(rbt));
|
||||
REQUIRE(dns_name_isabsolute(name));
|
||||
REQUIRE(FAST_ISABSOLUTE(name));
|
||||
|
||||
/*
|
||||
* search_name is the name segment being sought in each tree level.
|
||||
*/
|
||||
search_name = name;
|
||||
dns_name_init(&orig, o1);
|
||||
dns_name_toregion(name, &r);
|
||||
dns_name_fromregion(&orig, &r);
|
||||
search_name = &orig;
|
||||
|
||||
current = rbt->root;
|
||||
dont_count_root_label = 1;
|
||||
|
||||
dns_name_init(&holder1, NULL);
|
||||
dns_name_init(&holder2, NULL);
|
||||
dns_name_init(&holder1, o2);
|
||||
dns_name_init(&holder2, o3);
|
||||
|
||||
current_name = &holder1;
|
||||
|
||||
@ -517,7 +568,7 @@ dns_rbt_findnode(dns_rbt_t *rbt, dns_name_t *name, node_chain_t *chain) {
|
||||
}
|
||||
|
||||
while (current != NULL) {
|
||||
dns_rbt_namefromnode(current, current_name);
|
||||
NODENAME(current, current_name);
|
||||
compared = cmp_names_for_depth(search_name, current_name);
|
||||
|
||||
if (compared == BOTH_ARE_EQUAL)
|
||||
@ -554,7 +605,7 @@ dns_rbt_findnode(dns_rbt_t *rbt, dns_name_t *name, node_chain_t *chain) {
|
||||
* the down pointer and search in the new tree.
|
||||
*/
|
||||
|
||||
current_labels = dns_name_countlabels(current_name)
|
||||
current_labels = FAST_COUNTLABELS(current_name)
|
||||
- dont_count_root_label;
|
||||
|
||||
if (compared == current_labels) {
|
||||
@ -570,11 +621,11 @@ dns_rbt_findnode(dns_rbt_t *rbt, dns_name_t *name, node_chain_t *chain) {
|
||||
current_name = &holder1;
|
||||
}
|
||||
|
||||
keep_labels = dns_name_countlabels(search_name)
|
||||
keep_labels = FAST_COUNTLABELS(search_name)
|
||||
- dont_count_root_label
|
||||
- compared;
|
||||
|
||||
dns_name_init(new_search_name, NULL);
|
||||
dns_name_init(new_search_name, o4);
|
||||
dns_name_getlabelsequence(search_name,
|
||||
0,
|
||||
keep_labels,
|
||||
@ -630,10 +681,10 @@ dns_result_t
|
||||
dns_rbt_deletename(dns_rbt_t *rbt, dns_name_t *name, isc_boolean_t recurse) {
|
||||
dns_rbtnode_t *node;
|
||||
dns_result_t result;
|
||||
node_chain_t chain;
|
||||
dns_rbtnodechain_t chain;
|
||||
|
||||
REQUIRE(VALID_RBT(rbt));
|
||||
REQUIRE(dns_name_isabsolute(name));
|
||||
REQUIRE(FAST_ISABSOLUTE(name));
|
||||
|
||||
/*
|
||||
* Find the node, building the ancestor chain.
|
||||
@ -668,7 +719,7 @@ dns_rbt_deletename(dns_rbt_t *rbt, dns_name_t *name, isc_boolean_t recurse) {
|
||||
|
||||
static dns_result_t
|
||||
zapnode_and_fixlevels(dns_rbt_t *rbt, dns_rbtnode_t *node,
|
||||
isc_boolean_t recurse, node_chain_t *chain) {
|
||||
isc_boolean_t recurse, dns_rbtnodechain_t *chain) {
|
||||
dns_rbtnode_t *down, *parent, **rootp;
|
||||
dns_result_t result;
|
||||
|
||||
@ -687,7 +738,8 @@ zapnode_and_fixlevels(dns_rbt_t *rbt, dns_rbtnode_t *node,
|
||||
|
||||
} else {
|
||||
if (rbt->data_deleter != NULL)
|
||||
rbt->data_deleter(DATA(node));
|
||||
rbt->data_deleter(DATA(node),
|
||||
rbt->deleter_arg);
|
||||
DATA(node) = NULL;
|
||||
|
||||
if (LEFT(down) != NULL || RIGHT(down) != NULL)
|
||||
@ -725,7 +777,7 @@ zapnode_and_fixlevels(dns_rbt_t *rbt, dns_rbtnode_t *node,
|
||||
dns_rbt_deletefromlevel(rbt, node, chain);
|
||||
|
||||
if (rbt->data_deleter != NULL)
|
||||
rbt->data_deleter(DATA(node));
|
||||
rbt->data_deleter(DATA(node), rbt->deleter_arg);
|
||||
isc_mem_put(rbt->mctx, node, NODE_SIZE(node));
|
||||
|
||||
/*
|
||||
@ -773,27 +825,37 @@ zapnode_and_fixlevels(dns_rbt_t *rbt, dns_rbtnode_t *node,
|
||||
|
||||
void
|
||||
dns_rbt_namefromnode(dns_rbtnode_t *node, dns_name_t *name) {
|
||||
isc_region_t r;
|
||||
|
||||
r.length = NAMELEN(node);
|
||||
r.base = NAME(node);
|
||||
REQUIRE(name->offsets == NULL);
|
||||
|
||||
dns_name_fromregion(name, &r);
|
||||
NODENAME(node, name);
|
||||
}
|
||||
|
||||
static dns_result_t
|
||||
create_node(isc_mem_t *mctx, dns_name_t *name, dns_rbtnode_t **nodep) {
|
||||
dns_rbtnode_t *node;
|
||||
isc_region_t region;
|
||||
unsigned int labels;
|
||||
unsigned char *current;
|
||||
unsigned char absolute;
|
||||
|
||||
REQUIRE(name->offsets != NULL); /* XXX direct access to name. */
|
||||
|
||||
dns_name_toregion(name, ®ion);
|
||||
labels = FAST_COUNTLABELS(name);
|
||||
if (FAST_ISABSOLUTE(name))
|
||||
absolute = 1;
|
||||
else
|
||||
absolute = 0;
|
||||
|
||||
/*
|
||||
* Allocate space for the node structure, plus the length byte,
|
||||
* plus the length of the name.
|
||||
*/
|
||||
node = (dns_rbtnode_t *)isc_mem_get(mctx,
|
||||
sizeof(*node) + 1 + region.length);
|
||||
sizeof(*node) + 3 +
|
||||
region.length + labels);
|
||||
|
||||
if (node == NULL)
|
||||
return (DNS_R_NOMEMORY);
|
||||
|
||||
@ -802,14 +864,31 @@ create_node(isc_mem_t *mctx, dns_name_t *name, dns_rbtnode_t **nodep) {
|
||||
DOWN(node) = NULL;
|
||||
DATA(node) = NULL;
|
||||
|
||||
LOCK(node) = 0; /* @@@ ? */
|
||||
LOCK(node) = 0;
|
||||
REFS(node) = 0;
|
||||
DIRTY(node) = 0;
|
||||
|
||||
MAKE_BLACK(node);
|
||||
|
||||
NAMELEN(node) = region.length;
|
||||
memcpy(NAME(node), region.base, region.length);
|
||||
/*
|
||||
* To make reconstructing a name from the stored value in the node
|
||||
* easy, we store the length of the name, the number of labels,
|
||||
* whether the name is absolute or not, the name itself, and the
|
||||
* name's offsets table.
|
||||
*
|
||||
* XXX Finding a way not to waste a byte on "absolute" would be
|
||||
* a good thing, though it may be that we'll have to store
|
||||
* other attributes someday. The offsets table could be made
|
||||
* smaller by eliminating the first offset, which is always 0.
|
||||
* This requires changes to lib/dns/name.c.
|
||||
*/
|
||||
current = (unsigned char *)&node[1];
|
||||
*current++ = region.length;
|
||||
*current++ = labels;
|
||||
*current++ = absolute;
|
||||
memcpy(current, region.base, region.length);
|
||||
current += region.length;
|
||||
memcpy(current, name->offsets, labels);
|
||||
|
||||
*nodep = node;
|
||||
|
||||
@ -824,6 +903,7 @@ join_nodes(dns_rbt_t *rbt,
|
||||
dns_name_t newname;
|
||||
isc_region_t r;
|
||||
int newsize;
|
||||
dns_offsets_t offsets;
|
||||
|
||||
REQUIRE(VALID_RBT(rbt));
|
||||
REQUIRE(node != NULL);
|
||||
@ -844,13 +924,11 @@ join_nodes(dns_rbt_t *rbt,
|
||||
|
||||
r.length = newsize;
|
||||
|
||||
dns_name_init(&newname, NULL);
|
||||
dns_name_init(&newname, offsets);
|
||||
dns_name_fromregion(&newname, &r);
|
||||
|
||||
result = create_node(rbt->mctx, &newname, &newnode);
|
||||
if (result == DNS_R_SUCCESS) {
|
||||
isc_mem_put(rbt->mctx, r.base, r.length);
|
||||
|
||||
COLOR(newnode) = COLOR(node);
|
||||
RIGHT(newnode) = RIGHT(node);
|
||||
LEFT(newnode) = LEFT(node);
|
||||
@ -873,12 +951,13 @@ join_nodes(dns_rbt_t *rbt,
|
||||
isc_mem_put(rbt->mctx, node, NODE_SIZE(node));
|
||||
isc_mem_put(rbt->mctx, down, NODE_SIZE(down));
|
||||
}
|
||||
isc_mem_put(rbt->mctx, r.base, r.length);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
static inline dns_result_t
|
||||
get_ancestor_mem(isc_mem_t *mctx, node_chain_t *chain) {
|
||||
get_ancestor_mem(isc_mem_t *mctx, dns_rbtnodechain_t *chain) {
|
||||
dns_rbtnode_t **ancestor_mem;
|
||||
int oldsize, newsize;
|
||||
|
||||
@ -955,7 +1034,7 @@ rotate_right(dns_rbtnode_t *node, dns_rbtnode_t *parent, dns_rbtnode_t **rootp)
|
||||
*/
|
||||
static dns_result_t
|
||||
dns_rbt_addonlevel(dns_rbt_t *rbt, dns_rbtnode_t *node, dns_rbtnode_t **rootp,
|
||||
node_chain_t *chain) {
|
||||
dns_rbtnodechain_t *chain) {
|
||||
dns_rbtnode_t *current, *child, *root, *tmp, *parent, *grandparent;
|
||||
dns_name_t add_name, current_name;
|
||||
dns_offsets_t offsets;
|
||||
@ -979,7 +1058,7 @@ dns_rbt_addonlevel(dns_rbt_t *rbt, dns_rbtnode_t *node, dns_rbtnode_t **rootp,
|
||||
child = root;
|
||||
|
||||
dns_name_init(&add_name, offsets);
|
||||
dns_rbt_namefromnode(node, &add_name);
|
||||
NODENAME(node, &add_name);
|
||||
|
||||
dns_name_init(¤t_name, NULL);
|
||||
|
||||
@ -991,7 +1070,7 @@ dns_rbt_addonlevel(dns_rbt_t *rbt, dns_rbtnode_t *node, dns_rbtnode_t **rootp,
|
||||
|
||||
current = child;
|
||||
|
||||
dns_rbt_namefromnode(current, ¤t_name);
|
||||
NODENAME(current, ¤t_name);
|
||||
|
||||
i = cmp_names_on_level(&add_name, ¤t_name);
|
||||
if (i == 0)
|
||||
@ -1086,7 +1165,7 @@ dns_rbt_addonlevel(dns_rbt_t *rbt, dns_rbtnode_t *node, dns_rbtnode_t **rootp,
|
||||
*/
|
||||
static void
|
||||
dns_rbt_deletefromlevel(dns_rbt_t *rbt, dns_rbtnode_t *delete,
|
||||
node_chain_t *chain) {
|
||||
dns_rbtnodechain_t *chain) {
|
||||
dns_rbtnode_t *sibling, *parent, *grandparent, *child;
|
||||
dns_rbtnode_t *successor, **rootp;
|
||||
int depth;
|
||||
@ -1321,7 +1400,7 @@ dns_rbt_deletefromlevel(dns_rbt_t *rbt, dns_rbtnode_t *delete,
|
||||
*
|
||||
* If the function is ever intended to be used to delete something where
|
||||
* a pointer needs to be told that this tree no longer exists,
|
||||
* this function would need to adjusted accordinly.
|
||||
* this function would need to adjusted accordingly.
|
||||
*/
|
||||
static void
|
||||
dns_rbt_deletetree(dns_rbt_t *rbt, dns_rbtnode_t *node) {
|
||||
@ -1339,7 +1418,7 @@ dns_rbt_deletetree(dns_rbt_t *rbt, dns_rbtnode_t *node) {
|
||||
dns_rbt_deletetree(rbt, DOWN(node));
|
||||
|
||||
if (DATA(node) != NULL && rbt->data_deleter != NULL)
|
||||
rbt->data_deleter(DATA(node));
|
||||
rbt->data_deleter(DATA(node), rbt->deleter_arg);
|
||||
|
||||
isc_mem_put(rbt->mctx, node, NODE_SIZE(node));
|
||||
}
|
||||
@ -1358,7 +1437,7 @@ dns_rbt_deletetree(dns_rbt_t *rbt, dns_rbtnode_t *node) {
|
||||
* This whole file as yet does nothing special with bitstrings.
|
||||
*/
|
||||
|
||||
static int
|
||||
static inline int
|
||||
cmp_label(dns_label_t *a, dns_label_t *b) {
|
||||
int i;
|
||||
|
||||
@ -1392,21 +1471,25 @@ static inline int
|
||||
cmp_names_for_depth(dns_name_t *a, dns_name_t *b) {
|
||||
dns_label_t alabel, blabel;
|
||||
int aindex, bindex, compared, common;
|
||||
isc_boolean_t aabs, babs;
|
||||
|
||||
aindex = dns_name_countlabels(a) - 1;
|
||||
bindex = dns_name_countlabels(b) - 1;
|
||||
aindex = FAST_COUNTLABELS(a) - 1;
|
||||
bindex = FAST_COUNTLABELS(b) - 1;
|
||||
aabs = FAST_ISABSOLUTE(a);
|
||||
babs = FAST_ISABSOLUTE(b);
|
||||
|
||||
INSIST(( dns_name_isabsolute(a) && dns_name_isabsolute(b)) ||
|
||||
(!dns_name_isabsolute(a) && !dns_name_isabsolute(b)));
|
||||
INSIST((aabs && babs) || (!aabs && !babs));
|
||||
|
||||
if (dns_name_isabsolute(a))
|
||||
aindex--, bindex--;
|
||||
if (aabs) {
|
||||
aindex--;
|
||||
bindex--;
|
||||
}
|
||||
|
||||
common = 0;
|
||||
|
||||
for (; aindex >= 0 && bindex >= 0; aindex--, bindex--) {
|
||||
dns_name_getlabel(a, aindex, &alabel);
|
||||
dns_name_getlabel(b, bindex, &blabel);
|
||||
FAST_GETLABEL(a, aindex, &alabel);
|
||||
FAST_GETLABEL(b, bindex, &blabel);
|
||||
|
||||
compared = cmp_label(&alabel, &blabel);
|
||||
if (compared == 0)
|
||||
@ -1438,18 +1521,22 @@ static inline int
|
||||
cmp_names_on_level(dns_name_t *a, dns_name_t *b) {
|
||||
dns_label_t alabel, blabel;
|
||||
int a_last_label, b_last_label;
|
||||
isc_boolean_t aabs, babs;
|
||||
|
||||
a_last_label = dns_name_countlabels(a) - 1;
|
||||
b_last_label = dns_name_countlabels(b) - 1;
|
||||
a_last_label = FAST_COUNTLABELS(a) - 1;
|
||||
b_last_label = FAST_COUNTLABELS(b) - 1;
|
||||
aabs = FAST_ISABSOLUTE(a);
|
||||
babs = FAST_ISABSOLUTE(b);
|
||||
|
||||
INSIST(( dns_name_isabsolute(a) && dns_name_isabsolute(b)) ||
|
||||
(!dns_name_isabsolute(a) && !dns_name_isabsolute(b)));
|
||||
INSIST((aabs && babs) || (!aabs && !babs));
|
||||
|
||||
if (dns_name_isabsolute(a))
|
||||
a_last_label--, b_last_label--;
|
||||
if (aabs) {
|
||||
a_last_label--;
|
||||
b_last_label--;
|
||||
}
|
||||
|
||||
dns_name_getlabel(a, a_last_label, &alabel);
|
||||
dns_name_getlabel(b, b_last_label, &blabel);
|
||||
FAST_GETLABEL(a, a_last_label, &alabel);
|
||||
FAST_GETLABEL(b, b_last_label, &blabel);
|
||||
|
||||
return cmp_label(&alabel, &blabel);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user