2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-30 14:07:59 +00:00

performance enhancements, deleter arg

This commit is contained in:
Bob Halley
1999-02-06 01:27:35 +00:00
parent c5839c39bd
commit 1630fce031
2 changed files with 163 additions and 81 deletions

View File

@@ -24,14 +24,9 @@
/* /*
* This is the structure that is used for each node in the red/black * 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 * tree of trees. NOTE WELL: the implementation manages this as a variable
* length structure, with the actual wire-format name being stored as * length structure, with the actual wire-format name and other data appended
* a sequence of "name_length" bytes appended to this structure. Allocating * appended to this structure. Allocating a contiguous block of memory for
* a contiguous block of memory for multiple dns_rbt_node structures is * multiple dns_rbt_node structures will not work.
* 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.
*/ */
typedef struct dns_rbt dns_rbt_t; typedef struct dns_rbt dns_rbt_t;
@@ -52,7 +47,7 @@ typedef struct dns_rbt_node {
unsigned int references:DNS_RBT_REFLENGTH; unsigned int references:DNS_RBT_REFLENGTH;
} dns_rbtnode_t; } 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); 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, 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'. * 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_printtree(dns_rbtnode_t *root, dns_rbtnode_t *parent, int depth);
void dns_rbt_printall(dns_rbt_t *rbt); void dns_rbt_printall(dns_rbt_t *rbt);
dns_result_t dns_rbt_create(isc_mem_t *mctx, void (*deleter)(void *), dns_result_t dns_rbt_create(isc_mem_t *mctx, void (*deleter)(void *, void *),
dns_rbt_t **rbtp); void *arg, dns_rbt_t **rbtp);
void dns_rbt_destroy(dns_rbt_t **rbtp); void dns_rbt_destroy(dns_rbt_t **rbtp);

View File

