rbtree: consider all parent's children versions when comparing self in next/prev
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Tue, 9 Mar 2010 23:31:47 +0000 (18:31 -0500)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Tue, 9 Mar 2010 23:31:47 +0000 (18:31 -0500)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
urcu-rbtree.c

index f834ef3e839b554190040946fd05b0cda64415b8..bd0f6a0303996360a44d4534e75b237c80d1861f 100644 (file)
@@ -105,20 +105,25 @@ struct rcu_rbtree_node *rcu_rbtree_next(struct rcu_rbtree_node *x,
        if ((xr = rcu_dereference(x->right)) != &rcu_rbtree_nil)
                return rcu_rbtree_min(xr, comp);
        y = rcu_dereference(x->p);
-       while ((yredir = rcu_dereference(y->redir)) != NULL)
-               y = yredir;
        for (;;) {
+               int found = 0;
                if (y == &rcu_rbtree_nil)
                        break;
                yr = rcu_dereference(y->right);
-               while ((yrredir = rcu_dereference(yr->redir)) != NULL)
-                       yr = yrredir;
-               if (x != yr)
+               /* Find out if x is one of the parent right children versions */
+               if (x == yr) {
+                       goto found;
+               } else {
+                       while ((yrredir = rcu_dereference(yr->redir)) != NULL) {
+                               yr = yrredir;
+                               if (x == yr)
+                                       goto found;
+                       }
                        break;
+               }
+found:
                x = y;
                y = rcu_dereference(y->p);
-               while ((yredir = rcu_dereference(y->redir)) != NULL)
-                       y = yredir;
        }
        return y;
 }
@@ -126,27 +131,32 @@ struct rcu_rbtree_node *rcu_rbtree_next(struct rcu_rbtree_node *x,
 struct rcu_rbtree_node *rcu_rbtree_prev(struct rcu_rbtree_node *x,
                                        rcu_rbtree_comp comp)
 {
-       struct rcu_rbtree_node *xl, *y, *yredir, *yl, *ylredir;;
+       struct rcu_rbtree_node *xl, *y, *yredir, *yl, *ylredir;
 
        x = rcu_dereference(x);
 
        if ((xl = rcu_dereference(x->left)) != &rcu_rbtree_nil)
-               return rcu_rbtree_max(xl, comp);
+               return rcu_rbtree_min(xl, comp);
        y = rcu_dereference(x->p);
-       while ((yredir = rcu_dereference(y->redir)) != NULL)
-               y = yredir;
        for (;;) {
+               int found = 0;
                if (y == &rcu_rbtree_nil)
                        break;
                yl = rcu_dereference(y->left);
-               while ((ylredir = rcu_dereference(yl->redir)) != NULL)
-                       yl = ylredir;
-               if (x != yl)
+               /* Find out if x is one of the parent left children versions */
+               if (x == yl) {
+                       goto found;
+               } else {
+                       while ((ylredir = rcu_dereference(yl->redir)) != NULL) {
+                               yl = ylredir;
+                               if (x == yl)
+                                       goto found;
+                       }
                        break;
+               }
+found:
                x = y;
                y = rcu_dereference(y->p);
-               while ((yredir = rcu_dereference(y->redir)) != NULL)
-                       y = yredir;
        }
        return y;
 }
This page took 0.026397 seconds and 4 git commands to generate.