Ejemplo n.º 1
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>::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;
}
Ejemplo n.º 2
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 &current->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 = &current->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 ();
    }
}
Ejemplo n.º 3
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>::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;
}