]> wimlib.net Git - wimlib/commitdiff
rbtree code: Reorganize and delete some unneeded stuff
authorEric Biggers <ebiggers3@gmail.com>
Tue, 18 Dec 2012 17:58:36 +0000 (11:58 -0600)
committerEric Biggers <ebiggers3@gmail.com>
Tue, 18 Dec 2012 17:58:36 +0000 (11:58 -0600)
src/rbtree.c
src/rbtree.h
src/rbtree_augmented.h [deleted file]

index 90e467d739af9baa862cad5c58ee2d7827f858e6..71a2c533e1fbbbdaec30e99bf67225402f5ab8c3 100644 (file)
@@ -21,8 +21,7 @@
   linux/lib/rbtree.c
 */
 
   linux/lib/rbtree.c
 */
 
-#include "rbtree_augmented.h"
-#include "util.h"
+#include "rbtree.h"
 
 /*
  * red-black trees properties:  http://en.wikipedia.org/wiki/Rbtree
 
 /*
  * red-black trees properties:  http://en.wikipedia.org/wiki/Rbtree
  *  parentheses and have some accompanying text comment.
  */
 
  *  parentheses and have some accompanying text comment.
  */
 
+struct rb_augment_callbacks {
+       void (*propagate)(struct rb_node *node, struct rb_node *stop);
+       void (*copy)(struct rb_node *old, struct rb_node *new);
+       void (*rotate)(struct rb_node *old, struct rb_node *new);
+};
+
+#define        RB_RED          0
+#define        RB_BLACK        1
+
+#define __rb_parent(pc)    ((struct rb_node *)(pc & ~3))
+
+#define __rb_color(pc)     ((pc) & 1)
+#define __rb_is_black(pc)  __rb_color(pc)
+#define __rb_is_red(pc)    (!__rb_color(pc))
+#define rb_color(rb)       __rb_color((rb)->__rb_parent_color)
+#define rb_is_red(rb)      __rb_is_red((rb)->__rb_parent_color)
+#define rb_is_black(rb)    __rb_is_black((rb)->__rb_parent_color)
+
+static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p)
+{
+       rb->__rb_parent_color = rb_color(rb) | (unsigned long)p;
+}
+
+static inline void rb_set_parent_color(struct rb_node *rb,
+                                      struct rb_node *p, int color)
+{
+       rb->__rb_parent_color = (unsigned long)p | color;
+}
+
 static inline void rb_set_black(struct rb_node *rb)
 {
        rb->__rb_parent_color |= RB_BLACK;
 static inline void rb_set_black(struct rb_node *rb)
 {
        rb->__rb_parent_color |= RB_BLACK;
@@ -54,6 +82,19 @@ static inline struct rb_node *rb_red_parent(struct rb_node *red)
        return (struct rb_node *)red->__rb_parent_color;
 }
 
        return (struct rb_node *)red->__rb_parent_color;
 }
 
