Commit b65f2ab1 authored by David Lawrence's avatar David Lawrence
Browse files

534. [func] Ancestors have been removed from RBT chains. Ancestor

			information can be discerned via node parent pointers.

 533.	[func]		Incorporated name hashing into the RBT database to
			improve search speed.

There is still evidence of a bug with regard to bitstring labels.  It shows
up in bin/test/rbt/t_rbt -x -t 4 when the assertion at lib/dns/rbt.c:1631
is uncommented -- essentially a bitstring node's location in the hashtable
is not getting properly updated at some point.  This shouldn't affect
searching, because a bitstring label as the parent of a new level will
generally cause the standard old binary search to be done.  I will be looking
at this more closely in the very near future.
parent e6d3ffb6
534. [func] Ancestors have been removed from RBT chains. Ancestor
information can be discerned via node parent pointers.
533. [func] Incorporated name hashing into the RBT database to
improve search speed.
532. [func] Implement DNS UPDATE pseudo records using
DNS_RDATA_UPDATE flag.
531. [func] Rdata really should be initalized before being
assigned to (dns_rdata_fromwire(), dns_rdata_fromtext(),
531. [func] Rdata really should be initalized before being assigned
to (dns_rdata_fromwire(), dns_rdata_fromtext(),
dns_rdata_clone(), dns_rdata_fromregion()),
check that it is.
......
......@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: rbt.h,v 1.49 2000/08/24 01:19:58 gson Exp $ */
/* $Id: rbt.h,v 1.50 2000/10/25 07:21:31 tale Exp $ */
#ifndef DNS_RBT_H
#define DNS_RBT_H 1
......@@ -53,6 +53,7 @@ typedef struct dns_rbtnode {
struct dns_rbtnode *left;
struct dns_rbtnode *right;
struct dns_rbtnode *down;
struct dns_rbtnode *hashnext;
/*
* The following bitfields add up to a total bitwidth of 32.
* The range of values necessary for each item is indicated,
......@@ -72,6 +73,9 @@ typedef struct dns_rbtnode {
unsigned int namelen : 8; /* range is 1..255 */
unsigned int offsetlen : 8; /* range is 1..128 */
unsigned int padbytes : 9; /* range is 0..380 */
unsigned int hashval;
/*
* These values are used in the RBT DB implementation. The appropriate
* node lock must be held before accessing them.
......@@ -129,24 +133,14 @@ typedef isc_result_t (*dns_rbtfindcallback_t)(dns_rbtnode_t *node,
* dns_rbtnodechain_current is similar to the _first, _last, _prev and _next
* functions but additionally can provide the node to which the chain points. */
/*
* For use in allocating space for the chain of ancestor nodes.
*
* The maximum number of ancestors is theoretically not limited by the
* data tree. This initial value of 24 ancestors would be able to scan
* the full height of a single level of 16,777,216 nodes, more than double
* the current size of .com.
*/
#define DNS_RBT_ANCESTORBLOCK 24
/*
* The number of level blocks to allocate at a time. Currently the maximum
* number of levels is allocated directly in the structure, but future
* revisions of this code might treat levels like ancestors -- that is, have
* a static initial block with dynamic growth. Allocating space for 256
* levels when the tree is almost never that deep is wasteful, but it's not
* clear that it matters, since the waste is only 2MB for 1000 concurrently
* active chains on a system with 64-bit pointers.
* revisions of this code might have a static initial block with dynamic
* growth. Allocating space for 256 levels when the tree is almost never that
* deep is wasteful, but it's not clear that it matters, since the waste is
* only 2MB for 1000 concurrently active chains on a system with 64-bit
* pointers.
*/
#define DNS_RBT_LEVELBLOCK 254
......@@ -154,20 +148,12 @@ typedef struct dns_rbtnodechain {
unsigned int magic;
isc_mem_t * mctx;
/*
* The terminal node of the chain. It is not in levels[] or
* ancestors[]. This is ostensibly private ... but in a pinch
* it could be used tell that the chain points nowhere without
* needing to call dns_rbtnodechain_current().
* The terminal node of the chain. It is not in levels[].
* This is ostensibly private ... but in a pinch it could be
* used tell that the chain points nowhere without needing to
* call dns_rbtnodechain_current().
*/
dns_rbtnode_t * end;
dns_rbtnode_t ** ancestors;
/*
* ancestor_block avoids doing any memory allocation (a MP
* bottleneck) in 99%+ of the real-world cases.
*/
dns_rbtnode_t * ancestor_block[DNS_RBT_ANCESTORBLOCK];
unsigned int ancestor_count;
unsigned int ancestor_maxitems;
/*
* The maximum number of labels in a name is 128; bitstrings mean
* a conceptually very large number (which I have not bothered to
......@@ -372,16 +358,8 @@ dns_rbt_findnode(dns_rbt_t *rbt, dns_name_t *name, dns_name_t *foundname,
* everything. But you can certainly construct a trivial tree and a
* search for it that has no predecessor.
*
* Within the chain structure, 'ancestors' will point
* to each successive node encountered in the search, with the root
* of each level searched indicated by a NULL. ancestor_count
* indicates how many node pointers are in the ancestor list. The
* 'levels' member of the structure holds the root node of each level
* except the first; it corresponds with the NULL pointers in
* 'ancestors' (except the first). That is, for the [n+1]'th NULL
* 'ancestors' pointer, the [n]'th 'levels' pointer is the node with
* the down pointer to the next level. That node is not stored
* at all in the 'ancestors' list.
* Within the chain structure, the 'levels' member of the structure holds
* the root node of each level except the first.
*
* The 'level_count' of the chain indicates how deep the chain to the
* predecessor name is, as an index into the 'levels[]' array. It does
......@@ -396,12 +374,6 @@ dns_rbt_findnode(dns_rbt_t *rbt, dns_name_t *name, dns_name_t *foundname,
* the node is found in the top level tree, or no node is found at all,
* level_matches is 0.
*
* If any space was allocated to hold 'ancestors' in the chain,
* the 'ancestor_maxitems' member will be greater than
* DNS_RBT_ANCESTORBLOCK and will indicate how many ancestors
* could have been stored; the amount to be freed from the rbt->mctx
* is ancestor_maxitems * sizeof(dns_rbtnode_t *).
*
* 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. In this case, the chain
......@@ -452,19 +424,11 @@ dns_rbt_findnode(dns_rbt_t *rbt, dns_name_t *name, dns_name_t *foundname,
*
* chain->level_matches is 0.
*
* If result is ISC_R_NOMEMORY:
* The function could not complete because memory could not
* be allocated to maintain the chain. However, it
* is possible that some memory was allocated;
* the chain's ancestor_maxitems will be greater than
* DNS_RBT_ANCESTORBLOCK if so.
*
* Returns:
* ISC_R_SUCCESS Success
* DNS_R_PARTIALMATCH Superdomain found with data
* ISC_R_NOTFOUND No match, or superdomain with no data
* ISC_R_NOMEMORY Resource Limit: Out of Memory building chain
* ISC_R_NOSPACE Concatenating nodes to form foundname failed
* ISC_R_NOSPACE Concatenating nodes to form foundname failed
*/
isc_result_t
......
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment