BIND 10 #1803: update the RBTreeNodeChain class to identify the "previous" node

BIND 10 Development do-not-reply at isc.org
Sun Mar 18 08:30:05 UTC 2012


#1803: update the RBTreeNodeChain class to identify the "previous" node
-------------------------------------+-------------------------------------
            Reporter:  jinmei        |                        Owner:
                Type:  task          |                       Status:  new
            Priority:  medium        |                    Milestone:  New
           Component:  data source   |  Tasks
           Sensitive:  0             |                     Keywords:
         Sub-Project:  DNS           |              Defect Severity:  N/A
Estimated Difficulty:  0             |  Feature Depending on Ticket:  in-
         Total Hours:  0             |  memory NSEC
                                     |          Add Hours to Ticket:  0
                                     |                    Internal?:  0
-------------------------------------+-------------------------------------
 This is necessary for in-memory NSEC, and will be the trickiest part of
 the entire feature.

 What I'd do is as follows (which is not the only way to implement
 this).  This will be pretty big, so I propose separating the step
 "1" below from others.  Even without this step some other tasks can be
 done.

 Introduce two new private members to `RBTreeNodeChain`:

 {{{#!c++
     const RBNode<T>* cursor_node_;
     int cursor_level_;
 }}}

 These values are invalid (NULL and -1 or something) until the
 following new method is called:

 {{{#!c++
 template <typename T>
 const RBNode<T>* RBTreeNodeChain::getPreviousNode();
 }}}

 When first time it's called after find(), it identifies the node in
 the tree whose corresponding name is the closest (but not equal) to
 the qname of find() in the sorted list of zone names smaller than the
 qname (that is, that's the node for the "previous name" of the qname).
 Then cursor_node_ is set to the identified node, and cursor_level_ is
 set to the level in the nodes_ array corresponding to that node.  The
 method returns a pointer to the identified cursor_node_.

 This process is complicated and depends on how the preceding find()
 ends:

 1. if last_comparison_.getRelation() is COMMONANCESTOR,
    last_comparison_.getCommonLabels() is 1, last_compared_.getLength() !=
 1,
    (the condition so far means the search stops due to a binary search
    and last_comparison_.getOrder() > 0, then that means find() stopped
    by seeing a node whose name (corresponding to last_compared_) is
    smaller than the qname.  This node may or may not be "the previous
    node".  Identify the real previous node as described in the
    following comment of BIND 9's lib/dns/rbt.c:
 {{{#!c
                                  * If the stop node is less, it is not
                                  * necessarily the predecessor.  If the
 stop
                                  * node has a down pointer, then the real
                                  * predecessor is at the end of a level
 below
                                  * (not necessarily the next level).
                                  * Move down levels until the rightmost
 node
                                  * does not have a down pointer.
 }}}

 2. otherwise, last_compared_ corresponds to either the qname or the
    immediate successor (wrt DNSSEC order) of the qname.  Identify the
    "previous node" of it using the same algorithm as BIND 9's
    lib/dns/rbt.c:dns_rbtnodechain_prev() (our rbtree is simpler so we
    may be able to simplify some part of it).

 In the second and later calls of this method, it will identify the
 node in the rbtree corresponding to the previous name of cursor_node_
 wrt the DNSSEC order, and returns a pointer to that node.
 cursor_node_ and cursor_level_ are updated accordingly (so this method
 cannot be a const member function).  This node can be identified using
 the same algorithm as case 2 above.

 This method can be called repeatedly to examine "previous" nodes
 toward the zone origin.

 Carefully test all cases in the algorithm.  Also don't forget what
 should happen if it's called beyond the very root of the tree.

-- 
Ticket URL: <http://bind10.isc.org/ticket/1803>
BIND 10 Development <http://bind10.isc.org>
BIND 10 Development


More information about the bind10-tickets mailing list