rbt_datasrc.h 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. // Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #ifndef _RBTREE_H
  15. #define _RBTREE_H 1
  16. #include <dns/name.h>
  17. #include <dns/rrset.h>
  18. #include <dns/rrsetlist.h>
  19. #include <boost/shared_ptr.hpp>
  20. #include <boost/utility.hpp>
  21. using namespace isc::dns;
  22. namespace isc {
  23. namespace datasrc {
  24. /// \brief rbtree color define
  25. enum RBTreeColor {BLACK = 1, RED};
  26. class RBTree;
  27. /// \brief \c RBNode class represent one domain name in the domain space
  28. /// It has two roles, the first one is as one node in the \c RBTree the second one
  29. /// is store the data related to DNS. As for the first role, it has left, right, parent and color memebers
  30. /// which used to keey the balance of the \c RBTree. As for the second role,
  31. // it stores the rrsets belongs to the domain name and a rbtree which includes all the subdomains of this node
  32. /// the name stored in the node is relative related to its parent node.
  33. /// One special kind of node is non-terminal node
  34. /// which has subdomains with rrset but it self doesn't has any rrset
  35. ///
  36. /// \b Note: \c RBNode should create or destroied only by \c RBTree so constructor and destructor function aren't exposed
  37. class RBNode : public boost::noncopyable{
  38. public:
  39. /// only /c RBTree can create and destroy \c RBNode
  40. friend class RBTree;
  41. typedef boost::shared_ptr<RRsetList> RRsetListPtr;
  42. /// \name Test functions
  43. ///
  44. //@{
  45. /// \brief return whether current domain name has ns records
  46. bool isDelegate() const { return is_delegate_;}
  47. /// \brief return whether current domain name is non-terminal
  48. /// A non-terminal domain has no rrsets but at least one its descendant
  49. /// domain has rrset
  50. bool isNonterminal() const { return is_nonterminal_;}
  51. /// \brief return the name of current node, it's relative to its parents
  52. //
  53. /// \todo Is it meaningful to return the absolute of the node?
  54. const Name &getName() const {return name_;}
  55. // \brief return next node whose name is bigger than current node
  56. RBNode* successor();
  57. //@}
  58. /// \name modify function
  59. //@{
  60. /// \brief add the rrset to the node
  61. /// \Note: there is no check whether the node already has the rrset or not
  62. /// and no check about whether the name of the rrset is same with the node or not
  63. /// All of above is rely on interface user
  64. int addRRset(RRsetPtr rrset);
  65. //@}
  66. private:
  67. /// \name Constructors and destructor
  68. //@{
  69. /// \param nullnode The null point for \c RBNode isnot use \c NULL, but use one specified
  70. /// default node singled as null node, this is intended to keep the code more unify
  71. RBNode(const Name& name, RRsetListPtr rrsets = RRsetListPtr(), RBNode* nullnode = NULL);
  72. /// the class isn't left to be inherted
  73. ~RBNode();
  74. //@}
  75. /// \brief copy the DNS related date to another node except the sub domain tree
  76. void cloneDNSData(RBNode& node);
  77. /// \brief when copy the DNS data from one node to another, except the rrsets, name etc,
  78. /// also needs to maintain the down and up relationship, which includes set the down point of current
  79. /// node and up point of sub domain tree
  80. void setDownTree(RBTree* down);
  81. /// data to maintain the rbtree balance
  82. RBNode* parent_;
  83. RBNode* left_;
  84. RBNode* right_;
  85. int color_;
  86. /// data to carry dns info
  87. Name name_;
  88. RRsetListPtr rrsets_;
  89. RBTree* down_;
  90. bool is_delegate_;
  91. bool is_nonterminal_;
  92. };
  93. /// \brief \c RBTree class represent all the domains with same suffix, so it can be used to store
  94. /// the domains in one zone
  95. ///
  96. /// \c RBTree is a generic red black tree, and contains all the node with same suffix, since each
  97. /// name may have sub domain names so \c RBTree is a recursive data struct or tree in tree
  98. /// So for one zone, severl RBTrees are involved. But from outside, the sub tree is
  99. /// opaque for end user.
  100. class RBTree : public boost::noncopyable{
  101. friend class RBNode;
  102. public:
  103. /// \brief The return value for find method
  104. /// - EXACTMATCH: return the node in the tree exactly same with the target
  105. /// - FINDREFERRAL: return the node which is the ancestor of the target containing ns record
  106. /// - NOTFOUND: other conditions except EXACTMATCH & FINDREFERRAL
  107. enum FindResult{EXACTMATCH, FINDREFERRAL, NOTFOUND};
  108. /// \name Constructor and Destructor
  109. //@{
  110. RBTree();
  111. /// \b Note: RBTree is not intended to be inherited so the destructor isnot virtual
  112. ~RBTree();
  113. //@}
  114. /// \name Inquery methods
  115. //@{
  116. /// \brief find the node with the name
  117. /// \param name Target to be found
  118. /// \param node Point to the node when the return vaule is \c not NOTFOUND, if
  119. /// if the return value is NOTFOUND, the value of node is \c unknown
  120. FindResult find(const Name& name, RBNode** node)const;
  121. /// \brief Get all the node count in the tree
  122. int getNodeCount() const;
  123. //@}
  124. /// \name Debug function
  125. //@{
  126. /// \brief print the node in the trees
  127. /// \todo is it better to return one string instead of print to the stdout?
  128. void printTree(int depth = 0)const;
  129. //@}
  130. /// \name Modify function
  131. //@{
  132. /// \brief insert the domain name into the tree
  133. /// \param name The name want to be inserted into the tree
  134. /// \param inserted_node If no node with the name in the tree,
  135. /// new \c RBNode will be created, otherwise nothing will be done
  136. /// anyway the pointer point to the node with the name will be assign to inserted_node
  137. /// \return return 0 means no node exists in the tree with the name before insert
  138. /// return 1 means already has the node with the given name
  139. //
  140. /// If want to add rrset into one node, but not sure whether the node already exist
  141. /// Instead of call \c find, call \c insert and then call the RBNode interface to
  142. /// add rrset into the node is a better way
  143. int insert(const Name& name, RBNode** inserted_node);
  144. /// \brief erase the node with the domain name
  145. /// \return If no node with the name, return one otherwise return zero
  146. int erase(const Name& name);
  147. //@}
  148. private:
  149. /// \name RBTree balance function
  150. //@{
  151. void deleteRebalance(RBNode* node);
  152. void insertRebalance(RBNode* node);
  153. RBNode* rightRotate(RBNode* p);
  154. RBNode* leftRotate(RBNode* p);
  155. //@}
  156. /// \name Helper function
  157. //@{
  158. /// All the public function has related recursive helper function
  159. void eraseNode(RBNode* node);
  160. FindResult findHelper(const Name& name, RBTree** tree, RBNode** node)const;
  161. int getNodeCountHelper(const RBNode* node) const;
  162. void printTreeHelper(RBNode* node, int depth)const;
  163. //@}
  164. RBNode* root_;
  165. RBNode* NULLNODE;
  166. RBNode* up_;
  167. /// the node count of current tree except the sub domain trees
  168. unsigned int node_count_;
  169. };
  170. }
  171. }
  172. #endif