]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
maple_tree: More efficient rev_awalk and mas_next()
authorLiam R. Howlett <Liam.Howlett@Oracle.com>
Mon, 16 Nov 2020 19:42:02 +0000 (14:42 -0500)
committerLiam R. Howlett <Liam.Howlett@Oracle.com>
Mon, 16 Nov 2020 19:42:02 +0000 (14:42 -0500)
Signed-off-by: Liam R. Howlett <Liam.Howlett@Oracle.com>
lib/maple_tree.c

index 02113349de6e6081e18d6e8125ff757d3b8b7cd4..02505ede97db08c2d06955b8521435300abc8c68 100644 (file)
@@ -3721,17 +3721,17 @@ static inline void *__mas_next(struct ma_state *mas, unsigned long limit,
        void *entry = NULL;
        struct maple_enode *prev_node;
        unsigned long index = mas->index;
+       enum maple_type mt = mte_node_type(mas->node);
 
        mas->offset++;
 retry:
        *range_start = mas->last + 1;
 
        while (!mas_is_none(mas)) {
-
-               if (mas->offset >= mt_slot_count(mas->node))
+               if (mas->offset >= mt_slots[mt])
                        goto next_node;
 
-               if (!mte_is_leaf(mas->node) || !mas->offset) {
+               if (!ma_is_leaf(mt) || !mas->offset) {
                        prev_node = mas->node;
                        *range_start = mas_first_entry(mas, limit);
                        if (mas_is_none(mas)) {
@@ -3749,6 +3749,7 @@ retry:
 next_node:
                mas_next_node(mas, limit);
                mas->offset = 0;
+               mt = mte_node_type(mas->node);
        }
 
        if (mas_is_none(mas))
@@ -3826,13 +3827,11 @@ EXPORT_SYMBOL_GPL(mas_prev);
 
 bool _mas_rev_awalk(struct ma_state *mas, unsigned long size)
 {
-       struct maple_node *node = mas_mn(mas);
        enum maple_type type = mte_node_type(mas->node);
+       struct maple_node *node = mas_mn(mas);
        unsigned long *pivots, *gaps;
        void **slots;
-       unsigned char offset = mas->offset;
-       unsigned long max;
-       unsigned long gap, min;
+       unsigned long gap, max, min;
 
        if (ma_is_dense(type)) { // dense nodes.
                mas->offset = (unsigned char)(mas->index - mas->min);
@@ -3844,10 +3843,10 @@ bool _mas_rev_awalk(struct ma_state *mas, unsigned long size)
        if (!ma_is_leaf(type))
                gaps = ma_gaps(node, type);
 
-       min = _mas_safe_pivot(mas, pivots, offset, type) + 1;
+       min = _mas_safe_pivot(mas, pivots, mas->offset, type) + 1;
        do {
                max = min - 1;
-               min = mas_safe_min(mas, pivots, offset);
+               min = mas_safe_min(mas, pivots, mas->offset);
                if (mas->last < min)
                        continue;
 
@@ -3857,8 +3856,8 @@ bool _mas_rev_awalk(struct ma_state *mas, unsigned long size)
                }
 
                if (!ma_is_leaf(type))
-                       gap = gaps[offset];
-               else if (mas_slot(mas, slots, offset))
+                       gap = gaps[mas->offset];
+               else if (mas_slot(mas, slots, mas->offset))
                        continue; // no gap in leaf.
                else
                        gap = max - min + 1;
@@ -3872,19 +3871,18 @@ bool _mas_rev_awalk(struct ma_state *mas, unsigned long size)
                if (ma_is_leaf(type)) {
                        mas->min = min;
                        mas->max = min + gap - 1;
-                       mas->offset = offset;
                        return true;
                }
                break;
-       } while (offset--);
+       } while (mas->offset--);
 
-       if (offset >= mt_slots[type]) {  // Overflow, node exhausted.
-               offset = 0;
+       if (mas->offset >= mt_slots[type]) {  // Overflow, node exhausted.
+               mas->offset = 0;
                goto ascend;
        }
 
        //descend
-       mas->node = mas_slot(mas, slots, offset);
+       mas->node = mas_slot(mas, slots, mas->offset);
        mas->min = min;
        mas->max = max;
        mas->offset = mas_data_end(mas);
@@ -3894,7 +3892,6 @@ ascend:
        if (mte_is_root(mas->node))
                mas_set_err(mas, -EBUSY);
 
-       mas->offset = offset;
        return false;
 }