I added support for the full search algorithm to the RBT database
code. The database has some special needs in searching, in particular
certain nodes need to be examined before the DOWN pointer is followed.
I solved this problem by adding a 'callback' bit to the node structure.
When findnode is called, the caller can supply a callback. Before we go
DOWN at a node, we call the callback if the callback bit is set at the
node. If the callback returns DNS_R_CONTINUE, we proceed. Otherwise, we
will stop right there and return what the caller said to return. I
added an 'empty_data_ok' flag to findnode as well, so that nodes with
empty data can be made candidates for partial match status.
I also wanted to make dns_rbtnodechain_t public, so that a chain could
be allocated on the stack by the caller. I added two routines,
dns_rbtnodechain_init() and dns_rbtnodechain_reset() to work with them.
The latter routine frees any dynamically allocated memory associated with
the chain. The chain structure now contains the memory context. I also
moved get_ancestor_mem() and put_ancestor_mem() up in the file, so that
inlining could be more effective.
In the nits department, you wrote
*node = result == DNS_R_SUCCESS ? current : NULL;
In the future, please write this instead (the patch has this change in it):
if (result == DNS_R_SUCCESS)
*node = current;
else
*node = NULL;
is currently fine, because there are only two attribute flags a name
can have, one of which the node definitely needs to have set, and the
other of which is functionally irrelevant (because it happens to be set
by the NODENAME macro, namely the read-only flag). This might not
be the right thing to do in the future when more name attributes get
added, but we'll cross that bridge if we get to it. (_Some_ change was
necessary because the node's attributes was not properly initialized when
created, and under certain circumstances this ended up triggering an
exception in the dns_name_* functions.
Watch for level overflow during dns_rbt_addnode(). Returns DNS_R_NOSPACE,
which is probably not the right thing.
Comment cleanups.
changes to rbt.c by passing a NULL pointer for the dns_name_t that
receives the full name of the node that is found. There is probably something
better to do, but this just keeps things compiling.
returns a dns_result_t.
dns_rbt_created requires deleter_arg NULL if deleter is NULL.
dns_rbt_addnode always returns DNS_R_EXISTS if the node is found, regardless
of if it has data.
dns_rbt_addname will add the data and return SUCCESS if addnode says
EXISTS but there is no data at the node.
make sure memory is freed even when get_ancestor_mem to reallocate fails.
partialmatch returned by findnode must have data associated with it.
fixed up deletename; prematurely exited without freeing chain memory if
the node was not found. made deletename responsible for identifying whether
a node could be removed rather than zapnode.
turned a few of the print support functions static.
name attributes, name length, offset length, and number of bytes
of "padding" that are left over when a node is split.
adjusted node splitting algorithm to preserve the original location
of the lower portion of the split node (eg, when a node has "a.b" as
its name and is split into "a" and "b", "a" retains the same address
space as "a.b".)