Jacek Caban : rbtree.h: Use parent pointer instead of stack in wine_rb_postorder.
Alexandre Julliard
julliard at winehq.org
Tue Aug 30 10:30:45 CDT 2016
Module: wine
Branch: master
Commit: 20740d849e443bc47d1850791897394a12ff779a
URL: http://source.winehq.org/git/wine.git/?a=commit;h=20740d849e443bc47d1850791897394a12ff779a
Author: Jacek Caban <jacek at codeweavers.com>
Date: Mon Aug 15 21:53:26 2016 +0200
rbtree.h: Use parent pointer instead of stack in wine_rb_postorder.
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
include/wine/rbtree.h | 49 +++++++++++++++++++++----------------------------
1 file changed, 21 insertions(+), 28 deletions(-)
diff --git a/include/wine/rbtree.h b/include/wine/rbtree.h
index 11f42f7..2d364e3 100644
--- a/include/wine/rbtree.h
+++ b/include/wine/rbtree.h
@@ -59,8 +59,6 @@ typedef void (wine_rb_traverse_func_t)(struct wine_rb_entry *entry, void *contex
#define WINE_RB_FLAG_RED 0x1
#define WINE_RB_FLAG_STOP 0x2
-#define WINE_RB_FLAG_TRAVERSED_LEFT 0x4
-#define WINE_RB_FLAG_TRAVERSED_RIGHT 0x8
static inline void wine_rb_stack_clear(struct wine_rb_stack *stack)
{
@@ -185,37 +183,32 @@ static inline void wine_rb_move_red_right(struct wine_rb_tree *tree, struct wine
}
}
-static inline void wine_rb_postorder(struct wine_rb_tree *tree, wine_rb_traverse_func_t *callback, void *context)
+static inline struct wine_rb_entry *wine_rb_postorder_head(struct wine_rb_entry *iter)
{
- struct wine_rb_entry **entry;
-
- if (!tree->root) return;
+ if (!iter) return NULL;
- for (entry = &tree->root;;)
- {
- struct wine_rb_entry *e = *entry;
-
- if (e->left && !(e->flags & WINE_RB_FLAG_TRAVERSED_LEFT))
- {
- wine_rb_stack_push(&tree->stack, entry);
- e->flags |= WINE_RB_FLAG_TRAVERSED_LEFT;
- entry = &e->left;
- continue;
- }
+ for (;;) {
+ while (iter->left) iter = iter->left;
+ if (!iter->right) return iter;
+ iter = iter->right;
+ }
+}
- if (e->right && !(e->flags & WINE_RB_FLAG_TRAVERSED_RIGHT))
- {
- wine_rb_stack_push(&tree->stack, entry);
- e->flags |= WINE_RB_FLAG_TRAVERSED_RIGHT;
- entry = &e->right;
- continue;
- }
+static inline struct wine_rb_entry *wine_rb_postorder_next(struct wine_rb_entry *iter)
+{
+ if (!iter->parent) return NULL;
+ if (iter == iter->parent->right || !iter->parent->right) return iter->parent;
+ return wine_rb_postorder_head(iter->parent->right);
+}
- e->flags &= ~(WINE_RB_FLAG_TRAVERSED_LEFT | WINE_RB_FLAG_TRAVERSED_RIGHT);
- callback(e, context);
+static inline void wine_rb_postorder(struct wine_rb_tree *tree, wine_rb_traverse_func_t *callback, void *context)
+{
+ struct wine_rb_entry *iter, *next;
- if (!tree->stack.count) break;
- entry = tree->stack.entries[--tree->stack.count];
+ for (iter = wine_rb_postorder_head(tree->root); iter; iter = next)
+ {
+ next = wine_rb_postorder_next(iter);
+ callback(iter, context);
}
}
More information about the wine-cvs
mailing list