@@ -37,10 +37,11 @@ struct dns_rbt {
unsigned int magic; unsigned int magic;
isc_mem_t * mctx; isc_mem_t * mctx;
dns_rbtnode_t * root; 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; dns_rbtnode_t ** ancestors;
int ancestor_count; int ancestor_count;
int ancestor_maxitems; int ancestor_maxitems;
@@ -63,8 +64,9 @@ struct node_chain {
#define LEFT(node) ((node)->left) #define LEFT(node) ((node)->left)
#define RIGHT(node) ((node)->right) #define RIGHT(node) ((node)->right)
#define DOWN(node) ((node)->down) #define DOWN(node) ((node)->down)
#define NAMELEN(node) (*(unsigned char *)((node) + 1)) #define NAMELEN(node) (((unsigned char *)((node) + 1))[0])
#define NAME(node) ((void *)((char *)(node) + sizeof(*node) + 1)) #define OFFSETLEN(node) (((unsigned char *)((node) + 1))[1])
#define NAME(node) (&((unsigned char *)((node) + 1))[3])
#define DATA(node) ((node)->data) #define DATA(node) ((node)->data)
#define COLOR(node) ((node)->color) #define COLOR(node) ((node)->color)
#define DIRTY(node) ((node)->dirty) #define DIRTY(node) ((node)->dirty)
@@ -76,7 +78,43 @@ struct node_chain {
#define MAKE_RED(node) ((node)->color = RED) #define MAKE_RED(node) ((node)->color = RED)
#define MAKE_BLACK(node) ((node)->color = BLACK) #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(). * 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); dns_rbtnode_t **rootp);
static inline dns_result_t get_ancestor_mem(isc_mem_t *mctx, 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 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); 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, static dns_result_t dns_rbt_addonlevel(dns_rbt_t *rbt,
dns_rbtnode_t *node, dns_rbtnode_t *node,
dns_rbtnode_t **rootp, dns_rbtnode_t **rootp,
node_chain_t *chain); dns_rbtnodechain_t *chain);
static void dns_rbt_deletefromlevel(dns_rbt_t *rbt, static void dns_rbt_deletefromlevel(dns_rbt_t *rbt,
dns_rbtnode_t *delete, 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 void dns_rbt_deletetree(dns_rbt_t *rbt, dns_rbtnode_t *node);
static dns_result_t zapnode_and_fixlevels(dns_rbt_t *rbt, static dns_result_t zapnode_and_fixlevels(dns_rbt_t *rbt,
dns_rbtnode_t *node, dns_rbtnode_t *node,
isc_boolean_t recurse, isc_boolean_t recurse,
node_chain_t *chain); dns_rbtnodechain_t *chain);
/* /*
* Initialize a red/black tree of trees. * Initialize a red/black tree of trees.
*/ */
dns_result_t 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; dns_rbt_t *rbt;
REQUIRE(mctx != NULL); 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->mctx = mctx;
rbt->data_deleter = deleter; rbt->data_deleter = deleter;
rbt->deleter_arg = arg;
rbt->root = NULL; rbt->root = NULL;
rbt->magic = RBT_MAGIC; 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; dns_name_t add_name, current_name, new_name, tmp_name;
int compared, add_labels, current_labels, keep_labels, start_label; int compared, add_labels, current_labels, keep_labels, start_label;
dns_result_t result; 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(VALID_RBT(rbt));
REQUIRE(dns_name_isabsolute(name)); REQUIRE(FAST_ISABSOLUTE(name));
REQUIRE(nodep != NULL && *nodep == NULL); REQUIRE(nodep != NULL && *nodep == NULL);
/* /*
* Create a copy of the name so the original name structure is * Create a copy of the name so the original name structure is
* not modified. * 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) { if (rbt->root == NULL) {
result = create_node(rbt->mctx, &add_name, &new_node); 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 { do {
current = child; current = child;
dns_rbt_namefromnode(current, &current_name); NODENAME(current, &current_name);
compared = cmp_names_for_depth(&add_name, &current_name); compared = cmp_names_for_depth(&add_name, &current_name);
if (compared == BOTH_ARE_EQUAL) { 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 * the non-common parts of these two names should
* start a new tree. * start a new tree.
*/ */
add_labels = dns_name_countlabels(&add_name); add_labels = FAST_COUNTLABELS(&add_name);
current_labels = dns_name_countlabels(&current_name); current_labels = FAST_COUNTLABELS(&current_name);
/* /*
* When *root == rbt->root, the current tree level is * 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; start_label = current_labels - compared;
keep_labels = compared + (*root == rbt->root); keep_labels = compared + (*root == rbt->root);
dns_name_init(&tmp_name, NULL); dns_name_init(&tmp_name, o2);
dns_name_getlabelsequence(&current_name, dns_name_getlabelsequence(&current_name,
start_label, start_label,
keep_labels, 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 * 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. * nodes, the old node can be freed.
*/ */
isc_mem_put(rbt->mctx, current, 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); result = dns_rbt_addonlevel(rbt, new_node, root, &chain);
/* XXXRTH Free node if add fails? */ /* XXXRTH Free node if add fails? */
/* XXXRTH Is it true that result should never be DNS_R_EXISTS? */ /* XXXRTH Is it true that result should never be DNS_R_EXISTS? */
INSIST(result != DNS_R_EXISTS);
if (chain.ancestor_maxitems > 0) if (chain.ancestor_maxitems > 0)
isc_mem_put(rbt->mctx, chain.ancestors, 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; dns_rbtnode_t *node;
REQUIRE(VALID_RBT(rbt)); REQUIRE(VALID_RBT(rbt));
REQUIRE(dns_name_isabsolute(name)); REQUIRE(FAST_ISABSOLUTE(name));
node = NULL; 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. * the down pointer for the found node.
*/ */
dns_rbtnode_t * 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_rbtnode_t *current;
dns_name_t *search_name, *new_search_name, *current_name; 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; 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(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 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; current = rbt->root;
dont_count_root_label = 1; dont_count_root_label = 1;
dns_name_init(&holder1, NULL); dns_name_init(&holder1, o2);
dns_name_init(&holder2, NULL); dns_name_init(&holder2, o3);
current_name = &holder1; 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) { while (current != NULL) {
dns_rbt_namefromnode(current, current_name); NODENAME(current, current_name);
compared = cmp_names_for_depth(search_name, current_name); compared = cmp_names_for_depth(search_name, current_name);
if (compared == BOTH_ARE_EQUAL) 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. * 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; - dont_count_root_label;
if (compared == current_labels) { 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; current_name = &holder1;
} }
keep_labels = dns_name_countlabels(search_name) keep_labels = FAST_COUNTLABELS(search_name)
- dont_count_root_label - dont_count_root_label
- compared; - compared;
dns_name_init(new_search_name, NULL); dns_name_init(new_search_name, o4);
dns_name_getlabelsequence(search_name, dns_name_getlabelsequence(search_name,
0, 0,
keep_labels, 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_rbt_deletename(dns_rbt_t *rbt, dns_name_t *name, isc_boolean_t recurse) {
dns_rbtnode_t *node; dns_rbtnode_t *node;
dns_result_t result; dns_result_t result;
node_chain_t chain; dns_rbtnodechain_t chain;
REQUIRE(VALID_RBT(rbt)); REQUIRE(VALID_RBT(rbt));
REQUIRE(dns_name_isabsolute(name)); REQUIRE(FAST_ISABSOLUTE(name));
/* /*
* Find the node, building the ancestor chain. * 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 static dns_result_t
zapnode_and_fixlevels(dns_rbt_t *rbt, dns_rbtnode_t *node, 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_rbtnode_t *down, *parent, **rootp;
dns_result_t result; dns_result_t result;
@@ -687,7 +738,8 @@ zapnode_and_fixlevels(dns_rbt_t *rbt, dns_rbtnode_t *node,
} else { } else {
if (rbt->data_deleter != NULL) if (rbt->data_deleter != NULL)
rbt->data_deleter(DATA(node)); rbt->data_deleter(DATA(node),
rbt->deleter_arg);
DATA(node) = NULL; DATA(node) = NULL;
if (LEFT(down) != NULL || RIGHT(down) != 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); dns_rbt_deletefromlevel(rbt, node, chain);
if (rbt->data_deleter != NULL) 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)); 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 void
dns_rbt_namefromnode(dns_rbtnode_t *node, dns_name_t *name) { dns_rbt_namefromnode(dns_rbtnode_t *node, dns_name_t *name) {
isc_region_t r;
r.length = NAMELEN(node); REQUIRE(name->offsets == NULL);
r.base = NAME(node);
dns_name_fromregion(name, &r); NODENAME(node, name);
} }
static dns_result_t static dns_result_t
create_node(isc_mem_t *mctx, dns_name_t *name, dns_rbtnode_t **nodep) { create_node(isc_mem_t *mctx, dns_name_t *name, dns_rbtnode_t **nodep) {
dns_rbtnode_t *node; dns_rbtnode_t *node;
isc_region_t region; 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, &region); dns_name_toregion(name, &region);
labels = FAST_COUNTLABELS(name);
if (FAST_ISABSOLUTE(name))
absolute = 1;
else
absolute = 0;
/* /*
* Allocate space for the node structure, plus the length byte, * Allocate space for the node structure, plus the length byte,
* plus the length of the name. * plus the length of the name.
*/ */
node = (dns_rbtnode_t *)isc_mem_get(mctx, node = (dns_rbtnode_t *)isc_mem_get(mctx,
sizeof(*node) + 1 + region.length); sizeof(*node) + 3 +
region.length + labels);
if (node == NULL) if (node == NULL)
return (DNS_R_NOMEMORY); 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; DOWN(node) = NULL;
DATA(node) = NULL; DATA(node) = NULL;
LOCK(node) = 0; /* @@@ ? */ LOCK(node) = 0;
REFS(node) = 0; REFS(node) = 0;
DIRTY(node) = 0; DIRTY(node) = 0;
MAKE_BLACK(node); 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; *nodep = node;
@@ -824,6 +903,7 @@ join_nodes(dns_rbt_t *rbt,
dns_name_t newname; dns_name_t newname;
isc_region_t r; isc_region_t r;
int newsize; int newsize;
dns_offsets_t offsets;
REQUIRE(VALID_RBT(rbt)); REQUIRE(VALID_RBT(rbt));
REQUIRE(node != NULL); REQUIRE(node != NULL);
@@ -844,13 +924,11 @@ join_nodes(dns_rbt_t *rbt,
r.length = newsize; r.length = newsize;
dns_name_init(&newname, NULL); dns_name_init(&newname, offsets);
dns_name_fromregion(&newname, &r); dns_name_fromregion(&newname, &r);
result = create_node(rbt->mctx, &newname, &newnode); result = create_node(rbt->mctx, &newname, &newnode);
if (result == DNS_R_SUCCESS) { if (result == DNS_R_SUCCESS) {
isc_mem_put(rbt->mctx, r.base, r.length);
COLOR(newnode) = COLOR(node); COLOR(newnode) = COLOR(node);
RIGHT(newnode) = RIGHT(node); RIGHT(newnode) = RIGHT(node);
LEFT(newnode) = LEFT(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, node, NODE_SIZE(node));
isc_mem_put(rbt->mctx, down, NODE_SIZE(down)); isc_mem_put(rbt->mctx, down, NODE_SIZE(down));
} }
isc_mem_put(rbt->mctx, r.base, r.length);
return (result); return (result);
} }
static inline dns_result_t 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; dns_rbtnode_t **ancestor_mem;
int oldsize, newsize; 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 static dns_result_t
dns_rbt_addonlevel(dns_rbt_t *rbt, dns_rbtnode_t *node, dns_rbtnode_t **rootp, 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_rbtnode_t *current, *child, *root, *tmp, *parent, *grandparent;
dns_name_t add_name, current_name; dns_name_t add_name, current_name;
dns_offsets_t offsets; 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; child = root;
dns_name_init(&add_name, offsets); dns_name_init(&add_name, offsets);
dns_rbt_namefromnode(node, &add_name); NODENAME(node, &add_name);
dns_name_init(&current_name, NULL); dns_name_init(&current_name, NULL);
@@ -991,7 +1070,7 @@ dns_rbt_addonlevel(dns_rbt_t *rbt, dns_rbtnode_t *node, dns_rbtnode_t **rootp,
current = child; current = child;
dns_rbt_namefromnode(current, &current_name); NODENAME(current, &current_name);
i = cmp_names_on_level(&add_name, &current_name); i = cmp_names_on_level(&add_name, &current_name);
if (i == 0) if (i == 0)
@@ -1086,7 +1165,7 @@ dns_rbt_addonlevel(dns_rbt_t *rbt, dns_rbtnode_t *node, dns_rbtnode_t **rootp,
*/ */
static void static void
dns_rbt_deletefromlevel(dns_rbt_t *rbt, dns_rbtnode_t *delete, 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 *sibling, *parent, *grandparent, *child;
dns_rbtnode_t *successor, **rootp; dns_rbtnode_t *successor, **rootp;
int depth; 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 * 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, * 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 static void
dns_rbt_deletetree(dns_rbt_t *rbt, dns_rbtnode_t *node) { 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)); dns_rbt_deletetree(rbt, DOWN(node));
if (DATA(node) != NULL && rbt->data_deleter != NULL) 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)); 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. * 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) { cmp_label(dns_label_t *a, dns_label_t *b) {
int i; int i;
@@ -1392,21 +1471,25 @@ static inline int
cmp_names_for_depth(dns_name_t *a, dns_name_t *b) { cmp_names_for_depth(dns_name_t *a, dns_name_t *b) {
dns_label_t alabel, blabel; dns_label_t alabel, blabel;
int aindex, bindex, compared, common; int aindex, bindex, compared, common;
isc_boolean_t aabs, babs;
aindex = dns_name_countlabels(a) - 1; aindex = FAST_COUNTLABELS(a) - 1;
bindex = dns_name_countlabels(b) - 1; bindex = FAST_COUNTLABELS(b) - 1;
aabs = FAST_ISABSOLUTE(a);
babs = FAST_ISABSOLUTE(b);
INSIST(( dns_name_isabsolute(a) && dns_name_isabsolute(b)) || INSIST((aabs && babs) || (!aabs && !babs));
(!dns_name_isabsolute(a) && !dns_name_isabsolute(b)));
if (dns_name_isabsolute(a)) if (aabs) {
aindex--, bindex--; aindex--;
bindex--;
}
common = 0; common = 0;
for (; aindex >= 0 && bindex >= 0; aindex--, bindex--) { for (; aindex >= 0 && bindex >= 0; aindex--, bindex--) {
dns_name_getlabel(a, aindex, &alabel); FAST_GETLABEL(a, aindex, &alabel);
dns_name_getlabel(b, bindex, &blabel); FAST_GETLABEL(b, bindex, &blabel);
compared = cmp_label(&alabel, &blabel); compared = cmp_label(&alabel, &blabel);
if (compared == 0) if (compared == 0)
@@ -1438,18 +1521,22 @@ static inline int
cmp_names_on_level(dns_name_t *a, dns_name_t *b) { cmp_names_on_level(dns_name_t *a, dns_name_t *b) {
dns_label_t alabel, blabel; dns_label_t alabel, blabel;
int a_last_label, b_last_label; int a_last_label, b_last_label;
isc_boolean_t aabs, babs;
a_last_label = dns_name_countlabels(a) - 1; a_last_label = FAST_COUNTLABELS(a) - 1;
b_last_label = dns_name_countlabels(b) - 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)) || INSIST((aabs && babs) || (!aabs && !babs));
(!dns_name_isabsolute(a) && !dns_name_isabsolute(b)));
if (dns_name_isabsolute(a)) if (aabs) {
a_last_label--, b_last_label--; a_last_label--;
b_last_label--;
}
dns_name_getlabel(a, a_last_label, &alabel); FAST_GETLABEL(a, a_last_label, &alabel);
dns_name_getlabel(b, b_last_label, &blabel); FAST_GETLABEL(b, b_last_label, &blabel);
return cmp_label(&alabel, &blabel); return cmp_label(&alabel, &blabel);
} }