diff options
Diffstat (limited to 'lib/rbtree.c')
-rw-r--r-- | lib/rbtree.c | 35 |
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 | ||
369 | void rb_erase(struct rb_node *node, struct rb_root *root) | 369 | void 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 | |||
416 | color: | ||
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 | } |