Beispiel #1
0
PRTL_SPLAY_LINKS
RtlDelete (
    IN PRTL_SPLAY_LINKS Links
    )

/*++

Routine Description:

    The Delete function takes as input a pointer to a splay link in a tree
    and deletes that node from the tree.  Its function return value is a
    pointer to the root of the tree.  If the tree is now empty, the return
    value is NULL.

Arguments:

    Links - Supplies a pointer to a splay link in a tree.

Return Value:

    PRTL_SPLAY_LINKS - returns a pointer to the root of the tree.

--*/

{
    PRTL_SPLAY_LINKS Predecessor;
    PRTL_SPLAY_LINKS Parent;
    PRTL_SPLAY_LINKS Child;

    PRTL_SPLAY_LINKS *ParentChildPtr;

    //
    //  First check to see if Links as two children.  If it does then swap
    //  Links with its subtree predecessor.  Now we are guaranteed that Links
    //  has at most one child.
    //

    if ((RtlLeftChild(Links) != NULL) && (RtlRightChild(Links) != NULL)) {

        //
        //  get the predecessor, and swap their position in the tree
        //

        Predecessor = RtlSubtreePredecessor(Links);
        SwapSplayLinks(Predecessor, Links);

    }

    //
    //  If Links has no children then delete links by checking if it is
    //  already the root or has a parent.  If it is the root then the
    //  tree is now empty, otherwise it set the appropriate parent's child
    //  pointer (i.e., the one to links) to NULL, and splay the parent.
    //

    if ((RtlLeftChild(Links) == NULL) && (RtlRightChild(Links) == NULL)) {

        //
        //  Links has no children, if it is the root then return NULL
        //

        if (RtlIsRoot(Links)) {

            return NULL;
        }

        //
        //  Links as not children and is not the root, so to the parent's
        //  child pointer to NULL and splay the parent.
        //

        Parent = RtlParent(Links);

        ParentChildPtr = ParentsChildPointerAddress(Links);
        *ParentChildPtr = NULL;

        return RtlSplay(Parent);

    }

    //
    //  otherwise Links has one child.  If it is the root then make the child
    //  the new root, otherwise link together the child and parent, and splay
    //  the parent.  But first remember who our child is.
    //

    if (RtlLeftChild(Links) != NULL) {
        Child = RtlLeftChild(Links);
    } else {
        Child = RtlRightChild(Links);
    }

    //
    //  If links is the root then we make the child the root and return the
    //  child.
    //

    if (RtlIsRoot(Links)) {
        Child->Parent = Child;
        return Child;
    }

    //
    //  Links is not the root, so set link's parent child pointer to be
    //  the child and the set child's parent to be link's parent, and splay
    //  the parent.
    //

    ParentChildPtr = ParentsChildPointerAddress(Links);
    *ParentChildPtr = Child;
    Child->Parent = Links->Parent;

    return RtlSplay(RtlParent(Child));

}
Beispiel #2
0
VOID
RtlDeleteNoSplay (
    IN PRTL_SPLAY_LINKS Links,
    IN OUT PRTL_SPLAY_LINKS *Root
    )

/*++

Routine Description:

    The Delete function takes as input a pointer to a splay link in a tree,
    a pointer to the callers pointer to the tree and deletes that node from
    the tree.  The caller's pointer is updated upon return.  If the tree is
    now empty, the value is NULL.

    Unfortunately, the original RtlDelete() always splays and this is not
    always a desireable side-effect.

Arguments:

    Links - Supplies a pointer to a splay link in a tree.

    Root - Pointer to the callers pointer to the root 

Return Value:

    None

--*/

