template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> ACE_RB_Tree_Node<EXT_ID, INT_ID> * ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::find_node (const EXT_ID &k, ACE_RB_Tree_Base::RB_SearchResult &result) { ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::find_node"); // Start at the root. ACE_RB_Tree_Node<EXT_ID, INT_ID> *current = root_; while (current) { // While there are more nodes to examine. if (this->lessthan (current->key (), k)) { // If the search key is greater than the current node's key. if (current->right ()) // If the right subtree is not empty, search to the right. current = current->right (); else { // If the right subtree is empty, we're done searching, // and are positioned to the left of the insertion point. result = LEFT; break; } } else if (this->lessthan (k, current->key ())) { // Else if the search key is less than the current node's key. if (current->left ()) // If the left subtree is not empty, search to the left. current = current->left (); else { // If the left subtree is empty, we're done searching, // and are positioned to the right of the insertion point. result = RIGHT; break; } } else { // If the keys match exactly, we're done as well. result = EXACT; break; } } return current; }
template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> ACE_RB_Tree_Node<EXT_ID, INT_ID> * ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::RB_tree_successor (ACE_RB_Tree_Node<EXT_ID, INT_ID> *x) const { ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::RB_tree_successor"); if (x == 0) return 0; if (x->right ()) return RB_tree_minimum (x->right ()); ACE_RB_Tree_Node<EXT_ID, INT_ID> *y = x->parent (); while ((y) && (x == y->right ())) { x = y; y = y->parent (); } return y; }
template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> int ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::remove_i (ACE_RB_Tree_Node<EXT_ID, INT_ID> *z) { ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::remove_i (ACE_RB_Tree_Node<EXT_ID, INT_ID> *z)"); // Delete the node and reorganize the tree to satisfy the Red-Black // properties. ACE_RB_Tree_Node<EXT_ID, INT_ID> *x; ACE_RB_Tree_Node<EXT_ID, INT_ID> *y; ACE_RB_Tree_Node<EXT_ID, INT_ID> *parent; if (z->left () && z->right ()) y = RB_tree_successor (z); else y = z; if (!y) return -1; if (y->left ()) x = y->left (); else x = y->right (); parent = y->parent (); if (x) { x->parent (parent); } if (parent) { if (y == parent->left ()) parent->left (x); else parent->right (x); } else this->root_ = x; if (y != z) { // Replace node z with node y, since y's pointer may well be // held externally, and be linked with y's key and item. // We will end up deleting the old unlinked, node z. ACE_RB_Tree_Node<EXT_ID, INT_ID> *zParent = z->parent (); ACE_RB_Tree_Node<EXT_ID, INT_ID> *zLeftChild = z->left (); ACE_RB_Tree_Node<EXT_ID, INT_ID> *zRightChild = z->right (); if (zParent) { if (z == zParent->left ()) { zParent->left (y); } else { zParent->right (y); } } else { this->root_ = y; } y->parent (zParent); if (zLeftChild) { zLeftChild->parent (y); } y->left (zLeftChild); if (zRightChild) { zRightChild->parent (y); } y->right (zRightChild); if (parent == z) { parent = y; } ACE_RB_Tree_Node_Base::RB_Tree_Node_Color yColor = y->color (); y->color (z->color ()); z->color (yColor); //Reassign the y pointer to z because the node that y points to will be //deleted y = z; } // CLR pp. 263 says that nil nodes are implicitly colored BLACK if (!y || y->color () == ACE_RB_Tree_Node_Base::BLACK) RB_delete_fixup (x, parent); y->parent (0); y->right (0); y->left (0); ACE_DES_FREE_TEMPLATE2 (y, this->allocator_->free, ACE_RB_Tree_Node, EXT_ID, INT_ID); --this->current_size_; return 0; }
template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> int ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::insert_i (const EXT_ID &k, const INT_ID &t, ACE_RB_Tree_Node<EXT_ID, INT_ID> *&entry) { ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::insert_i"); // Find the closest matching node, if there is one. RB_SearchResult result = LEFT; ACE_RB_Tree_Node<EXT_ID, INT_ID> *current = find_node (k, result); if (current) { // If the keys match, just return a pointer to the node's item. if (result == EXACT) { entry = current; return 1; } // Otherwise if we're to the left of the insertion // point, insert into the right subtree. else if (result == LEFT) { if (current->right ()) { // If there is already a right subtree, complain. ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("\nright subtree already present in ") ACE_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::insert_i\n")), -1); } else { // The right subtree is empty: insert new node there. ACE_RB_Tree_Node<EXT_ID, INT_ID> *tmp = 0; ACE_NEW_MALLOC_RETURN (tmp, (reinterpret_cast<ACE_RB_Tree_Node<EXT_ID, INT_ID>*> (this->allocator_->malloc (sizeof (*tmp)))), (ACE_RB_Tree_Node<EXT_ID, INT_ID>) (k, t), -1); current->right (tmp); // If the node was successfully inserted, set its parent, rebalance // the tree, color the root black, and return a pointer to the // inserted item. entry = current->right (); current->right ()->parent (current); RB_rebalance (current->right ()); this->root_->color (ACE_RB_Tree_Node_Base::BLACK); ++this->current_size_; return 0; } } // Otherwise, we're to the right of the insertion point, so // insert into the left subtree. else // (result == RIGHT) { if (current->left ()) // If there is already a left subtree, complain. ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("\nleft subtree already present in ") ACE_TEXT ("ACE_RB_Tree<EXT_ID, INT_ID>::insert_i\n")), -1); else { // The left subtree is empty: insert new node there. ACE_RB_Tree_Node<EXT_ID, INT_ID> *tmp = 0; ACE_NEW_MALLOC_RETURN (tmp, (reinterpret_cast<ACE_RB_Tree_Node<EXT_ID, INT_ID>*> (this->allocator_->malloc (sizeof (*tmp)))), (ACE_RB_Tree_Node<EXT_ID, INT_ID>) (k, t), -1); current->left (tmp); // If the node was successfully inserted, set its // parent, rebalance the tree, color the root black, and // return a pointer to the inserted item. entry = current->left (); current->left ()->parent (current); RB_rebalance (current->left ()); this->root_->color (ACE_RB_Tree_Node_Base::BLACK); ++this->current_size_; return 0; } } } else { // The tree is empty: insert at the root and color the root black. ACE_NEW_MALLOC_RETURN (this->root_, (reinterpret_cast<ACE_RB_Tree_Node<EXT_ID, INT_ID>*> (this->allocator_->malloc (sizeof (ACE_RB_Tree_Node<EXT_ID, INT_ID>)))), (ACE_RB_Tree_Node<EXT_ID, INT_ID>) (k, t), -1); this->root_->color (ACE_RB_Tree_Node_Base::BLACK); ++this->current_size_; entry = this->root_; return 0; } }
template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> void ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>:: RB_delete_fixup (ACE_RB_Tree_Node<EXT_ID, INT_ID> *x, ACE_RB_Tree_Node<EXT_ID, INT_ID> *parent) { ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::RB_delete_fixup"); while (x != this->root_ && (!x || x->color () == ACE_RB_Tree_Node_Base::BLACK)) { if (x == parent->left ()) { ACE_RB_Tree_Node<EXT_ID, INT_ID> *w = parent->right (); if (w && w->color () == ACE_RB_Tree_Node_Base::RED) { w->color (ACE_RB_Tree_Node_Base::BLACK); parent->color (ACE_RB_Tree_Node_Base::RED); RB_rotate_left (parent); w = parent->right (); } // CLR pp. 263 says that nil nodes are implicitly colored BLACK if (w && (!w->left () || w->left ()->color () == ACE_RB_Tree_Node_Base::BLACK) && (!w->right () || w->right ()->color () == ACE_RB_Tree_Node_Base::BLACK)) { w->color (ACE_RB_Tree_Node_Base::RED); x = parent; parent = x->parent (); } else { // CLR pp. 263 says that nil nodes are implicitly colored BLACK if (w && (!w->right () || w->right ()->color () == ACE_RB_Tree_Node_Base::BLACK)) { if (w->left ()) w->left ()->color (ACE_RB_Tree_Node_Base::BLACK); w->color (ACE_RB_Tree_Node_Base::RED); RB_rotate_right (w); w = parent->right (); } if (w) { w->color (parent->color ()); if (w->right ()) w->right ()->color (ACE_RB_Tree_Node_Base::BLACK); } parent->color (ACE_RB_Tree_Node_Base::BLACK); RB_rotate_left (parent); x = root_; } } else { ACE_RB_Tree_Node<EXT_ID, INT_ID> *w = parent->left (); if (w && w->color () == ACE_RB_Tree_Node_Base::RED) { w->color (ACE_RB_Tree_Node_Base::BLACK); parent->color (ACE_RB_Tree_Node_Base::RED); RB_rotate_right (parent); w = parent->left (); } // CLR pp. 263 says that nil nodes are implicitly colored BLACK if (w && (!w->left () || w->left ()->color () == ACE_RB_Tree_Node_Base::BLACK) && (!w->right () || w->right ()->color () == ACE_RB_Tree_Node_Base::BLACK)) { w->color (ACE_RB_Tree_Node_Base::RED); x = parent; parent = x->parent (); } else { // CLR pp. 263 says that nil nodes are implicitly colored BLACK if (w && (!w->left () || w->left ()->color () == ACE_RB_Tree_Node_Base::BLACK)) { w->color (ACE_RB_Tree_Node_Base::RED); if (w->right ()) w->right ()->color (ACE_RB_Tree_Node_Base::BLACK); RB_rotate_left (w); w = parent->left (); } if (w) { w->color (parent->color ()); if (w->left ()) w->left ()->color (ACE_RB_Tree_Node_Base::BLACK); } parent->color (ACE_RB_Tree_Node_Base::BLACK); RB_rotate_right (parent); x = root_; } } } if (x) x->color (ACE_RB_Tree_Node_Base::BLACK); }
template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> int ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::remove_i (ACE_RB_Tree_Node<EXT_ID, INT_ID> *z) { ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::remove_i (ACE_RB_Tree_Node<EXT_ID, INT_ID> *z)"); // Delete the node and reorganize the tree to satisfy the Red-Black // properties. ACE_RB_Tree_Node<EXT_ID, INT_ID> *x; ACE_RB_Tree_Node<EXT_ID, INT_ID> *y; ACE_RB_Tree_Node<EXT_ID, INT_ID> *parent; if (z->left () && z->right ()) y = RB_tree_successor (z); else y = z; if (!y) return -1; if (y->left ()) x = y->left (); else x = y->right (); parent = y->parent (); if (x) { x->parent (parent); } if (parent) { if (y == parent->left ()) parent->left (x); else parent->right (x); } else this->root_ = x; if (y != z) { // Copy the elements of y into z. z->key () = y->key (); z->item () = y->item (); } // CLR pp. 263 says that nil nodes are implicitly colored BLACK if (!y || y->color () == ACE_RB_Tree_Node_Base::BLACK) RB_delete_fixup (x, parent); y->parent (0); y->right (0); y->left (0); ACE_DES_FREE_TEMPLATE2 (y, this->allocator_->free, ACE_RB_Tree_Node, EXT_ID, INT_ID); --this->current_size_; return 0; }