+static inline void
+__rb_change_child(struct rb_node *old, struct rb_node *new,
+                 struct rb_node *parent, struct rb_root *root)
+{
+       if (parent) {
+               if (parent->rb_left == old)
+                       parent->rb_left = new;
+               else
+                       parent->rb_right = new;
+       } else
+               root->rb_node = new;
+}
+
 /*
  * Helper function for rotations:
  * - old's parent and color get assigned to new
 /*
  * Helper function for rotations:
  * - old's parent and color get assigned to new
@@ -69,132 +110,7 @@ __rb_rotate_set_parents(struct rb_node *old, struct rb_node *new,
        __rb_change_child(old, new, parent, root);
 }
 
        __rb_change_child(old, new, parent, root);
 }
 
-static ALWAYS_INLINE void
-__rb_insert(struct rb_node *node, struct rb_root *root,
-           void (*augment_rotate)(struct rb_node *old, struct rb_node *new))
-{
-       struct rb_node *parent = rb_red_parent(node), *gparent, *tmp;
-
-       while (true) {
-               /*
-                * Loop invariant: node is red
-                *
-                * If there is a black parent, we are done.
-                * Otherwise, take some corrective action as we don't
-                * want a red root or two consecutive red nodes.
-                */
-               if (!parent) {
-                       rb_set_parent_color(node, NULL, RB_BLACK);
-                       break;
-               } else if (rb_is_black(parent))
-                       break;
-
-               gparent = rb_red_parent(parent);
-
-               tmp = gparent->rb_right;
-               if (parent != tmp) {    /* parent == gparent->rb_left */
-                       if (tmp && rb_is_red(tmp)) {
-                               /*
-                                * Case 1 - color flips
-                                *
-                                *       G            g
-                                *      / \          / \
-                                *     p   u  -->   P   U
-                                *    /            /
-                                *   n            N
-                                *
-                                * However, since g's parent might be red, and
-                                * 4) does not allow this, we need to recurse
-                                * at g.
-                                */
-                               rb_set_parent_color(tmp, gparent, RB_BLACK);
-                               rb_set_parent_color(parent, gparent, RB_BLACK);
-                               node = gparent;
-                               parent = rb_parent(node);
-                               rb_set_parent_color(node, parent, RB_RED);
-                               continue;
-                       }
-
-                       tmp = parent->rb_right;
-                       if (node == tmp) {
-                               /*
-                                * Case 2 - left rotate at parent
-                                *
-                                *      G             G
-                                *     / \           / \
-                                *    p   U  -->    n   U
-                                *     \           /
-                                *      n         p
-                                *
-                                * This still leaves us in violation of 4), the
-                                * continuation into Case 3 will fix that.
-                                */
-                               parent->rb_right = tmp = node->rb_left;
-                               node->rb_left = parent;
-                               if (tmp)
-                                       rb_set_parent_color(tmp, parent,
-                                                           RB_BLACK);
-                               rb_set_parent_color(parent, node, RB_RED);
-                               augment_rotate(parent, node);
-                               parent = node;
-                               tmp = node->rb_right;
-                       }
-
-                       /*
-                        * Case 3 - right rotate at gparent
-                        *
-                        *        G           P
-                        *       / \         / \
-                        *      p   U  -->  n   g
-                        *     /                 \
-                        *    n                   U
-                        */
-                       gparent->rb_left = tmp;  /* == parent->rb_right */
-                       parent->rb_right = gparent;
-                       if (tmp)
-                               rb_set_parent_color(tmp, gparent, RB_BLACK);
-                       __rb_rotate_set_parents(gparent, parent, root, RB_RED);
-                       augment_rotate(gparent, parent);
-                       break;
-               } else {
-                       tmp = gparent->rb_left;
-                       if (tmp && rb_is_red(tmp)) {
-                               /* Case 1 - color flips */
-                               rb_set_parent_color(tmp, gparent, RB_BLACK);
-                               rb_set_parent_color(parent, gparent, RB_BLACK);
-                               node = gparent;
-                               parent = rb_parent(node);
-                               rb_set_parent_color(node, parent, RB_RED);
-                               continue;
-                       }
-
-                       tmp = parent->rb_left;
-                       if (node == tmp) {
-                               /* Case 2 - right rotate at parent */
-                               parent->rb_left = tmp = node->rb_right;
-                               node->rb_right = parent;
-                               if (tmp)
-                                       rb_set_parent_color(tmp, parent,
-                                                           RB_BLACK);
-                               rb_set_parent_color(parent, node, RB_RED);
-                               augment_rotate(parent, node);
-                               parent = node;
-                               tmp = node->rb_left;
-                       }
-
-                       /* Case 3 - left rotate at gparent */
-                       gparent->rb_right = tmp;  /* == parent->rb_left */
-                       parent->rb_left = gparent;
-                       if (tmp)
-                               rb_set_parent_color(tmp, gparent, RB_BLACK);
-                       __rb_rotate_set_parents(gparent, parent, root, RB_RED);
-                       augment_rotate(gparent, parent);
-                       break;
-               }
-       }
-}
-
-ALWAYS_INLINE void
+static inline void
 __rb_erase_color(struct rb_node *parent, struct rb_root *root,
        void (*augment_rotate)(struct rb_node *old, struct rb_node *new))
 {
 __rb_erase_color(struct rb_node *parent, struct rb_root *root,
        void (*augment_rotate)(struct rb_node *old, struct rb_node *new))
 {
@@ -356,6 +272,231 @@ __rb_erase_color(struct rb_node *parent, struct rb_root *root,
        }
 }
 
        }
 }
 