{
    PRTL_SPLAY_LINKS Predecessor;
    PRTL_SPLAY_LINKS Parent;
    PRTL_SPLAY_LINKS Child;

    PRTL_SPLAY_LINKS *ParentChildPtr;

    //
    //  First check to see if Links as two children.  If it does then swap
    //  Links with its subtree predecessor.  Now we are guaranteed that Links
    //  has at most one child.
    //

    if ((RtlLeftChild(Links) != NULL) && (RtlRightChild(Links) != NULL)) {

        //
        //  get the predecessor, and swap their position in the tree
        //

        Predecessor = RtlSubtreePredecessor(Links);

        if (RtlIsRoot(Links)) {

            //
            //  If we're switching with the root of the tree, fix the
            //  caller's root pointer
            //

            *Root = Predecessor;
        }

        SwapSplayLinks(Predecessor, Links);

    }

    //
    //  If Links has no children then delete links by checking if it is
    //  already the root or has a parent.  If it is the root then the
    //  tree is now empty, otherwise it set the appropriate parent's child
    //  pointer (i.e., the one to links) to NULL.
    //

    if ((RtlLeftChild(Links) == NULL) && (RtlRightChild(Links) == NULL)) {

        //
        //  Links has no children, if it is the root then set root to NULL
        //

        if (RtlIsRoot(Links)) {

            *Root = NULL;

            return;
        }

        //
        //  Links as not children and is not the root, so to the parent's
        //  child pointer to NULL.
        //

        ParentChildPtr = ParentsChildPointerAddress(Links);
        *ParentChildPtr = NULL;

        return;
    }

    //
    //  otherwise Links has one child.  If it is the root then make the child
    //  the new root, otherwise link together the child and parent. But first
    //  remember who our child is.
    //

    if (RtlLeftChild(Links) != NULL) {
        Child = RtlLeftChild(Links);
    } else {
        Child = RtlRightChild(Links);
    }

    //
    //  If links is the root then we make the child the root and return the
    //  child.
    //

    if (RtlIsRoot(Links)) {
        Child->Parent = Child;

        *Root = Child;

        return;
    }

    //
    //  Links is not the root, so set link's parent child pointer to be
    //  the child and the set child's parent to be link's parent.
    //

    ParentChildPtr = ParentsChildPointerAddress(Links);
    *ParentChildPtr = Child;
    Child->Parent = Links->Parent;

    return;
}
Beispiel #3
0
/*
 * @implemented
 */
PRTL_SPLAY_LINKS
NTAPI
RtlDelete(PRTL_SPLAY_LINKS Links)
{
    PRTL_SPLAY_LINKS N, P, C, SP;
    N = Links;

    /* Check if we have two children */
    if ((RtlLeftChild(N)) && (RtlRightChild(N)))
    {
        /* Get the predecessor */
        SP = RtlSubtreePredecessor(N);

        /* Swap it with N, this will guarantee that N will have only a child */
        SwapSplayLinks(SP, N);
    }

    /* Check if we have no children */
    if (!(RtlLeftChild(N)) && !(RtlRightChild(N)))
    {
        /* If we are also the root, then the tree is gone */
        if (RtlIsRoot(N)) return NULL;

        /* Get our parent */
        P = RtlParent(N);

        /* Find out who is referencing us and delete the reference */
        if (RtlIsLeftChild(N))
        {
            /* N was a left child, so erase its parent's left child link */
            RtlLeftChild(RtlParent(N)) = NULL;
        }
        else
        {
            /* N was a right child, so erase its parent's right child link */
            RtlRightChild(RtlParent(N)) = NULL;
        }

        /* And finally splay the parent */
        return RtlSplay(P);
    }

    /* If we got here, we have a child (not two: we swapped above!) */
    if (RtlLeftChild(N))
    {
        /* We have a left child, so get it */
        C = RtlLeftChild(N);
    }
    else
    {
        /* We have a right child, get him instead */
        C = RtlRightChild(N);
    }

    /* Check if we are the root entry */
    if (RtlIsRoot(N))
    {
        /* Our child is now root, return him */
        C->Parent = C;
        return C;
    }

    /* Find out who is referencing us and link to our child instead */
    if (RtlIsLeftChild(N))
    {
        /* N was a left child, so set its parent's left child as our child */
        RtlLeftChild(RtlParent(N)) = C;
    }
    else
    {
        /* N was a right child, so set its parent's right child as our child */
        RtlRightChild(RtlParent(N)) = C;
    }

    /* Finally, inherit our parent and splay the parent */
    C->Parent = N->Parent;
    return RtlSplay(RtlParent(C));
}