]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
rebalance wip
authorLiam R. Howlett <howlett@gmail.com>
Tue, 4 Feb 2025 18:05:35 +0000 (13:05 -0500)
committerLiam R. Howlett <howlett@gmail.com>
Tue, 4 Feb 2025 18:05:35 +0000 (13:05 -0500)
Signed-off-by: Liam R. Howlett <howlett@gmail.com>
lib/maple_tree.c

index 23f56d15a4a3d1e37036710342a91236f135d3c3..5f76c8bce6e244311ac317e478fe21fd6c9b2904 100644 (file)
@@ -3225,8 +3225,8 @@ static __always_inline
 void mns_insert_part(struct ma_node_part *part,
                struct ma_node_state *dst)
 {
-       //printk("insert pos %u/%u %u/%u\n", part->pos, part->size,
-         //     dst->offset, part->dst_max_off);
+       printk("insert pos %u/%u %u/%u\n", part->pos, part->size,
+              dst->offset, part->dst_max_off);
 
        while (dst->offset < mt_slots[dst->type]) {
                //printk("Store part %u into %u %p\n", part->pos, dst->offset, part->slots[part->pos]);
@@ -3240,30 +3240,30 @@ void mns_insert_part(struct ma_node_part *part,
 
                if (dst->offset < mt_pivots[dst->type])
                        dst->pivots[dst->offset] = part->pivots[part->pos];
-               //printk ("offset %lx\n", part->pivots[part->pos]);
+               printk ("offset %lx\n", part->pivots[part->pos]);
 
                dst->offset++;
                dst->max = part->pivots[part->pos];
-               //printk("Offset is %u, use max for pivot\n", dst->offset);
+               printk("Offset is %u, use max for pivot\n", dst->offset);
                part->pos++;
-               //printk("dst offset is %u\n", dst->offset);
+               printk("dst offset is %u\n", dst->offset);
                if (part->pos >= part->size) {
-                       //printk("pos >= size\n");
+                       printk("pos >= size\n");
                        part->unfinished = false;
                        return; /* Nothing to do */
                }
 
                if (dst->offset > part->dst_max_off) {
-                       //printk("push part to next node\n");
+                       printk("push part to next node\n");
                        /* push to next node */
                        part->unfinished = true;
                        return;
                }
-               //printk("dst offset is %u max is %u\n", dst->offset, part->dst_max_off);
+               printk("dst offset is %u max is %u\n", dst->offset, part->dst_max_off);
 
        }
 
-       //printk("OUT OF ROOM??\n");
+       printk("OUT OF ROOM??\n");
        /* Out of room.. */
        //WARN_ON_ONCE(1);
        part->unfinished = true;
@@ -3309,6 +3309,17 @@ static inline
 void mns_pmns_init(struct ma_node_state *mns, struct ma_node_state *pmns,
                unsigned char p_off, struct maple_tree *mt)
 {
+       if (p_off == pmns->end) {
+               mns->max = pmns->max;
+               mns->min = pmns->pivots[p_off - 1];
+       } else {
+               mns->max = pmns->pivots[p_off];
+               if (p_off)
+                       mns->min = pmns->pivots[p_off - 1];
+               else
+                       mns->min = pmns->min;
+       }
+
        mns->enode = mt_slot_locked(mt, pmns->slots, p_off);
        mns->insert = p_off;
        _mns_node_init(mns, mte_to_node(mns->enode),
@@ -3328,10 +3339,10 @@ void mns_cp(struct ma_node_state *src, struct ma_node_state *dst,
        unsigned long max;
        size_t size;
 
-       //printk("Cp %p %u-%u\n", dst->node, dst->offset, dst->offset + len - 1);
-       //printk("src %p %u-%u\n", src->node, src->offset, src->offset + len - 1);
+       printk("Cp %p %u-%u\n", dst->node, dst->offset, dst->offset + len - 1);
+       printk("src %p %u-%u\n", src->node, src->offset, src->offset + len - 1);
        size = len * sizeof(void *);
-       //printk("Copy %lu (%lu)\n", size, len);
+       printk("Copy %lu (%u)\n", size, len);
        memcpy(dst->slots + dst->offset, src->slots + src->offset, size);
 
        size = len * sizeof(unsigned long);
@@ -3341,18 +3352,18 @@ void mns_cp(struct ma_node_state *src, struct ma_node_state *dst,
        if (src->offset + len > mt_pivots[src->type]) {
                size = mt_pivots[src->type] - src->offset;
                max = src->max;
-               //printk("Avoid overflow, use max %lx\n", max);
+               printk("Avoid overflow, use max %lx\n", max);
        } else {
                size = len;
                max = src->pivots[src->offset + len - 1];
-               //printk("use max %lx\n", max);
+               printk("use max %lx from %p[%u]\n", max, src->node, src->offset + len - 1);
        }
 
        if (dst->offset + len > mt_pivots[dst->type]) {
                size = mt_pivots[dst->type] - dst->offset;
-               //printk("Avoid overflow, SET max %lx\n", max);
+               printk("Avoid overflow, SET max %lx\n", max);
        } else {
-               //printk("Set piv %u to %lx\n", dst->offset + len - 1, max);
+               printk("Set piv %u to %lx\n", dst->offset + len - 1, max);
                dst->pivots[dst->offset + len - 1] = max;
        }
 
@@ -3502,6 +3513,7 @@ static inline void mas_wr_converged(struct ma_node_state *src,
                struct ma_state *mas)
 {
        mns_node_init(dst, mas_pop_node(mas), src->type);
+       printk("%s: %p -> %p\n", __func__, src->node, dst->node);
 
        if (mas->offset)
                mns_cp(src, dst, mas->offset);
@@ -3674,21 +3686,26 @@ static void mas_wr_rebalance_nodes(
        l_end = l_src->end;
        r_end = r_src->end;
        if (left_store) { /* Store is targeting l_src */
+               printk("%s %d\n", __func__, __LINE__);
                if (mas_off <= split) { /* Store will end up in left */
+               printk("%s %d\n", __func__, __LINE__);
                        if (mas_off)
                                mns_cp(l_src, left, mas_off);
 
                        ma_part->dst_max_off = split;
                        mns_insert_part(ma_part, left);
                        l_src->offset+= ma_part->skip;
-                       //printk("%d\n", __LINE__);
+                       printk("%d\n", __LINE__);
 
+                       printk("\tright min %lu left max %lu\n", right->min, left->max);
                        if (left->offset <= split)
                                mns_cp(l_src, left, split - left->offset + 1);
 
+                       printk("\tright min %lu left max %lu\n", right->min, left->max);
                        mas_wr_split_no_null(l_src, left, right,
                                             r_end + new_end + 1, ma_part);
                        right->min = left->max + 1;
+                       printk("\tright min %lu left max %lu\n", right->min, left->max);
                        if (ma_part->unfinished)
                                mns_insert_part(ma_part, right);
 
@@ -3696,6 +3713,7 @@ static void mas_wr_rebalance_nodes(
                                mns_cp(l_src, right, l_end - l_src->offset + 1);
 
                } else { /* Store will end up in right */
+               printk("%s %d\n", __func__, __LINE__);
                        mns_cp(l_src, left, split + 1);
                        mas_wr_split_no_null(l_src, left, right,
                                             r_end + new_end + 1, ma_part);
@@ -3710,7 +3728,9 @@ static void mas_wr_rebalance_nodes(
 
                mns_cp(r_src, right, r_end + 1);
        } else { /* Store is targeting r_src */
+               printk("%s %d\n", __func__, __LINE__);
                if (split <= l_end) { /* Store will end up in right */
+               printk("%s %d\n", __func__, __LINE__);
                        mns_cp(l_src, left, split + 1);
                        mas_wr_split_no_null(l_src, left, right,
                                             l_end + new_end + 1, ma_part);
@@ -3727,6 +3747,7 @@ static void mas_wr_rebalance_nodes(
                } else  { /* Store will end up in left */
                        unsigned char r_split;
 
+               printk("%s %d\n", __func__, __LINE__);
                        r_split = split - l_end - 1;
                        mns_cp(l_src, left, l_end + 1);
                        if (mas_off <= r_split) {
@@ -3884,44 +3905,62 @@ static void mas_wr_rebalance(struct ma_wr_state *wr_mas)
        struct ma_node_state left, right;
        struct ma_node_part ma_part;
        unsigned char total, split, height;
+       unsigned char insert;
 
        trace_ma_op(__func__, mas);
+       mt_dump(mas->tree, mt_dump_dec);
        height = mas_mt_height(mas);
        mns_mas_init(&src, mas);
+       src.min = mas->min;
+       src.max = mas->max;
+       src.end = mas->end;
        mns_node_part_leaf_init(&ma_part, wr_mas, &src);
        /* Total will lack sibling data until the sibling is known */
+       printk("end %p %u\n", mas->node, mas->end);
        total = mas->end + ma_part.size - ma_part.skip - 1;
+       printk("%p will have %u in the end\n", mas->node, total);
+       printk("Skip %u\n", ma_part.skip);
+       // Skipping is causing a copy beyond the end of the src.
+
+       printk("Rebalance %p %lu-%lu", mas->node, mas->index, mas->last);
 
+       insert = mas->offset;
+       printk("Write to node at %u\n", insert);
        while (mas->depth) {
-               bool consume = false;
-               unsigned char data_size;
                bool l_store;
 
                mas_wr_ascend_init(mas, &parent);
+               printk("Ascend to parent %p\n", parent.node);
+               printk("offset of child is %u\n", mas->offset);
                mas->depth--;
                mns_set_end(&parent);
                parent.insert = mas->offset;
+               printk("parent insert is %u\n", parent.insert);
 
-               if (!parent.insert) {
-                       /* Pull data from l_src */
-                       mns_pmns_init(&l_src, &parent, mas->offset + 1, mas->tree);
-                       r_src = src;
-                       r_src.end = mas->end;
-                       r_src.insert = mas->offset;
-                       mns_set_end(&l_src);
-                       total += l_src.end;
-                       l_store = false;
-               } else {
+               if (parent.insert < parent.end) {
                        /* Pull data from r_src */
-                       mns_pmns_init(&r_src, &parent, mas->offset - 1, mas->tree);
+                       printk("Pull from right\n");
+                       mns_pmns_init(&r_src, &parent, mas->offset + 1, mas->tree);
                        mns_set_end(&r_src);
+                       printk("right is %p %lu-%lu\n", r_src.node, r_src.min, r_src.max);
                        l_src = src;
-                       l_src.end = mas->end;
-                       l_src.insert = mas->offset;
+                       l_src.insert = insert;
                        total += r_src.end;
                        l_store = true;
+               } else {
+                       /* Pull data from l_src */
+                       printk("Pull from left\n");
+                       mns_pmns_init(&l_src, &parent, mas->offset - 1, mas->tree);
+                       printk("left is %p\n", l_src.node);
+                       r_src = src;
+                       r_src.insert = insert;
+                       mns_set_end(&l_src);
+                       total += l_src.end;
+                       l_store = false;
+                       parent.insert--;
                }
 
+               printk("\tNew total will be %u\n", total);
                mns_node_init(&left, mas_pop_node(mas), l_src.type);
                /*
                 * Two possibilities:
@@ -3932,33 +3971,35 @@ static void mas_wr_rebalance(struct ma_wr_state *wr_mas)
                    ma_is_root(parent.node)) {
                        struct ma_node_state new_parent;
 
+                       printk("Rebalance\n");
                        /*
                         * Rebalance between nodes is possible, so the
                         * operation stops early.
                         */
 
                        mns_node_init(&right, mas_pop_node(mas), r_src.type);
+                       printk("new right will be %p\n", right.node);
                        split = mas_wr_rebalance_calc(total, l_src.type);
+                       printk("split is %u\n", split);
                        left.min = l_src.min;
                        mas_wr_rebalance_nodes(&l_src, &r_src, &left, &right,
                                               l_store, split, &ma_part,
-                                              mas->offset, total);
+                                              insert, total);
 
                        mns_finalise(&left);
                        mns_finalise(&right);
-                       mas_ascend(mas);
-                       mas->end = parent.end;
-                       mas->offset = parent.insert;
                        mns_node_part_init(&ma_part, &left, &right);
                        ma_part.skip = 2;
                        mas_wr_converged(&parent, &new_parent, &ma_part, mas);
                        src.enode = parent.enode;
                        mas->node = new_parent.enode;
                        mas->depth = height;
+                       printk("Height is %u\n", mas->depth);
                        break;
                }
 
 
+               printk("consume\n");
                /* Reduce two nodes into one */
                if (l_store) {
                        if (l_src.insert)
@@ -3997,6 +4038,7 @@ static void mas_wr_rebalance(struct ma_wr_state *wr_mas)
 
        mas_wmb_replace(mas, parent.enode);
        mtree_range_walk(mas);
+       mt_dump(mas->tree, mt_dump_dec);
 }
 
 /*
@@ -4792,7 +4834,7 @@ static inline void mas_wr_store_entry(struct ma_wr_state *wr_mas)
                mas_wr_split(wr_mas);
                break;
        case wr_rebalance:
-               mas_wr_bnode(wr_mas);
+               mas_wr_rebalance(wr_mas);
                break;
        case wr_exact_fit:
                rcu_assign_pointer(wr_mas->slots[mas->offset], wr_mas->entry);