PageRenderTime 49ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/dep/acelite/ace/RB_Tree.cpp

https://github.com/chucho/FaceCore
C++ | 1250 lines | 935 code | 164 blank | 151 comment | 174 complexity | cdb0bd77d5423e075b5b734f2a8320e4 MD5 | raw file
  1. // $Id: RB_Tree.cpp 91813 2010-09-17 07:52:52Z johnnyw $
  2. #ifndef ACE_RB_TREE_CPP
  3. #define ACE_RB_TREE_CPP
  4. #include "ace/Global_Macros.h"
  5. #include "ace/RB_Tree.h"
  6. #include "ace/SString.h"
  7. #if !defined (ACE_LACKS_PRAGMA_ONCE)
  8. # pragma once
  9. #endif /* ACE_LACKS_PRAGMA_ONCE */
  10. #if !defined (__ACE_INLINE__)
  11. #include "ace/RB_Tree.inl"
  12. #endif /* __ACE_INLINE__ */
  13. #include "ace/Log_Msg.h"
  14. ACE_BEGIN_VERSIONED_NAMESPACE_DECL
  15. // Constructor.
  16. template <class EXT_ID, class INT_ID>
  17. ACE_RB_Tree_Node<EXT_ID, INT_ID>::ACE_RB_Tree_Node (const EXT_ID &k, const INT_ID &t)
  18. : k_ (k),
  19. t_ (t),
  20. color_ (RED),
  21. parent_ (0),
  22. left_ (0),
  23. right_ (0)
  24. {
  25. ACE_TRACE ("ACE_RB_Tree_Node<EXT_ID, INT_ID>::ACE_RB_Tree_Node (const EXT_ID &k, const INT_ID &t)");
  26. }
  27. // Destructor.
  28. template <class EXT_ID, class INT_ID>
  29. ACE_RB_Tree_Node<EXT_ID, INT_ID>::~ACE_RB_Tree_Node (void)
  30. {
  31. ACE_TRACE ("ACE_RB_Tree_Node<EXT_ID, INT_ID>::~ACE_RB_Tree_Node");
  32. }
  33. // Constructor.
  34. template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
  35. ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree (ACE_Allocator *alloc)
  36. : root_ (0),
  37. current_size_ (0)
  38. {
  39. ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::"
  40. "ACE_RB_Tree (ACE_Allocator *alloc)");
  41. allocator_ = alloc;
  42. if (this->open (alloc) == -1)
  43. ACE_ERROR ((LM_ERROR,
  44. ACE_TEXT ("ACE_RB_Tree::ACE_RB_Tree\n")));
  45. }
  46. // Copy constructor.
  47. template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
  48. ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree (const ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> &rbt)
  49. : root_ (0),
  50. current_size_ (0)
  51. {
  52. ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::"
  53. "ACE_RB_Tree (const ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> &rbt)");
  54. ACE_WRITE_GUARD (ACE_LOCK, ace_mon, this->lock_);
  55. allocator_ = rbt.allocator_;
  56. // Make a deep copy of the passed tree.
  57. ACE_RB_Tree_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> iter(rbt);
  58. for (iter.first ();
  59. iter.is_done () == 0; iter.next ())
  60. insert_i (*(iter.key ()),
  61. *(iter.item ()));
  62. }
  63. template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
  64. ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree (
  65. void *location,
  66. ACE_Allocator *alloc
  67. )
  68. {
  69. if (location != this)
  70. {
  71. this->root_ = 0;
  72. this->current_size_ = 0;
  73. }
  74. this->allocator_ = alloc;
  75. }
  76. // Destructor.
  77. template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
  78. ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::~ACE_RB_Tree ()
  79. {
  80. ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::~ACE_RB_Tree");
  81. // Use the locked public method, to be totally safe, as the class
  82. // can be used with an allocator and placement new.
  83. this->close ();
  84. }
  85. // Assignment operator.
  86. template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> void
  87. ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::operator = (const ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> &rbt)
  88. {
  89. ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::operator =");
  90. ACE_WRITE_GUARD (ACE_LOCK, ace_mon, this->lock_);
  91. if (this != &rbt)
  92. {
  93. // Clear out the existing tree.
  94. close_i ();
  95. // Make a deep copy of the passed tree.
  96. ACE_RB_Tree_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> iter(rbt);
  97. for (iter.first ();
  98. iter.is_done () == 0;
  99. iter.next ())
  100. insert_i (*(iter.key ()),
  101. *(iter.item ()));
  102. // Use the same allocator as the rhs.
  103. allocator_ = rbt.allocator_;
  104. }
  105. }
  106. // Less than comparison function for keys, default functor
  107. // implementation returns 1 if k1 < k2, 0 otherwise.
  108. template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> int
  109. ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::lessthan (const EXT_ID &k1, const EXT_ID &k2)
  110. {
  111. ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::lessthan");
  112. return this->compare_keys_ (k1, k2);
  113. }
  114. // Method for right rotation of the tree about a given node.
  115. template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> void
  116. ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::RB_rotate_right (ACE_RB_Tree_Node<EXT_ID, INT_ID> *x)
  117. {
  118. ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::RB_rotate_right");
  119. if (!x)
  120. ACE_ERROR ((LM_ERROR,
  121. ACE_TEXT ("%p\n"),
  122. ACE_TEXT ("\nerror: x is a null pointer in ")
  123. ACE_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::RB_rotate_right\n")));
  124. else if (! (x->left()))
  125. ACE_ERROR ((LM_ERROR,
  126. ACE_TEXT ("%p\n"),
  127. ACE_TEXT ("\nerror: x->left () is a null pointer in ")
  128. ACE_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::RB_rotate_right\n")));
  129. else
  130. {
  131. ACE_RB_Tree_Node<EXT_ID, INT_ID> * y;
  132. y = x->left ();
  133. x->left (y->right ());
  134. if (y->right ())
  135. y->right ()->parent (x);
  136. y->parent (x->parent ());
  137. if (x->parent ())
  138. {
  139. if (x == x->parent ()->right ())
  140. x->parent ()->right (y);
  141. else
  142. x->parent ()->left (y);
  143. }
  144. else
  145. root_ = y;
  146. y->right (x);
  147. x->parent (y);
  148. }
  149. }
  150. // Method for left rotation of the tree about a given node.
  151. template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> void
  152. ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::RB_rotate_left (ACE_RB_Tree_Node<EXT_ID, INT_ID> * x)
  153. {
  154. ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::RB_rotate_left");
  155. if (! x)
  156. ACE_ERROR ((LM_ERROR,
  157. ACE_TEXT ("%p\n"),
  158. ACE_TEXT ("\nerror: x is a null pointer in ")
  159. ACE_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::RB_rotate_left\n")));
  160. else if (! (x->right()))
  161. ACE_ERROR ((LM_ERROR,
  162. ACE_TEXT ("%p\n"),
  163. ACE_TEXT ("\nerror: x->right () is a null pointer ")
  164. ACE_TEXT ("in ACE_RB_Tree<EXT_ID, INT_ID>::RB_rotate_left\n")));
  165. else
  166. {
  167. ACE_RB_Tree_Node<EXT_ID, INT_ID> * y;
  168. y = x->right ();
  169. x->right (y->left ());
  170. if (y->left ())
  171. y->left ()->parent (x);
  172. y->parent (x->parent ());
  173. if (x->parent ())
  174. {
  175. if (x == x->parent ()->left ())
  176. x->parent ()->left (y);
  177. else
  178. x->parent ()->right (y);
  179. }
  180. else
  181. root_ = y;
  182. y->left (x);
  183. x->parent (y);
  184. }
  185. }
  186. // Method for restoring Red-Black properties after a specific deletion case.
  187. template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> void
  188. ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::
  189. RB_delete_fixup (ACE_RB_Tree_Node<EXT_ID, INT_ID> *x,
  190. ACE_RB_Tree_Node<EXT_ID, INT_ID> *parent)
  191. {
  192. ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::RB_delete_fixup");
  193. while (x != this->root_
  194. && (!x
  195. || x->color () == ACE_RB_Tree_Node_Base::BLACK))
  196. {
  197. if (x == parent->left ())
  198. {
  199. ACE_RB_Tree_Node<EXT_ID, INT_ID> *w = parent->right ();
  200. if (w && w->color () == ACE_RB_Tree_Node_Base::RED)
  201. {
  202. w->color (ACE_RB_Tree_Node_Base::BLACK);
  203. parent->color (ACE_RB_Tree_Node_Base::RED);
  204. RB_rotate_left (parent);
  205. w = parent->right ();
  206. }
  207. // CLR pp. 263 says that nil nodes are implicitly colored BLACK
  208. if (w
  209. && (!w->left ()
  210. || w->left ()->color () == ACE_RB_Tree_Node_Base::BLACK)
  211. && (!w->right ()
  212. || w->right ()->color () == ACE_RB_Tree_Node_Base::BLACK))
  213. {
  214. w->color (ACE_RB_Tree_Node_Base::RED);
  215. x = parent;
  216. parent = x->parent ();
  217. }
  218. else
  219. {
  220. // CLR pp. 263 says that nil nodes are implicitly colored BLACK
  221. if (w
  222. && (!w->right ()
  223. || w->right ()->color () == ACE_RB_Tree_Node_Base::BLACK))
  224. {
  225. if (w->left ())
  226. w->left ()->color (ACE_RB_Tree_Node_Base::BLACK);
  227. w->color (ACE_RB_Tree_Node_Base::RED);
  228. RB_rotate_right (w);
  229. w = parent->right ();
  230. }
  231. if (w)
  232. {
  233. w->color (parent->color ());
  234. if (w->right ())
  235. w->right ()->color (ACE_RB_Tree_Node_Base::BLACK);
  236. }
  237. parent->color (ACE_RB_Tree_Node_Base::BLACK);
  238. RB_rotate_left (parent);
  239. x = root_;
  240. }
  241. }
  242. else
  243. {
  244. ACE_RB_Tree_Node<EXT_ID, INT_ID> *w = parent->left ();
  245. if (w && w->color () == ACE_RB_Tree_Node_Base::RED)
  246. {
  247. w->color (ACE_RB_Tree_Node_Base::BLACK);
  248. parent->color (ACE_RB_Tree_Node_Base::RED);
  249. RB_rotate_right (parent);
  250. w = parent->left ();
  251. }
  252. // CLR pp. 263 says that nil nodes are implicitly colored BLACK
  253. if (w
  254. && (!w->left ()
  255. || w->left ()->color () == ACE_RB_Tree_Node_Base::BLACK)
  256. && (!w->right ()
  257. || w->right ()->color () == ACE_RB_Tree_Node_Base::BLACK))
  258. {
  259. w->color (ACE_RB_Tree_Node_Base::RED);
  260. x = parent;
  261. parent = x->parent ();
  262. }
  263. else
  264. {
  265. // CLR pp. 263 says that nil nodes are implicitly colored BLACK
  266. if (w
  267. && (!w->left ()
  268. || w->left ()->color () == ACE_RB_Tree_Node_Base::BLACK))
  269. {
  270. w->color (ACE_RB_Tree_Node_Base::RED);
  271. if (w->right ())
  272. w->right ()->color (ACE_RB_Tree_Node_Base::BLACK);
  273. RB_rotate_left (w);
  274. w = parent->left ();
  275. }
  276. if (w)
  277. {
  278. w->color (parent->color ());
  279. if (w->left ())
  280. w->left ()->color (ACE_RB_Tree_Node_Base::BLACK);
  281. }
  282. parent->color (ACE_RB_Tree_Node_Base::BLACK);
  283. RB_rotate_right (parent);
  284. x = root_;
  285. }
  286. }
  287. }
  288. if (x)
  289. x->color (ACE_RB_Tree_Node_Base::BLACK);
  290. }
  291. // Return a pointer to a matching node if there is one, a pointer to
  292. // the node under which to insert the item if the tree is not empty
  293. // and there is no such match, or 0 if the tree is empty.
  294. template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> ACE_RB_Tree_Node<EXT_ID, INT_ID> *
  295. ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::find_node (const EXT_ID &k, ACE_RB_Tree_Base::RB_SearchResult &result)
  296. {
  297. ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::find_node");
  298. // Start at the root.
  299. ACE_RB_Tree_Node<EXT_ID, INT_ID> *current = root_;
  300. while (current)
  301. {
  302. // While there are more nodes to examine.
  303. if (this->lessthan (current->key (), k))
  304. {
  305. // If the search key is greater than the current node's key.
  306. if (current->right ())
  307. // If the right subtree is not empty, search to the right.
  308. current = current->right ();
  309. else
  310. {
  311. // If the right subtree is empty, we're done searching,
  312. // and are positioned to the left of the insertion point.
  313. result = LEFT;
  314. break;
  315. }
  316. }
  317. else if (this->lessthan (k, current->key ()))
  318. {
  319. // Else if the search key is less than the current node's key.
  320. if (current->left ())
  321. // If the left subtree is not empty, search to the left.
  322. current = current->left ();
  323. else
  324. {
  325. // If the left subtree is empty, we're done searching,
  326. // and are positioned to the right of the insertion point.
  327. result = RIGHT;
  328. break;
  329. }
  330. }
  331. else
  332. {
  333. // If the keys match exactly, we're done as well.
  334. result = EXACT;
  335. break;
  336. }
  337. }
  338. return current;
  339. }
  340. // Rebalance the tree after insertion of a node.
  341. template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> void
  342. ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::RB_rebalance (ACE_RB_Tree_Node<EXT_ID, INT_ID> * x)
  343. {
  344. ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::RB_rebalance");
  345. ACE_RB_Tree_Node<EXT_ID, INT_ID> *y = 0;
  346. while (x &&
  347. x->parent ()
  348. && x->parent ()->color () == ACE_RB_Tree_Node_Base::RED)
  349. {
  350. if (! x->parent ()->parent ())
  351. {
  352. // If we got here, something is drastically wrong!
  353. ACE_ERROR ((LM_ERROR,
  354. ACE_TEXT ("%p\n"),
  355. ACE_TEXT ("\nerror: parent's parent is null in ")
  356. ACE_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::RB_rebalance\n")));
  357. return;
  358. }
  359. if (x->parent () == x->parent ()->parent ()->left ())
  360. {
  361. y = x->parent ()->parent ()->right ();
  362. if (y && y->color () == ACE_RB_Tree_Node_Base::RED)
  363. {
  364. // Handle case 1 (see CLR book, pp. 269).
  365. x->parent ()->color (ACE_RB_Tree_Node_Base::BLACK);
  366. y->color (ACE_RB_Tree_Node_Base::BLACK);
  367. x->parent ()->parent ()->color (ACE_RB_Tree_Node_Base::RED);
  368. x = x->parent ()->parent ();
  369. }
  370. else
  371. {
  372. if (x == x->parent ()->right ())
  373. {
  374. // Transform case 2 into case 3 (see CLR book, pp. 269).
  375. x = x->parent ();
  376. RB_rotate_left (x);
  377. }
  378. // Handle case 3 (see CLR book, pp. 269).
  379. x->parent ()->color (ACE_RB_Tree_Node_Base::BLACK);
  380. x->parent ()->parent ()->color (ACE_RB_Tree_Node_Base::RED);
  381. RB_rotate_right (x->parent ()->parent ());
  382. }
  383. }
  384. else
  385. {
  386. y = x->parent ()->parent ()->left ();
  387. if (y && y->color () == ACE_RB_Tree_Node_Base::RED)
  388. {
  389. // Handle case 1 (see CLR book, pp. 269).
  390. x->parent ()->color (ACE_RB_Tree_Node_Base::BLACK);
  391. y->color (ACE_RB_Tree_Node_Base::BLACK);
  392. x->parent ()->parent ()->color (ACE_RB_Tree_Node_Base::RED);
  393. x = x->parent ()->parent ();
  394. }
  395. else
  396. {
  397. if (x == x->parent ()->left ())
  398. {
  399. // Transform case 2 into case 3 (see CLR book, pp. 269).
  400. x = x->parent ();
  401. RB_rotate_right (x);
  402. }
  403. // Handle case 3 (see CLR book, pp. 269).
  404. x->parent ()->color (ACE_RB_Tree_Node_Base::BLACK);
  405. x->parent ()->parent ()->color (ACE_RB_Tree_Node_Base::RED);
  406. RB_rotate_left (x->parent ()->parent ());
  407. }
  408. }
  409. }
  410. }
  411. // Method to find the successor node of the given node in the tree.
  412. template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> ACE_RB_Tree_Node<EXT_ID, INT_ID> *
  413. ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::RB_tree_successor (ACE_RB_Tree_Node<EXT_ID, INT_ID> *x) const
  414. {
  415. ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::RB_tree_successor");
  416. if (x == 0)
  417. return 0;
  418. if (x->right ())
  419. return RB_tree_minimum (x->right ());
  420. ACE_RB_Tree_Node<EXT_ID, INT_ID> *y = x->parent ();
  421. while ((y) && (x == y->right ()))
  422. {
  423. x = y;
  424. y = y->parent ();
  425. }
  426. return y;
  427. }
  428. // Method to find the predecessor node of the given node in the tree.
  429. template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> ACE_RB_Tree_Node<EXT_ID, INT_ID> *
  430. ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::RB_tree_predecessor (ACE_RB_Tree_Node<EXT_ID, INT_ID> *x) const
  431. {
  432. ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::RB_tree_predecessor");
  433. if (x == 0)
  434. return 0;
  435. if (x->left ())
  436. return RB_tree_maximum (x->left ());
  437. ACE_RB_Tree_Node<EXT_ID, INT_ID> *y = x->parent ();
  438. while ((y) && (x == y->left ()))
  439. {
  440. x = y;
  441. y = y->parent ();
  442. }
  443. return y;
  444. }
  445. // Method to find the minimum node of the subtree rooted at the given node.
  446. template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> ACE_RB_Tree_Node<EXT_ID, INT_ID> *
  447. ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::RB_tree_minimum (ACE_RB_Tree_Node<EXT_ID, INT_ID> *x) const
  448. {
  449. ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::RB_tree_minimum");
  450. while ((x) && (x->left ()))
  451. x = x->left ();
  452. return x;
  453. }
  454. // Method to find the maximum node of the subtree rooted at the given node.
  455. template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> ACE_RB_Tree_Node<EXT_ID, INT_ID> *
  456. ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::RB_tree_maximum (ACE_RB_Tree_Node<EXT_ID, INT_ID> *x) const
  457. {
  458. ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::RB_tree_maximum");
  459. while ((x) && (x->right ()))
  460. x = x->right ();
  461. return x;
  462. }
  463. // Delete children (left and right) of the node. Must be called with
  464. // lock held.
  465. template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
  466. void ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::delete_children_i
  467. (ACE_RB_Tree_Node<EXT_ID, INT_ID> *parent)
  468. {
  469. if (parent)
  470. {
  471. this->delete_children_i (parent->left ());
  472. this->delete_children_i (parent->right ());
  473. ACE_DES_FREE_TEMPLATE2
  474. (parent->left (),
  475. this->allocator_->free,
  476. ACE_RB_Tree_Node,
  477. EXT_ID, INT_ID);
  478. ACE_DES_FREE_TEMPLATE2
  479. (parent->right (),
  480. this->allocator_->free,
  481. ACE_RB_Tree_Node,
  482. EXT_ID, INT_ID);
  483. parent->left (0);
  484. parent->right (0);
  485. }
  486. return;
  487. }
  488. // Close down an RB_Tree. this method should only be called with
  489. // locks already held.
  490. template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> int
  491. ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::close_i ()
  492. {
  493. ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::close_i");
  494. this->delete_children_i (this->root_);
  495. ACE_DES_FREE_TEMPLATE2 (this->root_,
  496. this->allocator()->free,
  497. ACE_RB_Tree_Node,
  498. EXT_ID, INT_ID);
  499. this->current_size_ = 0;
  500. this->root_ = 0;
  501. return 0;
  502. }
  503. // Returns a pointer to the item corresponding to the given key, or 0
  504. // if it cannot find the key in the tree. This method should only be
  505. // called with locks already held.
  506. template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> int
  507. ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::find_i (const EXT_ID &k,
  508. ACE_RB_Tree_Node<EXT_ID, INT_ID>* &entry, int find_exact)
  509. {
  510. ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::find_i");
  511. // Try to find a match.
  512. RB_SearchResult result = LEFT;
  513. ACE_RB_Tree_Node<EXT_ID, INT_ID> *current = find_node (k, result);
  514. if (current)
  515. {
  516. // Found a match
  517. if (!find_exact || result == EXACT)
  518. entry = current; // Assign the entry for any match.
  519. return (result == EXACT ? 0 : -1);
  520. }
  521. else
  522. // The node is not there.
  523. return -1;
  524. }
  525. // Inserts a *copy* of the key and the item into the tree: both the
  526. // key type EXT_ID and the item type INT_ID must have well defined
  527. // semantics for copy construction and < comparison. This method
  528. // returns a pointer to the inserted item copy, or 0 if an error
  529. // occurred. NOTE: if an identical key already exists in the tree, no
  530. // new item is created, and the returned pointer addresses the
  531. // existing item associated with the existing key. This method should
  532. // only be called with locks already held.
  533. template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> INT_ID *
  534. ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::insert_i (const EXT_ID &k, const INT_ID &t)
  535. {
  536. ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::insert_i (const EXT_ID &k, const INT_ID &t)");
  537. // Find the closest matching node, if there is one.
  538. RB_SearchResult result = LEFT;
  539. ACE_RB_Tree_Node<EXT_ID, INT_ID> *current = find_node (k, result);
  540. if (current)
  541. {
  542. // If the keys match, just return a pointer to the node's item.
  543. if (result == EXACT)
  544. return &current->item ();
  545. // Otherwise if we're to the left of the insertion point, insert
  546. // into the right subtree.
  547. else if (result == LEFT)
  548. {
  549. if (current->right ())
  550. {
  551. // If there is already a right subtree, complain.
  552. ACE_ERROR_RETURN ((LM_ERROR,
  553. ACE_TEXT ("%p\n"),
  554. ACE_TEXT ("\nright subtree already present in ")
  555. ACE_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::insert_i\n")),
  556. 0);
  557. }
  558. else
  559. {
  560. // The right subtree is empty: insert new node there.
  561. ACE_RB_Tree_Node<EXT_ID, INT_ID> *tmp = 0;
  562. ACE_NEW_MALLOC_RETURN
  563. (tmp,
  564. (reinterpret_cast<ACE_RB_Tree_Node<EXT_ID, INT_ID>*>
  565. (this->allocator_->malloc (sizeof (*tmp)))),
  566. (ACE_RB_Tree_Node<EXT_ID, INT_ID>) (k, t),
  567. 0);
  568. current->right (tmp);
  569. // If the node was successfully inserted, set its
  570. // parent, rebalance the tree, color the root black, and
  571. // return a pointer to the inserted item.
  572. INT_ID *item = &(current->right ()->item ());
  573. current->right ()->parent (current);
  574. RB_rebalance (current->right ());
  575. root_->color (ACE_RB_Tree_Node_Base::BLACK);
  576. ++current_size_;
  577. return item;
  578. }
  579. }
  580. // Otherwise, we're to the right of the insertion point, so
  581. // insert into the left subtree.
  582. else // (result == RIGHT)
  583. {
  584. if (current->left ())
  585. // If there is already a left subtree, complain.
  586. ACE_ERROR_RETURN ((LM_ERROR,
  587. ACE_TEXT ("%p\n"),
  588. ACE_TEXT ("\nleft subtree already present in ")
  589. ACE_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::insert_i\n")),
  590. 0);
  591. else
  592. {
  593. // The left subtree is empty: insert new node there.
  594. ACE_RB_Tree_Node<EXT_ID, INT_ID> *tmp = 0;
  595. ACE_NEW_MALLOC_RETURN
  596. (tmp,
  597. (reinterpret_cast<ACE_RB_Tree_Node<EXT_ID, INT_ID>*>
  598. (this->allocator_->malloc (sizeof (*tmp)))),
  599. (ACE_RB_Tree_Node<EXT_ID, INT_ID>) (k, t),
  600. 0);
  601. current->left (tmp);
  602. // If the node was successfully inserted, set its
  603. // parent, rebalance the tree, color the root black, and
  604. // return a pointer to the inserted item.
  605. INT_ID *item = &current->left ()->item ();
  606. current->left ()->parent (current);
  607. RB_rebalance (current->left ());
  608. root_->color (ACE_RB_Tree_Node_Base::BLACK);
  609. ++current_size_;
  610. return item;
  611. }
  612. }
  613. }
  614. else
  615. {
  616. // The tree is empty: insert at the root and color the root
  617. // black.
  618. ACE_NEW_MALLOC_RETURN
  619. (this->root_,
  620. (reinterpret_cast<ACE_RB_Tree_Node<EXT_ID, INT_ID>*>
  621. (this->allocator_->malloc (sizeof (ACE_RB_Tree_Node<EXT_ID, INT_ID>)))),
  622. (ACE_RB_Tree_Node<EXT_ID, INT_ID>) (k, t),
  623. 0);
  624. this->root_->color (ACE_RB_Tree_Node_Base::BLACK);
  625. ++current_size_;
  626. return &this->root_->item ();
  627. }
  628. }
  629. // Inserts a *copy* of the key and the item into the tree: both the
  630. // key type EXT_ID and the item type INT_ID must have well defined
  631. // semantics for copy construction. The default implementation also
  632. // requires that the key type support well defined < semantics. This
  633. // method passes back a pointer to the inserted (or existing) node,
  634. // and the search status. If the node already exists, the method
  635. // returns 1. If the node does not exist, and a new one is
  636. // successfully created, and the method returns 0. If there was an
  637. // error, the method returns -1.
  638. template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> int
  639. ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::insert_i (const EXT_ID &k,
  640. const INT_ID &t,
  641. ACE_RB_Tree_Node<EXT_ID, INT_ID> *&entry)
  642. {
  643. ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::insert_i (const EXT_ID &k, const INT_ID &t, "
  644. "ACE_RB_Tree_Node<EXT_ID, INT_ID> *&entry)");
  645. // Find the closest matching node, if there is one.
  646. RB_SearchResult result = LEFT;
  647. ACE_RB_Tree_Node<EXT_ID, INT_ID> *current = find_node (k, result);
  648. if (current)
  649. {
  650. // If the keys match, just return a pointer to the node's item.
  651. if (result == EXACT)
  652. {
  653. entry = current;
  654. return 1;
  655. }
  656. // Otherwise if we're to the left of the insertion
  657. // point, insert into the right subtree.
  658. else if (result == LEFT)
  659. {
  660. if (current->right ())
  661. {
  662. // If there is already a right subtree, complain.
  663. ACE_ERROR_RETURN ((LM_ERROR,
  664. ACE_TEXT ("%p\n"),
  665. ACE_TEXT ("\nright subtree already present in ")
  666. ACE_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::insert_i\n")),
  667. -1);
  668. }
  669. else
  670. {
  671. // The right subtree is empty: insert new node there.
  672. ACE_RB_Tree_Node<EXT_ID, INT_ID> *tmp = 0;
  673. ACE_NEW_MALLOC_RETURN
  674. (tmp,
  675. (reinterpret_cast<ACE_RB_Tree_Node<EXT_ID, INT_ID>*>
  676. (this->allocator_->malloc (sizeof (*tmp)))),
  677. (ACE_RB_Tree_Node<EXT_ID, INT_ID>) (k, t),
  678. -1);
  679. current->right (tmp);
  680. // If the node was successfully inserted, set its parent, rebalance
  681. // the tree, color the root black, and return a pointer to the
  682. // inserted item.
  683. entry = current->right ();
  684. current->right ()->parent (current);
  685. RB_rebalance (current->right ());
  686. this->root_->color (ACE_RB_Tree_Node_Base::BLACK);
  687. ++this->current_size_;
  688. return 0;
  689. }
  690. }
  691. // Otherwise, we're to the right of the insertion point, so
  692. // insert into the left subtree.
  693. else // (result == RIGHT)
  694. {
  695. if (current->left ())
  696. // If there is already a left subtree, complain.
  697. ACE_ERROR_RETURN ((LM_ERROR,
  698. ACE_TEXT ("%p\n"),
  699. ACE_TEXT ("\nleft subtree already present in ")
  700. ACE_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::insert_i\n")),
  701. -1);
  702. else
  703. {
  704. // The left subtree is empty: insert new node there.
  705. ACE_RB_Tree_Node<EXT_ID, INT_ID> *tmp = 0;
  706. ACE_NEW_MALLOC_RETURN
  707. (tmp,
  708. (reinterpret_cast<ACE_RB_Tree_Node<EXT_ID, INT_ID>*>
  709. (this->allocator_->malloc (sizeof (*tmp)))),
  710. (ACE_RB_Tree_Node<EXT_ID, INT_ID>) (k, t),
  711. -1);
  712. current->left (tmp);
  713. // If the node was successfully inserted, set its
  714. // parent, rebalance the tree, color the root black, and
  715. // return a pointer to the inserted item.
  716. entry = current->left ();
  717. current->left ()->parent (current);
  718. RB_rebalance (current->left ());
  719. this->root_->color (ACE_RB_Tree_Node_Base::BLACK);
  720. ++this->current_size_;
  721. return 0;
  722. }
  723. }
  724. }
  725. else
  726. {
  727. // The tree is empty: insert at the root and color the root black.
  728. ACE_NEW_MALLOC_RETURN
  729. (this->root_,
  730. (reinterpret_cast<ACE_RB_Tree_Node<EXT_ID, INT_ID>*>
  731. (this->allocator_->malloc (sizeof (ACE_RB_Tree_Node<EXT_ID, INT_ID>)))),
  732. (ACE_RB_Tree_Node<EXT_ID, INT_ID>) (k, t),
  733. -1);
  734. this->root_->color (ACE_RB_Tree_Node_Base::BLACK);
  735. ++this->current_size_;
  736. entry = this->root_;
  737. return 0;
  738. }
  739. }
  740. // Removes the item associated with the given key from the tree and
  741. // destroys it. Returns 1 if it found the item and successfully
  742. // destroyed it, 0 if it did not find the item, or -1 if an error
  743. // occurred. This method should only be called with locks already
  744. // held.
  745. template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> int
  746. ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::remove_i (const EXT_ID &k, INT_ID &i)
  747. {
  748. ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::remove_i (const EXT_ID &k, INT_ID &i)");
  749. // Find a matching node, if there is one.
  750. ACE_RB_Tree_Node<EXT_ID, INT_ID> *z;
  751. RB_SearchResult result = LEFT;
  752. z = find_node (k, result);
  753. // If there is a matching node: remove and destroy it.
  754. if (z && result == EXACT)
  755. {
  756. // Return the internal id stored in the deleted node.
  757. i = z->item ();
  758. return -1 == this->remove_i (z) ? -1 : 1;
  759. }
  760. // No matching node was found: return 0.
  761. return 0;
  762. }
  763. /// Recursive function to dump the state of an object.
  764. template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> void
  765. ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::
  766. dump_i (ACE_RB_Tree_Node<EXT_ID, INT_ID> *node) const
  767. {
  768. #if defined (ACE_HAS_DUMP)
  769. if (node)
  770. {
  771. dump_node_i (*node);
  772. ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ndown left\n")));
  773. this->dump_i (node->left ());
  774. ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nup left\n")));
  775. ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ndown right\n")));
  776. this->dump_i (node->right ());
  777. ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nup right\n")));
  778. }
  779. else
  780. {
  781. ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nNULL POINTER (BLACK)\n")));
  782. }
  783. #else /* !ACE_HAS_DUMP */
  784. ACE_UNUSED_ARG (node);
  785. #endif /* ACE_HAS_DUMP */
  786. }
  787. /// Function to dump node itself. Does not show parameterized node contents
  788. /// in its basic form, but template specialization can be used to
  789. /// provide definitions for various EXT_ID and INT_ID types.
  790. template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> void
  791. ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::
  792. dump_node_i (ACE_RB_Tree_Node<EXT_ID, INT_ID> &node) const
  793. {
  794. #if defined (ACE_HAS_DUMP)
  795. const char * color_str = (node.color () == ACE_RB_Tree_Node_Base::RED)
  796. ? "RED" : "BLACK";
  797. ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" color=[%s]\n"), color_str));
  798. #else /* !ACE_HAS_DUMP */
  799. ACE_UNUSED_ARG (node);
  800. #endif /* ACE_HAS_DUMP */
  801. }
  802. /// Tests the red-black invariant(s) throughout the whole tree.
  803. template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> int
  804. ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::test_invariant (void)
  805. {
  806. ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::test_invariant");
  807. ACE_READ_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1);
  808. // Recurse from the root, starting with the measured black height at
  809. // 0, and the expected black height at -1, which will cause the
  810. // count from first measured path to a leaf to be used as the
  811. // expected one from that point onward (the key is to check
  812. // consistency).
  813. int expected_black_height = -1;
  814. if (this->test_invariant_recurse (this->root_, expected_black_height, 0) == 0)
  815. {
  816. ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("invariant holds\n")));
  817. return 0;
  818. }
  819. return -1;
  820. }
  821. /// Recursive function to test the red-black invariant(s) at all nodes in a subtree.
  822. template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> int
  823. ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::test_invariant_recurse (ACE_RB_Tree_Node<EXT_ID, INT_ID> *x,
  824. int & expected_black_height,
  825. int measured_black_height)
  826. {
  827. ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::test_invariant_recurse");
  828. if (!x)
  829. {
  830. // Count each leaf (zero pointer) as a black node (per CLR algorithm description).
  831. ++measured_black_height;
  832. if (expected_black_height == -1)
  833. {
  834. expected_black_height = measured_black_height;
  835. }
  836. else if (expected_black_height != measured_black_height)
  837. {
  838. ACE_ERROR_RETURN ((LM_ERROR,
  839. ACE_TEXT ("\nexpected_black_height = %d but ")
  840. ACE_TEXT ("\nmeasured_black_height = %d in ")
  841. ACE_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::test_invariant_recurse\n"),
  842. expected_black_height, measured_black_height),
  843. -1);
  844. }
  845. return 0;
  846. }
  847. // Check the invariant that a red node cannot have a red child.
  848. if (x->color () == ACE_RB_Tree_Node_Base::RED)
  849. {
  850. if (x->left () && x->left ()->color () == ACE_RB_Tree_Node_Base::RED)
  851. {
  852. ACE_ERROR_RETURN ((LM_ERROR,
  853. ACE_TEXT ("%p\n"),
  854. ACE_TEXT ("\nRED parent has RED left child in ")
  855. ACE_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::test_invariant_recurse\n")),
  856. -1);
  857. }
  858. if (x->right () && x->right ()->color () == ACE_RB_Tree_Node_Base::RED)
  859. {
  860. ACE_ERROR_RETURN ((LM_ERROR,
  861. ACE_TEXT ("%p\n"),
  862. ACE_TEXT ("\nRED parent has RED right child in ")
  863. ACE_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::test_invariant_recurse\n")),
  864. -1);
  865. }
  866. }
  867. else
  868. {
  869. // Count each black node traversed.
  870. ++measured_black_height;
  871. }
  872. return (test_invariant_recurse (x->left (), expected_black_height, measured_black_height) == 0)
  873. ? test_invariant_recurse (x->right (), expected_black_height, measured_black_height)
  874. : -1;
  875. }
  876. template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> int
  877. ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::remove_i (ACE_RB_Tree_Node<EXT_ID, INT_ID> *z)
  878. {
  879. ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::remove_i (ACE_RB_Tree_Node<EXT_ID, INT_ID> *z)");
  880. // Delete the node and reorganize the tree to satisfy the Red-Black
  881. // properties.
  882. ACE_RB_Tree_Node<EXT_ID, INT_ID> *x;
  883. ACE_RB_Tree_Node<EXT_ID, INT_ID> *y;
  884. ACE_RB_Tree_Node<EXT_ID, INT_ID> *parent;
  885. if (z->left () && z->right ())
  886. y = RB_tree_successor (z);
  887. else
  888. y = z;
  889. if (!y)
  890. return -1;
  891. if (y->left ())
  892. x = y->left ();
  893. else
  894. x = y->right ();
  895. parent = y->parent ();
  896. if (x)
  897. {
  898. x->parent (parent);
  899. }
  900. if (parent)
  901. {
  902. if (y == parent->left ())
  903. parent->left (x);
  904. else
  905. parent->right (x);
  906. }
  907. else
  908. this->root_ = x;
  909. if (y != z)
  910. {
  911. // Replace node z with node y, since y's pointer may well be
  912. // held externally, and be linked with y's key and item.
  913. // We will end up deleting the old unlinked, node z.
  914. ACE_RB_Tree_Node<EXT_ID, INT_ID> *zParent = z->parent ();
  915. ACE_RB_Tree_Node<EXT_ID, INT_ID> *zLeftChild = z->left ();
  916. ACE_RB_Tree_Node<EXT_ID, INT_ID> *zRightChild = z->right ();
  917. if (zParent)
  918. {
  919. if (z == zParent->left ())
  920. {
  921. zParent->left (y);
  922. }
  923. else
  924. {
  925. zParent->right (y);
  926. }
  927. }
  928. else
  929. {
  930. this->root_ = y;
  931. }
  932. y->parent (zParent);
  933. if (zLeftChild)
  934. {
  935. zLeftChild->parent (y);
  936. }
  937. y->left (zLeftChild);
  938. if (zRightChild)
  939. {
  940. zRightChild->parent (y);
  941. }
  942. y->right (zRightChild);
  943. if (parent == z)
  944. {
  945. parent = y;
  946. }
  947. ACE_RB_Tree_Node_Base::RB_Tree_Node_Color yColor = y->color ();
  948. y->color (z->color ());
  949. z->color (yColor);
  950. //Reassign the y pointer to z because the node that y points to will be
  951. //deleted
  952. y = z;
  953. }
  954. // CLR pp. 263 says that nil nodes are implicitly colored BLACK
  955. if (!y || y->color () == ACE_RB_Tree_Node_Base::BLACK)
  956. RB_delete_fixup (x, parent);
  957. y->parent (0);
  958. y->right (0);
  959. y->left (0);
  960. ACE_DES_FREE_TEMPLATE2 (y,
  961. this->allocator_->free,
  962. ACE_RB_Tree_Node,
  963. EXT_ID, INT_ID);
  964. --this->current_size_;
  965. return 0;
  966. }
  967. ACE_ALLOC_HOOK_DEFINE(ACE_RB_Tree_Iterator_Base)
  968. // Constructor.
  969. template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
  970. ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree_Iterator_Base (const ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> &tree, int set_first)
  971. : tree_ (&tree), node_ (0)
  972. {
  973. ACE_TRACE ("ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree_Iterator_Base (ACE_RB_Tree, int)");
  974. // Position the iterator at the first (or last) node in the tree.
  975. if (set_first)
  976. node_ = tree_->RB_tree_minimum (tree_->root_);
  977. else
  978. node_ = tree_->RB_tree_maximum (tree_->root_);
  979. }
  980. template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
  981. ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree_Iterator_Base (const ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> &tree, ACE_RB_Tree_Node<EXT_ID, INT_ID>* entry)
  982. : tree_ (&tree), node_ (0)
  983. {
  984. ACE_TRACE ("ACE_RB_Tree_Iterator_Base(const ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> &tree, ACE_RB_Tree_Node<EXT_ID, INT_ID>* entry)");
  985. node_ = entry;
  986. }
  987. template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
  988. ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree_Iterator_Base (const EXT_ID& key,ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> &tree)
  989. : tree_ (&tree), node_ (0)
  990. {
  991. ACE_TRACE("ACE_RB_Tree_Iterator_Base (ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> &tree, const EXT_ID& key)");
  992. ACE_RB_Tree_Node<EXT_ID, INT_ID>* entry = 0;
  993. tree.find_i(key, entry);
  994. node_ = entry;
  995. }
  996. // Copy constructor.
  997. template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
  998. ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree_Iterator_Base (const ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> &iter)
  999. : tree_ (iter.tree_),
  1000. node_ (iter.node_)
  1001. {
  1002. ACE_TRACE ("ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree_Iterator_Base (ACE_RB_Tree_Iterator_Base)");
  1003. }
  1004. // Assignment operator.
  1005. template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> void
  1006. ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::operator= (const ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> &iter)
  1007. {
  1008. ACE_TRACE ("ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::operator=");
  1009. if (this != &iter)
  1010. {
  1011. tree_ = iter.tree_;
  1012. node_ = iter.node_;
  1013. }
  1014. }
  1015. // Destructor.
  1016. template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
  1017. ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::~ACE_RB_Tree_Iterator_Base ()
  1018. {
  1019. ACE_TRACE ("ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::~ACE_RB_Tree_Iterator_Base");
  1020. }
  1021. // Dump the state of an object.
  1022. template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
  1023. void
  1024. ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::dump_i (void) const
  1025. {
  1026. ACE_TRACE ("ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::dump_i");
  1027. ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
  1028. ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nnode_ = %x\n"), this->node_));
  1029. ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
  1030. }
  1031. ACE_ALLOC_HOOK_DEFINE(ACE_RB_Tree_Iterator)
  1032. // Constructor.
  1033. template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
  1034. ACE_RB_Tree_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree_Iterator (const ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> &tree,
  1035. int set_first)
  1036. : ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> (tree, set_first)
  1037. {
  1038. ACE_TRACE ("ACE_RB_Tree_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree_Iterator");
  1039. }
  1040. template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
  1041. ACE_RB_Tree_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree_Iterator (const ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> &tree,
  1042. ACE_RB_Tree_Node<EXT_ID, INT_ID>* entry)
  1043. : ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> (tree,entry)
  1044. {
  1045. ACE_TRACE ("ACE_RB_Tree_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree_Iterator");
  1046. }
  1047. template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
  1048. ACE_RB_Tree_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree_Iterator (const EXT_ID& key,ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> &tree)
  1049. : ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>(key,tree)
  1050. {
  1051. ACE_TRACE ("ACE_RB_Tree_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree_Iterator");
  1052. }
  1053. // Destructor.
  1054. template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
  1055. ACE_RB_Tree_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::~ACE_RB_Tree_Iterator ()
  1056. {
  1057. ACE_TRACE ("ACE_RB_Tree_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::~ACE_RB_Tree_Iterator");
  1058. }
  1059. ACE_ALLOC_HOOK_DEFINE(ACE_RB_Tree_Reverse_Iterator)
  1060. // Constructor.
  1061. template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
  1062. ACE_RB_Tree_Reverse_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree_Reverse_Iterator (const ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> &tree, int set_last)
  1063. : ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> (tree, set_last ? 0 : 1)
  1064. {
  1065. ACE_TRACE ("ACE_RB_Tree_Reverse_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree_Reverse_Iterator");
  1066. }
  1067. template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
  1068. ACE_RB_Tree_Reverse_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree_Reverse_Iterator (const ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> &tree, ACE_RB_Tree_Node<EXT_ID, INT_ID>* entry)
  1069. : ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> (tree,entry)
  1070. {
  1071. ACE_TRACE ("ACE_RB_Tree_Reverse_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree_Reverse_Iterator");
  1072. }
  1073. template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
  1074. ACE_RB_Tree_Reverse_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree_Reverse_Iterator (const EXT_ID& key,ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> &tree)
  1075. : ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>(key,tree)
  1076. {
  1077. ACE_TRACE ("ACE_RB_Tree_Reverse_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree_Reverse_Iterator");
  1078. }
  1079. // Destructor.
  1080. template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
  1081. ACE_RB_Tree_Reverse_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::~ACE_RB_Tree_Reverse_Iterator ()
  1082. {
  1083. ACE_TRACE ("ACE_RB_Tree_Reverse_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::~ACE_RB_Tree_Reverse_Iterator");
  1084. }
  1085. ACE_END_VERSIONED_NAMESPACE_DECL
  1086. #endif /* !ACE_RB_TREE_CPP */