]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
maple_tree: Rewrite mas_next_node to be less complex.
authorLiam R. Howlett <Liam.Howlett@Oracle.com>
Wed, 9 Sep 2020 19:40:57 +0000 (15:40 -0400)
committerLiam R. Howlett <Liam.Howlett@Oracle.com>
Fri, 30 Oct 2020 19:11:31 +0000 (15:11 -0400)
Remove double while (1) loop, pull in parent slot lookup.

Signed-off-by: Liam R. Howlett <Liam.Howlett@Oracle.com>
lib/maple_tree.c

index ff4fc500c640d1abd8d85be111904d5342d728ff..8647337a66df3f6fdabe93652b654d9c29bd6274 100644 (file)
@@ -1818,8 +1818,6 @@ static inline bool mast_cousin_rebalance_right(struct maple_subtree_state *mast)
        MA_STATE(tmp, mast->orig_r->tree, mast->orig_r->index, mast->orig_r->last);
 
        mas_dup_state(&tmp, mast->orig_r);
-       mas_set_offset(mast->orig_r,
-                    mte_parent_slot(mast->orig_r->node));
        mas_next_node(mast->orig_r, ULONG_MAX);
        if (!mas_is_none(mast->orig_r)) {
                mast_rebalance_next(mast, old_r);
@@ -3239,76 +3237,57 @@ no_entry:
 static inline unsigned long mas_next_node(struct ma_state *mas,
                unsigned long max)
 {
-       int level;
-       unsigned long start_piv;
+       unsigned long start_piv, prev_piv, pivot;
+       int offset, level = 0;
+       enum maple_type mt;
+       void **slots;
 
 restart_next_node:
        level = 0;
-       while (1) {
-               int offset;
-               struct maple_enode *mn;
-               unsigned long prev_piv;
-               enum maple_type mt;
-               void **slots;
-
-               if (mte_is_root(mas->node) || mas->node == MAS_NONE)
+       while (!mas_is_none(mas)) {
+               if (mte_is_root(mas->node))
                        goto no_entry;
 
-               mn = mas->node;
-               offset= mas_offset(mas);
-               start_piv = mas_safe_pivot(mas, offset);
-               level++;
+               offset = mte_parent_slot(mas->node);
                mas_ascend(mas);
-
+               start_piv = mas_safe_pivot(mas, offset);
                if (mas_dead_node(mas, start_piv))
                        goto restart_next_node;
 
+               level++;
                mt = mte_node_type(mas->node);
                slots = ma_get_slots(mas_mn(mas), mt);
                prev_piv = mas_safe_pivot(mas, offset);
-               while (++offset< mt_slots[mt]) {
-                       unsigned long pivot = mas_safe_pivot(mas, offset);
-
-                       if (prev_piv > max)
-                               goto no_entry;
-
-                       if (!pivot && offset)
-                               break;
-
-                       mn = rcu_dereference(slots[offset]);
-                       if (!mn) {
-                               prev_piv = pivot;
-                               continue;
-                       }
+               if (prev_piv > max)
+                       goto no_entry;
 
-                       mas->min = prev_piv + 1;
-                       mas->max = pivot;
+               if (prev_piv == mas->max) // last in node.
+                       continue;
 
-                       if (level == 1) {
-                               mas_set_offset(mas, offset);
-                               mas->node = mn;
-                               if (mas_dead_node(mas, start_piv))
-                                       goto restart_next_node;
+               if (++offset >= mt_slots[mt])
+                       continue;
 
-                               return pivot;
-                       }
+               pivot = mas_safe_pivot(mas, offset);
 
+               // Descend, if necessary.
+               while (level > 1) {
                        level--;
-                       mas->node = mn;
-                       offset = -1;
+                       mas->node = rcu_dereference(slots[offset]);
                        mt = mte_node_type(mas->node);
                        slots = ma_get_slots(mas_mn(mas), mt);
+                       offset = 0;
+                       pivot = mas_safe_pivot(mas, offset);
                }
 
-               if (mte_is_root(mas->node))
-                       goto no_entry;
-               mas_set_offset(mas, mte_parent_slot(mas->node));
+               mas->node = rcu_dereference(slots[offset]);
+               mas->min = prev_piv + 1;
+               mas->max = pivot;
+               return mas->max;
        }
 
 no_entry:
        mas->node = MAS_NONE;
        return mas->max;
-
 }
 
 /*
@@ -3459,7 +3438,6 @@ retry:
        *range_start = mas->last + 1;
 
        while (!mas_is_none(mas)) {
-               unsigned char p_slot = 0;
                struct maple_enode *last_node = mas->node;
 
                slot = mas_offset(mas);
@@ -3483,8 +3461,6 @@ retry:
                }
 
 next_node:
-               p_slot = mte_parent_slot(mas->node);
-               mas_set_offset(mas, p_slot);
                mas_next_node(mas, limit);
                mas_set_offset(mas, 0);
        }
@@ -5175,7 +5151,6 @@ static inline void mas_dfs_postorder(struct ma_state *mas, unsigned long max)
        struct maple_enode *p = MAS_NONE, *mn = mas->node;
        unsigned long p_min, p_max;
 
-       mas_set_offset(mas, mte_parent_slot(mas->node));
        mas_next_node(mas, max);
        if (!mas_is_none(mas))
                return;