rbtree.h 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215
  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. //! \file datasrc/rbtree.h
  17. ///
  18. /// \note The purpose of the RBTree is to provide a generic map with
  19. /// domain names as the key that can be used by various BIND 10 modules or
  20. /// even by other applications. However, because of some unresolved design
  21. /// issue, the design and interface are not fixed, and RBTree isn't ready
  22. /// to be used as a base data structure by other modules.
  23. #include <dns/name.h>
  24. #include <boost/utility.hpp>
  25. #include <boost/shared_ptr.hpp>
  26. #include <exceptions/exceptions.h>
  27. #include <ostream>
  28. #include <algorithm>
  29. #include <cassert>
  30. namespace isc {
  31. namespace datasrc {
  32. namespace helper {
  33. /// \brief Helper function to remove the base domain from super domain.
  34. ///
  35. /// The precondition of this function is the super_name contains the
  36. /// sub_name so
  37. /// \code Name a("a.b.c");
  38. /// Name b("b.c");
  39. /// Name c = a - b;
  40. /// \endcode
  41. /// c will contain "a".
  42. ///
  43. /// \note Functions in this namespace is not intended to be used outside of
  44. /// RBTree implementation.
  45. inline isc::dns::Name
  46. operator-(const isc::dns::Name& super_name, const isc::dns::Name& sub_name) {
  47. return (super_name.split(0, super_name.getLabelCount() -
  48. sub_name.getLabelCount()));
  49. }
  50. }
  51. /// \brief Invalid RBTreeNodeChain exception
  52. ///
  53. /// Normally, RBTreeNodeChain is initialized and manipuate by RBTRee,
  54. /// this is thrown when using one RBTreeNodeChain which is created by default
  55. /// constructor but not initialized by RBTree through find function
  56. struct InvalidNodeChain : public isc::Exception {
  57. InvalidNodeChain(const char* file, size_t line, const char* what) :
  58. Exception(file, line, what){}
  59. };
  60. /// \brief Too long RBTreeNodeChain exception
  61. ///
  62. /// RBTreeNodeChain has length limitation as 128, this exception is thrown
  63. /// when RBTreeNodeChain is longer than that limitation which is caused by
  64. /// too deep RBTree.
  65. struct TooLongNodeChain : public isc::Exception {
  66. TooLongNodeChain(const char *file, size_t line, const char *what) :
  67. Exception(file, line, what){}
  68. };
  69. /// Forward declare RBTree class here is convinent for following friend
  70. /// class declare inside RBNode and RBTreeNodeChain
  71. template <typename T>
  72. class RBTree;
  73. /// \brief \c RBNode is used by RBTree to store any data related to one domain
  74. /// name.
  75. ///
  76. /// This is meant to be used only from RBTree. It is meaningless to inherit it
  77. /// or create instances of it from elsewhere. For that reason, the constructor
  78. /// is private.
  79. ///
  80. /// It serves three roles. One is to keep structure of the \c RBTree as a
  81. /// red-black tree. For that purpose, it has left, right and parent pointers
  82. /// and color member. These are private and accessed only from within the tree.
  83. ///
  84. /// The second one is to store data for one domain name. The data related
  85. /// functions can be used to access and set the data.
  86. ///
  87. /// The third role is to keep the hierarchy of domains. The down pointer points
  88. /// to a subtree of subdomains. Note that we can traverse the hierarchy down,
  89. /// but not up.
  90. ///
  91. /// One special kind of node is non-terminal node. It has subdomains with
  92. /// RRsets, but doesn't have any RRsets itself.
  93. template <typename T>
  94. class RBNode : public boost::noncopyable {
  95. private:
  96. /// The RBNode is meant for use from within RBTree, so it has access to
  97. /// it.
  98. friend class RBTree<T>;
  99. /// \name Constructors
  100. ///
  101. /// \note The existence of a RBNode without a RBTree is meaningless.
  102. /// Therefore the constructors are private.
  103. //@{
  104. /// \brief Default constructor.
  105. ///
  106. /// This constructor is provided specifically for generating a special
  107. /// "null" node.
  108. RBNode();
  109. /// \brief Constructor from the node name.
  110. ///
  111. /// \param name The *relative* domain name (if this will live inside
  112. /// a.b.c and is called d.e.a.b.c, then you pass d.e).
  113. RBNode(const isc::dns::Name& name);
  114. //@}
  115. public:
  116. /// \brief Alias for shared pointer to the data.
  117. typedef boost::shared_ptr<T> NodeDataPtr;
  118. /// \brief Destructor
  119. ///
  120. /// It might seem strange that constructors are private and destructor
  121. /// public, but this is needed because of shared pointers need access
  122. /// to the destructor.
  123. ///
  124. /// You should never call anything like:
  125. /// \code delete pointer_to_node; \endcode
  126. /// The RBTree handles both creation and destructoion of nodes.
  127. ~RBNode();
  128. /// \name Getter functions.
  129. //@{
  130. /// \brief Return the name of current node.
  131. ///
  132. /// It's relative to its containing node.
  133. ///
  134. /// To get the absolute name of one node, the node path from the top node
  135. /// to current node has to be recorded.
  136. const isc::dns::Name& getName() const { return (name_); }
  137. /// \brief Return the data stored in this node.
  138. ///
  139. /// You should not delete the data, it is handled by shared pointers.
  140. NodeDataPtr& getData() { return (data_); }
  141. /// \brief Return the data stored in this node.
  142. const NodeDataPtr& getData() const { return (data_); }
  143. /// \brief return whether the node has related data.
  144. ///
  145. /// There can be empty nodes inside the RBTree. They are usually the
  146. /// non-terminal domains, but it is possible (yet probably meaningless)
  147. /// empty nodes anywhere.
  148. bool isEmpty() const { return (data_.get() == NULL); }
  149. //@}
  150. /// \name Setter functions.
  151. //@{
  152. /// \brief Set the data stored in the node.
  153. void setData(const NodeDataPtr& data) { data_ = data; }
  154. //@}
  155. /// \name Callback related methods
  156. ///
  157. /// See the description of \c RBTree<T>::find() about callbacks.
  158. ///
  159. /// These methods never throw an exception.
  160. //@{
  161. /// Return if callback is enabled at the node.
  162. bool isCallbackEnabled() const { return (callback_required_); }
  163. /// Enable callback at the node.
  164. void enableCallback() { callback_required_ = true; }
  165. /// Disable callback at the node.
  166. void disableCallback() { callback_required_ = false; }
  167. //@}
  168. private:
  169. /// \brief Define rbnode color
  170. enum RBNodeColor {BLACK, RED};
  171. /// This is a factory class method of a special singleton null node.
  172. static RBNode<T>* NULL_NODE() {
  173. static RBNode<T> null_node;
  174. return (&null_node);
  175. }
  176. /// \brief return the next node which is bigger than current node
  177. /// in the same subtree
  178. ///
  179. /// The next successor for this node is the next bigger node in terms of
  180. /// the DNSSEC order relation within the same single subtree.
  181. /// Note that it may NOT be the next bigger node in the entire RBTree;
  182. /// RBTree is a tree in tree, and the real next node may reside in
  183. /// an upper or lower subtree of the subtree where this node belongs.
  184. /// For example, if this node has a sub domain, the real next node is
  185. /// the smallest node in the sub domain tree.
  186. ///
  187. /// If this node is the biggest node within the subtree, this method
  188. /// returns \c NULL_NODE().
  189. ///
  190. /// This method never throws an exception.
  191. const RBNode<T>* successor() const;
  192. /// \name Data to maintain the rbtree structure.
  193. //@{
  194. RBNode<T>* parent_;
  195. RBNode<T>* left_;
  196. RBNode<T>* right_;
  197. RBNodeColor color_;
  198. //@}
  199. /// \brief Relative name of the node.
  200. isc::dns::Name name_;
  201. /// \brief Data stored here.
  202. NodeDataPtr data_;
  203. /// \brief The subdomain tree.
  204. ///
  205. /// This points to the root node of trees of subdomains of this domain.
  206. ///
  207. /// \par Adding down pointer to \c RBNode has two purposes:
  208. /// \li Accelerate the search process, with sub domain tree, it splits the
  209. /// big flat tree into several hierarchy trees.
  210. /// \li It saves memory useage as it allows storing only relative names,
  211. /// avoiding storage of the same domain labels multiple times.
  212. RBNode<T>* down_;
  213. /// \brief If callback should be called when traversing this node in
  214. /// RBTree::find().
  215. ///
  216. /// \todo It might be needed to put it into more general attributes field.
  217. bool callback_required_;
  218. };
  219. // This is only to support NULL nodes.
  220. template <typename T>
  221. RBNode<T>::RBNode() :
  222. parent_(this),
  223. left_(this),
  224. right_(this),
  225. color_(BLACK),
  226. // dummy name, the value doesn't matter:
  227. name_(isc::dns::Name::ROOT_NAME()),
  228. down_(this),
  229. callback_required_(false)
  230. {
  231. }
  232. template <typename T>
  233. RBNode<T>::RBNode(const isc::dns::Name& name) :
  234. parent_(NULL_NODE()),
  235. left_(NULL_NODE()),
  236. right_(NULL_NODE()),
  237. color_(RED),
  238. name_(name),
  239. down_(NULL_NODE()),
  240. callback_required_(false)
  241. {
  242. }
  243. template <typename T>
  244. RBNode<T>::~RBNode() {
  245. }
  246. template <typename T>
  247. const RBNode<T>*
  248. RBNode<T>::successor() const {
  249. const RBNode<T>* current = this;
  250. // If it has right node, the successor is the left-most node of the right
  251. // subtree.
  252. if (right_ != NULL_NODE()) {
  253. current = right_;
  254. while (current->left_ != NULL_NODE()) {
  255. current = current->left_;
  256. }
  257. return (current);
  258. }
  259. // Otherwise go up until we find the first left branch on our path to
  260. // root. If found, the parent of the branch is the successor.
  261. // Otherwise, we return the null node
  262. const RBNode<T>* parent = current->parent_;
  263. while (parent != NULL_NODE() && current == parent->right_) {
  264. current = parent;
  265. parent = parent->parent_;
  266. }
  267. return (parent);
  268. }
  269. /// \brief RBTreeNodeChain is used to keep track of the sequence of
  270. /// nodes to reach any given node from the root of RBTree.
  271. ///
  272. /// Currently, RBNode does not have "up" pointers in them (i.e., back pointers
  273. /// from the root of one level of tree of trees to the node in the parent
  274. /// tree whose down pointer points to that root node) for memory usage
  275. /// reasons, so there is no way to find the path back to the root from any
  276. /// given RBNode.
  277. /// Note: this design may change in future versions. In particular, it's
  278. /// quite likely we want to have that pointer if we want to optimize name
  279. /// compression by exploiting the structure of the zone. If and when that
  280. /// happens we should also revisit the need for the chaining.
  281. ///
  282. /// RBTreeNodeChain is constructed and manipulate only by \c RBTree.
  283. /// \c RBTree uses it as an inner data structure to iterate over the whole
  284. /// RBTree.
  285. /// This is the reason why manipulation methods such as \c push() and \c pop()
  286. /// are private.
  287. template <typename T>
  288. class RBTreeNodeChain {
  289. /// RBTreeNodeChain is initialized by RBTree, only RBTree has
  290. /// knowledge to manipuate it.
  291. friend class RBTree<T>;
  292. public:
  293. /// \name Constructors and Assignment Operator.
  294. ///
  295. /// \note empty RBTreeNodeChain isn't meaningful, use it
  296. /// as parameter for functions like getAbsoluteName or
  297. /// nextNode in \c RBTree will throw InvalidNodeChain exception
  298. /// empty RBTreeNodeChain has to be initialized by RBTree, through
  299. /// \c find function call.
  300. //{@
  301. /// The default constructor.
  302. ///
  303. /// \exception None
  304. RBTreeNodeChain() : node_count_(0) {}
  305. /// Copy constructor.
  306. ///
  307. /// \exception None
  308. RBTreeNodeChain(const RBTreeNodeChain<T>& node_path) {
  309. node_count_ = node_path.node_count_;
  310. if (node_count_ > 0) {
  311. memcpy(nodes_, node_path.nodes_, node_count_ * sizeof(RBNode<T>*));
  312. }
  313. }
  314. /// Assignment operator.
  315. ///
  316. /// \exception None
  317. RBTreeNodeChain<T>&
  318. operator=(const RBTreeNodeChain<T>& node_path) {
  319. node_count_ = node_path.node_count_;
  320. if (node_count_ > 0) {
  321. memcpy(nodes_, node_path.nodes_, node_count_ * sizeof(RBNode<T>*));
  322. }
  323. return (*this);
  324. }
  325. //@}
  326. /// \brief Return the number of levels stored in the chain.
  327. ///
  328. /// It's equal to the number of nodes in the chain; for an empty
  329. /// chain, 0 will be returned.
  330. ///
  331. /// \exception None
  332. unsigned int getLevelCount() const { return (node_count_); }
  333. /// \brief return the absolute name for the node which current
  334. /// RBTreeNodeChain traces.
  335. ///
  336. /// \exception RBTreeNodeChain has to be initialized by RBTree,
  337. /// otherwise InvalidNodeChain exception will be thrown
  338. isc::dns::Name getAbsoluteName() const {
  339. const RBNode<T>* top_node = top();
  340. isc::dns::Name absolute_name = top_node->getName();
  341. int node_count = node_count_ - 1;
  342. while (node_count > 0) {
  343. top_node = nodes_[node_count - 1];
  344. absolute_name = absolute_name.concatenate(top_node->getName());
  345. --node_count;
  346. }
  347. return (absolute_name);
  348. }
  349. private:
  350. /// \brief return whther node chain has node in it.
  351. ///
  352. /// \exception None
  353. bool isEmpty() const { return (node_count_ == 0); }
  354. /// \brief return the top node for the node chain
  355. ///
  356. /// RBTreeNodeChain store all the nodes along top node to
  357. /// root node of RBTree
  358. ///
  359. /// \exception If RBTreeNodeChain isn't initialized by RBTree
  360. /// InvalidNodeChain exception will be thrown
  361. const RBNode<T>* top() const {
  362. if (isEmpty()) {
  363. isc_throw(InvalidNodeChain, "empty node chain");
  364. }
  365. return (nodes_[node_count_ - 1]);
  366. }
  367. /// \brief pop the top node from the node chain
  368. ///
  369. /// After pop, up/super node of original top node will be
  370. /// the top node
  371. ///
  372. /// \exception If RBTreeNodeChain isn't initialized by RBTree
  373. /// InvalidNodeChain exception will be thrown
  374. void pop() {
  375. if (isEmpty()) {
  376. isc_throw(InvalidNodeChain, "empty node chain");
  377. }
  378. --node_count_;
  379. }
  380. /// \brief add the node into the node chain
  381. ///
  382. /// If the node chain isn't empty, the node should be
  383. /// the sub domain of the original top node in node chain
  384. /// otherwise the node should be the root node of RBTree.
  385. ///
  386. /// \exception If RBTreeNodeChain is initialized by RBTree who
  387. /// is too deep with level bigger than RBT_MAX_LEVEL, the node
  388. /// chain for leaf node will longer than RBT_MAX_LEVEL then
  389. /// exception TooLongNodeChain will be thrown
  390. ///
  391. /// \note Since RBTree grows through inserting new node
  392. /// and Name class has the check whether the name is too long
  393. /// or has too many labels, so TooLongNodeChain exception is
  394. /// hidden by TooLongName exception since it's impossible to create
  395. /// the RBTree which is deeper than MAX_LABELS of Name class.
  396. void push(const RBNode<T>* node) {
  397. if (node_count_ >= RBT_MAX_LEVEL) {
  398. isc_throw(TooLongNodeChain, "node chain is too long");
  399. }
  400. nodes_[node_count_++] = node;
  401. }
  402. private:
  403. // The max label count for one domain name is Name::MAX_LABELS (128).
  404. // Since each node in rbtree stores at least one label, and the root
  405. // name always shares the same level with some others (which means
  406. // all top level nodes except the one for the root name contain at least
  407. // two labels), the possible maximum level is MAX_LABELS - 1.
  408. // It's also the possible maximum nodes stored in a chain.
  409. const static int RBT_MAX_LEVEL = isc::dns::Name::MAX_LABELS - 1;
  410. const RBNode<T>* nodes_[RBT_MAX_LEVEL];
  411. int node_count_;
  412. };
  413. // note: the following class description is documented using multiline comments
  414. // because the verbatim diagram contain a backslash, which could be interpreted
  415. // as escape of newline in singleline comment.
  416. /**
  417. * \brief \c RBTree class represents all the domains with the same suffix.
  418. * It can be used to store the domains in one zone, for example.
  419. *
  420. * RBTree is a generic map from domain names to any kind of data. Internally,
  421. * it uses a red-black tree. However, it isn't one tree containing everything.
  422. * Subdomains are trees, so this structure is recursive - trees inside trees.
  423. * But, from the interface point of view, it is opaque data structure.
  424. *
  425. * \c RBTree splits the domain space into hierarchy red black trees; nodes
  426. * in one tree has the same base name. The benefit of this struct is that:
  427. * - Enhances the query performace compared with one big flat red black tree.
  428. * - Decreases the memory footprint, as it doesn't store the suffix labels
  429. * multiple times.
  430. *
  431. * Depending on different usage, rbtree will support different search policies.
  432. * Whether to return an empty node to end user is one policy among them.
  433. * The default policy is to NOT return an empty node to end user;
  434. * to change the behavior, specify \c true for the constructor parameter
  435. * \c returnEmptyNode.
  436. * \note The search policy only affects the \c find() behavior of RBTree.
  437. * When inserting one name into RBTree, if the node with the name already
  438. * exists in the RBTree and it's an empty node which doesn't have any data,
  439. * the \c insert() method will still return \c ALREADYEXISTS regardless of
  440. * the search policy.
  441. *
  442. * \anchor diagram
  443. *
  444. * with the following names:
  445. * - a
  446. * - b
  447. * - c
  448. * - x.d.e.f
  449. * - z.d.e.f
  450. * - g.h
  451. * - o.w.y.d.e.f
  452. * - p.w.y.d.e.f
  453. * - q.w.y.d.e.f
  454. *
  455. * the tree will look like:
  456. * \verbatim
  457. b
  458. / \
  459. a d.e.f
  460. /|\
  461. c | g.h
  462. |
  463. w.y
  464. /|\
  465. x | z
  466. |
  467. p
  468. / \
  469. o q
  470. \endverbatim
  471. * \todo
  472. * - add remove interface
  473. * - add iterator to iterate over the whole \c RBTree. This may be necessary,
  474. * for example, to support AXFR.
  475. */
  476. template <typename T>
  477. class RBTree : public boost::noncopyable {
  478. friend class RBNode<T>;
  479. public:
  480. /// \brief The return value for the \c find() and insert() methods
  481. enum Result {
  482. SUCCESS, ///< Insert was successful
  483. /// \brief The node returned from find mathes exactly the name given
  484. EXACTMATCH,
  485. PARTIALMATCH, ///< A superdomain node was found
  486. NOTFOUND, ///< Not even any superdomain was found
  487. /// \brief Returned by insert() if a node of the name already exists
  488. ALREADYEXISTS,
  489. };
  490. /// \name Constructor and Destructor
  491. //@{
  492. /// The constructor.
  493. ///
  494. /// It never throws an exception.
  495. explicit RBTree(bool returnEmptyNode = false);
  496. /// \b Note: RBTree is not intended to be inherited so the destructor
  497. /// is not virtual
  498. ~RBTree();
  499. //@}
  500. /// \name Find methods
  501. ///
  502. /// \brief Find the node that gives a longest match against the given name.
  503. ///
  504. /// \anchor find
  505. ///
  506. /// These methods search the RBTree for a node whose name is longest
  507. /// against name. The found node, if any, is returned via the node pointer.
  508. ///
  509. /// By default, nodes that don't have data (see RBNode::isEmpty) are
  510. /// ignored and the result can be NOTFOUND even if there's a node whose
  511. /// name matches. If the \c RBTree is constructed with its
  512. /// \c returnEmptyNode parameter being \c true, an empty node will also
  513. /// be match candidates.
  514. ///
  515. /// \note Even when \c returnEmptyNode is \c true, not all empty nodes
  516. /// in terms of the DNS protocol may necessarily be found by this method.
  517. /// For example, in the \ref diagram shown in the class description,
  518. /// the name y.d.e.f is logically contained in the tree as part of the
  519. /// node w.y, but the \c find() variants cannot find the former for
  520. /// the search key of y.d.e.f, no matter how the \c RBTree is constructed.
  521. /// The caller of this method must use a different way to identify the
  522. /// hidden match when necessary.
  523. ///
  524. /// These methods involve operations on names that can throw an exception.
  525. /// If that happens the exception will be propagated to the caller.
  526. /// The callback function should generally not throw an exception, but
  527. /// if it throws, the exception will be propagated to the caller.
  528. ///
  529. /// The \c name parameter says what should be found. The node parameter
  530. /// is output only and in case of EXACTMATCH and PARTIALMATCH, it is set
  531. /// to a pointer to the found node.
  532. ///
  533. /// They return:
  534. /// - EXACTMATCH when a node with the same name as requested exists.
  535. /// - PARTIALMATCH when a node with the same name does not exist (or is
  536. /// empty), but there's a (nonempty) superdomain of the requested one.
  537. /// The superdomain with longest name is returned through the node
  538. /// parameter. Beware that if you store a zone in the tree, you may get
  539. /// PARTIALMATCH with zone apex when the given domain name is not there.
  540. /// You should not try to delegate into another zone in that case.
  541. /// - NOTFOUND if there's no node with the same name nor any superdomain
  542. /// of it. In that case, node parameter is left intact.
  543. //@{
  544. /// \brief Simple find.
  545. ///
  546. /// Acts as described in the \ref find section.
  547. Result find(const isc::dns::Name& name, RBNode<T>** node) const {
  548. RBTreeNodeChain<T> node_path;
  549. return (find<void*>(name, node, node_path, NULL, NULL));
  550. }
  551. /// \brief Simple find returning immutable node.
  552. ///
  553. /// Acts as described in the \ref find section, but returns immutable node
  554. /// pointer.
  555. Result find(const isc::dns::Name& name, const RBNode<T>** node) const {
  556. RBTreeNodeChain<T> node_path;
  557. RBNode<T> *target_node = NULL;
  558. Result ret = (find<void*>(name, &target_node, node_path, NULL, NULL));
  559. if (ret != NOTFOUND) {
  560. *node = target_node;
  561. }
  562. return (ret);
  563. }
  564. /// \brief Find with callback and node chain.
  565. ///
  566. /// This version of \c find() is specifically designed for the backend
  567. /// of the \c MemoryZone class, and implements all necessary features
  568. /// for that purpose. Other applications shouldn't need these additional
  569. /// features, and should normally use the simpler versions.
  570. ///
  571. /// This version of \c find() calls the callback whenever traversing (on
  572. /// the way from root down the tree) a marked node on the way down through
  573. /// the domain namespace (see RBNode::enableCallback and related
  574. /// functions).
  575. ///
  576. /// If you return true from the callback, the search is stopped and a
  577. /// PARTIALMATCH is returned with the given node. Note that this node
  578. /// doesn't really need to be the one with longest possible match.
  579. ///
  580. /// This callback mechanism was designed with zone cut (delegation)
  581. /// processing in mind. The marked nodes would be the ones at delegation
  582. /// points. It is not expected that any other applications would need
  583. /// callbacks; they should use the versions of find without callbacks.
  584. /// The callbacks are not general functors for the same reason - we don't
  585. /// expect it to be needed.
  586. ///
  587. /// Another special feature of this version is the ability to provide
  588. /// a node chain containing a path to the found node. The chain will be
  589. /// returned via the \c node_path parameter.
  590. /// The passed parameter must be empty.
  591. /// On success, it will contain all the ancestor nodes from the found
  592. /// node towards the root.
  593. /// For example, if we look for o.w.y.d.e.f in the example \ref diagram,
  594. /// \c node_path will contain w.y and d.e.f; the \c top() node of the
  595. /// chain will be o, w.f and d.e.f will be stored below it.
  596. ///
  597. /// This feature can be used to get the absolute name for a node;
  598. /// to do so, we need to travel upside from the node toward the root,
  599. /// concatenating all ancestor names. With the current implementation
  600. /// it's not possible without a node chain, because there is a no pointer
  601. /// from the root of a subtree to the parent subtree (this may change
  602. /// in a future version). A node chain can also be used to find the next
  603. /// node of a given node in the entire RBTree; the \c nextNode() method
  604. /// takes a node chain as a parameter.
  605. ///
  606. /// \param name Target to be found
  607. /// \param node On success (either \c EXACTMATCH or \c PARTIALMATCH)
  608. /// it will store a pointer to the matching node
  609. /// \param node_path It will store all the ancestor nodes in the RBTree
  610. /// from the found node to the root. The found node is stored.
  611. /// \param callback If non \c NULL, a call back function to be called
  612. /// at marked nodes (see above).
  613. /// \param callback_arg A caller supplied argument to be passed to
  614. /// \c callback.
  615. ///
  616. /// \return As described above, but in case of callback returning true,
  617. /// it returns immediately with the current node.
  618. template <typename CBARG>
  619. Result find(const isc::dns::Name& name,
  620. RBNode<T>** node,
  621. RBTreeNodeChain<T>& node_path,
  622. bool (*callback)(const RBNode<T>&, CBARG),
  623. CBARG callback_arg) const;
  624. /// \brief Simple find returning immutable node.
  625. ///
  626. /// Acts as described in the \ref find section, but returns immutable
  627. /// node pointer.
  628. template <typename CBARG>
  629. Result find(const isc::dns::Name& name,
  630. const RBNode<T>** node,
  631. RBTreeNodeChain<T>& node_path,
  632. bool (*callback)(const RBNode<T>&, CBARG),
  633. CBARG callback_arg) const
  634. {
  635. RBNode<T>* target_node = NULL;
  636. Result ret = find(name, &target_node, node_path, callback,
  637. callback_arg);
  638. if (ret != NOTFOUND) {
  639. *node = target_node;
  640. }
  641. return (ret);
  642. }
  643. //@}
  644. /// \brief return the next bigger node in DNSSEC order of the given node.
  645. ///
  646. /// \note nextNode will iterator all the nodes in RBTree including empty
  647. /// nodes. If empty node isn't desired, it's easy to add logic to check
  648. /// return node and keep invoking nextNode until the non-empty node is
  649. /// retrived
  650. ///
  651. /// This method also updates the given \c node_path so that it will store
  652. /// the path for the returned next node.
  653. /// It will be convenient when we want to iterate over the all nodes
  654. /// of \c RBTree; we can do this by calling this method repeatedly
  655. /// starting from the root node.
  656. ///
  657. /// \exception If the node_path isn't initalized by find function and not
  658. /// get from previous nextNode function call, InvalidNodeChain exception
  659. /// will be thrown
  660. ///
  661. /// \param node_path A node chain that stores all the nodes along the path
  662. /// from root to node.
  663. ///
  664. /// \return An \c RBNode that is next bigger than \c node; if \c node is
  665. /// the largest, \c NULL will be returned.
  666. const RBNode<T>* nextNode(RBTreeNodeChain<T>& node_path) const;
  667. /// \brief Get the total number of nodes in the tree
  668. ///
  669. /// It includes nodes internally created as a result of adding a domain
  670. /// name that is a subdomain of an existing node of the tree.
  671. /// This function is mainly intended to be used for debugging.
  672. int getNodeCount() const { return (node_count_); }
  673. /// \name Debug function
  674. //@{
  675. /// \brief Print the nodes in the trees.
  676. ///
  677. /// \param os A \c std::ostream object to which the tree is printed.
  678. /// \param depth A factor of the initial indentation. Each line
  679. /// will begin with space character repeating <code>5 * depth</code>
  680. /// times.
  681. void dumpTree(std::ostream& os, unsigned int depth = 0) const;
  682. //@}
  683. /// \name Modify functions
  684. //@{
  685. /// \brief Insert the domain name into the tree.
  686. ///
  687. /// It either finds an already existing node of the given name or inserts
  688. /// a new one, if none exists yet. In any case, the inserted_node parameter
  689. /// is set to point to that node. You can fill data into it or modify it.
  690. /// So, if you don't know if a node exists or not and you need to modify
  691. /// it, just call insert and act by the result.
  692. ///
  693. /// Please note that the tree can add some empty nodes by itself, so don't
  694. /// assume that if you didn't insert a node of that name it doesn't exist.
  695. ///
  696. /// This method normally involves resource allocation. If it fails
  697. /// the corresponding standard exception will be thrown.
  698. ///
  699. /// This method does not provide the strong exception guarantee in its
  700. /// strict sense; if an exception is thrown in the middle of this
  701. /// method, the internal structure may change. However, it should
  702. /// still retain the same property as a mapping container before this
  703. /// method is called. For example, the result of \c find() should be
  704. /// the same. This method provides the weak exception guarantee in its
  705. /// normal sense.
  706. ///
  707. /// \param name The name to be inserted into the tree.
  708. /// \param inserted_node This is an output parameter and is set to the
  709. /// node.
  710. ///
  711. /// \return
  712. /// - SUCCESS The node was added.
  713. /// - ALREADYEXISTS There was already a node of that name, so it was not
  714. /// added.
  715. Result insert(const isc::dns::Name& name, RBNode<T>** inserted_node);
  716. /// \brief Swaps two tree's contents.
  717. ///
  718. /// This acts the same as many std::*.swap functions, exchanges the
  719. /// contents. This doesn't throw anything.
  720. void swap(RBTree<T>& other) {
  721. std::swap(root_, other.root_);
  722. std::swap(NULLNODE, other.NULLNODE);
  723. std::swap(node_count_, other.node_count_);
  724. }
  725. //@}
  726. private:
  727. /// \name RBTree balance functions
  728. //@{
  729. void insertRebalance(RBNode<T>** root, RBNode<T>* node);
  730. RBNode<T>* rightRotate(RBNode<T>** root, RBNode<T>* node);
  731. RBNode<T>* leftRotate(RBNode<T>** root, RBNode<T>* node);
  732. //@}
  733. /// \name Helper functions
  734. //@{
  735. /// \brief delete tree whose root is equal to node
  736. void deleteHelper(RBNode<T> *node);
  737. /// \brief find the node with name
  738. ///
  739. /// Internal searching function.
  740. ///
  741. void dumpTreeHelper(std::ostream& os, const RBNode<T>* node,
  742. unsigned int depth) const;
  743. /// \brief Indentation helper function for dumpTree
  744. static void indent(std::ostream& os, unsigned int depth);
  745. /// Split one node into two nodes, keep the old node and create one new
  746. /// node, old node will hold the base name, new node will be the down node
  747. /// of old node, new node will hold the sub_name, the data
  748. /// of old node will be move into new node, and old node became non-terminal
  749. void nodeFission(RBNode<T>& node, const isc::dns::Name& sub_name);
  750. //@}
  751. RBNode<T>* NULLNODE;
  752. RBNode<T>* root_;
  753. /// the node count of current tree
  754. unsigned int node_count_;
  755. /// search policy for rbtree
  756. const bool needsReturnEmptyNode_;
  757. };
  758. template <typename T>
  759. RBTree<T>::RBTree(bool returnEmptyNode) :
  760. NULLNODE(RBNode<T>::NULL_NODE()),
  761. root_(NULLNODE),
  762. node_count_(0),
  763. needsReturnEmptyNode_(returnEmptyNode)
  764. {
  765. }
  766. template <typename T>
  767. RBTree<T>::~RBTree() {
  768. deleteHelper(root_);
  769. assert(node_count_ == 0);
  770. }
  771. template <typename T>
  772. void
  773. RBTree<T>::deleteHelper(RBNode<T>* root) {
  774. if (root == NULLNODE) {
  775. return;
  776. }
  777. RBNode<T>* node = root;
  778. while (root->left_ != NULLNODE || root->right_ != NULLNODE) {
  779. while (node->left_ != NULLNODE || node->right_ != NULLNODE) {
  780. node = (node->left_ != NULLNODE) ? node->left_ : node->right_;
  781. }
  782. RBNode<T>* parent = node->parent_;
  783. if (parent->left_ == node) {
  784. parent->left_ = NULLNODE;
  785. } else {
  786. parent->right_ = NULLNODE;
  787. }
  788. deleteHelper(node->down_);
  789. delete node;
  790. --node_count_;
  791. node = parent;
  792. }
  793. deleteHelper(root->down_);
  794. delete root;
  795. --node_count_;
  796. }
  797. template <typename T>
  798. template <typename CBARG>
  799. typename RBTree<T>::Result
  800. RBTree<T>::find(const isc::dns::Name& target_name,
  801. RBNode<T>** target,
  802. RBTreeNodeChain<T>& node_path,
  803. bool (*callback)(const RBNode<T>&, CBARG),
  804. CBARG callback_arg) const
  805. {
  806. using namespace helper;
  807. RBNode<T>* node = root_;
  808. Result ret = NOTFOUND;
  809. isc::dns::Name name = target_name;
  810. while (node != NULLNODE) {
  811. const isc::dns::NameComparisonResult compare_result =
  812. name.compare(node->name_);
  813. const isc::dns::NameComparisonResult::NameRelation relation =
  814. compare_result.getRelation();
  815. if (relation == isc::dns::NameComparisonResult::EQUAL) {
  816. if (needsReturnEmptyNode_ || !node->isEmpty()) {
  817. node_path.push(node);
  818. *target = node;
  819. ret = EXACTMATCH;
  820. }
  821. break;
  822. } else {
  823. const int common_label_count = compare_result.getCommonLabels();
  824. // If the common label count is 1, there is no common label between
  825. // the two names, except the trailing "dot".
  826. if (common_label_count == 1) {
  827. node = (compare_result.getOrder() < 0) ?
  828. node->left_ : node->right_;
  829. } else if (relation == isc::dns::NameComparisonResult::SUBDOMAIN) {
  830. if (needsReturnEmptyNode_ || !node->isEmpty()) {
  831. ret = PARTIALMATCH;
  832. *target = node;
  833. if (callback != NULL && node->callback_required_) {
  834. if ((callback)(*node, callback_arg)) {
  835. break;
  836. }
  837. }
  838. }
  839. node_path.push(node);
  840. name = name - node->name_;
  841. node = node->down_;
  842. } else {
  843. break;
  844. }
  845. }
  846. }
  847. return (ret);
  848. }
  849. template <typename T>
  850. const RBNode<T>*
  851. RBTree<T>::nextNode(RBTreeNodeChain<T>& node_path) const {
  852. const RBNode<T>* node = node_path.top();
  853. // if node has sub domain, the next domain is the smallest
  854. // domain in sub domain tree
  855. if (node->down_ != NULLNODE) {
  856. const RBNode<T>* left_most = node->down_;
  857. while (left_most->left_ != NULLNODE) {
  858. left_most = left_most->left_;
  859. }
  860. node_path.push(left_most);
  861. return (left_most);
  862. }
  863. // node_path go to up level
  864. node_path.pop();
  865. // otherwise found the successor node in current level
  866. const RBNode<T>* successor = node->successor();
  867. if (successor != NULLNODE) {
  868. node_path.push(successor);
  869. return (successor);
  870. }
  871. // if no successor found move to up level, the next successor
  872. // is the successor of up node in the up level tree, if
  873. // up node doesn't have successor we gonna keep moving to up
  874. // level
  875. while (!node_path.isEmpty()) {
  876. const RBNode<T>* up_node_successor = node_path.top()->successor();
  877. node_path.pop();
  878. if (up_node_successor != NULLNODE) {
  879. node_path.push(up_node_successor);
  880. return (up_node_successor);
  881. }
  882. }
  883. return (NULL);
  884. }
  885. template <typename T>
  886. typename RBTree<T>::Result
  887. RBTree<T>::insert(const isc::dns::Name& target_name, RBNode<T>** new_node) {
  888. using namespace helper;
  889. RBNode<T>* parent = NULLNODE;
  890. RBNode<T>* current = root_;
  891. RBNode<T>* up_node = NULLNODE;
  892. isc::dns::Name name = target_name;
  893. int order = -1;
  894. while (current != NULLNODE) {
  895. const isc::dns::NameComparisonResult compare_result =
  896. name.compare(current->name_);
  897. const isc::dns::NameComparisonResult::NameRelation relation =
  898. compare_result.getRelation();
  899. if (relation == isc::dns::NameComparisonResult::EQUAL) {
  900. if (new_node != NULL) {
  901. *new_node = current;
  902. }
  903. return (ALREADYEXISTS);
  904. } else {
  905. const int common_label_count = compare_result.getCommonLabels();
  906. if (common_label_count == 1) {
  907. parent = current;
  908. order = compare_result.getOrder();
  909. current = order < 0 ? current->left_ : current->right_;
  910. } else {
  911. // insert sub domain to sub tree
  912. if (relation == isc::dns::NameComparisonResult::SUBDOMAIN) {
  913. parent = NULLNODE;
  914. up_node = current;
  915. name = name - current->name_;
  916. current = current->down_;
  917. } else {
  918. // The number of labels in common is fewer
  919. // than the number of labels at the current
  920. // node, so the current node must be adjusted
  921. // to have just the common suffix, and a down
  922. // pointer made to a new tree.
  923. const isc::dns::Name common_ancestor = name.split(
  924. name.getLabelCount() - common_label_count,
  925. common_label_count);
  926. nodeFission(*current, common_ancestor);
  927. }
  928. }
  929. }
  930. }
  931. RBNode<T>** current_root = (up_node != NULLNODE) ?
  932. &(up_node->down_) : &root_;
  933. // using auto_ptr here is avoid memory leak in case of exceptoin raised
  934. // after the RBNode creation, if we can make sure no exception will be
  935. // raised until the end of the function, we can remove it for optimization
  936. std::auto_ptr<RBNode<T> > node(new RBNode<T>(name));
  937. node->parent_ = parent;
  938. if (parent == NULLNODE) {
  939. *current_root = node.get();
  940. //node is the new root of sub tree, so its init color
  941. // is BLACK
  942. node->color_ = RBNode<T>::BLACK;
  943. } else if (order < 0) {
  944. parent->left_ = node.get();
  945. } else {
  946. parent->right_ = node.get();
  947. }
  948. insertRebalance(current_root, node.get());
  949. if (new_node != NULL) {
  950. *new_node = node.get();
  951. }
  952. ++node_count_;
  953. node.release();
  954. return (SUCCESS);
  955. }
  956. template <typename T>
  957. void
  958. RBTree<T>::nodeFission(RBNode<T>& node, const isc::dns::Name& base_name) {
  959. using namespace helper;
  960. const isc::dns::Name sub_name = node.name_ - base_name;
  961. // using auto_ptr here is to avoid memory leak in case of exception raised
  962. // after the RBNode creation
  963. std::auto_ptr<RBNode<T> > down_node(new RBNode<T>(sub_name));
  964. node.name_ = base_name;
  965. // the rest of this function should be exception free so that it keeps
  966. // consistent behavior (i.e., a weak form of strong exception guarantee)
  967. // even if code after the call to this function throws an exception.
  968. std::swap(node.data_, down_node->data_);
  969. std::swap(node.callback_required_, down_node->callback_required_);
  970. down_node->down_ = node.down_;
  971. node.down_ = down_node.get();
  972. // root node of sub tree, the initial color is BLACK
  973. down_node->color_ = RBNode<T>::BLACK;
  974. ++node_count_;
  975. down_node.release();
  976. }
  977. template <typename T>
  978. void
  979. RBTree<T>::insertRebalance(RBNode<T>** root, RBNode<T>* node) {
  980. RBNode<T>* uncle;
  981. while (node != *root && node->parent_->color_ == RBNode<T>::RED) {
  982. if (node->parent_ == node->parent_->parent_->left_) {
  983. uncle = node->parent_->parent_->right_;
  984. if (uncle->color_ == RBNode<T>::RED) {
  985. node->parent_->color_ = RBNode<T>::BLACK;
  986. uncle->color_ = RBNode<T>::BLACK;
  987. node->parent_->parent_->color_ = RBNode<T>::RED;
  988. node = node->parent_->parent_;
  989. } else {
  990. if (node == node->parent_->right_) {
  991. node = node->parent_;
  992. leftRotate(root, node);
  993. }
  994. node->parent_->color_ = RBNode<T>::BLACK;
  995. node->parent_->parent_->color_ = RBNode<T>::RED;
  996. rightRotate(root, node->parent_->parent_);
  997. }
  998. } else {
  999. uncle = node->parent_->parent_->left_;
  1000. if (uncle->color_ == RBNode<T>::RED) {
  1001. node->parent_->color_ = RBNode<T>::BLACK;
  1002. uncle->color_ = RBNode<T>::BLACK;
  1003. node->parent_->parent_->color_ = RBNode<T>::RED;
  1004. node = node->parent_->parent_;
  1005. } else {
  1006. if (node == node->parent_->left_) {
  1007. node = node->parent_;
  1008. rightRotate(root, node);
  1009. }
  1010. node->parent_->color_ = RBNode<T>::BLACK;
  1011. node->parent_->parent_->color_ = RBNode<T>::RED;
  1012. leftRotate(root, node->parent_->parent_);
  1013. }
  1014. }
  1015. }
  1016. (*root)->color_ = RBNode<T>::BLACK;
  1017. }
  1018. template <typename T>
  1019. RBNode<T>*
  1020. RBTree<T>::leftRotate(RBNode<T>** root, RBNode<T>* node) {
  1021. RBNode<T>* right = node->right_;
  1022. node->right_ = right->left_;
  1023. if (right->left_ != NULLNODE)
  1024. right->left_->parent_ = node;
  1025. right->parent_ = node->parent_;
  1026. if (node->parent_ != NULLNODE) {
  1027. if (node == node->parent_->left_) {
  1028. node->parent_->left_ = right;
  1029. } else {
  1030. node->parent_->right_ = right;
  1031. }
  1032. } else {
  1033. *root = right;
  1034. }
  1035. right->left_ = node;
  1036. node->parent_ = right;
  1037. return (node);
  1038. }
  1039. template <typename T>
  1040. RBNode<T>*
  1041. RBTree<T>::rightRotate(RBNode<T>** root, RBNode<T>* node) {
  1042. RBNode<T>* left = node->left_;
  1043. node->left_ = left->right_;
  1044. if (left->right_ != NULLNODE)
  1045. left->right_->parent_ = node;
  1046. left->parent_ = node->parent_;
  1047. if (node->parent_ != NULLNODE) {
  1048. if (node == node->parent_->right_) {
  1049. node->parent_->right_ = left;
  1050. } else {
  1051. node->parent_->left_ = left;
  1052. }
  1053. } else {
  1054. *root = left;
  1055. }
  1056. left->right_ = node;
  1057. node->parent_ = left;
  1058. return (node);
  1059. }
  1060. template <typename T>
  1061. void
  1062. RBTree<T>::dumpTree(std::ostream& os, unsigned int depth) const {
  1063. indent(os, depth);
  1064. os << "tree has " << node_count_ << " node(s)\n";
  1065. dumpTreeHelper(os, root_, depth);
  1066. }
  1067. template <typename T>
  1068. void
  1069. RBTree<T>::dumpTreeHelper(std::ostream& os, const RBNode<T>* node,
  1070. unsigned int depth) const
  1071. {
  1072. if (node == NULLNODE) {
  1073. indent(os, depth);
  1074. os << "NULL\n";
  1075. return;
  1076. }
  1077. indent(os, depth);
  1078. os << node->name_.toText() << " ("
  1079. << ((node->color_ == RBNode<T>::BLACK) ? "black" : "red") << ")";
  1080. os << ((node->isEmpty()) ? "[invisible] \n" : "\n");
  1081. if (node->down_ != NULLNODE) {
  1082. indent(os, depth + 1);
  1083. os << "begin down from " << node->name_.toText() << "\n";
  1084. dumpTreeHelper(os, node->down_, depth + 1);
  1085. indent(os, depth + 1);
  1086. os << "end down from " << node->name_.toText() << "\n";
  1087. }
  1088. dumpTreeHelper(os, node->left_, depth + 1);
  1089. dumpTreeHelper(os, node->right_, depth + 1);
  1090. }
  1091. template <typename T>
  1092. void
  1093. RBTree<T>::indent(std::ostream& os, unsigned int depth) {
  1094. static const unsigned int INDENT_FOR_EACH_DEPTH = 5;
  1095. os << std::string(depth * INDENT_FOR_EACH_DEPTH, ' ');
  1096. }
  1097. }
  1098. }
  1099. #endif // _RBTREE_H
  1100. // Local Variables:
  1101. // mode: c++
  1102. // End: