RB_Tree.cpp

Go to the documentation of this file.
00001 // RB_Tree.cpp,v 1.45 2006/03/14 21:15:49 sjiang Exp
00002 
00003 #ifndef ACE_RB_TREE_CPP
00004 #define ACE_RB_TREE_CPP
00005 
00006 #include "ace/Global_Macros.h"
00007 #include "ace/RB_Tree.h"
00008 #include "ace/SString.h"
00009 
00010 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00011 # pragma once
00012 #endif /* ACE_LACKS_PRAGMA_ONCE */
00013 
00014 #if !defined (__ACE_INLINE__)
00015 #include "ace/RB_Tree.inl"
00016 #endif /* __ACE_INLINE__ */
00017 
00018 #include "ace/Log_Msg.h"
00019 
00020 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00021 
00022 // Constructor.
00023 
00024 template <class EXT_ID, class INT_ID>
00025 ACE_RB_Tree_Node<EXT_ID, INT_ID>::ACE_RB_Tree_Node (const EXT_ID &k, const INT_ID &t)
00026   : k_ (k),
00027     t_ (t),
00028     color_ (RED),
00029     parent_ (0),
00030     left_ (0),
00031     right_ (0)
00032 {
00033   ACE_TRACE ("ACE_RB_Tree_Node<EXT_ID, INT_ID>::ACE_RB_Tree_Node (const EXT_ID &k, const INT_ID &t)");
00034 }
00035 
00036 
00037 // Destructor.
00038 
00039 template <class EXT_ID, class INT_ID>
00040 ACE_RB_Tree_Node<EXT_ID, INT_ID>::~ACE_RB_Tree_Node (void)
00041 {
00042   ACE_TRACE ("ACE_RB_Tree_Node<EXT_ID, INT_ID>::~ACE_RB_Tree_Node");
00043 }
00044 
00045 // Constructor.
00046 
00047 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
00048 ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree (ACE_Allocator *alloc)
00049   : root_ (0),
00050     current_size_ (0)
00051 {
00052   ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::"
00053              "ACE_RB_Tree (ACE_Allocator *alloc)");
00054   allocator_ = alloc;
00055   if (this->open (alloc) == -1)
00056     ACE_ERROR ((LM_ERROR,
00057                 ACE_LIB_TEXT ("ACE_RB_Tree::ACE_RB_Tree\n")));
00058 }
00059 
00060 // Copy constructor.
00061 
00062 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
00063 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)
00064   : root_ (0),
00065     current_size_ (0)
00066 {
00067   ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::"
00068              "ACE_RB_Tree (const ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> &rbt)");
00069   ACE_WRITE_GUARD (ACE_LOCK, ace_mon, this->lock_);
00070   allocator_ = rbt.allocator_;
00071 
00072   // Make a deep copy of the passed tree.
00073   ACE_RB_Tree_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> iter(rbt);
00074 
00075   for (iter.first ();
00076 
00077        iter.is_done () == 0; iter.next ())
00078     insert_i (*(iter.key ()),
00079               *(iter.item ()));
00080 }
00081 
00082 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
00083 ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree (
00084     void *location,
00085     ACE_Allocator *alloc
00086 )
00087 {
00088   if (location != this)
00089     {
00090       this->root_ = 0;
00091       this->current_size_ = 0;
00092     }
00093 
00094   this->allocator_ = alloc;
00095 }
00096 // Destructor.
00097 
00098 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
00099 ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::~ACE_RB_Tree ()
00100 {
00101   ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::~ACE_RB_Tree");
00102 
00103   // Use the locked public method, to be totally safe, as the class
00104   // can be used with an allocator and placement new.
00105   this->close ();
00106 }
00107 
00108 // Assignment operator.
00109 
00110 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> void
00111 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)
00112 {
00113   ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::operator =");
00114   ACE_WRITE_GUARD (ACE_LOCK, ace_mon, this->lock_);
00115 
00116   if (this != &rbt)
00117     {
00118       // Clear out the existing tree.
00119       close_i ();
00120 
00121       // Make a deep copy of the passed tree.
00122       ACE_RB_Tree_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> iter(rbt);
00123 
00124       for (iter.first ();
00125            iter.is_done () == 0;
00126            iter.next ())
00127         insert_i (*(iter.key ()),
00128                   *(iter.item ()));
00129 
00130       // Use the same allocator as the rhs.
00131       allocator_ = rbt.allocator_;
00132     }
00133 }
00134 // Less than comparison function for keys, default functor
00135 // implementation returns 1 if k1 < k2, 0 otherwise.
00136 
00137 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> int
00138 ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::lessthan (const EXT_ID &k1, const EXT_ID &k2)
00139 {
00140   ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::lessthan");
00141   return this->compare_keys_ (k1, k2);
00142 }
00143 
00144 // Method for right rotation of the tree about a given node.
00145 
00146 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>  void
00147 ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::RB_rotate_right (ACE_RB_Tree_Node<EXT_ID, INT_ID> *x)
00148 {
00149   ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::RB_rotate_right");
00150 
00151   if (!x)
00152     ACE_ERROR ((LM_ERROR,
00153                 ACE_LIB_TEXT ("%p\n"),
00154                 ACE_LIB_TEXT ("\nerror: x is a null pointer in ")
00155                 ACE_LIB_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::RB_rotate_right\n")));
00156   else if (! (x->left()))
00157     ACE_ERROR ((LM_ERROR,
00158                 ACE_LIB_TEXT ("%p\n"),
00159                 ACE_LIB_TEXT ("\nerror: x->left () is a null pointer in ")
00160                 ACE_LIB_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::RB_rotate_right\n")));
00161   else
00162     {
00163       ACE_RB_Tree_Node<EXT_ID, INT_ID> * y;
00164       y = x->left ();
00165       x->left (y->right ());
00166       if (y->right ())
00167         y->right ()->parent (x);
00168       y->parent (x->parent ());
00169       if (x->parent ())
00170         {
00171           if (x == x->parent ()->right ())
00172             x->parent ()->right (y);
00173           else
00174             x->parent ()->left (y);
00175         }
00176       else
00177         root_ = y;
00178       y->right (x);
00179       x->parent (y);
00180     }
00181 }
00182 
00183 // Method for left rotation of the tree about a given node.
00184 
00185 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> void
00186 ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::RB_rotate_left (ACE_RB_Tree_Node<EXT_ID, INT_ID> * x)
00187 {
00188   ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::RB_rotate_left");
00189 
00190   if (! x)
00191     ACE_ERROR ((LM_ERROR,
00192                 ACE_LIB_TEXT ("%p\n"),
00193                 ACE_LIB_TEXT ("\nerror: x is a null pointer in ")
00194                 ACE_LIB_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::RB_rotate_left\n")));
00195   else if (! (x->right()))
00196     ACE_ERROR ((LM_ERROR,
00197                 ACE_LIB_TEXT ("%p\n"),
00198                 ACE_LIB_TEXT ("\nerror: x->right () is a null pointer ")
00199                 ACE_LIB_TEXT ("in ACE_RB_Tree<EXT_ID, INT_ID>::RB_rotate_left\n")));
00200   else
00201     {
00202       ACE_RB_Tree_Node<EXT_ID, INT_ID> * y;
00203       y = x->right ();
00204       x->right (y->left ());
00205       if (y->left ())
00206         y->left ()->parent (x);
00207       y->parent (x->parent ());
00208       if (x->parent ())
00209         {
00210           if (x == x->parent ()->left ())
00211             x->parent ()->left (y);
00212           else
00213             x->parent ()->right (y);
00214         }
00215       else
00216         root_ = y;
00217       y->left (x);
00218       x->parent (y);
00219     }
00220 }
00221 
00222 // Method for restoring Red-Black properties after a specific deletion case.
00223 
00224 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>  void
00225 ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::
00226 RB_delete_fixup (ACE_RB_Tree_Node<EXT_ID, INT_ID> *x,
00227                  ACE_RB_Tree_Node<EXT_ID, INT_ID> *parent)
00228 {
00229   ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::RB_delete_fixup");
00230 
00231   while (x != this->root_
00232          && (!x
00233              || x->color () == ACE_RB_Tree_Node_Base::BLACK))
00234     {
00235       if (x == parent->left ())
00236         {
00237           ACE_RB_Tree_Node<EXT_ID, INT_ID> *w = parent->right ();
00238           if (w && w->color () == ACE_RB_Tree_Node_Base::RED)
00239             {
00240               w->color (ACE_RB_Tree_Node_Base::BLACK);
00241               parent->color (ACE_RB_Tree_Node_Base::RED);
00242               RB_rotate_left (parent);
00243               w = parent->right ();
00244             }
00245           // CLR pp. 263 says that nil nodes are implicitly colored BLACK
00246           if (w
00247               && (!w->left ()
00248                   || w->left ()->color () == ACE_RB_Tree_Node_Base::BLACK)
00249               && (!w->right ()
00250                   || w->right ()->color () == ACE_RB_Tree_Node_Base::BLACK))
00251             {
00252               w->color (ACE_RB_Tree_Node_Base::RED);
00253               x = parent;
00254               parent = x->parent ();
00255             }
00256           else
00257             {
00258               // CLR pp. 263 says that nil nodes are implicitly colored BLACK
00259               if (w
00260                   && (!w->right ()
00261                       || w->right ()->color () == ACE_RB_Tree_Node_Base::BLACK))
00262                 {
00263                   if (w->left ())
00264                     w->left ()->color (ACE_RB_Tree_Node_Base::BLACK);
00265                   w->color (ACE_RB_Tree_Node_Base::RED);
00266                   RB_rotate_right (w);
00267                   w = parent->right ();
00268                 }
00269               if (w)
00270                 {
00271                   w->color (parent->color ());
00272                   if (w->right ())
00273                     w->right ()->color (ACE_RB_Tree_Node_Base::BLACK);
00274                 }
00275               parent->color (ACE_RB_Tree_Node_Base::BLACK);
00276               RB_rotate_left (parent);
00277               x = root_;
00278             }
00279         }
00280       else
00281         {
00282           ACE_RB_Tree_Node<EXT_ID, INT_ID> *w = parent->left ();
00283           if (w && w->color () == ACE_RB_Tree_Node_Base::RED)
00284             {
00285               w->color (ACE_RB_Tree_Node_Base::BLACK);
00286               parent->color (ACE_RB_Tree_Node_Base::RED);
00287               RB_rotate_right (parent);
00288               w = parent->left ();
00289             }
00290           // CLR pp. 263 says that nil nodes are implicitly colored BLACK
00291           if (w
00292               && (!w->left ()
00293                   || w->left ()->color () == ACE_RB_Tree_Node_Base::BLACK)
00294               && (!w->right ()
00295                   || w->right ()->color () == ACE_RB_Tree_Node_Base::BLACK))
00296             {
00297               w->color (ACE_RB_Tree_Node_Base::RED);
00298               x = parent;
00299               parent = x->parent ();
00300             }
00301           else
00302             {
00303               // CLR pp. 263 says that nil nodes are implicitly colored BLACK
00304               if (w
00305                   && (!w->left ()
00306                       || w->left ()->color () == ACE_RB_Tree_Node_Base::BLACK))
00307                 {
00308                   w->color (ACE_RB_Tree_Node_Base::RED);
00309                   if (w->right ())
00310                     w->right ()->color (ACE_RB_Tree_Node_Base::BLACK);
00311                   RB_rotate_left (w);
00312                   w = parent->left ();
00313                 }
00314               if (w)
00315                 {
00316                   w->color (parent->color ());
00317                   if (w->left ())
00318                     w->left ()->color (ACE_RB_Tree_Node_Base::BLACK);
00319                 }
00320               parent->color (ACE_RB_Tree_Node_Base::BLACK);
00321               RB_rotate_right (parent);
00322               x = root_;
00323             }
00324         }
00325     }
00326 
00327   if (x)
00328     x->color (ACE_RB_Tree_Node_Base::BLACK);
00329 }
00330 
00331 // Return a pointer to a matching node if there is one, a pointer to
00332 // the node under which to insert the item if the tree is not empty
00333 // and there is no such match, or 0 if the tree is empty.
00334 
00335 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> ACE_RB_Tree_Node<EXT_ID, INT_ID> *
00336 ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::find_node (const EXT_ID &k, ACE_RB_Tree_Base::RB_SearchResult &result)
00337 {
00338   ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::find_node");
00339 
00340   // Start at the root.
00341   ACE_RB_Tree_Node<EXT_ID, INT_ID> *current = root_;
00342 
00343   while (current)
00344     {
00345       // While there are more nodes to examine.
00346       if (this->lessthan (current->key (), k))
00347         {
00348           // If the search key is greater than the current node's key.
00349           if (current->right ())
00350             // If the right subtree is not empty, search to the right.
00351             current = current->right ();
00352           else
00353             {
00354               // If the right subtree is empty, we're done searching,
00355               // and are positioned to the left of the insertion point.
00356               result = LEFT;
00357               break;
00358             }
00359         }
00360       else if (this->lessthan (k, current->key ()))
00361         {
00362           // Else if the search key is less than the current node's key.
00363           if (current->left ())
00364             // If the left subtree is not empty, search to the left.
00365             current = current->left ();
00366           else
00367             {
00368               // If the left subtree is empty, we're done searching,
00369               // and are positioned to the right of the insertion point.
00370               result = RIGHT;
00371               break;
00372             }
00373         }
00374       else
00375         {
00376           // If the keys match exactly, we're done as well.
00377           result = EXACT;
00378           break;
00379         }
00380     }
00381 
00382   return current;
00383 }
00384 
00385 // Rebalance the tree after insertion of a node.
00386 
00387 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> void
00388 ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::RB_rebalance (ACE_RB_Tree_Node<EXT_ID, INT_ID> * x)
00389 {
00390   ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::RB_rebalance");
00391 
00392   ACE_RB_Tree_Node<EXT_ID, INT_ID> *y = 0;
00393 
00394   while (x &&
00395          x->parent ()
00396          && x->parent ()->color () == ACE_RB_Tree_Node_Base::RED)
00397     {
00398       if (! x->parent ()->parent ())
00399         {
00400           // If we got here, something is drastically wrong!
00401           ACE_ERROR ((LM_ERROR,
00402                       ACE_LIB_TEXT ("%p\n"),
00403                       ACE_LIB_TEXT ("\nerror: parent's parent is null in ")
00404                       ACE_LIB_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::RB_rebalance\n")));
00405           return;
00406         }
00407 
00408       if (x->parent () == x->parent ()->parent ()->left ())
00409         {
00410           y = x->parent ()->parent ()->right ();
00411           if (y && y->color () == ACE_RB_Tree_Node_Base::RED)
00412             {
00413               // Handle case 1 (see CLR book, pp. 269).
00414               x->parent ()->color (ACE_RB_Tree_Node_Base::BLACK);
00415               y->color (ACE_RB_Tree_Node_Base::BLACK);
00416               x->parent ()->parent ()->color (ACE_RB_Tree_Node_Base::RED);
00417               x = x->parent ()->parent ();
00418             }
00419           else
00420             {
00421               if (x == x->parent ()->right ())
00422                 {
00423                   // Transform case 2 into case 3 (see CLR book, pp. 269).
00424                   x = x->parent ();
00425                   RB_rotate_left (x);
00426                 }
00427 
00428               // Handle case 3 (see CLR book, pp. 269).
00429               x->parent ()->color (ACE_RB_Tree_Node_Base::BLACK);
00430               x->parent ()->parent ()->color (ACE_RB_Tree_Node_Base::RED);
00431               RB_rotate_right (x->parent ()->parent ());
00432             }
00433         }
00434       else
00435         {
00436           y = x->parent ()->parent ()->left ();
00437           if (y && y->color () == ACE_RB_Tree_Node_Base::RED)
00438             {
00439               // Handle case 1 (see CLR book, pp. 269).
00440               x->parent ()->color (ACE_RB_Tree_Node_Base::BLACK);
00441               y->color (ACE_RB_Tree_Node_Base::BLACK);
00442               x->parent ()->parent ()->color (ACE_RB_Tree_Node_Base::RED);
00443               x = x->parent ()->parent ();
00444             }
00445           else
00446             {
00447               if (x == x->parent ()->left ())
00448                 {
00449                   // Transform case 2 into case 3 (see CLR book, pp. 269).
00450                   x = x->parent ();
00451                   RB_rotate_right (x);
00452                 }
00453 
00454               // Handle case 3 (see CLR book, pp. 269).
00455               x->parent ()->color (ACE_RB_Tree_Node_Base::BLACK);
00456               x->parent ()->parent ()->color (ACE_RB_Tree_Node_Base::RED);
00457               RB_rotate_left (x->parent ()->parent ());
00458             }
00459         }
00460     }
00461 }
00462 
00463 // Method to find the successor node of the given node in the tree.
00464 
00465 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> ACE_RB_Tree_Node<EXT_ID, INT_ID> *
00466 ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::RB_tree_successor (ACE_RB_Tree_Node<EXT_ID, INT_ID> *x) const
00467 {
00468   ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::RB_tree_successor");
00469 
00470   if (x == 0)
00471     return 0;
00472 
00473   if (x->right ())
00474     return RB_tree_minimum (x->right ());
00475 
00476   ACE_RB_Tree_Node<EXT_ID, INT_ID> *y = x->parent ();
00477   while ((y) && (x == y->right ()))
00478     {
00479       x = y;
00480       y = y->parent ();
00481     }
00482 
00483   return y;
00484 }
00485 
00486 // Method to find the predecessor node of the given node in the tree.
00487 
00488 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> ACE_RB_Tree_Node<EXT_ID, INT_ID> *
00489 ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::RB_tree_predecessor (ACE_RB_Tree_Node<EXT_ID, INT_ID> *x) const
00490 {
00491   ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::RB_tree_predecessor");
00492   if (x == 0)
00493     return 0;
00494 
00495   if (x->left ())
00496     return RB_tree_maximum (x->left ());
00497 
00498   ACE_RB_Tree_Node<EXT_ID, INT_ID> *y = x->parent ();
00499 
00500   while ((y) && (x == y->left ()))
00501     {
00502       x = y;
00503       y = y->parent ();
00504     }
00505 
00506   return y;
00507 }
00508 
00509 // Method to find the minimum node of the subtree rooted at the given node.
00510 
00511 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> ACE_RB_Tree_Node<EXT_ID, INT_ID> *
00512 ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::RB_tree_minimum (ACE_RB_Tree_Node<EXT_ID, INT_ID> *x) const
00513 {
00514   ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::RB_tree_minimum");
00515 
00516   while ((x) && (x->left ()))
00517     x = x->left ();
00518 
00519   return x;
00520 }
00521 
00522 // Method to find the maximum node of the subtree rooted at the given node.
00523 
00524 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> ACE_RB_Tree_Node<EXT_ID, INT_ID> *
00525 ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::RB_tree_maximum (ACE_RB_Tree_Node<EXT_ID, INT_ID> *x) const
00526 {
00527   ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::RB_tree_maximum");
00528 
00529   while ((x) && (x->right ()))
00530     x = x->right ();
00531 
00532   return x;
00533 }
00534 
00535 // Delete children (left and right) of the node. Must be called with
00536 // lock held.
00537 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
00538 void ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::delete_children_i
00539   (ACE_RB_Tree_Node<EXT_ID, INT_ID> *parent)
00540 {
00541   if (parent)
00542     {
00543       this->delete_children_i (parent->left ());
00544       this->delete_children_i (parent->right ());
00545       ACE_DES_FREE_TEMPLATE2
00546         (parent->left (),
00547          this->allocator_->free,
00548          ACE_RB_Tree_Node,
00549          EXT_ID, INT_ID);
00550       ACE_DES_FREE_TEMPLATE2
00551         (parent->right (),
00552          this->allocator_->free,
00553          ACE_RB_Tree_Node,
00554          EXT_ID, INT_ID);
00555       parent->left (0);
00556       parent->right (0);
00557     }
00558   return;
00559 }
00560 
00561 // Close down an RB_Tree.  this method should only be called with
00562 // locks already held.
00563 
00564 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> int
00565 ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::close_i ()
00566 {
00567   ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::close_i");
00568 
00569   this->delete_children_i (this->root_);
00570   ACE_DES_FREE_TEMPLATE2 (this->root_,
00571                           this->allocator()->free,
00572                           ACE_RB_Tree_Node,
00573                           EXT_ID, INT_ID);
00574   this->current_size_ = 0;
00575   this->root_ = 0;
00576   return 0;
00577 }
00578 
00579 // Returns a pointer to the item corresponding to the given key, or 0
00580 // if it cannot find the key in the tree.  This method should only be
00581 // called with locks already held.
00582 
00583 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> int
00584 ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::find_i (const EXT_ID &k,
00585                                                              ACE_RB_Tree_Node<EXT_ID, INT_ID>* &entry, int find_exact)
00586 {
00587   ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::find_i");
00588 
00589   // Try to find a match.
00590   RB_SearchResult result = LEFT;
00591   ACE_RB_Tree_Node<EXT_ID, INT_ID> *current = find_node (k, result);
00592 
00593   if (current)
00594     {
00595       // Found a match
00596       if (!find_exact || result == EXACT)
00597         entry = current;  // Assign the entry for any match.
00598       return (result == EXACT ? 0 : -1);
00599     }
00600   else
00601     // The node is not there.
00602     return -1;
00603 }
00604 
00605 // Inserts a *copy* of the key and the item into the tree: both the
00606 // key type EXT_ID and the item type INT_ID must have well defined
00607 // semantics for copy construction and < comparison.  This method
00608 // returns a pointer to the inserted item copy, or 0 if an error
00609 // occurred.  NOTE: if an identical key already exists in the tree, no
00610 // new item is created, and the returned pointer addresses the
00611 // existing item associated with the existing key.  This method should
00612 // only be called with locks already held.
00613 
00614 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> INT_ID *
00615 ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::insert_i (const EXT_ID &k, const INT_ID &t)
00616 {
00617   ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::insert_i (const EXT_ID &k, const INT_ID &t)");
00618 
00619   // Find the closest matching node, if there is one.
00620   RB_SearchResult result = LEFT;
00621   ACE_RB_Tree_Node<EXT_ID, INT_ID> *current = find_node (k, result);
00622   if (current)
00623     {
00624       // If the keys match, just return a pointer to the node's item.
00625       if (result == EXACT)
00626         return &current->item ();
00627 
00628       // Otherwise if we're to the left of the insertion point, insert
00629       // into the right subtree.
00630       else if (result == LEFT)
00631         {
00632           if (current->right ())
00633             {
00634               // If there is already a right subtree, complain.
00635               ACE_ERROR_RETURN ((LM_ERROR,
00636                                  ACE_LIB_TEXT ("%p\n"),
00637                                  ACE_LIB_TEXT ("\nright subtree already present in ")
00638                                  ACE_LIB_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::insert_i\n")),
00639                                 0);
00640             }
00641           else
00642             {
00643               // The right subtree is empty: insert new node there.
00644               ACE_RB_Tree_Node<EXT_ID, INT_ID> *tmp = 0;
00645 
00646               ACE_NEW_MALLOC_RETURN
00647                 (tmp,
00648                  (reinterpret_cast<ACE_RB_Tree_Node<EXT_ID, INT_ID>*>
00649                    (this->allocator_->malloc (sizeof (*tmp)))),
00650                  (ACE_RB_Tree_Node<EXT_ID, INT_ID>) (k, t),
00651                  0);
00652               current->right (tmp);
00653 
00654               // If the node was successfully inserted, set its
00655               // parent, rebalance the tree, color the root black, and
00656               // return a pointer to the inserted item.
00657               INT_ID *item = &(current->right ()->item ());
00658               current->right ()->parent (current);
00659               RB_rebalance (current->right ());
00660               root_->color (ACE_RB_Tree_Node_Base::BLACK);
00661               ++current_size_;
00662               return item;
00663             }
00664         }
00665       // Otherwise, we're to the right of the insertion point, so
00666       // insert into the left subtree.
00667       else // (result == RIGHT)
00668         {
00669           if (current->left ())
00670             // If there is already a left subtree, complain.
00671             ACE_ERROR_RETURN ((LM_ERROR,
00672                                ACE_LIB_TEXT ("%p\n"),
00673                                ACE_LIB_TEXT ("\nleft subtree already present in ")
00674                                ACE_LIB_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::insert_i\n")),
00675                               0);
00676           else
00677             {
00678               // The left subtree is empty: insert new node there.
00679               ACE_RB_Tree_Node<EXT_ID, INT_ID> *tmp = 0;
00680               ACE_NEW_MALLOC_RETURN
00681                 (tmp,
00682                  (reinterpret_cast<ACE_RB_Tree_Node<EXT_ID, INT_ID>*>
00683                    (this->allocator_->malloc (sizeof (*tmp)))),
00684                  (ACE_RB_Tree_Node<EXT_ID, INT_ID>) (k, t),
00685                  0);
00686               current->left (tmp);
00687 
00688               // If the node was successfully inserted, set its
00689               // parent, rebalance the tree, color the root black, and
00690               // return a pointer to the inserted item.
00691               INT_ID *item = &current->left ()->item ();
00692               current->left ()->parent (current);
00693               RB_rebalance (current->left ());
00694               root_->color (ACE_RB_Tree_Node_Base::BLACK);
00695               ++current_size_;
00696               return item;
00697             }
00698         }
00699     }
00700   else
00701     {
00702       // The tree is empty: insert at the root and color the root
00703       // black.
00704       ACE_NEW_MALLOC_RETURN
00705         (this->root_,
00706          (reinterpret_cast<ACE_RB_Tree_Node<EXT_ID, INT_ID>*>
00707            (this->allocator_->malloc (sizeof (ACE_RB_Tree_Node<EXT_ID, INT_ID>)))),
00708          (ACE_RB_Tree_Node<EXT_ID, INT_ID>) (k, t),
00709          0);
00710       this->root_->color (ACE_RB_Tree_Node_Base::BLACK);
00711       ++current_size_;
00712       return &this->root_->item ();
00713     }  
00714 }
00715 
00716 // Inserts a *copy* of the key and the item into the tree: both the
00717 // key type EXT_ID and the item type INT_ID must have well defined
00718 // semantics for copy construction.  The default implementation also
00719 // requires that the key type support well defined < semantics.  This
00720 // method passes back a pointer to the inserted (or existing) node,
00721 // and the search status.  If the node already exists, the method
00722 // returns 1.  If the node does not exist, and a new one is
00723 // successfully created, and the method returns 0.  If there was an
00724 // error, the method returns -1.
00725 
00726 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> int
00727 ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::insert_i (const EXT_ID &k,
00728                                                                const INT_ID &t,
00729                                                                ACE_RB_Tree_Node<EXT_ID, INT_ID> *&entry)
00730 {
00731   ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::insert_i (const EXT_ID &k, const INT_ID &t, "
00732              "ACE_RB_Tree_Node<EXT_ID, INT_ID> *&entry)");
00733 
00734   // Find the closest matching node, if there is one.
00735   RB_SearchResult result = LEFT;
00736   ACE_RB_Tree_Node<EXT_ID, INT_ID> *current = find_node (k, result);
00737   if (current)
00738     {
00739       // If the keys match, just return a pointer to the node's item.
00740       if (result == EXACT)
00741         {
00742           entry = current;
00743           return 1;
00744         }
00745       // Otherwise if we're to the left of the insertion
00746       // point, insert into the right subtree.
00747       else if (result == LEFT)
00748         {
00749           if (current->right ())
00750             {
00751               // If there is already a right subtree, complain.
00752               ACE_ERROR_RETURN ((LM_ERROR,
00753                                  ACE_LIB_TEXT ("%p\n"),
00754                                  ACE_LIB_TEXT ("\nright subtree already present in ")
00755                                  ACE_LIB_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::insert_i\n")),
00756                                 -1);
00757             }
00758           else
00759             {
00760               // The right subtree is empty: insert new node there.
00761               ACE_RB_Tree_Node<EXT_ID, INT_ID> *tmp = 0;
00762               ACE_NEW_MALLOC_RETURN
00763                 (tmp,
00764                  (reinterpret_cast<ACE_RB_Tree_Node<EXT_ID, INT_ID>*>
00765                    (this->allocator_->malloc (sizeof (*tmp)))),
00766                  (ACE_RB_Tree_Node<EXT_ID, INT_ID>) (k, t),
00767                  -1);
00768               current->right (tmp);
00769 
00770               // If the node was successfully inserted, set its parent, rebalance
00771               // the tree, color the root black, and return a pointer to the
00772               // inserted item.
00773               entry = current->right ();
00774               current->right ()->parent (current);
00775               RB_rebalance (current->right ());
00776               this->root_->color (ACE_RB_Tree_Node_Base::BLACK);
00777               ++this->current_size_;
00778               return 0;
00779             }
00780         }
00781       // Otherwise, we're to the right of the insertion point, so
00782       // insert into the left subtree.
00783       else // (result == RIGHT)
00784         {
00785           if (current->left ())
00786             // If there is already a left subtree, complain.
00787             ACE_ERROR_RETURN ((LM_ERROR,
00788                                ACE_LIB_TEXT ("%p\n"),
00789                                ACE_LIB_TEXT ("\nleft subtree already present in ")
00790                                ACE_LIB_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::insert_i\n")),
00791                               -1);
00792           else
00793             {
00794               // The left subtree is empty: insert new node there.
00795               ACE_RB_Tree_Node<EXT_ID, INT_ID> *tmp = 0;
00796               ACE_NEW_MALLOC_RETURN
00797                 (tmp,
00798                  (reinterpret_cast<ACE_RB_Tree_Node<EXT_ID, INT_ID>*>
00799                    (this->allocator_->malloc (sizeof (*tmp)))),
00800                  (ACE_RB_Tree_Node<EXT_ID, INT_ID>) (k, t),
00801                  -1);
00802               current->left (tmp);
00803               // If the node was successfully inserted, set its
00804               // parent, rebalance the tree, color the root black, and
00805               // return a pointer to the inserted item.
00806               entry = current->left ();
00807               current->left ()->parent (current);
00808               RB_rebalance (current->left ());
00809               this->root_->color (ACE_RB_Tree_Node_Base::BLACK);
00810               ++this->current_size_;
00811               return 0;
00812             }
00813         }
00814     }
00815   else
00816     {
00817       // The tree is empty: insert at the root and color the root black.
00818       ACE_NEW_MALLOC_RETURN
00819         (this->root_,
00820          (reinterpret_cast<ACE_RB_Tree_Node<EXT_ID, INT_ID>*>
00821            (this->allocator_->malloc (sizeof (ACE_RB_Tree_Node<EXT_ID, INT_ID>)))),
00822          (ACE_RB_Tree_Node<EXT_ID, INT_ID>) (k, t),
00823          -1);
00824       this->root_->color (ACE_RB_Tree_Node_Base::BLACK);
00825       ++this->current_size_;
00826       entry = this->root_;
00827       return 0;
00828     }
00829 }
00830 
00831 // Removes the item associated with the given key from the tree and
00832 // destroys it.  Returns 1 if it found the item and successfully
00833 // destroyed it, 0 if it did not find the item, or -1 if an error
00834 // occurred.  This method should only be called with locks already
00835 // held.
00836 
00837 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>  int
00838 ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::remove_i (const EXT_ID &k, INT_ID &i)
00839 {
00840   ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::remove_i (const EXT_ID &k, INT_ID &i)");
00841 
00842   // Find a matching node, if there is one.
00843   ACE_RB_Tree_Node<EXT_ID, INT_ID> *z;
00844   RB_SearchResult result = LEFT;
00845   z = find_node (k, result);
00846 
00847   // If there is a matching node: remove and destroy it.
00848   if (z && result == EXACT)
00849     {
00850       // Return the internal id stored in the deleted node.
00851       i = z->item ();
00852       return -1 == this->remove_i (z) ? -1 : 1;
00853     }
00854 
00855   // No matching node was found: return 0.
00856   return 0;
00857 }
00858 
00859 /// Recursive function to dump the state of an object.
00860 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> void
00861 ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::
00862 dump_i (ACE_RB_Tree_Node<EXT_ID, INT_ID> *node) const
00863 {
00864 #if defined (ACE_HAS_DUMP)
00865   if (node)
00866     {
00867       dump_node_i (*node);
00868 
00869       ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("\ndown left\n")));
00870       this->dump_i (node->left ());
00871       ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("\nup left\n")));
00872 
00873       ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("\ndown right\n")));
00874       this->dump_i (node->right ());
00875       ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("\nup right\n")));
00876     }
00877   else
00878     {
00879       ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("\nNULL POINTER (BLACK)\n")));
00880     }
00881 #else /* !ACE_HAS_DUMP */
00882   ACE_UNUSED_ARG (node);
00883 #endif /* ACE_HAS_DUMP */
00884 }
00885 
00886 /// Function to dump node itself.  Does not show parameterized node contents
00887 /// in its basic form, but template specialization can be used to
00888 /// provide definitions for various EXT_ID and INT_ID types.
00889 
00890 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> void
00891 ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::
00892 dump_node_i (ACE_RB_Tree_Node<EXT_ID, INT_ID> &node) const
00893 {
00894 #if defined (ACE_HAS_DUMP)
00895   const char * color_str = (node.color () == ACE_RB_Tree_Node_Base::RED)
00896                            ? "RED" : "BLACK";
00897 
00898   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT (" color=[%s]\n"), color_str));
00899 #else /* !ACE_HAS_DUMP */
00900   ACE_UNUSED_ARG (node);
00901 #endif /* ACE_HAS_DUMP */
00902 }
00903 
00904 /// Tests the red-black invariant(s) throughout the whole tree.
00905 
00906 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>  int
00907 ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::test_invariant (void)
00908 {
00909   ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::test_invariant");
00910   ACE_READ_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1);
00911 
00912   // Recurse from the root, starting with the measured black height at
00913   // 0, and the expected black height at -1, which will cause the
00914   // count from first measured path to a leaf to be used as the
00915   // expected one from that point onward (the key is to check
00916   // consistency).
00917   int expected_black_height = -1;
00918   if (this->test_invariant_recurse (this->root_, expected_black_height, 0) == 0)
00919     {
00920       ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("invariant holds\n")));
00921       return 0;
00922     }
00923 
00924   return -1;
00925 }
00926 
00927 /// Recursive function to test the red-black invariant(s) at all nodes in a subtree.
00928 
00929 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>  int
00930 ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::test_invariant_recurse (ACE_RB_Tree_Node<EXT_ID, INT_ID> *x,
00931                                                                              int & expected_black_height,
00932                                                                              int measured_black_height)
00933 {
00934   ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::test_invariant_recurse");
00935 
00936   if (!x)
00937     {
00938       // Count each leaf (zero pointer) as a black node (per CLR algorithm description).
00939       ++measured_black_height;
00940 
00941       if (expected_black_height == -1)
00942         {
00943           expected_black_height = measured_black_height;
00944         }
00945       else if (expected_black_height != measured_black_height)
00946         {
00947           ACE_ERROR_RETURN ((LM_ERROR,
00948                              ACE_LIB_TEXT ("\nexpected_black_height = %d but ")
00949                              ACE_LIB_TEXT ("\nmeasured_black_height = %d in ")
00950                              ACE_LIB_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::test_invariant_recurse\n"),
00951                              expected_black_height, measured_black_height),
00952                             -1);
00953         }
00954 
00955       return 0;
00956     }
00957 
00958   // Check the invariant that a red node cannot have a red child.
00959   if (x->color () == ACE_RB_Tree_Node_Base::RED)
00960     {
00961       if (x->left () && x->left ()->color () == ACE_RB_Tree_Node_Base::RED)
00962         {
00963           ACE_ERROR_RETURN ((LM_ERROR,
00964                              ACE_LIB_TEXT ("%p\n"),
00965                              ACE_LIB_TEXT ("\nRED parent has RED left child in ")
00966                              ACE_LIB_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::test_invariant_recurse\n")),
00967                             -1);
00968         }
00969 
00970       if (x->right () && x->right ()->color () == ACE_RB_Tree_Node_Base::RED)
00971         {
00972           ACE_ERROR_RETURN ((LM_ERROR,
00973                              ACE_LIB_TEXT ("%p\n"),
00974                              ACE_LIB_TEXT ("\nRED parent has RED right child in ")
00975                              ACE_LIB_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::test_invariant_recurse\n")),
00976                             -1);
00977         }
00978     }
00979   else
00980     {
00981       // Count each black node traversed.
00982       ++measured_black_height;
00983     }
00984 
00985   return (test_invariant_recurse (x->left (), expected_black_height, measured_black_height) == 0)
00986           ? test_invariant_recurse (x->right (), expected_black_height, measured_black_height)
00987           : -1;
00988 }
00989 
00990 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>  int
00991 ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::remove_i (ACE_RB_Tree_Node<EXT_ID, INT_ID> *z)
00992 {
00993   ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::remove_i (ACE_RB_Tree_Node<EXT_ID, INT_ID> *z)");
00994 
00995   // Delete the node and reorganize the tree to satisfy the Red-Black
00996   // properties.
00997 
00998   ACE_RB_Tree_Node<EXT_ID, INT_ID> *x;
00999   ACE_RB_Tree_Node<EXT_ID, INT_ID> *y;
01000   ACE_RB_Tree_Node<EXT_ID, INT_ID> *parent;
01001 
01002   if (z->left () && z->right ())
01003     y = RB_tree_successor (z);
01004   else
01005     y = z;
01006 
01007   if (y->left ())
01008     x = y->left ();
01009   else
01010     x = y->right ();
01011 
01012   parent = y->parent ();
01013   if (x)
01014     {
01015       x->parent (parent);
01016     }
01017 
01018   if (parent)
01019     {
01020       if (y == parent->left ())
01021         parent->left (x);
01022       else
01023         parent->right (x);
01024     }
01025   else
01026     this->root_ = x;
01027 
01028   if (y != z)
01029     {
01030       // Copy the elements of y into z.
01031       z->key () = y->key ();
01032       z->item () = y->item ();
01033     }
01034 
01035   // CLR pp. 263 says that nil nodes are implicitly colored BLACK
01036   if (!y || y->color () == ACE_RB_Tree_Node_Base::BLACK)
01037     RB_delete_fixup (x, parent);
01038 
01039   y->parent (0);
01040   y->right (0);
01041   y->left (0);
01042   ACE_DES_FREE_TEMPLATE2 (y,
01043                           this->allocator_->free,
01044                           ACE_RB_Tree_Node,
01045                           EXT_ID, INT_ID);
01046   --this->current_size_;
01047 
01048   return 0;
01049 }
01050 
01051 ACE_ALLOC_HOOK_DEFINE(ACE_RB_Tree_Iterator_Base)
01052 
01053 // Constructor.
01054 
01055 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
01056 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)
01057   : tree_ (&tree), node_ (0)
01058 {
01059   ACE_TRACE ("ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree_Iterator_Base (ACE_RB_Tree, int)");
01060 
01061   // Position the iterator at the first (or last) node in the tree.
01062   if (set_first)
01063     node_ = tree_->RB_tree_minimum (tree_->root_);
01064   else
01065     node_ = tree_->RB_tree_maximum (tree_->root_);
01066 }
01067 
01068 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
01069 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)
01070   : tree_ (&tree), node_ (0)
01071 {
01072   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)");
01073   node_ = entry;
01074 }
01075 
01076 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
01077 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)
01078    : tree_ (&tree), node_ (0)
01079 {
01080   ACE_TRACE("ACE_RB_Tree_Iterator_Base (ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> &tree, const EXT_ID& key)");
01081   ACE_RB_Tree_Node<EXT_ID, INT_ID>* entry = 0;
01082   tree.find_i(key, entry);
01083   node_ = entry;
01084 }
01085 
01086 // Copy constructor.
01087 
01088 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
01089 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)
01090   : tree_ (iter.tree_),
01091     node_ (iter.node_)
01092 {
01093   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)");
01094 }
01095 
01096 // Assignment operator.
01097 
01098 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> void
01099 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)
01100 {
01101   ACE_TRACE ("ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::operator=");
01102   if (this != &iter)
01103     {
01104       tree_ = iter.tree_;
01105       node_ = iter.node_;
01106     }
01107 }
01108 
01109 // Destructor.
01110 
01111 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
01112 ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::~ACE_RB_Tree_Iterator_Base ()
01113 {
01114   ACE_TRACE ("ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::~ACE_RB_Tree_Iterator_Base");
01115 }
01116 
01117 // Dump the state of an object.
01118 
01119 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
01120 void
01121 ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::dump_i (void) const
01122 {
01123   ACE_TRACE ("ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::dump_i");
01124 
01125   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
01126   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("\nnode_ = %x\n"), this->node_));
01127   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
01128 }
01129 
01130 
01131 ACE_ALLOC_HOOK_DEFINE(ACE_RB_Tree_Iterator)
01132 
01133 // Constructor.
01134 
01135 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
01136 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,
01137      int set_first)
01138   : ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> (tree, set_first)
01139 {
01140   ACE_TRACE ("ACE_RB_Tree_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree_Iterator");
01141 }
01142 
01143 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
01144 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,
01145      ACE_RB_Tree_Node<EXT_ID, INT_ID>* entry)
01146   : ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> (tree,entry)
01147 {
01148   ACE_TRACE ("ACE_RB_Tree_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree_Iterator");
01149 }
01150 
01151 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
01152 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)
01153   : ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>(key,tree)
01154 {
01155   ACE_TRACE ("ACE_RB_Tree_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree_Iterator");
01156 }
01157 
01158 // Destructor.
01159 
01160 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
01161 ACE_RB_Tree_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::~ACE_RB_Tree_Iterator ()
01162 {
01163   ACE_TRACE ("ACE_RB_Tree_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::~ACE_RB_Tree_Iterator");
01164 }
01165 
01166 ACE_ALLOC_HOOK_DEFINE(ACE_RB_Tree_Reverse_Iterator)
01167 
01168 // Constructor.
01169 
01170 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
01171 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)
01172   : ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> (tree, set_last ? 0 : 1)
01173 {
01174   ACE_TRACE ("ACE_RB_Tree_Reverse_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree_Reverse_Iterator");
01175 }
01176 
01177 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
01178 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)
01179   : ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> (tree,entry)
01180 {
01181   ACE_TRACE ("ACE_RB_Tree_Reverse_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree_Reverse_Iterator");
01182 }
01183 
01184 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
01185 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)
01186  : ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>(key,tree)
01187 {
01188   ACE_TRACE ("ACE_RB_Tree_Reverse_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::ACE_RB_Tree_Reverse_Iterator");
01189 }
01190 
01191 // Destructor.
01192 
01193 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
01194 ACE_RB_Tree_Reverse_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::~ACE_RB_Tree_Reverse_Iterator ()
01195 {
01196   ACE_TRACE ("ACE_RB_Tree_Reverse_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::~ACE_RB_Tree_Reverse_Iterator");
01197 }
01198 
01199 ACE_END_VERSIONED_NAMESPACE_DECL
01200 
01201 #endif /* !ACE_RB_TREE_CPP */

Generated on Thu Nov 9 09:42:00 2006 for ACE by doxygen 1.3.6