rbtree.h 48 KB

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