RB_Tree.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 //=============================================================================
00004 /**
00005  *  @file    RB_Tree.h
00006  *
00007  *  RB_Tree.h,v 1.54 2006/06/06 03:58:27 jtc Exp
00008  *
00009  *  @author  Chris Gill
00010  */
00011 //=============================================================================
00012 
00013 
00014 #ifndef ACE_RB_TREE_H
00015 #define ACE_RB_TREE_H
00016 #include /**/ "ace/pre.h"
00017 
00018 #include "ace/Global_Macros.h"
00019 #include "ace/Functor_T.h"
00020 
00021 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00022 # pragma once
00023 #endif /* ACE_LACKS_PRAGMA_ONCE */
00024 
00025 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00026 
00027 // Forward decl.
00028 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
00029 class ACE_RB_Tree_Iterator_Base;
00030 
00031 // Forward decl.
00032 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
00033 class ACE_RB_Tree_Iterator;
00034 
00035 // Forward decl.
00036 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
00037 class ACE_RB_Tree_Reverse_Iterator;
00038 
00039 // Forward decl.
00040 class ACE_Allocator;
00041 
00042 class ACE_RB_Tree_Node_Base
00043 {
00044 public:
00045   enum RB_Tree_Node_Color {RED, BLACK};
00046 };
00047 
00048 /**
00049  * @class ACE_RB_Tree_Node
00050  *
00051  * @brief Implements a node in a Red-Black Tree ADT.
00052  */
00053 template <class EXT_ID, class INT_ID>
00054 class ACE_RB_Tree_Node : public ACE_RB_Tree_Node_Base
00055 {
00056 public:
00057   // = Initialization and termination methods.
00058 
00059   /// Constructor.
00060   ACE_RB_Tree_Node (const EXT_ID &k, const INT_ID &t);
00061 
00062   /// Destructor.
00063   ~ACE_RB_Tree_Node (void);
00064 
00065   /// Key accessor.
00066   EXT_ID &key (void);
00067 
00068   /// Item accessor.
00069   INT_ID &item (void);
00070 
00071   /// Set color of the node.
00072   void color (RB_Tree_Node_Color c);
00073 
00074   /// Get color of the node.
00075   RB_Tree_Node_Color color (void);
00076 
00077   /// Accessor for node's parent pointer.
00078   ACE_RB_Tree_Node<EXT_ID, INT_ID> *parent (void);
00079 
00080   /// Mutator for node's parent pointer.
00081   void parent (ACE_RB_Tree_Node<EXT_ID, INT_ID> * p);
00082 
00083   /// Accessor for node's left child pointer.
00084   ACE_RB_Tree_Node<EXT_ID, INT_ID> *left (void);
00085 
00086   /// Mutator for node's left child pointer.
00087   void left (ACE_RB_Tree_Node<EXT_ID, INT_ID> *l);
00088 
00089   /// Accessor for node's right child pointer.
00090   ACE_RB_Tree_Node<EXT_ID, INT_ID> *right (void);
00091 
00092   /// Mutator for node's right child pointer
00093   void right (ACE_RB_Tree_Node<EXT_ID, INT_ID> * r);
00094 
00095 private:
00096 
00097   /// The key.
00098   EXT_ID k_;
00099 
00100   /// The item.
00101   INT_ID t_;
00102 
00103   /// Color of the node.
00104   RB_Tree_Node_Color color_;
00105 
00106   /// Pointer to node's parent.
00107   ACE_RB_Tree_Node<EXT_ID, INT_ID> *parent_;
00108 
00109   /// Pointer to node's left child.
00110   ACE_RB_Tree_Node<EXT_ID, INT_ID> *left_;
00111 
00112   /// Pointer to node's right child.
00113   ACE_RB_Tree_Node<EXT_ID, INT_ID> *right_;
00114 };
00115 
00116 class ACE_RB_Tree_Base
00117 {
00118 public:
00119   /// Search result enumeration.
00120   enum RB_SearchResult {LEFT, EXACT, RIGHT};
00121 
00122   /// Get the allocator;
00123   /**
00124    * @note This method is inlined here rather than in RB_Tree.inl
00125    *       since that file may be included multiple times when
00126    *       inlining is disabled and on platforms where
00127    *       @c ACE_TEMPLATES_REQUIRE_SOURCE is defined.  In those
00128    *       platform/configuration combinations, multiple definitions
00129    *       of this method occured.  Placing the definition inline in
00130    *       the header avoids such errors.
00131    */
00132   ACE_Allocator * allocator (void) const { return this->allocator_; }
00133 
00134 protected:
00135   // = Protected members.
00136 
00137   /// Pointer to a memory allocator.
00138   ACE_Allocator *allocator_;
00139 };
00140 
00141 /**
00142  * @class ACE_RB_Tree
00143  *
00144  * @brief Implements a Red-Black Tree ADT, according to T. H. Corman,
00145  * C. E. Leiserson, and R. L. Rivest, "Introduction to Algorithms"
00146  * 1990, MIT, chapter 14.
00147  *
00148  * A number of Changes have been made to this class template
00149  * in order to conform to the ACE_Hash_Map_Manager_Ex
00150  * interface.  All previously supported public methods are
00151  * still part of this class. However, these are marked as
00152  * DEPRECATED and will be removed from this class in
00153  * a future version of ACE.  Please migrate your code
00154  * to the appropriate public methods indicated in the
00155  * method deprecation comments.
00156  * This class uses an ACE_Allocator to allocate memory.  The
00157  * user can make this a persistent class by providing an
00158  * ACE_Allocator with a persistable memory pool.
00159  *
00160  * <b> Requirements and Performance Characteristics</b>
00161  *   - Internal Structure:
00162  *       Binary tree
00163  *   - Duplicates allowed?
00164  *       No
00165  *   - Random access allowed?
00166  *       No
00167  *   - Search speed:
00168  *       Log(n)
00169  *   - Insert/replace speed:
00170  *       Log(n)
00171  *   - Iterator still valid after change to container?
00172  *       Yes, except if the iterated-over element is removed.
00173  *   - Frees memory for removed elements?
00174  *       Yes
00175  *   - Items inserted by:
00176  *       Value
00177  *   - Requirements for contained type
00178  *       -# Default constructor
00179  *       -# Copy constructor
00180  *       -# operator=
00181  *       -# operator==
00182  *       -# operator<
00183  */
00184 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
00185 class ACE_RB_Tree : public ACE_RB_Tree_Base
00186 {
00187 
00188 public:
00189   friend class ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>;
00190   friend class ACE_RB_Tree_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>;
00191   friend class ACE_RB_Tree_Reverse_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>;
00192 
00193   typedef EXT_ID KEY;
00194   typedef INT_ID VALUE;
00195   typedef ACE_LOCK lock_type;
00196   typedef ACE_RB_Tree_Node<EXT_ID, INT_ID> ENTRY;
00197 
00198   // = ACE-style iterator typedefs.
00199   typedef ACE_RB_Tree_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> ITERATOR;
00200   typedef ACE_RB_Tree_Reverse_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> REVERSE_ITERATOR;
00201 
00202   // = STL-style iterator typedefs.
00203   typedef ACE_RB_Tree_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> iterator;
00204   typedef ACE_RB_Tree_Reverse_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> reverse_iterator;
00205 
00206   // = Initialization and termination methods.
00207 
00208   /// Constructor.
00209   ACE_RB_Tree (ACE_Allocator *alloc = 0);
00210 
00211 
00212   /// Copy constructor.
00213   ACE_RB_Tree (const ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> &rbt);
00214 
00215   /// Initialize an RB Tree.
00216   int open (ACE_Allocator *alloc = 0);
00217 
00218   /// Close down an RB_Tree and release dynamically allocated
00219   /// resources.
00220   int close (void);
00221 
00222   /// Destructor.
00223   virtual ~ACE_RB_Tree (void);
00224 
00225   // = insertion, removal, and search methods.
00226 
00227   /**
00228    * Associate @a ext_id with @a int_id.  If @a ext_id is already in the
00229    * tree then the <ACE_RB_Tree_Node> is not changed.  Returns 0 if a
00230    * new entry is bound successfully, returns 1 if an attempt is made
00231    * to bind an existing entry, and returns -1 if failures occur.
00232    */
00233   int bind (const EXT_ID &item,
00234             const INT_ID &int_id);
00235 
00236   /**
00237    * Same as a normal bind, except the tree entry is also passed back
00238    * to the caller.  The entry in this case will either be the newly
00239    * created entry, or the existing one.
00240    */
00241   int bind (const EXT_ID &ext_id,
00242             const INT_ID &int_id,
00243             ACE_RB_Tree_Node<EXT_ID, INT_ID> *&entry);
00244 
00245 
00246   /**
00247    * Associate @a ext_id with @a int_id if and only if @a ext_id is not
00248    * in the tree.  If @a ext_id is already in the tree then the @a int_id
00249    * parameter is assigned the existing value in the tree.  Returns 0
00250    * if a new entry is bound successfully, returns 1 if an attempt is
00251    * made to bind an existing entry, and returns -1 if failures occur.
00252    */
00253   int trybind (const EXT_ID &ext_id,
00254                INT_ID &int_id);
00255 
00256   /**
00257    * Same as a normal trybind, except the tree entry is also passed
00258    * back to the caller.  The entry in this case will either be the
00259    * newly created entry, or the existing one.
00260    */
00261   int trybind (const EXT_ID &ext_id,
00262                INT_ID &int_id,
00263                ACE_RB_Tree_Node<EXT_ID, INT_ID> *&entry);
00264 
00265   /**
00266    * Reassociate @a ext_id with @a int_id.  If @a ext_id is not in the
00267    * tree then behaves just like <bind>.  Returns 0 if a new entry is
00268    * bound successfully, returns 1 if an existing entry was rebound,
00269    * and returns -1 if failures occur.
00270    */
00271   int rebind (const EXT_ID &ext_id,
00272               const INT_ID &int_id);
00273 
00274   /**
00275    * Same as a normal rebind, except the tree entry is also passed back
00276    * to the caller.  The entry in this case will either be the newly
00277    * created entry, or the existing one.
00278    */
00279   int rebind (const EXT_ID &ext_id,
00280               const INT_ID &int_id,
00281               ACE_RB_Tree_Node<EXT_ID, INT_ID> *&entry);
00282 
00283   /**
00284    * Associate @a ext_id with @a int_id.  If @a ext_id is not in the tree
00285    * then behaves just like <bind>.  Otherwise, store the old value of
00286    * @a int_id into the "out" parameter and rebind the new parameters.
00287    * Returns 0 if a new entry is bound successfully, returns 1 if an
00288    * existing entry was rebound, and returns -1 if failures occur.
00289    */
00290   int rebind (const EXT_ID &ext_id,
00291               const INT_ID &int_id,
00292               INT_ID &old_int_id);
00293 
00294   /**
00295    * Same as a normal rebind, except the tree entry is also passed back
00296    * to the caller.  The entry in this case will either be the newly
00297    * created entry, or the existing one.
00298    */
00299   int rebind (const EXT_ID &ext_id,
00300               const INT_ID &int_id,
00301               INT_ID &old_int_id,
00302               ACE_RB_Tree_Node<EXT_ID, INT_ID> *&entry);
00303 
00304   /**
00305    * Associate @a ext_id with @a int_id.  If @a ext_id is not in the tree
00306    * then behaves just like <bind>.  Otherwise, store the old values
00307    * of @a ext_id and @a int_id into the "out" parameters and rebind the
00308    * new parameters.  This is very useful if you need to have an
00309    * atomic way of updating <ACE_RB_Tree_Nodes> and you also need
00310    * full control over memory allocation.  Returns 0 if a new entry is
00311    * bound successfully, returns 1 if an existing entry was rebound,
00312    * and returns -1 if failures occur.
00313    */
00314   int rebind (const EXT_ID &ext_id,
00315               const INT_ID &int_id,
00316               EXT_ID &old_ext_id,
00317               INT_ID &old_int_id);
00318 
00319   /**
00320    * Same as a normal rebind, except the tree entry is also passed back
00321    * to the caller.  The entry in this case will either be the newly
00322    * created entry, or the existing one.
00323    */
00324   int rebind (const EXT_ID &ext_id,
00325               const INT_ID &int_id,
00326               EXT_ID &old_ext_id,
00327               INT_ID &old_int_id,
00328               ACE_RB_Tree_Node<EXT_ID, INT_ID> *&entry);
00329 
00330   /// Locate @a ext_id and pass out parameter via @a int_id.  If found,
00331   /// return 0, returns -1 if not found.
00332   int find (const EXT_ID &ext_id,
00333             INT_ID &int_id);
00334 
00335   /// Locate @a ext_id and pass out parameter via <entry>.  If found,
00336   /// return 0, returns -1 if not found.
00337   int find (const EXT_ID &ext_id,
00338             ACE_RB_Tree_Node<EXT_ID, INT_ID> *&entry);
00339 
00340   /**
00341    * Unbind (remove) the @a ext_id from the tree.  Don't return the
00342    * @a int_id to the caller (this is useful for collections where the
00343    * @c int_ids are *not* dynamically allocated...)
00344    */
00345   int unbind (const EXT_ID &ext_id);
00346 
00347   /// Break any association of @a ext_id.  Returns the value of @a int_id
00348   /// in case the caller needs to deallocate memory.
00349   int unbind (const EXT_ID &ext_id,
00350               INT_ID &int_id);
00351 
00352   /**
00353    * Remove entry from tree.  This method should be used with *extreme*
00354    * caution, and only for optimization purposes.  The node being passed
00355    * in had better have been allocated by the tree that is unbinding it.
00356    */
00357   int unbind (ACE_RB_Tree_Node<EXT_ID, INT_ID> *entry);
00358 
00359   // = Public helper methods.
00360 
00361   /// Returns the current number of nodes in the tree.
00362   size_t current_size (void) const;
00363 
00364   /// Assignment operator.
00365   void operator= (const ACE_RB_Tree<EXT_ID,
00366                   INT_ID,
00367                   COMPARE_KEYS,
00368                   ACE_LOCK> &rbt);
00369 
00370   /**
00371    * Returns a reference to the underlying <ACE_LOCK>.  This makes it
00372    * possible to acquire the lock explicitly, which can be useful in
00373    * some cases if you instantiate the ACE_Atomic_Op with an
00374    * ACE_Recursive_Mutex or ACE_Process_Mutex, or if you need to
00375    * guard the state of an iterator.
00376    * @note The right name would be <lock>, but HP/C++ will choke on that!
00377    */
00378   ACE_LOCK &mutex (void);
00379 
00380   /// Dump the state of an object.
00381   void dump (void) const;
00382 
00383   // = STL styled iterator factory functions.
00384 
00385   /// Return forward iterator positioned at first node in tree.
00386   ACE_RB_Tree_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> begin (void);
00387 
00388   /// Return forward iterator positioned at last node in tree.
00389   ACE_RB_Tree_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> end (void);
00390 
00391   /// Return reverse iterator positioned at last node in tree.
00392   ACE_RB_Tree_Reverse_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> rbegin (void);
00393 
00394   /// Return reverse iterator positioned at first node in tree.
00395   ACE_RB_Tree_Reverse_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> rend (void);
00396 
00397   /// Recursively tests the invariant red-black properties at each
00398   /// node of the tree.  Returns 0 if invariant holds, else -1.
00399   /// This method is computationally expensive, and should only be
00400   /// called for testing purposes, and not in code that depends on the
00401   /// algorithmic complexity bounds provided by the other methods.
00402   int test_invariant (void);
00403 
00404   // = DEPRECATED methods.
00405   //   Please migrate your code to use the new methods instead
00406 
00407   /**
00408    * Returns a pointer to the item corresponding to the
00409    * given key, or 0 if it cannot find the key in the tree.
00410    *
00411    * @deprecated signature will change to become
00412    * int find (const EXT_ID &ext_id); which will return
00413    * 0 if the @a ext_id is in the tree, otherwise -1.
00414    */
00415   INT_ID* find (const EXT_ID &k);
00416 
00417   /**
00418    * Inserts a *copy* of the key and the item into the tree: both the
00419    * key type EXT_ID and the item type INT_ID must have well defined semantics
00420    * for copy construction.  The default implementation also requires that
00421    * the key type support well defined < semantics.  This method returns a
00422    * pointer to the inserted item copy, or 0 if an error occurred.
00423    * @note If an identical key already exists in the tree, no new item
00424    * is created, and the returned pointer addresses the existing item
00425    * associated with the existing key.
00426    * @deprecated
00427    */
00428   INT_ID* insert (const EXT_ID &k, const INT_ID &t);
00429 
00430   /**
00431    * Removes the item associated with the given key from the tree and
00432    * destroys it.  Returns 1 if it found the item and successfully
00433    * destroyed it, 0 if it did not find the item, or -1 if an error
00434    * occurred.
00435    * @deprecated
00436    */
00437   int remove (const EXT_ID &k);
00438 
00439   /// @deprecated
00440   /// Destroys all nodes and sets the root pointer null.
00441   void clear (void);
00442 
00443 protected:
00444   /// Reinitialize constructor.
00445   /**
00446    * This constructor is used to provide a valid vtable and allocator
00447    * if the tree is reconstructed from shared memory.  Constructor
00448    * used by the derived class that has an allocator
00449    */
00450   ACE_RB_Tree (void *location,
00451                ACE_Allocator *alloc);
00452 
00453   // = Protected methods. These should only be called with locks held.
00454 
00455   /// Recursively tests the invariant red-black properties at each
00456   /// node of the tree.  Returns 0 if invariant holds, else -1.
00457   int test_invariant_recurse (ACE_RB_Tree_Node<EXT_ID, INT_ID> * x,
00458                               int & expected_black_height,
00459                               int measured_black_height);
00460 
00461   /// Method for right rotation of the tree about a given node.
00462   void RB_rotate_right (ACE_RB_Tree_Node<EXT_ID, INT_ID> * x);
00463 
00464   /// Method for left rotation of the tree about a given node.
00465   void RB_rotate_left (ACE_RB_Tree_Node<EXT_ID, INT_ID> * x);
00466 
00467   /// Method for restoring Red-Black properties after deletion.
00468   void RB_delete_fixup (ACE_RB_Tree_Node<EXT_ID, INT_ID> * x,
00469                         ACE_RB_Tree_Node<EXT_ID, INT_ID> * parent);
00470 
00471   /// Method to find the successor node of the given node in the tree.
00472   ACE_RB_Tree_Node<EXT_ID, INT_ID> *
00473     RB_tree_successor (ACE_RB_Tree_Node<EXT_ID, INT_ID> *x) const;
00474 
00475   /// Method to find the predecessor node of the given node in the
00476   /// tree.
00477   ACE_RB_Tree_Node<EXT_ID, INT_ID> *
00478     RB_tree_predecessor (ACE_RB_Tree_Node<EXT_ID, INT_ID> *x) const;
00479 
00480   /// Method to find the minimum node of the subtree rooted at the
00481   /// given node.
00482   ACE_RB_Tree_Node<EXT_ID, INT_ID> *
00483     RB_tree_minimum (ACE_RB_Tree_Node<EXT_ID, INT_ID> *x) const;
00484 
00485   /// Method to find the maximum node of the subtree rooted at the
00486   /// given node.
00487   ACE_RB_Tree_Node<EXT_ID, INT_ID> *
00488     RB_tree_maximum (ACE_RB_Tree_Node<EXT_ID, INT_ID> *x) const;
00489 
00490   /**
00491    * Returns a pointer to a matching node if there is one, a pointer
00492    * to the node under which to insert the item if the tree is not
00493    * empty and there is no such match, or 0 if the tree is empty.
00494    * It stores the result of the search in the result argument:
00495    * LEFT if the node is to the left of the node to be inserted,
00496    * RIGHT if the node is to the right of the node to be inserted,
00497    * or EXACT if an exactly matching node already exists.
00498    */
00499   ACE_RB_Tree_Node<EXT_ID, INT_ID> *find_node (const EXT_ID &k,
00500                                                ACE_RB_Tree_Base::RB_SearchResult &result);
00501 
00502   /// Rebalance the tree after insertion of a node.
00503   void RB_rebalance (ACE_RB_Tree_Node<EXT_ID, INT_ID> * x);
00504 
00505   /// Delete children (left and right) of the node. Must be called with
00506   /// lock held.
00507   void delete_children_i (ACE_RB_Tree_Node<EXT_ID, INT_ID> *parent);
00508 
00509   /// Close down an RB_Tree.  this method should
00510   /// only be called with locks already held.
00511   int close_i (void);
00512 
00513   /**
00514    * Retrieves a pointer to the item corresponding to the
00515    * given key. If find_exact==1, find the exact match node,
00516    * otherwise just find a match node
00517    * Returns 0 for success, or -1 if it cannot find the key in the tree.
00518    */
00519   int find_i (const EXT_ID &ext_id, ACE_RB_Tree_Node<EXT_ID, INT_ID>* &entry, int find_exact = 1);
00520 
00521   /**
00522    * Inserts a *copy* of the key and the item into the tree: both the
00523    * key type EXT_ID and the item type INT_ID must have well defined semantics
00524    * for copy construction.  The default implementation also requires that
00525    * the key type support well defined < semantics.  This method returns a
00526    * pointer to the inserted item copy, or 0 if an error occurred.
00527    * @note If an identical key already exists in the tree, no new item
00528    * is created, and the returned pointer addresses the existing item
00529    * associated with the existing key.
00530    */
00531   INT_ID* insert_i (const EXT_ID &k, const INT_ID &t);
00532 
00533   /**
00534    * Inserts a *copy* of the key and the item into the tree: both the
00535    * key type EXT_ID and the item type INT_ID must have well defined semantics
00536    * for copy construction.  The default implementation also requires that
00537    * the key type support well defined < semantics.  This method passes back
00538    * a pointer to the inserted (or existing) node, and the search status.  If
00539    * the node already exists, the method returns 1.  If the node does not
00540    * exist, and a new one is successfully created, and the method returns 0.
00541    * If there was an error, the method returns -1.
00542    */
00543   int insert_i (const EXT_ID &k, const INT_ID &t,
00544                 ACE_RB_Tree_Node<EXT_ID, INT_ID> *&entry);
00545 
00546   /**
00547    * Removes the item associated with the given key from the tree and
00548    * destroys it.  Returns 1 if it found the item and successfully
00549    * destroyed it, 0 if it did not find the item, or -1 if an error
00550    * occurred.  Returns the stored internal id in the second argument.
00551    */
00552   int remove_i (const EXT_ID &k, INT_ID &i);
00553 
00554   /// Removes the item associated with the given key from the tree and
00555   /// destroys it.
00556   int remove_i (ACE_RB_Tree_Node<EXT_ID, INT_ID> *z);
00557 
00558   /// Recursive function to dump the state of an object.
00559   void dump_i (ACE_RB_Tree_Node<EXT_ID, INT_ID> *node) const;
00560 
00561   /// Function to dump node contents.   Does nothing in its
00562   /// basic form, but template specialization can be used to
00563   /// provide definitions for various EXT_ID and INT_ID types.
00564   void dump_node_i (ACE_RB_Tree_Node<EXT_ID, INT_ID> &node) const;
00565 
00566   /// Less than comparison function for keys, using comparison functor.
00567   int lessthan (const EXT_ID &k1, const EXT_ID &k2);
00568 
00569 private:
00570 
00571   // = Private members.
00572 
00573   /// Synchronization variable for the MT_SAFE <ACE_RB_Tree>.
00574   ACE_LOCK lock_;
00575 
00576   /// The root of the tree.
00577   ACE_RB_Tree_Node<EXT_ID, INT_ID> *root_;
00578 
00579   /// Comparison functor for comparing nodes in the tree.
00580   COMPARE_KEYS compare_keys_;
00581 
00582   /// The current number of nodes in the tree.
00583   size_t current_size_;
00584 };
00585 
00586 /**
00587  * @class ACE_RB_Tree_Iterator_Base
00588  *
00589  * @brief Implements a common base class for iterators for a Red-Black Tree ADT.
00590  */
00591 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
00592 class ACE_RB_Tree_Iterator_Base
00593 {
00594 
00595 public:
00596 
00597   /// Assignment operator: copies both the tree reference and the position in the tree.
00598   void operator= (const ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> &iter);
00599 
00600   // = Iteration methods.
00601 
00602   /// Returns 1 when the iteration has completed, otherwise 0.
00603   int done (void) const;
00604 
00605   /// STL-like iterator dereference operator: returns a reference
00606   /// to the node underneath the iterator.
00607   ACE_RB_Tree_Node<EXT_ID, INT_ID> & operator* (void) const;
00608 
00609   /// STL-like iterator dereference operator: returns a pointer
00610   /// to the node underneath the iterator.
00611   ACE_RB_Tree_Node<EXT_ID, INT_ID> * operator-> (void) const;
00612 
00613   /// Returns a const reference to the tree over which we're iterating.
00614   const ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> &tree (void);
00615 
00616   /// Comparison operator: returns 1 if both iterators point to the same position, otherwise 0.
00617   bool operator== (const ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> &) const;
00618 
00619   /// Comparison operator: returns 1 if the iterators point to different positions, otherwise 0.
00620   bool operator!= (const ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> &) const;
00621 
00622   /// Declare the dynamic allocation hooks.
00623   ACE_ALLOC_HOOK_DECLARE;
00624 
00625 protected:
00626 
00627   // = Initialization and termination methods.
00628 
00629   /// Create the singular iterator.  No valid iterator can be equal to
00630   /// it, it is illegal to dereference a singular iterator, etc. etc.
00631   ACE_RB_Tree_Iterator_Base (void);
00632 
00633   /**
00634    * Constructor.  Takes an ACE_RB_Tree over which to iterate, and
00635    * an integer indicating (if non-zero) to position the iterator
00636    * at the first element in the tree (if this integer is 0, the
00637    * iterator is positioned at the last element in the tree).
00638    */
00639   ACE_RB_Tree_Iterator_Base (const ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> &tree,
00640                              int set_first);
00641 
00642   /**
00643    * Constructor.  Takes an ACE_RB_Tree over which to iterate, and
00644    * a pointer to a node in the tree.
00645    */
00646   ACE_RB_Tree_Iterator_Base (const ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> &tree,
00647                              ACE_RB_Tree_Node<EXT_ID, INT_ID>* entry);
00648 
00649   /**
00650    * Constructor.  Takes an ACE_RB_Tree over which to iterate, and a key.
00651    * The key must come first to distinguish the case of EXT_ID == int.
00652    */
00653   ACE_RB_Tree_Iterator_Base (const EXT_ID& key,
00654                              ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS,ACE_LOCK> &tree);
00655 
00656   /// Copy constructor.
00657   ACE_RB_Tree_Iterator_Base (const ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> &iter);
00658 
00659   /// Destructor.
00660   ~ACE_RB_Tree_Iterator_Base (void);
00661 
00662   // = Internal methods
00663 
00664   /// Move forward by one element in the tree.  Returns 0 when
00665   /// there are no more elements in the tree, otherwise 1.
00666   int forward_i (void);
00667 
00668   /// Move back by one element in the tree.  Returns 0 when
00669   /// there are no more elements in the tree, otherwise 1.
00670   int reverse_i (void);
00671 
00672   /// Dump the state of an object.
00673   void dump_i (void) const;
00674 
00675   // = Protected members.
00676 
00677   /// Reference to the ACE_RB_Tree over which we're iterating.
00678   const ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> *tree_;
00679 
00680   /// Pointer to the node currently under the iterator.
00681   ACE_RB_Tree_Node <EXT_ID, INT_ID> *node_;
00682 
00683 };
00684 
00685 /**
00686  * @class ACE_RB_Tree_Iterator
00687  *
00688  * @brief Implements an iterator for a Red-Black Tree ADT.
00689  */
00690 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
00691 class ACE_RB_Tree_Iterator : public ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>
00692 {
00693 
00694 public:
00695 
00696   // = Initialization and termination methods.
00697   /**
00698    * Create the singular iterator.
00699    * It is illegal to deference the iterator, no valid iterator is
00700    * equal to a singular iterator, etc. etc.
00701    */
00702   ACE_RB_Tree_Iterator (void);
00703 
00704   /**
00705    * Constructor.  Takes an ACE_RB_Tree over which to iterate, and
00706    * an integer indicating (if non-zero) to position the iterator
00707    * at the first element in the tree (if this integer is 0, the
00708    * iterator is positioned at the last element in the tree).
00709    */
00710   ACE_RB_Tree_Iterator (const ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> &tree,
00711                         int set_first = 1);
00712   /**
00713    * Constructor.  Takes an ACE_RB_Tree over which to iterate
00714    * and a pointer to a node in the tree.
00715    */
00716   ACE_RB_Tree_Iterator (const ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> &tree,
00717                         ACE_RB_Tree_Node<EXT_ID, INT_ID>* entry);
00718 
00719    /**
00720    * Constructor.  Takes an ACE_RB_Tree over which to iterate, and a key;
00721    * the key comes first in order to distinguish the case of EXT_ID == int.
00722    */
00723   ACE_RB_Tree_Iterator (const EXT_ID &key,
00724                         ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> &tree);
00725 
00726   /// Destructor.
00727   ~ACE_RB_Tree_Iterator (void);
00728 
00729   // = ACE-style iteration methods.
00730 
00731   /// Move forward by one element in the tree.  Returns
00732   /// 0 when all elements have been seen, else 1.
00733   int advance (void);
00734 
00735   /// Dump the state of an object.
00736   void dump (void) const;
00737 
00738   // = STL-style iteration methods.
00739 
00740   /// Prefix advance.
00741   ACE_RB_Tree_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> & operator++ (void);
00742 
00743   /// Postfix advance.
00744   ACE_RB_Tree_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> operator++ (int);
00745 
00746   /// Prefix reverse.
00747   ACE_RB_Tree_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> & operator-- (void);
00748 
00749   /// Postfix reverse.
00750   ACE_RB_Tree_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> operator-- (int);
00751 
00752   /// Declare the dynamic allocation hooks.
00753   ACE_ALLOC_HOOK_DECLARE;
00754 
00755   /**
00756    * Passes back the <entry> under the iterator.  Returns 0 if
00757    * the iteration has completed, otherwise 1.  This method must
00758    * be declared and defined in both the derived forward and
00759    * reverse iterator classes rather than in the base iterator
00760    * class because of a method signature resolution problem
00761    * caused by the existence of the deprecated next (void)
00762    * method in the derived forward iterator class.  When that
00763    * deprecated method is removed, this method should be removed
00764    * from the derived classes and placed in the base class.
00765    */
00766   int next (ACE_RB_Tree_Node<EXT_ID, INT_ID> *&next_entry) const;
00767 
00768   // = DEPRECATED methods.  Please migrate your code to use the new methods instead
00769 
00770   /// @deprecated
00771   /// Accessor for key of node under iterator (if any).
00772   EXT_ID *key (void);
00773 
00774   /// @deprecated
00775   /// Accessor for item of node under iterator (if any).
00776   INT_ID *item (void);
00777 
00778   /// @deprecated
00779   /// Move to the first item in the iteration (and in the tree).
00780   int first (void);
00781 
00782   /// @deprecated
00783   /// Move to the last item in the iteration (and in the tree).
00784   int last (void);
00785 
00786   /// @deprecated
00787   /// Move to the next item in the iteration (and in the tree).
00788   int next (void);
00789 
00790   /// @deprecated
00791   /// Move to the previous item in the iteration (and in the tree).
00792   int previous (void);
00793 
00794   /**
00795    * @deprecated: use the base class <done> method instead.
00796    * Returns 0 if the iterator is positioned over a valid ACE_RB_Tree
00797    * node, returns 1 if not.
00798    */
00799   int is_done (void);
00800 
00801 };
00802 
00803 /**
00804  * @class ACE_RB_Tree_Reverse_Iterator
00805  *
00806  * @brief Implements a reverse iterator for a Red-Black Tree ADT.
00807  */
00808 template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK>
00809 class ACE_RB_Tree_Reverse_Iterator : public ACE_RB_Tree_Iterator_Base<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>
00810 {
00811 
00812 public:
00813 
00814   // = Initialization and termination methods.
00815   /**
00816    * Create the singular iterator.
00817    * It is illegal to deference the iterator, no valid iterator is
00818    * equal to a singular iterator, etc. etc.
00819    */
00820   ACE_RB_Tree_Reverse_Iterator (void);
00821 
00822   /**
00823    * Constructor.  Takes an ACE_RB_Tree over which to iterate, and
00824    * an integer indicating (if non-zero) to position the iterator
00825    * at the last element in the tree (if this integer is 0, the
00826    * iterator is positioned at the first element in the tree).
00827    */
00828   ACE_RB_Tree_Reverse_Iterator (const ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> &tree,
00829                                 int set_last = 1);
00830 
00831   /**
00832    * Constructor.  Takes an ACE_RB_Tree over which to iterate, and
00833    * a point to a node in the tree.
00834    */
00835   ACE_RB_Tree_Reverse_Iterator (const ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> &tree,
00836                                 ACE_RB_Tree_Node<EXT_ID, INT_ID>* entry);
00837 
00838   /**
00839    * Constructor.  Takes an ACE_RB_Tree over which to iterate, and a key;
00840    * the key comes first in order to distinguish the case of EXT_ID == int.
00841    */
00842   ACE_RB_Tree_Reverse_Iterator (const EXT_ID &key,
00843                                 ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> &tree);
00844 
00845   /// Destructor.
00846   ~ACE_RB_Tree_Reverse_Iterator (void);
00847 
00848   // = ACE-style iteration methods.
00849 
00850   /// Move forward by one element in the tree.  Returns
00851   /// 0 when all elements have been seen, else 1.
00852   int advance (void);
00853 
00854   /// Dump the state of an object.
00855   void dump (void) const;
00856 
00857   // = STL-style iteration methods.
00858 
00859   /// Prefix advance.
00860   ACE_RB_Tree_Reverse_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> & operator++ (void);
00861 
00862   /// Postfix advance.
00863   ACE_RB_Tree_Reverse_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> operator++ (int);
00864 
00865   /// Prefix reverse.
00866   ACE_RB_Tree_Reverse_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> & operator-- (void);
00867 
00868   /// Postfix reverse.
00869   ACE_RB_Tree_Reverse_Iterator<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK> operator-- (int);
00870 
00871   /// Declare the dynamic allocation hooks.
00872   ACE_ALLOC_HOOK_DECLARE;
00873 
00874   /**
00875    * Passes back the <entry> under the iterator.  Returns 0 if
00876    * the iteration has completed, otherwise 1.  This method must
00877    * be declared and defined in both the derived forward and
00878    * reverse iterator classes rather than in the base iterator
00879    * class because of a method signature resolution problem
00880    * caused by the existence of the deprecated next (void)
00881    * method in the derived forward iterator class.  When that
00882    * deprecated method is removed, this method should be removed
00883    * from the derived classes and placed in the base class.
00884    */
00885   int next (ACE_RB_Tree_Node<EXT_ID, INT_ID> *&next_entry) const;
00886 
00887 };
00888 
00889 ACE_END_VERSIONED_NAMESPACE_DECL
00890 
00891 #if defined (__ACE_INLINE__)
00892 #include "ace/RB_Tree.inl"
00893 #endif /* __ACE_INLINE__ */
00894 
00895 #if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
00896 #include "ace/RB_Tree.cpp"
00897 #endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
00898 
00899 #if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
00900 #pragma implementation ("RB_Tree.cpp")
00901 #endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
00902 
00903 #include /**/ "ace/post.h"
00904 #endif /* ! defined (ACE_RB_TREE_H) */

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