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 (const EXT_ID &k, INT_ID &i) { ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::remove_i (const EXT_ID &k, INT_ID &i)"); // Find a matching node, if there is one. ACE_RB_Tree_Node<EXT_ID, INT_ID> *z; RB_SearchResult result = LEFT; z = find_node (k, result); // If there is a matching node: remove and destroy it. if (z && result == EXACT) { // Return the internal id stored in the deleted node. i = z->item (); return -1 == this->remove_i (z) ? -1 : 1; } // No matching node was found: return 0. return 0; }
template <class EXT_ID, class INT_ID, class COMPARE_KEYS, class ACE_LOCK> INT_ID * ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::insert_i (const EXT_ID &k, const INT_ID &t) { ACE_TRACE ("ACE_RB_Tree<EXT_ID, INT_ID, COMPARE_KEYS, ACE_LOCK>::insert_i (const EXT_ID &k, const INT_ID &t)"); // 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) return ¤t->item (); // 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")), 0); } 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), 0); 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. INT_ID *item = &(current->right ()->item ()); current->right ()->parent (current); RB_rebalance (current->right ()); root_->color (ACE_RB_Tree_Node_Base::BLACK); ++current_size_; return item; } } // 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")), 0); 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), 0); 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. INT_ID *item = ¤t->left ()->item (); current->left ()->parent (current); RB_rebalance (current->left ()); root_->color (ACE_RB_Tree_Node_Base::BLACK); ++current_size_; return item; } } } 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), 0); this->root_->color (ACE_RB_Tree_Node_Base::BLACK); ++current_size_; return &this->root_->item (); } }
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; }