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) */