diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/rbtree.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/lib/rbtree.c b/lib/rbtree.c index c0e31fe2fabf..65f4effd117f 100644 --- a/lib/rbtree.c +++ b/lib/rbtree.c | |||
@@ -518,3 +518,43 @@ void rb_replace_node(struct rb_node *victim, struct rb_node *new, | |||
518 | *new = *victim; | 518 | *new = *victim; |
519 | } | 519 | } |
520 | EXPORT_SYMBOL(rb_replace_node); | 520 | EXPORT_SYMBOL(rb_replace_node); |
521 | |||
522 | static struct rb_node *rb_left_deepest_node(const struct rb_node *node) | ||
523 | { | ||
524 | for (;;) { | ||
525 | if (node->rb_left) | ||
526 | node = node->rb_left; | ||
527 | else if (node->rb_right) | ||
528 | node = node->rb_right; | ||
529 | else | ||
530 | return (struct rb_node *)node; | ||
531 | } | ||
532 | } | ||
533 | |||
534 | struct rb_node *rb_next_postorder(const struct rb_node *node) | ||
535 | { | ||
536 | const struct rb_node *parent; | ||
537 | if (!node) | ||
538 | return NULL; | ||
539 | parent = rb_parent(node); | ||
540 | |||
541 | /* If we're sitting on node, we've already seen our children */ | ||
542 | if (parent && node == parent->rb_left && parent->rb_right) { | ||
543 | /* If we are the parent's left node, go to the parent's right | ||
544 | * node then all the way down to the left */ | ||
545 | return rb_left_deepest_node(parent->rb_right); | ||
546 | } else | ||
547 | /* Otherwise we are the parent's right node, and the parent | ||
548 | * should be next */ | ||
549 | return (struct rb_node *)parent; | ||
550 | } | ||
551 | EXPORT_SYMBOL(rb_next_postorder); | ||
552 | |||
553 | struct rb_node *rb_first_postorder(const struct rb_root *root) | ||
554 | { | ||
555 | if (!root->rb_node) | ||
556 | return NULL; | ||
557 | |||
558 | return rb_left_deepest_node(root->rb_node); | ||
559 | } | ||
560 | EXPORT_SYMBOL(rb_first_postorder); | ||