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]);
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;
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),
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);
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;
}
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);
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);
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);
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);
} 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) {
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:
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)
mas_wmb_replace(mas, parent.enode);
mtree_range_walk(mas);
+ mt_dump(mas->tree, mt_dump_dec);
}
/*
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);