aboutsummaryrefslogtreecommitdiffstats
path: root/lib/rbtree.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbtree.c')
-rw-r--r--lib/rbtree.c35
1 files changed, 18 insertions, 17 deletions
diff --git a/lib/rbtree.c b/lib/rbtree.c
index de89a614b1ba..bde1b5c5fb33 100644
--- a/lib/rbtree.c
+++ b/lib/rbtree.c
@@ -368,17 +368,28 @@ static void __rb_erase_color(struct rb_node *node, struct rb_node *parent,
368 368
369void rb_erase(struct rb_node *node, struct rb_root *root) 369void rb_erase(struct rb_node *node, struct rb_root *root)
370{ 370{
371 struct rb_node *child, *parent; 371 struct rb_node *child = node->rb_right, *tmp = node->rb_left;
372 struct rb_node *parent;
372 int color; 373 int color;
373 374
374 if (!node->rb_left) 375 if (!tmp) {
375 child = node->rb_right; 376 case1:
376 else if (!node->rb_right) 377 /* Case 1: node to erase has no more than 1 child (easy!) */
377 child = node->rb_left; 378
378 else { 379 parent = rb_parent(node);
380 color = rb_color(node);
381
382 if (child)
383 rb_set_parent(child, parent);
384 __rb_change_child(node, child, parent, root);
385 } else if (!child) {
386 /* Still case 1, but this time the child is node->rb_left */
387 child = tmp;
388 goto case1;
389 } else {
379 struct rb_node *old = node, *left; 390 struct rb_node *old = node, *left;
380 391
381 node = node->rb_right; 392 node = child;
382 while ((left = node->rb_left) != NULL) 393 while ((left = node->rb_left) != NULL)
383 node = left; 394 node = left;
384 395
@@ -402,18 +413,8 @@ void rb_erase(struct rb_node *node, struct rb_root *root)
402 node->__rb_parent_color = old->__rb_parent_color; 413 node->__rb_parent_color = old->__rb_parent_color;
403 node->rb_left = old->rb_left; 414 node->rb_left = old->rb_left;
404 rb_set_parent(old->rb_left, node); 415 rb_set_parent(old->rb_left, node);
405
406 goto color;
407 } 416 }
408 417
409 parent = rb_parent(node);
410 color = rb_color(node);
411
412 if (child)
413 rb_set_parent(child, parent);
414 __rb_change_child(node, child, parent, root);
415
416color:
417 if (color == RB_BLACK) 418 if (color == RB_BLACK)
418 __rb_erase_color(child, parent, root); 419 __rb_erase_color(child, parent, root);
419} 420}