]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
maple_tree: wip, rework of split and such
authorLiam R. Howlett <Liam.Howlett@Oracle.com>
Thu, 19 Dec 2019 15:56:33 +0000 (10:56 -0500)
committerLiam R. Howlett <Liam.Howlett@Oracle.com>
Fri, 30 Oct 2020 18:56:51 +0000 (14:56 -0400)
Signed-off-by: Liam R. Howlett <Liam.Howlett@Oracle.com>
lib/maple_tree.c
lib/test_maple_tree.c

index d5d84238040fd279a9c45e550cdd445980b40dff..8053dc9cfb28f92ce7eb894be34c164093567374 100644 (file)
@@ -1076,13 +1076,11 @@ static inline unsigned char mas_data_end(const struct ma_state *mas,
                entry = _mte_get_rcu_slot(mn, slot, type);
                if (mt_will_coalesce(entry)) {
                        if (piv == prev_piv) {
-                               printk("will coalesce %d\n", slot);
                                (*coalesce)++;
                        }
                        //counted_null = true;
                } else if (!entry) {
                        if (counted_null) {
-                               printk("has value\n");
                                (*coalesce)++;
                        }
                        counted_null = true;
@@ -1135,8 +1133,9 @@ static inline unsigned char mas_no_dense_split(struct ma_state *mas,
        enum maple_type mas_type = mte_node_type(mas->node);
        unsigned char ret = 0, half = mt_slots[mas_type] / 2;
        unsigned char src_slot = 0, slot = 0;
-       unsigned long piv, prev_piv = mas->min, written_piv = mas->min;
+       unsigned long piv = 0, prev_piv = mas->min, written_piv = mas->min;
        bool attempt_insert = false;
+       bool appending = false;
 
        MA_STATE(cp, mas->tree, mas->index, mas->last);
 
@@ -1146,34 +1145,35 @@ static inline unsigned char mas_no_dense_split(struct ma_state *mas,
        if (ma_is_leaf(mas_type))
                attempt_insert = true;
 
-       printk("%s %u\n", __func__, half);
        mas_dup_state(&cp, left);
        do {
                void *existing = NULL;
 
-               piv = mas_get_safe_pivot(mas, src_slot);
-               existing = mte_get_rcu_slot(mas->node, src_slot);
-               printk("%p[%u] (%lu)\n", mas_mn(mas), src_slot, piv);
+               if (entry_cnt <= 0) {
+                       appending = true;
+                       existing = NULL;
+               } else {
+                       piv = mas_get_safe_pivot(mas, src_slot);
+                       existing = mte_get_rcu_slot(mas->node, src_slot);
+               }
 
 
-               if (mt_will_coalesce(existing)) {
-                       printk("coalesce\n");
-                       goto skip_src_slot;
-               }
+               if (!appending) {
+                       if (mt_will_coalesce(existing)) {
+                               goto skip_src_slot;
+                       }
 
-               if (prev_piv > piv) {// insert overwrote this pivot.
-                       printk("prev_piv > piv\n");
-                       goto skip_src_slot;
-               }
+                       if (prev_piv > piv) {// insert overwrote this pivot.
+                               goto skip_src_slot;
+                       }
 
-               if (src_slot && piv == prev_piv) {
-                       printk("piv == prev_piv..\n");
-                       goto skip_src_slot;
+                       if (src_slot && piv == prev_piv) {
+                               goto skip_src_slot;
+                       }
                }
 
                // Insert happens in leaf
                if (attempt_insert && (cp.index <= piv)) {
-                       printk("%lu %lu\n", prev_piv, piv);
                        if (written_piv != cp.index - 1) {
                                // Insert a previous entry..
                                mte_set_rcu_slot(cp.node, slot, existing);
@@ -1181,11 +1181,10 @@ static inline unsigned char mas_no_dense_split(struct ma_state *mas,
                                slot++;
                        }
 
-                       printk("inserting new data at %p[%u]\n", cp.node, slot);
                        mte_set_rcu_slot(cp.node, slot, entry);
                        mte_set_pivot(cp.node, slot, cp.last);
                        slot++;
-                       if (piv > cp.last) {
+                       if (!appending && (piv > cp.last)) {
                                mte_set_rcu_slot(cp.node, slot, existing);
                                mte_set_pivot(cp.node, slot, piv);
                        } else
@@ -1193,7 +1192,6 @@ static inline unsigned char mas_no_dense_split(struct ma_state *mas,
 
                        attempt_insert = false;
                } else {
-                       printk("Copy %u -> %p[%u]\n", src_slot, mas_mn(&cp), slot);
                        mte_set_pivot(cp.node, slot, piv);
                        if (mas_type == maple_arange_64)
                                mte_cp_gap(cp.node, slot, mas->node, src_slot);
@@ -1204,9 +1202,7 @@ static inline unsigned char mas_no_dense_split(struct ma_state *mas,
                if ((slot >= half) && (cp.node != right->node)) {
                        ret = slot;
                        left->max = piv;
-                       printk("Set %p max %lu\n", mas_mn(left), piv);
                        right->min = piv + 1;
-                       printk("Switch dst %d\n", entry_cnt);
                        mas_dup_state(&cp, right);
                        slot = 0;
                } else {
@@ -1643,7 +1639,6 @@ static inline int mas_split_data(struct ma_state *mas, struct maple_enode *left,
 
        MA_CP(cp, mas->node, left, 0, split);
 
-       printk("cp %p[0-%u] to %p\n", mas_mn(mas), split, mte_to_node(left));
        mas_copy(mas, &cp);
        cp.src_start = split + 1;
 
@@ -1817,6 +1812,8 @@ static inline int mas_split(struct ma_state *mas, unsigned char slot,
        MA_STATE(left, mas->tree, mas->index, mas->last);
        MA_STATE(right , mas->tree, mas->index, mas->last);
 
+       printk("%s: %p\n", __func__, mas_mn(mas));
+       //mt_dump(mas->tree);
        if (mte_is_root(mas->node)) {
                old_parent = full;
                if (mt_is_alloc(mas->tree))
@@ -1824,21 +1821,18 @@ static inline int mas_split(struct ma_state *mas, unsigned char slot,
                else
                        ptype = maple_range_64;
                p_slot = 0;
-               printk("root\n");
        } else {
                unsigned long last_pivot;
                unsigned char coalesce;
 
                p_slot = mte_parent_slot(mas->node);
                mas_dup_state(&parent, mas);
-               printk("parent slot %u\n", p_slot);
                mas_encoded_parent(&parent);
                old_parent = parent.node;
 
                ptype = mte_node_type(parent.node);
                p_end = mas_data_end(&parent, ptype, &last_pivot, &coalesce);
                if (p_end - coalesce >= mt_slots[ptype] - 1) {
-                       printk("Split the parent\n");
                        /* Must split the parent */
                        split = mas_split(&parent, p_slot, active,
                                        p_end - coalesce + 1, entry);
@@ -1869,8 +1863,6 @@ static inline int mas_split(struct ma_state *mas, unsigned char slot,
        // split the data into left & right and do the insert.
        split = mas_do_split(mas, &left, &right, entry_cnt, entry);
 
-       // KEEP REWRITING THIS DOWN WITH left/right/parent states.
-       //
        // Copy the parents information
        if (!mte_is_root(full)) {
                MA_CP(cp, old_parent, new_parent, 0, p_slot - 1);
@@ -1889,7 +1881,6 @@ static inline int mas_split(struct ma_state *mas, unsigned char slot,
                        cp.src_start = p_slot + 1;
                        cp.src_end = p_end;
                        cp.dst_start += skip;
-                       printk("Copy anything larger than %lu\n", right.max);
                        _mas_copy(&parent, &cp, right.max);
                }
        }
@@ -1900,19 +1891,7 @@ static inline int mas_split(struct ma_state *mas, unsigned char slot,
        if (right.node)
                mte_link(right.node, new_parent, p_slot + 1,
                                right.max, ptype);
-#if 0
-       if (mt_is_alloc(mas->tree)) {
-               if (right->node) {
-                       unsigned long min = mas->min;
 
-                       mas->node = right;
-                       mas_gap_link(mas, new_parent, p_slot + 1, mas->max);
-                       mas->min = min;
-               }
-               mas->node = left;
-               mas_gap_link(mas, new_parent, p_slot, left.max);
-       }
-#endif
        // Copy grand parent to the parent, including slot encoding.
        mte_to_node(new_parent)->parent = mte_to_node(old_parent)->parent;
        // Update encoded slots in children
@@ -1936,14 +1915,6 @@ static inline int mas_split(struct ma_state *mas, unsigned char slot,
                p_slot += 2;
        }
 
-       // If we are going to insert into the parent..?
-       if (mas->index > mt_node_max(mas->node) &&
-               mas->index > mt_node_max(mas->node) + mas->min) {
-               // FIXME: Do the insert
-               mas->node = new_parent;
-               split = p_slot;
-       }
-
        // Free the full node.
        if (old_parent != full) {
                if (!active)
@@ -2060,17 +2031,14 @@ static inline int _mas_add_slot_cnt(struct ma_state *mas,
        end = mas_data_end(mas, mte_node_type(mas->node), &last_piv, &coalesce);
        req_slots = end - coalesce + 1;
 
-       printk("Start with %d, req_slots %d %lu\n", end, req_slots, last_piv);
        if (max == mas->max && min == mas->min)
                return req_slots;  // overwriting a single entry.
 
        if (min < mas->index) {
-               printk("min inc\n");
                req_slots++;  //slot needed at start.
        }
 
        if (max > mas->last) {
-               printk("max inc\n");
                req_slots++; // slot needed at end.
        }else {
                unsigned char end_slot = end;
@@ -2080,7 +2048,6 @@ static inline int _mas_add_slot_cnt(struct ma_state *mas,
                                break;
                        end_slot--;
                }
-               printk("Can go down slots?\n");
                req_slots -= (end_slot - slot);
        }
 
@@ -2189,27 +2156,18 @@ static inline int _mas_add(struct ma_state *mas, void *entry, bool overwrite,
 
        /* Check for splitting */
        new_end = _mas_add_slot_cnt(mas, slot, min, max);
-       printk("into %p old_end %u new %u %u\n", mas_mn(mas), old_end, new_end, slot);
        if (mas->index > min)
                null_entry = true;
 
        if (new_end > slot_cnt) {
                /* Not enough space in the node */
-               printk("Split %u > %u, %lu %lu\n", new_end, slot_cnt, mas->min, mas->max);
                unsigned char split = mas_split(mas, slot, active, new_end,
                                entry);
 
                if (mas_is_err(mas))
                        return 0;
 
-               if (mte_is_leaf(mas->node))
-                       return old_end - new_end;
-
-               if (split <= slot)
-                       slot = slot - split;
-
-               mas_set_slot(mas, slot);
-               return _mas_add(mas, entry, overwrite, active);
+               return old_end - new_end;
        }
 
        prev_enode = mas->node;
@@ -2220,7 +2178,6 @@ static inline int _mas_add(struct ma_state *mas, void *entry, bool overwrite,
                enum maple_type mt;
                unsigned char child_slot = 0;
 
-               printk("not a leaf\n");
                // Create a new node.
                mas_node_cnt(mas, 1);
                if (mas_is_err(mas))
@@ -2235,7 +2192,6 @@ static inline int _mas_add(struct ma_state *mas, void *entry, bool overwrite,
                leaf_state.node = leaf;
                leaf_state.min = mas->index;
                leaf_state.max = max;
-               printk("leaf %lu %lu\n", mas->index, max);
                if (null_entry)
                        child_slot = 1;
                mas_set_slot(&leaf_state, child_slot);
@@ -2285,7 +2241,6 @@ static inline int _mas_add(struct ma_state *mas, void *entry, bool overwrite,
                slot += 2;
        } else {
                if (overwrite && slot) {
-                       printk("Setting %p[%u] %lu\n", mas_mn(mas), slot - 1, mas->index-1);
                        mte_set_pivot(mas->node, slot-1, mas->index - 1);
                }
 
@@ -2854,7 +2809,7 @@ void *mas_range_load(struct ma_state *mas, unsigned long *range_min,
  * _mas_next() - Finds the next entry, sets index to the start of the range.
  *
  */
-static inline void *_mas_next(struct ma_state *mas, unsigned long max,
+static inline void *_mas_next(struct ma_state *mas, unsigned long limit,
                unsigned long *range_start)
 {
        void *entry = NULL;
@@ -2863,13 +2818,16 @@ static inline void *_mas_next(struct ma_state *mas, unsigned long max,
        if (mas->node && !mas_searchable(mas))
                return NULL;
 
-       if (!mas->node || mas_is_start(mas)) // First run.
+       if (!mas->node || mas_is_start(mas)) {// First run.
+               *range_start = 0;
+               mas_start(mas);
                entry = mas_range_load(mas, range_start, &range_max);
+       }
 
        if (entry)
                return entry;
 
-       return __mas_next(mas, max, range_start);
+       return __mas_next(mas, limit, range_start);
 }
 
 /*
@@ -3044,7 +3002,6 @@ static inline int mas_rebalance(struct ma_state *mas, unsigned char end,
        MA_CP(cp, this_enode, NULL, 0, end);
 
        l_slot_cnt = ma_hard_data(end, coalesce);
-       printk("l_slot_cnt %u %u %u\n", end, coalesce, l_slot_cnt);
        if (mte_is_root(this_enode))
                return mas_coalesce_node(mas, end, coalesce, true);
 
@@ -3064,7 +3021,6 @@ static inline int mas_rebalance(struct ma_state *mas, unsigned char end,
                        mas_descend(&p_state);
                        end = mas_data_end(&p_state,
                                mte_node_type(p_state.node), &l_piv, &coalesce);
-                       printk("%p end %u\n", mas_mn(&p_state), end);
                        return mas_rebalance(&p_state, end, coalesce);
                }
                // No left or right, rebalance the parent.
@@ -3087,10 +3043,8 @@ static inline int mas_rebalance(struct ma_state *mas, unsigned char end,
        mas_descend(&r_state);
        r_enode = r_state.node;
 
-       printk("Using right %p\n", mas_mn(&r_state));
        r_end = mas_data_end(&r_state, mte_node_type(r_enode), &l_piv, &r_coalesce);
        r_slot_cnt = ma_hard_data(r_end, r_coalesce);
-       printk("r_end %u %u\n", r_end, r_slot_cnt);
        if (r_end < r_coalesce) {
                // This node needs to be a skip entry.
                all_slots = l_slot_cnt;
@@ -3100,40 +3054,30 @@ static inline int mas_rebalance(struct ma_state *mas, unsigned char end,
        }
        // Add 1 for each slot 0.
        all_slots = r_slot_cnt + 2 + l_slot_cnt;
-       printk("Total slot count %u\n", all_slots);
-       printk("Using right %p\n", mas_mn(&r_state));
 
        node_cnt = 1;
        if (all_slots > mt_slot_count(this_enode) - 1)
                node_cnt++;
 
-       printk("Total slot count %u nodes %u\n", all_slots, node_cnt);
        mas_node_cnt(mas, node_cnt);
        if (mas_is_err(mas))
                return 0;
 
        // Coalesce this_enode into a new node.
        cp.dst_end = l_slot_cnt;
-       printk("copy from %p[%u-%u] to %p[%u-%u]\n", cp.src, cp.src_start, cp.src_end,
-                       cp.dst, cp.dst_start, cp.dst_end);
        mas_copy(mas, &cp); // cp.dst now has coalesced this_enode.
-       printk("dst_start = %u src_start %u\n", cp.dst_start, cp.src_start);
 
        // check if left ends in NULL, right start in NULL..
-       printk("Check %p[%u] %p\n", cp.dst, cp.dst_start - 1, mte_get_rcu_slot(cp.dst, cp.dst_start - 1));
        if (!mte_get_rcu_slot(cp.dst, cp.dst_start - 1))
                l_null_end = true;
 
-       printk("Check %p[%u] %p\n", r_enode, 0, mte_get_rcu_slot(r_enode, 0));
        if (mt_will_coalesce(mte_get_rcu_slot(r_enode, 0)) ||
                         !mte_get_rcu_slot(r_enode, 0))
                r_null_start = true;
 
        if (l_null_end && r_null_start)
        {
-               printk("r_enode %p[0] = %p\n", mas_mn(&r_state), mte_get_rcu_slot(r_enode, 0));
                all_slots--;
-               // Can remove a lost.
        } else if (!l_null_end && !r_null_start) {
                // Need an null if the pivots don't line up here.
                mte_set_pivot(cp.dst, cp.dst_start++, r_state.min);
@@ -3149,9 +3093,6 @@ static inline int mas_rebalance(struct ma_state *mas, unsigned char end,
        else
                cp.dst_end = (all_slots + 1)/ 2; // Take 1/2 the entries.
 
-       printk("copy from %p[%u-%u] to %p[%u-%u]\n", cp.src, cp.src_start, cp.src_end,
-                       cp.dst, cp.dst_start, cp.dst_end);
-
        mas_copy(&r_state, &cp); // cp.dst is now complete, place it in the tree.
        mte_to_node(cp.dst)->parent = mte_to_node(this_enode)->parent;
        new_type = mte_node_type(cp.dst);
@@ -3767,6 +3708,7 @@ skip_entry:
                mas_set_slot(mas, 0);
        }
 done:
+       printk("Set min %lu\n", min);
        mas_set_slot(mas, i);
        *range_max = max;
        *range_min = min;
@@ -3839,6 +3781,9 @@ static inline int mas_dead_node(struct ma_state *mas, unsigned long index)
 static inline bool mas_search_cont(struct ma_state *mas, unsigned long index,
                unsigned long max, void *entry)
 {
+       if (mas_is_start(mas))
+               return true;
+
        if (index >= max)
                return false;
 
@@ -3950,114 +3895,94 @@ void *mt_find(struct maple_tree *mt, unsigned long *index, unsigned long max,
 EXPORT_SYMBOL(mt_find);
 
 static inline void ma_inactive_insert(struct ma_state *mas, void *entry);
+
+
+/* Private
+ * mas_replace_tree() - Build a new tree and replace the entire structure.
+ *
+ */
 static inline int mas_replace_tree(struct ma_state *mas, void *new_entry)
 {
-       long l_node_cnt = 0, r_node_cnt = 0;
-       unsigned int r_slot_cnt = 0, slot_cnt = 0;
-       long node_cnt = 0, nodes = 0;
        void *entry;
-       struct maple_enode *r_node = NULL, *last = NULL;
-       unsigned char r_slot = 0, slot;
+       unsigned long piv;
+       unsigned char coalesce;
+       unsigned int slot_cnt = 0;
+       long node_cnt = 0, leaves= 0;
+       struct maple_enode *last = NULL;
+       enum maple_type p_type = mas_parent_enum(mas, mas->node);
 
        // Create a new tree.
        DEFINE_MTREE(new_tree);
        MA_STATE(new_mas, &new_tree, 0, 0);
+       MA_STATE(r_mas, mas->tree, mas->last + 1, mas->last + 1);
+       MA_STATE(l_mas, mas->tree, 0, 0);
 
+       // Count the slots that will be used in the node we landed.
+       slot_cnt = 3 + mas_get_slot(mas); // 3 is the max a new entry can create.
 
-       MA_STATE(r_mas, mas->tree, mas->last + 1, mas->last + 1);
-       slot_cnt = 1 + mas_get_slot(mas);
+       // Count the nodes that are currently used to the left. 
        mas_set_slot(mas, mte_parent_slot(mas->node));
-       while (mas->node != MAS_NONE) {
+       while (!mas_is_none(mas)) {
                last = mas->node;
                mas_prev_node(mas, 0);
-               l_node_cnt++;
+               leaves++;
        }
-
+       // Set mas->node to a valid node.
        mas->node = last;
-       _mas_walk(&r_mas);
-       if (mas_get_slot(&r_mas) != MAPLE_NODE_SLOTS) {
-               unsigned long piv;
-               unsigned char coalesce;
 
-               r_slot_cnt += mas_data_end(&r_mas, mte_node_type(r_mas.node),
-                               &piv, &coalesce);
-               if (piv != ULONG_MAX) {
-                       unsigned char p_slot = mte_parent_slot(r_mas.node);
-
-                       r_node = r_mas.node;
-                       r_slot = mas_get_slot(&r_mas);
-                       r_slot_cnt -= r_slot;
-                       slot_cnt += r_slot_cnt;
-                       mas_set_slot(&r_mas, p_slot);
-                       while (r_mas.node != MAS_NONE) {
-                               last = r_mas.node;
-                               mas_next_node(&r_mas, ULONG_MAX);
-                               r_node_cnt++;
-                       }
-                       r_mas.node = last;
-               }
-               if (r_mas.max < mas->last)
-                       slot_cnt++;
+       // Walk down to the right side of the tree.
+       _mas_walk(&r_mas);
+       // Add the slots to the right of where the search landed.
+       if (mas_get_slot(&r_mas) == MAPLE_NODE_SLOTS) {
+               r_mas.node = MAS_NONE;
+               goto skip_r_count;
+       }
+       slot_cnt -= mas_get_slot(&r_mas);
+       slot_cnt += mas_data_end(&r_mas, mte_node_type(r_mas.node), &piv,
+                       &coalesce);
+
+       // Count the nodes to the right.
+       mas_set_slot(&r_mas, mte_parent_slot(r_mas.node));
+       while (!mas_is_none(&r_mas)) {
+               last = r_mas.node;
+               mas_next_node(&r_mas, ULONG_MAX);
+               leaves++;
        }
+       r_mas.node = last;
 
+skip_r_count:
+       // Calculate all the nodes needed for a new tree.
        if (slot_cnt > mt_slot_count(mas->node))
-               nodes++;
+               leaves++;
 
-       nodes = l_node_cnt + r_node_cnt + 2;
        node_cnt = 1; // Root node.
-       while (nodes) {
-               node_cnt += nodes;
-               nodes /= 4;
+       while (leaves) { // add the number of nodes at each level.
+               node_cnt += leaves;
+               leaves /= mt_slots[p_type];
        }
 
-
-       // FIXME: When splitting & reusing we need an extra node.
-       mas_node_cnt(mas, node_cnt + 1);
+       mas_node_cnt(mas, node_cnt);
        if (mas_is_err(mas))
                return 0;
 
+       /* Move allocations from mas to new_mas.
+        * NOTE: This is necessary as mas will pass back errors and will retry
+        * the allocation, so it has to be done in mas and has to be moved for
+        * below.
+        */
        new_mas.alloc = mas->alloc;
        mas->alloc = NULL;
 
        // Copy left side
-       mas_set_slot(mas, 0);
-       new_mas.last = mas_first_entry(mas, mas->index);
-       slot = mas_get_slot(mas);
-       do {
-               new_mas.index = mas->min;
-               new_mas.last = mas->min;
-               while (slot < mt_slot_count(mas->node)) {
-                       if (new_mas.index == mas->index) {
-                               break;
-                       }
-                       new_mas.last = mas_get_safe_pivot(mas, slot);
-                       if (!new_mas.last && slot)
-                               break;
-
-                       if (new_mas.last > mas->index)
-                               new_mas.last = mas->index - 1;
-
-                       entry = mte_get_rcu_slot(mas->node, slot);
-                       if (entry) {
-                               int cnt = mas_get_alloc_cnt(&new_mas);
-                               ma_inactive_insert(&new_mas, entry);
-                               if (mas_is_err(&new_mas))
-                                       BUG_ON(1);
-                               if (cnt < mas_get_alloc_cnt(&new_mas) - 1)
-                                       BUG_ON(1);
-                       }
-
-                       if (new_mas.last == mas->index)
-                               break;
-
-                       new_mas.index = new_mas.last + 1;
-
-                       slot++;
-               }
-               mas_set_slot(mas, mte_parent_slot(mas->node));
-               mas_next_node(mas, mas->index);
-               slot = 0;
-       } while (!mas_is_none(mas) && mas->min < mas->index);
+       mas_for_each(&l_mas, entry, mas->index - 1) {
+               new_mas.index = l_mas.index;
+               new_mas.last = mas_get_safe_pivot(&l_mas, mas_get_slot(&l_mas));
+               printk("Insert %lu->%lu\n", new_mas.index, new_mas.last);
+               ma_inactive_insert(&new_mas, entry);
+               if (mas_is_err(&new_mas))
+                       BUG_ON(1);
+               mt_dump(new_mas.tree);
+       }
 
        // Insert the new value.
        new_mas.index = mas->index;
@@ -4074,47 +3999,29 @@ static inline int mas_replace_tree(struct ma_state *mas, void *new_entry)
         * - new_mas.last ends in a null
         * - new_mas.last has a sequentially next value (48)
         */
-       if (!r_node) // No entry beyond new_mas.last
+       if (mas_is_none(&r_mas)) // No entry beyond new_mas.last
                goto skip_right;
 
-       new_mas.index = new_mas.last + 1;
-       new_mas.last = mte_get_pivot(r_node, r_slot);
-
-       mas_set_slot(mas, r_slot);
-       mas->node = r_node;
-       mas->min = new_mas.index;
-       do {
-               new_mas.index = mas->min;
-               new_mas.last = mas->min;
-               slot = mas_get_slot(mas);
-               while (slot++ < mt_slot_count(mas->node)) {
-                       new_mas.last = mas_get_safe_pivot(mas, slot);
-                       if (!new_mas.last)
-                               break;
-
-                       entry = mte_get_rcu_slot(mas->node, slot);
-                       if (entry) {
-                               ma_inactive_insert(&new_mas, entry);
-                               if (mas_is_err(&new_mas))
-                                       BUG_ON(1);
-                       }
+       mas_for_each(&l_mas, entry, ULONG_MAX) {
+               if (l_mas.index < r_mas.index)
+                       continue;
 
-                       new_mas.index = new_mas.last + 1;
-               }
-               mas_next_node(mas, mas->index);
-               mas_set_slot(mas, 0);
-       } while (mas->node != MAS_NONE);
+               new_mas.index = l_mas.index;
+               new_mas.last = mas_get_safe_pivot(&l_mas, mas_get_slot(&l_mas));
+               ma_inactive_insert(&new_mas, entry);
+               if (mas_is_err(&new_mas))
+                       BUG_ON(1);
+       }
 
 skip_right:
 
-       r_node = mas->tree->ma_root;
+       last = mas->tree->ma_root;
        mas->node = new_tree.ma_root;
        _mas_replace(mas, false, false);
        mas->node = 0;
        mas->alloc = new_mas.alloc;
-       mte_destroy_walk(r_node);
+       mte_destroy_walk(last);
 
-       // Copy right side
        return node_cnt;
 }
 static inline bool mas_rewind_node(struct ma_state *mas);
index 6d63bce2228db155b15d788c88d2d5179d6bfb6f..d578bfe524f41634bccfd6e293095afee16260b0 100644 (file)
@@ -899,31 +899,31 @@ static noinline void check_erase2_testset(struct maple_tree *mt,
                case STORE:
                        printk("entry_cnt = %d\n", entry_cnt);
                        if ((s_min == e_min) && (s_max == e_max)) {
+                               printk("starts and ends in the same range\n");
                                if (!entry_cnt)
                                        entry_cnt++;
                                else if (!mt_is_empty(s_entry)) {
                                        if (e_max > mas_end.last)
                                                entry_cnt++;
-                                       else if (s_min < mas_start.index)
+                                       if (s_min < mas_start.index)
                                                entry_cnt++;
                                } else {
                                        entry_cnt++;
                                }
                        } else {
                                unsigned char cnt = 0;
-                               printk("%ld adn %ld\n", s_min, mas_start.index);
                                // check start
                                if (s_entry && (s_min <= mas_start.index))
                                        cnt++;
 
-                               printk("%ld and %ld\n", e_max, mas_end.last);
                                // check end
                                if (e_entry && (e_max >= mas_end.last))
                                        cnt++;
                                // count slots
+                               s_entry = mas_next(&mas_start,
+                                               set[i+2] - 1);
                                while (!mas_is_none(&mas_start) &&
-                                               (e_entry != s_entry))
-                               {
+                                      (mas_start.last != e_max) ) {
                                        if (s_entry) {
                                                printk("inc\n");
                                                cnt++;
@@ -935,9 +935,10 @@ static noinline void check_erase2_testset(struct maple_tree *mt,
                                entry_cnt = entry_cnt - cnt + 1;
                        }
 
+                       printk("Storing now\n");
                        erase_check_store_range(mt, set, i + 1,
                                        xa_mk_value(set[i+1]));
-                       printk("entry_cnt = %d\n", entry_cnt);
+                       printk("\nentry_cnt = %d\n", entry_cnt);
                        break;
                case ERASE:
                        check_erase(mt, set[i+1], xa_mk_value(set[i+1]));
@@ -967,7 +968,7 @@ static noinline void check_erase2_testset(struct maple_tree *mt,
                        if (check > entry_cnt)
                                break;
                }
-               printk("Check = %d\n", check);
+               printk("mas_for_each check = %d\n", check);
                mt_dump(mas.tree);
 
                MT_BUG_ON(mt, check != entry_cnt);