/* -*- C++ -*- */ // $Id$ // ============================================================================ // // = LIBRARY // ace // // = FILENAME // RB_Tree.h // // = AUTHOR // Chris Gill // // ============================================================================ #ifndef ACE_RB_TREE_H #define ACE_RB_TREE_H #include "ace/OS.h" #include "ace/Functor.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ // Forward decl. template class ACE_RB_Tree_Iterator_Base; // Forward decl. template class ACE_RB_Tree_Iterator; // Forward decl. template class ACE_RB_Tree_Reverse_Iterator; // Forward decl. class ACE_Allocator; class ACE_RB_Tree_Node_Base { public: enum RB_Tree_Node_Color {RED, BLACK}; }; template class ACE_RB_Tree_Node : public ACE_RB_Tree_Node_Base { // = TITLE // Implements a node in a Red-Black Tree ADT. // public: // = Initialization and termination methods. ACE_RB_Tree_Node (const EXT_ID &k, const INT_ID &t); // Constructor. ~ACE_RB_Tree_Node (void); // Destructor. EXT_ID &key (void); // Key accessor. INT_ID &item (void); // Item accessor. void color (RB_Tree_Node_Color c); // Set color of the node. RB_Tree_Node_Color color (void); // Get color of the node. ACE_RB_Tree_Node *parent (void); // Accessor for node's parent pointer. void parent (ACE_RB_Tree_Node * p); // Mutator for node's parent pointer. ACE_RB_Tree_Node *left (void); // Accessor for node's left child pointer. void left (ACE_RB_Tree_Node *l); // Mutator for node's left child pointer. ACE_RB_Tree_Node *right (void); // Accessor for node's right child pointer. void right (ACE_RB_Tree_Node * r); // Mutator for node's right child pointer private: EXT_ID k_; // The key. INT_ID t_; // The item. RB_Tree_Node_Color color_; // Color of the node. ACE_RB_Tree_Node *parent_; // Pointer to node's parent. ACE_RB_Tree_Node *left_; // Pointer to node's left child. ACE_RB_Tree_Node *right_; // Pointer to node's right child. }; class ACE_RB_Tree_Base { public: // = Search result enumeration. enum RB_SearchResult {LEFT, EXACT, RIGHT}; }; template class ACE_RB_Tree : public ACE_RB_Tree_Base { // = TITLE // Implements a Red-Black Tree ADT, according to T. H. Corman, // C. E. Leiserson, and R. L. Rivest, "Introduction to Algorithms" // 1990, MIT, chapter 14. // // = Description // A number of Changes have been made to this class template // in order to conform to the ACE_Hash_Map_Manager_Ex // interface. All previously supported public methods are // still part of this class. However, these are marked as // DEPRECATED and will be removed from this class in // a future version of ACE. Please migrate your code // to the appropriate public methods indicated in the // method deprecation comments. // // This class uses an to allocate memory. The // user can make this a persistent class by providing an // with a persistable memory pool. public: friend class ACE_RB_Tree_Iterator_Base; friend class ACE_RB_Tree_Iterator; friend class ACE_RB_Tree_Reverse_Iterator; typedef EXT_ID KEY; typedef INT_ID VALUE; typedef ACE_RB_Tree_Node ENTRY; // = ACE-style iterator typedefs. typedef ACE_RB_Tree_Iterator ITERATOR; typedef ACE_RB_Tree_Reverse_Iterator REVERSE_ITERATOR; // = STL-style iterator typedefs. typedef ACE_RB_Tree_Iterator iterator; typedef ACE_RB_Tree_Reverse_Iterator reverse_iterator; // = Initialization and termination methods. ACE_RB_Tree (ACE_Allocator *alloc = 0); // Constructor. ACE_RB_Tree (const ACE_RB_Tree &rbt); // Copy constructor. int open (ACE_Allocator *alloc = 0); // Initialize an RB Tree. int close (void); // Close down an RB_Tree and release dynamically allocated // resources. virtual ~ACE_RB_Tree (void); // Destructor. // = insertion, removal, and search methods. int bind (const EXT_ID &item, const INT_ID &int_id); // Associate with . If is already in the // tree then the is not changed. Returns 0 if a // new entry is bound successfully, returns 1 if an attempt is made // to bind an existing entry, and returns -1 if failures occur. int bind (const EXT_ID &ext_id, const INT_ID &int_id, ACE_RB_Tree_Node *&entry); // Same as a normal bind, except the tree entry is also passed back // to the caller. The entry in this case will either be the newly // created entry, or the existing one. int trybind (const EXT_ID &ext_id, INT_ID &int_id); // Associate with if and only if is not // in the tree. If is already in the tree then the // parameter is assigned the existing value in the tree. Returns 0 // if a new entry is bound successfully, returns 1 if an attempt is // made to bind an existing entry, and returns -1 if failures occur. int trybind (const EXT_ID &ext_id, INT_ID &int_id, ACE_RB_Tree_Node *&entry); // Same as a normal trybind, except the tree entry is also passed // back to the caller. The entry in this case will either be the // newly created entry, or the existing one. int rebind (const EXT_ID &ext_id, const INT_ID &int_id); // Reassociate with . If is not in the // tree then behaves just like . Returns 0 if a new entry is // bound successfully, returns 1 if an existing entry was rebound, // and returns -1 if failures occur. int rebind (const EXT_ID &ext_id, const INT_ID &int_id, ACE_RB_Tree_Node *&entry); // Same as a normal rebind, except the tree entry is also passed back // to the caller. The entry in this case will either be the newly // created entry, or the existing one. int rebind (const EXT_ID &ext_id, const INT_ID &int_id, INT_ID &old_int_id); // Associate with . If is not in the tree // then behaves just like . Otherwise, store the old value of // into the "out" parameter and rebind the new parameters. // Returns 0 if a new entry is bound successfully, returns 1 if an // existing entry was rebound, and returns -1 if failures occur. int rebind (const EXT_ID &ext_id, const INT_ID &int_id, INT_ID &old_int_id, ACE_RB_Tree_Node *&entry); // Same as a normal rebind, except the tree entry is also passed back // to the caller. The entry in this case will either be the newly // created entry, or the existing one. int rebind (const EXT_ID &ext_id, const INT_ID &int_id, EXT_ID &old_ext_id, INT_ID &old_int_id); // Associate with . If is not in the tree // then behaves just like . Otherwise, store the old values // of and into the "out" parameters and rebind the // new parameters. This is very useful if you need to have an // atomic way of updating and you also need // full control over memory allocation. Returns 0 if a new entry is // bound successfully, returns 1 if an existing entry was rebound, // and returns -1 if failures occur. int rebind (const EXT_ID &ext_id, const INT_ID &int_id, EXT_ID &old_ext_id, INT_ID &old_int_id, ACE_RB_Tree_Node *&entry); // Same as a normal rebind, except the tree entry is also passed back // to the caller. The entry in this case will either be the newly // created entry, or the existing one. int find (const EXT_ID &ext_id, INT_ID &int_id); // Locate and pass out parameter via . If found, // return 0, returns -1 if not found. int find (const EXT_ID &ext_id, ACE_RB_Tree_Node *&entry); // Locate and pass out parameter via . If found, // return 0, returns -1 if not found. int unbind (const EXT_ID &ext_id); // Unbind (remove) the from the tree. Don't return the // to the caller (this is useful for collections where the // s are *not* dynamically allocated...) int unbind (const EXT_ID &ext_id, INT_ID &int_id); // Break any association of . Returns the value of // in case the caller needs to deallocate memory. int unbind (ACE_RB_Tree_Node *entry); // Remove entry from tree. This method should be used with *extreme* // caution, and only for optimization purposes. The node being passed // in had better have been allocated by the tree that is unbinding it. // = Public helper methods. size_t current_size (void) const; // Returns the current number of nodes in the tree. void operator= (const ACE_RB_Tree &rbt); // Assignment operator. virtual int lessthan (const EXT_ID &k1, const EXT_ID &k2); // Less than comparison function for keys, using comparison functor. ACE_LOCK &mutex (void); // Returns a reference to the underlying . This makes it // possible to acquire the lock explicitly, which can be useful in // some cases if you instantiate the with an // or , or if you need to // guard the state of an iterator. NOTE: the right name would be // , but HP/C++ will choke on that! void dump (void) const; // Dump the state of an object. // = STL styled iterator factory functions. ACE_RB_Tree_Iterator begin (void); // Return forward iterator positioned at first node in tree. ACE_RB_Tree_Iterator end (void); // Return forward iterator positioned at last node in tree. ACE_RB_Tree_Reverse_Iterator rbegin (void); // Return reverse iterator positioned at last node in tree. ACE_RB_Tree_Reverse_Iterator rend (void); // Return reverse iterator positioned at first node in tree. // = DEPRECATED methods. Please migrate your code to use the new methods instead INT_ID* find (const EXT_ID &k); // Returns a pointer to the item corresponding to the // given key, or 0 if it cannot find the key in the tree. // // DEPRECATED: signature will change to become // int find (const EXT_ID &ext_id); which will return // 0 if the is in the tree, otherwise -1. INT_ID* insert (const EXT_ID &k, const INT_ID &t); // Inserts a *copy* of the key and the item into the tree: both the // key type EXT_ID and the item type INT_ID must have well defined semantics // for copy construction. The default implementation also requires that // the key type support well defined < semantics. This method returns a // pointer to the inserted item copy, or 0 if an error occurred. // NOTE: if an identical key already exists in the tree, no new item // is created, and the returned pointer addresses the existing item // associated with the existing key. // DEPRECATED int remove (const EXT_ID &k); // Removes the item associated with the given key from the tree and // destroys it. Returns 1 if it found the item and successfully // destroyed it, 0 if it did not find the item, or -1 if an error // occurred. // DEPRECATED void clear (void); // Destroys all nodes and sets the root pointer null. // DEPRECATED protected: // = Protected methods. These should only be called with locks held. void RB_rotate_right (ACE_RB_Tree_Node * x); // Method for right rotation of the tree about a given node. void RB_rotate_left (ACE_RB_Tree_Node * x); // Method for left rotation of the tree about a given node. void RB_delete_fixup (ACE_RB_Tree_Node * x); // Method for restoring Red-Black properties after deletion. ACE_RB_Tree_Node * RB_tree_successor (ACE_RB_Tree_Node *x) const; // Method to find the successor node of the given node in the tree. ACE_RB_Tree_Node * RB_tree_predecessor (ACE_RB_Tree_Node *x) const; // Method to find the predecessor node of the given node in the // tree. ACE_RB_Tree_Node * RB_tree_minimum (ACE_RB_Tree_Node *x) const; // Method to find the minimum node of the subtree rooted at the // given node. ACE_RB_Tree_Node * RB_tree_maximum (ACE_RB_Tree_Node *x) const; // Method to find the maximum node of the subtree rooted at the // given node. ACE_RB_Tree_Node * find_node (const EXT_ID &k, RB_SearchResult &result); // Returns a pointer to a matching node if there is one, a pointer // to the node under which to insert the item if the tree is not // empty and there is no such match, or 0 if the tree is empty. // It stores the result of the search in the result argument: // LEFT if the node is to the left of the node to be inserted, // RIGHT if the node is to the right of the node to be inserted, // or EXACT if an exactly matching node already exists. void RB_rebalance (ACE_RB_Tree_Node * x); // Rebalance the tree after insertion of a node. int close_i (void); // Close down an RB_Tree. this method should // only be called with locks already held. int find_i (const EXT_ID &ext_id, ACE_RB_Tree_Node* &entry); // Retrieves a pointer to the item corresponding to the // given key. Returns 0 for success, or -1 if it cannot find the key // in the tree. INT_ID* insert_i (const EXT_ID &k, const INT_ID &t); // Inserts a *copy* of the key and the item into the tree: both the // key type EXT_ID and the item type INT_ID must have well defined semantics // for copy construction. The default implementation also requires that // the key type support well defined < semantics. This method returns a // pointer to the inserted item copy, or 0 if an error occurred. // NOTE: if an identical key already exists in the tree, no new item // is created, and the returned pointer addresses the existing item // associated with the existing key. int insert_i (const EXT_ID &k, const INT_ID &t, ACE_RB_Tree_Node *&entry); // Inserts a *copy* of the key and the item into the tree: both the // key type EXT_ID and the item type INT_ID must have well defined semantics // for copy construction. The default implementation also requires that // the key type support well defined < semantics. This method passes back // a pointer to the inserted (or existing) node, and the search status. If // the node already exists, the method returns 1. If the node does not // exist, and a new one is successfully created, and the method returns 0. // If there was an error, the method returns -1. int remove_i (const EXT_ID &k, INT_ID &i); // Removes the item associated with the given key from the tree and // destroys it. Returns 1 if it found the item and successfully // destroyed it, 0 if it did not find the item, or -1 if an error // occurred. Returns the stored internal id in the second argument. int remove_i (ACE_RB_Tree_Node *z); // Removes the item associated with the given key from the tree and // destroys it. private: // = Private members. ACE_Allocator *allocator_; // Pointer to a memory allocator. ACE_LOCK lock_; // Synchronization variable for the MT_SAFE . ACE_RB_Tree_Node *root_; // The root of the tree. COMPARE_KEYS compare_keys_; // Comparison functor for comparing nodes in the tree. size_t current_size_; // The current number of nodes in the tree. }; template class ACE_RB_Tree_Iterator_Base { // = TITLE // Implements a common base class for iterators for a Red-Black Tree ADT. public: void operator= (const ACE_RB_Tree_Iterator_Base &iter); // Assignment operator: copies both the tree reference and the position in the tree. // = Iteration methods. int done (void) const; // Returns 1 when the iteration has completed, otherwise 0. ACE_RB_Tree_Node & operator* (void) const; // STL-like iterator dereference operator: returns a reference // to the node underneath the iterator. const ACE_RB_Tree &tree (void); // Returns a const reference to the tree over which we're iterating. int operator== (const ACE_RB_Tree_Iterator_Base &) const; // Comparison operator: returns 1 if both iterators point to the same position, otherwise 0. int operator!= (const ACE_RB_Tree_Iterator_Base &) const; // Comparison operator: returns 1 if the iterators point to different positions, otherwise 0. ACE_ALLOC_HOOK_DECLARE; // Declare the dynamic allocation hooks. protected: // = Initialization and termination methods. ACE_RB_Tree_Iterator_Base (const ACE_RB_Tree &tree, int set_first); // Constructor. Takes an ACE_RB_Tree over which to iterate, and // an integer indicating (if non-zero) to position the iterator // at the first element in the tree (if this integer is 0, the // iterator is positioned at the last element in the tree). ACE_RB_Tree_Iterator_Base (const ACE_RB_Tree_Iterator_Base &iter); // Copy constructor. ~ACE_RB_Tree_Iterator_Base (void); // Destructor. // = Internal methods int forward_i (void); // Move forward by one element in the tree. Returns 0 when // there are no more elements in the tree, otherwise 1. int reverse_i (void); // Move back by one element in the tree. Returns 0 when // there are no more elements in the tree, otherwise 1. void dump_i (void) const; // Dump the state of an object. // = Protected members. const ACE_RB_Tree *tree_; // Reference to the ACE_RB_Tree over which we're iterating. ACE_RB_Tree_Node *node_; // Pointer to the node currently under the iterator. }; template class ACE_RB_Tree_Iterator : public ACE_RB_Tree_Iterator_Base { // = TITLE // Implements an iterator for a Red-Black Tree ADT. public: // = Initialization and termination methods. ACE_RB_Tree_Iterator (const ACE_RB_Tree &tree, int set_first = 1); // Constructor. Takes an ACE_RB_Tree over which to iterate, and // an integer indicating (if non-zero) to position the iterator // at the first element in the tree (if this integer is 0, the // iterator is positioned at the last element in the tree). ~ACE_RB_Tree_Iterator (void); // Destructor. // = ACE-style iteration methods. int advance (void); // Move forward by one element in the tree. Returns // 0 when all elements have been seen, else 1. void dump (void) const; // Dump the state of an object. // = STL-style iteration methods. ACE_RB_Tree_Iterator & operator++ (void); // Prefix advance. ACE_RB_Tree_Iterator operator++ (int); // Postfix advance. ACE_RB_Tree_Iterator & operator-- (void); // Prefix reverse. ACE_RB_Tree_Iterator operator-- (int); // Postfix reverse. ACE_ALLOC_HOOK_DECLARE; // Declare the dynamic allocation hooks. int next (ACE_RB_Tree_Node *&next_entry) const; // Passes back the under the iterator. Returns 0 if // the iteration has completed, otherwise 1. This method must // be declared and defined in both the derived forward and // reverse iterator classes rather than in the base iterator // class because of a method signature resolution problem // caused by the existence of the deprecated next (void) // method in the derived forward iterator class. When that // deprecated method is removed, this method should be removed // from the derived classes and placed in the base class. // = DEPRECATED methods. Please migrate your code to use the new methods instead EXT_ID *key (void); // Accessor for key of node under iterator (if any). // DEPRECATED INT_ID *item (void); // Accessor for item of node under iterator (if any). // DEPRECATED int first (void); // Move to the first item in the iteration (and in the tree). // DEPRECATED int last (void); // Move to the last item in the iteration (and in the tree). // DEPRECATED int next (void); // Move to the next item in the iteration (and in the tree). // DEPRECATED int previous (void); // Move to the previous item in the iteration (and in the tree). // DEPRECATED int is_done (void); // Returns 0 if the iterator is positioned over a valid ACE_RB_Tree // node, returns 1 if not. // DEPRECATED: use the base class method instead. }; template class ACE_RB_Tree_Reverse_Iterator : public ACE_RB_Tree_Iterator_Base { // = TITLE // Implements a reverse iterator for a Red-Black Tree ADT. public: // = Initialization and termination methods. ACE_RB_Tree_Reverse_Iterator (const ACE_RB_Tree &tree, int set_last = 1); // Constructor. Takes an ACE_RB_Tree over which to iterate, and // an integer indicating (if non-zero) to position the iterator // at the last element in the tree (if this integer is 0, the // iterator is positioned at the first element in the tree). ~ACE_RB_Tree_Reverse_Iterator (void); // Destructor. // = ACE-style iteration methods. int advance (void); // Move forward by one element in the tree. Returns // 0 when all elements have been seen, else 1. void dump (void) const; // Dump the state of an object. // = STL-style iteration methods. ACE_RB_Tree_Reverse_Iterator & operator++ (void); // Prefix advance. ACE_RB_Tree_Reverse_Iterator operator++ (int); // Postfix advance. ACE_RB_Tree_Reverse_Iterator & operator-- (void); // Prefix reverse. ACE_RB_Tree_Reverse_Iterator operator-- (int); // Postfix reverse. ACE_ALLOC_HOOK_DECLARE; // Declare the dynamic allocation hooks. int next (ACE_RB_Tree_Node *&next_entry) const; // Passes back the under the iterator. Returns 0 if // the iteration has completed, otherwise 1. This method must // be declared and defined in both the derived forward and // reverse iterator classes rather than in the base iterator // class because of a method signature resolution problem // caused by the existence of the deprecated next (void) // method in the derived forward iterator class. When that // deprecated method is removed, this method should be removed // from the derived classes and placed in the base class. }; #if defined (__ACE_INLINE__) #include "ace/RB_Tree.i" #endif /* __ACE_INLINE__ */ #if defined (ACE_TEMPLATES_REQUIRE_SOURCE) #include "ace/RB_Tree.cpp" #endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ #if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) #pragma implementation ("RB_Tree.cpp") #endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ #endif /* ! defined (ACE_RB_TREE_H) */