+static inline void
+rb_erase_augmented(struct rb_node *node, struct rb_root *root,
+                  const struct rb_augment_callbacks *augment)
+{
+       struct rb_node *child = node->rb_right, *tmp = node->rb_left;
+       struct rb_node *parent, *rebalance;
+       unsigned long pc;
+
+       if (!tmp) {
+               /*
+                * Case 1: node to erase has no more than 1 child (easy!)
+                *
+                * Note that if there is one child it must be red due to 5)
+                * and node must be black due to 4). We adjust colors locally
+                * so as to bypass __rb_erase_color() later on.
+                */
+               pc = node->__rb_parent_color;
+               parent = __rb_parent(pc);
+               __rb_change_child(node, child, parent, root);
+               if (child) {
+                       child->__rb_parent_color = pc;
+                       rebalance = NULL;
+               } else
+                       rebalance = __rb_is_black(pc) ? parent : NULL;
+               tmp = parent;
+       } else if (!child) {
+               /* Still case 1, but this time the child is node->rb_left */
+               tmp->__rb_parent_color = pc = node->__rb_parent_color;
+               parent = __rb_parent(pc);
+               __rb_change_child(node, tmp, parent, root);
+               rebalance = NULL;
+               tmp = parent;
+       } else {
+               struct rb_node *successor = child, *child2;
+               tmp = child->rb_left;
+               if (!tmp) {
+                       /*
+                        * Case 2: node's successor is its right child
+                        *
+                        *    (n)          (s)
+                        *    / \          / \
+                        *  (x) (s)  ->  (x) (c)
+                        *        \
+                        *        (c)
+                        */
+                       parent = successor;
+                       child2 = successor->rb_right;
+                       augment->copy(node, successor);
+               } else {
+                       /*
+                        * Case 3: node's successor is leftmost under
+                        * node's right child subtree
+                        *
+                        *    (n)          (s)
+                        *    / \          / \
+                        *  (x) (y)  ->  (x) (y)
+                        *      /            /
+                        *    (p)          (p)
+                        *    /            /
+                        *  (s)          (c)
+                        *    \
+                        *    (c)
+                        */
+                       do {
+                               parent = successor;
+                               successor = tmp;
+                               tmp = tmp->rb_left;
+                       } while (tmp);
+                       parent->rb_left = child2 = successor->rb_right;
+                       successor->rb_right = child;
+                       rb_set_parent(child, successor);
+                       augment->copy(node, successor);
+                       augment->propagate(parent, successor);
+               }
+
+               successor->rb_left = tmp = node->rb_left;
+               rb_set_parent(tmp, successor);
+
+               pc = node->__rb_parent_color;
+               tmp = __rb_parent(pc);
+               __rb_change_child(node, successor, tmp, root);
+               if (child2) {
+                       successor->__rb_parent_color = pc;
+                       rb_set_parent_color(child2, parent, RB_BLACK);
+                       rebalance = NULL;
+               } else {
+                       unsigned long pc2 = successor->__rb_parent_color;
+                       successor->__rb_parent_color = pc;
+                       rebalance = __rb_is_black(pc2) ? parent : NULL;
+               }
+               tmp = successor;
+       }
+
+       augment->propagate(tmp, NULL);
+       if (rebalance)
+               __rb_erase_color(rebalance, root, augment->rotate);
+}
+
+
+static inline void
+__rb_insert(struct rb_node *node, struct rb_root *root,
+           void (*augment_rotate)(struct rb_node *old, struct rb_node *new))
+{
+       struct rb_node *parent = rb_red_parent(node), *gparent, *tmp;
+
+       while (true) {
+               /*
+                * Loop invariant: node is red
+                *
+                * If there is a black parent, we are done.
+                * Otherwise, take some corrective action as we don't
+                * want a red root or two consecutive red nodes.
+                */
+               if (!parent) {
+                       rb_set_parent_color(node, NULL, RB_BLACK);
+                       break;
+               } else if (rb_is_black(parent))
+                       break;
+
+               gparent = rb_red_parent(parent);
+
+               tmp = gparent->rb_right;
+               if (parent != tmp) {    /* parent == gparent->rb_left */
+                       if (tmp && rb_is_red(tmp)) {
+                               /*
+                                * Case 1 - color flips
+                                *
+                                *       G            g
+                                *      / \          / \
+                                *     p   u  -->   P   U
+                                *    /            /
+                                *   n            N
+                                *
+                                * However, since g's parent might be red, and
+                                * 4) does not allow this, we need to recurse
+                                * at g.
+                                */
+                               rb_set_parent_color(tmp, gparent, RB_BLACK);
+                               rb_set_parent_color(parent, gparent, RB_BLACK);
+                               node = gparent;
+                               parent = rb_parent(node);
+                               rb_set_parent_color(node, parent, RB_RED);
+                               continue;
+                       }
+
+                       tmp = parent->rb_right;
+                       if (node == tmp) {
+                               /*
+                                * Case 2 - left rotate at parent
+                                *
+                                *      G             G
+                                *     / \           / \
+                                *    p   U  -->    n   U
+                                *     \           /
+                                *      n         p
+                                *
+                                * This still leaves us in violation of 4), the
+                                * continuation into Case 3 will fix that.
+                                */
+                               parent->rb_right = tmp = node->rb_left;
+                               node->rb_left = parent;
+                               if (tmp)
+                                       rb_set_parent_color(tmp, parent,
+                                                           RB_BLACK);
+                               rb_set_parent_color(parent, node, RB_RED);
+                               augment_rotate(parent, node);
+                               parent = node;
+                               tmp = node->rb_right;
+                       }
+
+                       /*
+                        * Case 3 - right rotate at gparent
+                        *
+                        *        G           P
+                        *       / \         / \
+                        *      p   U  -->  n   g
+                        *     /                 \
+                        *    n                   U
+                        */
+                       gparent->rb_left = tmp;  /* == parent->rb_right */
+                       parent->rb_right = gparent;
+                       if (tmp)
+                               rb_set_parent_color(tmp, gparent, RB_BLACK);
+                       __rb_rotate_set_parents(gparent, parent, root, RB_RED);
+                       augment_rotate(gparent, parent);
+                       break;
+               } else {
+                       tmp = gparent->rb_left;
+                       if (tmp && rb_is_red(tmp)) {
+                               /* Case 1 - color flips */
+                               rb_set_parent_color(tmp, gparent, RB_BLACK);
+                               rb_set_parent_color(parent, gparent, RB_BLACK);
+                               node = gparent;
+                               parent = rb_parent(node);
+                               rb_set_parent_color(node, parent, RB_RED);
+                               continue;
+                       }
+
+                       tmp = parent->rb_left;
+                       if (node == tmp) {
+                               /* Case 2 - right rotate at parent */
+                               parent->rb_left = tmp = node->rb_right;
+                               node->rb_right = parent;
+                               if (tmp)
+                                       rb_set_parent_color(tmp, parent,
+                                                           RB_BLACK);
+                               rb_set_parent_color(parent, node, RB_RED);
+                               augment_rotate(parent, node);
+                               parent = node;
+                               tmp = node->rb_left;
+                       }
+
+                       /* Case 3 - left rotate at gparent */
+                       gparent->rb_right = tmp;  /* == parent->rb_left */
+                       parent->rb_left = gparent;
+                       if (tmp)
+                               rb_set_parent_color(tmp, gparent, RB_BLACK);
+                       __rb_rotate_set_parents(gparent, parent, root, RB_RED);
+                       augment_rotate(gparent, parent);
+                       break;
+               }
+       }
+}
+
+
 /*
  * Non-augmented rbtree manipulation functions.
  *
 /*
  * Non-augmented rbtree manipulation functions.
  *
index 3fa0f16c3a9937454bbbb1f4c782621c3d29f74e..583230e0e787bfa8688b6bf1fe2a44bc56612327 100644 (file)
 #ifndef        _LINUX_RBTREE_H
 #define        _LINUX_RBTREE_H
 
 #ifndef        _LINUX_RBTREE_H
 #define        _LINUX_RBTREE_H
 
-#include <stddef.h>
+#include "util.h"
 
 struct rb_node {
        unsigned long  __rb_parent_color;
        struct rb_node *rb_right;
        struct rb_node *rb_left;
 
 struct rb_node {
        unsigned long  __rb_parent_color;
        struct rb_node *rb_right;
        struct rb_node *rb_left;
-} __attribute__((aligned(sizeof(long))));
-    /* The alignment might seem pointless, but allegedly CRIS needs it */
+};
 
 struct rb_root {
        struct rb_node *rb_node;
 
 struct rb_root {
        struct rb_node *rb_node;
@@ -44,33 +43,11 @@ struct rb_root {
 
 
 #define rb_parent(r)   ((struct rb_node *)((r)->__rb_parent_color & ~3))
 
 
 #define rb_parent(r)   ((struct rb_node *)((r)->__rb_parent_color & ~3))
-
-#define RB_ROOT        (struct rb_root) { NULL, }
 #define        rb_entry(ptr, type, member) container_of(ptr, type, member)
 
 #define        rb_entry(ptr, type, member) container_of(ptr, type, member)
 
-#define RB_EMPTY_ROOT(root)  ((root)->rb_node == NULL)
-
-/* 'empty' nodes are nodes that are known not to be inserted in an rbree */
-#define RB_EMPTY_NODE(node)  \
-       ((node)->__rb_parent_color == (unsigned long)(node))
-#define RB_CLEAR_NODE(node)  \
-       ((node)->__rb_parent_color = (unsigned long)(node))
-
-
 extern void rb_insert_color(struct rb_node *, struct rb_root *);
 extern void rb_erase(struct rb_node *, struct rb_root *);
 
 extern void rb_insert_color(struct rb_node *, struct rb_root *);
 extern void rb_erase(struct rb_node *, struct rb_root *);
 
-
-/* Find logical next and previous nodes in a tree */
-extern struct rb_node *rb_next(const struct rb_node *);
-extern struct rb_node *rb_prev(const struct rb_node *);
-extern struct rb_node *rb_first(const struct rb_root *);
-extern struct rb_node *rb_last(const struct rb_root *);
-
-/* Fast replacement of a single node without remove/rebalance/add/rebalance */
-extern void rb_replace_node(struct rb_node *victim, struct rb_node *new,
-                           struct rb_root *root);
-
 static inline void rb_link_node(struct rb_node * node, struct rb_node * parent,
                                struct rb_node ** rb_link)
 {
 static inline void rb_link_node(struct rb_node * node, struct rb_node * parent,
                                struct rb_node ** rb_link)
 {
diff --git a/src/rbtree_augmented.h b/src/rbtree_augmented.h
deleted file mode 100644 (file)
index 9bca3bb..0000000
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
-  Red Black Trees
-  (C) 1999  Andrea Arcangeli <andrea@suse.de>
-  (C) 2002  David Woodhouse <dwmw2@infradead.org>
-  (C) 2012  Michel Lespinasse <walken@google.com>
-
-  This program is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-  linux/include/linux/rbtree_augmented.h
-*/
-
-#ifndef _LINUX_RBTREE_AUGMENTED_H
-#define _LINUX_RBTREE_AUGMENTED_H
-
-#include "rbtree.h"
-#include "util.h"
-
-/*
- * Please note - only struct rb_augment_callbacks and the prototypes for
- * rb_insert_augmented() and rb_erase_augmented() are intended to be public.
- * The rest are implementation details you are not expected to depend on.
- *
- * See Documentation/rbtree.txt for documentation and samples.
- */
-
-struct rb_augment_callbacks {
-       void (*propagate)(struct rb_node *node, struct rb_node *stop);
-       void (*copy)(struct rb_node *old, struct rb_node *new);
-       void (*rotate)(struct rb_node *old, struct rb_node *new);
-};
-
-extern void __rb_insert_augmented(struct rb_node *node, struct rb_root *root,
-       void (*augment_rotate)(struct rb_node *old, struct rb_node *new));
-static inline void
-rb_insert_augmented(struct rb_node *node, struct rb_root *root,
-                   const struct rb_augment_callbacks *augment)
-{
-       __rb_insert_augmented(node, root, augment->rotate);
-}
-
-#define RB_DECLARE_CALLBACKS(rbstatic, rbname, rbstruct, rbfield,      \
-                            rbtype, rbaugmented, rbcompute)            \
-static inline void                                                     \
-rbname ## _propagate(struct rb_node *rb, struct rb_node *stop)         \
-{                                                                      \
-       while (rb != stop) {                                            \
-               rbstruct *node = rb_entry(rb, rbstruct, rbfield);       \
-               rbtype augmented = rbcompute(node);                     \
-               if (node->rbaugmented == augmented)                     \
-                       break;                                          \
-               node->rbaugmented = augmented;                          \
-               rb = rb_parent(&node->rbfield);                         \
-       }                                                               \
-}                                                                      \
-static inline void                                                     \
-rbname ## _copy(struct rb_node *rb_old, struct rb_node *rb_new)                \
-{                                                                      \
-       rbstruct *old = rb_entry(rb_old, rbstruct, rbfield);            \
-       rbstruct *new = rb_entry(rb_new, rbstruct, rbfield);            \
-       new->rbaugmented = old->rbaugmented;                            \
-}                                                                      \
-static void                                                            \
-rbname ## _rotate(struct rb_node *rb_old, struct rb_node *rb_new)      \
-{                                                                      \
-       rbstruct *old = rb_entry(rb_old, rbstruct, rbfield);            \
-       rbstruct *new = rb_entry(rb_new, rbstruct, rbfield);            \
-       new->rbaugmented = old->rbaugmented;                            \
-       old->rbaugmented = rbcompute(old);                              \
-}                                                                      \
-rbstatic const struct rb_augment_callbacks rbname = {                  \
-       rbname ## _propagate, rbname ## _copy, rbname ## _rotate        \
-};
-
-
-#define        RB_RED          0
-#define        RB_BLACK        1
-
-#define __rb_parent(pc)    ((struct rb_node *)(pc & ~3))
-
-#define __rb_color(pc)     ((pc) & 1)
-#define __rb_is_black(pc)  __rb_color(pc)
-#define __rb_is_red(pc)    (!__rb_color(pc))
-#define rb_color(rb)       __rb_color((rb)->__rb_parent_color)
-#define rb_is_red(rb)      __rb_is_red((rb)->__rb_parent_color)
-#define rb_is_black(rb)    __rb_is_black((rb)->__rb_parent_color)
-
-static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p)
-{
-       rb->__rb_parent_color = rb_color(rb) | (unsigned long)p;
-}
-
-static inline void rb_set_parent_color(struct rb_node *rb,
-                                      struct rb_node *p, int color)
-{
-       rb->__rb_parent_color = (unsigned long)p | color;
-}
-
-static inline void
-__rb_change_child(struct rb_node *old, struct rb_node *new,
-                 struct rb_node *parent, struct rb_root *root)
-{
-       if (parent) {
-               if (parent->rb_left == old)
-                       parent->rb_left = new;
-               else
-                       parent->rb_right = new;
-       } else
-               root->rb_node = new;
-}
-
-extern void __rb_erase_color(struct rb_node *parent, struct rb_root *root,
-       void (*augment_rotate)(struct rb_node *old, struct rb_node *new));
-
-static ALWAYS_INLINE void
-rb_erase_augmented(struct rb_node *node, struct rb_root *root,
-                  const struct rb_augment_callbacks *augment)
-{
-       struct rb_node *child = node->rb_right, *tmp = node->rb_left;
-       struct rb_node *parent, *rebalance;
-       unsigned long pc;
-
-       if (!tmp) {
-               /*
-                * Case 1: node to erase has no more than 1 child (easy!)
-                *
-                * Note that if there is one child it must be red due to 5)
-                * and node must be black due to 4). We adjust colors locally
-                * so as to bypass __rb_erase_color() later on.
-                */
-               pc = node->__rb_parent_color;
-               parent = __rb_parent(pc);
-               __rb_change_child(node, child, parent, root);
-               if (child) {
-                       child->__rb_parent_color = pc;
-                       rebalance = NULL;
-               } else
-                       rebalance = __rb_is_black(pc) ? parent : NULL;
-               tmp = parent;
-       } else if (!child) {
-               /* Still case 1, but this time the child is node->rb_left */
-               tmp->__rb_parent_color = pc = node->__rb_parent_color;
-               parent = __rb_parent(pc);
-               __rb_change_child(node, tmp, parent, root);
-               rebalance = NULL;
-               tmp = parent;
-       } else {
-               struct rb_node *successor = child, *child2;
-               tmp = child->rb_left;
-               if (!tmp) {
-                       /*
-                        * Case 2: node's successor is its right child
-                        *
-                        *    (n)          (s)
-                        *    / \          / \
-                        *  (x) (s)  ->  (x) (c)
-                        *        \
-                        *        (c)
-                        */
-                       parent = successor;
-                       child2 = successor->rb_right;
-                       augment->copy(node, successor);
-               } else {
-                       /*
-                        * Case 3: node's successor is leftmost under
-                        * node's right child subtree
-                        *
-                        *    (n)          (s)
-                        *    / \          / \
-                        *  (x) (y)  ->  (x) (y)
-                        *      /            /
-                        *    (p)          (p)
-                        *    /            /
-                        *  (s)          (c)
-                        *    \
-                        *    (c)
-                        */
-                       do {
-                               parent = successor;
-                               successor = tmp;
-                               tmp = tmp->rb_left;
-                       } while (tmp);
-                       parent->rb_left = child2 = successor->rb_right;
-                       successor->rb_right = child;
-                       rb_set_parent(child, successor);
-                       augment->copy(node, successor);
-                       augment->propagate(parent, successor);
-               }
-
-               successor->rb_left = tmp = node->rb_left;
-               rb_set_parent(tmp, successor);
-
-               pc = node->__rb_parent_color;
-               tmp = __rb_parent(pc);
-               __rb_change_child(node, successor, tmp, root);
-               if (child2) {
-                       successor->__rb_parent_color = pc;
-                       rb_set_parent_color(child2, parent, RB_BLACK);
-                       rebalance = NULL;
-               } else {
-                       unsigned long pc2 = successor->__rb_parent_color;
-                       successor->__rb_parent_color = pc;
-                       rebalance = __rb_is_black(pc2) ? parent : NULL;
-               }
-               tmp = successor;
-       }
-
-       augment->propagate(tmp, NULL);
-       if (rebalance)
-               __rb_erase_color(rebalance, root, augment->rotate);
-}
-
-#endif /* _LINUX_RBTREE_AUGMENTED_H */