summaryrefslogtreecommitdiffstats
path: root/lib/rbtree.c
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2010-05-20 11:37:23 -0700
committerTony Lindgren <tony@atomide.com>2010-05-20 11:37:23 -0700
commitf6304f5804f228b6c2fea9e3dfac25c5b2db9b38 (patch)
tree362b9b6a3bd32b868e5917a32d448ac75c5854df /lib/rbtree.c
parent4fa73a1bf89ebea4eba8a9982b5f64d266d8b5e9 (diff)
parent6daa642d9b8ec762b3c5641cd5e5fa855a5405bf (diff)
Merge branch 'omap4-i2c-init' into omap-for-linus
Diffstat (limited to 'lib/rbtree.c')
-rw-r--r--lib/rbtree.c48
1 files changed, 44 insertions, 4 deletions
diff --git a/lib/rbtree.c b/lib/rbtree.c
index e2aa3be2985..15e10b1afdd 100644
--- a/lib/rbtree.c
+++ b/lib/rbtree.c
@@ -44,6 +44,11 @@ static void __rb_rotate_left(struct rb_node *node, struct rb_root *root)
else
root->rb_node = right;
rb_set_parent(node, right);
+
+ if (root->augment_cb) {
+ root->augment_cb(node);
+ root->augment_cb(right);
+ }
}
static void __rb_rotate_right(struct rb_node *node, struct rb_root *root)
@@ -67,12 +72,20 @@ static void __rb_rotate_right(struct rb_node *node, struct rb_root *root)
else
root->rb_node = left;
rb_set_parent(node, left);
+
+ if (root->augment_cb) {
+ root->augment_cb(node);
+ root->augment_cb(left);
+ }
}
void rb_insert_color(struct rb_node *node, struct rb_root *root)
{
struct rb_node *parent, *gparent;
+ if (root->augment_cb)
+ root->augment_cb(node);
+
while ((parent = rb_parent(node)) && rb_is_red(parent))
{
gparent = rb_parent(parent);
@@ -227,12 +240,15 @@ void rb_erase(struct rb_node *node, struct rb_root *root)
else
{
struct rb_node *old = node, *left;
+ int old_parent_cb = 0;
+ int successor_parent_cb = 0;
node = node->rb_right;
while ((left = node->rb_left) != NULL)
node = left;
if (rb_parent(old)) {
+ old_parent_cb = 1;
if (rb_parent(old)->rb_left == old)
rb_parent(old)->rb_left = node;
else
@@ -247,8 +263,10 @@ void rb_erase(struct rb_node *node, struct rb_root *root)
if (parent == old) {
parent = node;
} else {
+ successor_parent_cb = 1;
if (child)
rb_set_parent(child, parent);
+
parent->rb_left = child;
node->rb_right = old->rb_right;
@@ -259,6 +277,24 @@ void rb_erase(struct rb_node *node, struct rb_root *root)
node->rb_left = old->rb_left;
rb_set_parent(old->rb_left, node);
+ if (root->augment_cb) {
+ /*
+ * Here, three different nodes can have new children.
+ * The parent of the successor node that was selected
+ * to replace the node to be erased.
+ * The node that is getting erased and is now replaced
+ * by its successor.
+ * The parent of the node getting erased-replaced.
+ */
+ if (successor_parent_cb)
+ root->augment_cb(parent);
+
+ root->augment_cb(node);
+
+ if (old_parent_cb)
+ root->augment_cb(rb_parent(old));
+ }
+
goto color;
}
@@ -267,15 +303,19 @@ void rb_erase(struct rb_node *node, struct rb_root *root)
if (child)
rb_set_parent(child, parent);
- if (parent)
- {
+
+ if (parent) {
if (parent->rb_left == node)
parent->rb_left = child;
else
parent->rb_right = child;
- }
- else
+
+ if (root->augment_cb)
+ root->augment_cb(parent);
+
+ } else {
root->rb_node = child;
+ }
color:
if (color == RB_BLACK)