rbtree.h 47 KB

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