index = mas->index;
+ printk("%s: index %lu\n", __func__, index);
if (unlikely(ma_is_dense(wr_mas->type))) {
wr_mas->r_max = wr_mas->r_min = index;
mas->offset = mas->index = mas->min;
}
wr_mas->node = mas_mn(mas);
+ printk("at node %p\n", wr_mas->node);
pivs = wr_mas->pivots = ma_pivots(wr_mas->node, wr_mas->type);
count = mas->end = ma_data_end(wr_mas->node, wr_mas->type,
pivs, mas->max);
offset = mas->offset;
+ printk("start offset is %u\n", offset);
if (index > pivs[count - 1]) {
wr_mas->r_max = mas->max;
wr_mas->offset_end = mas->offset = count;
while (index > pivs[offset])
offset++;
+ printk("end offset is %u\n", offset);
wr_mas->r_max = pivs[offset];
wr_mas->r_min = mas_safe_min(mas, pivs, offset);
wr_mas->offset_end = mas->offset = offset;
part->skip = wr_mas->offset_end - wr_mas->mas->offset + 1;
part->leaf = true;
+ printk("%s skip %u\n", __func__, part->skip);
}
static inline
unsigned char size;
unsigned char max_copy;
+ printk("src %p dst %p\n", src->node, dst->node);
/* Configure one state */
state = &sd->states[sd->len];
size = sd->space;
if (max_copy < size)
size = max_copy;
+ printk("\tstore part: %u %u %u\n", sd->len, part->pos, size);
state->part = part;
mns_mni_init(state, dst, part->pos, size);
state->use_part = true;
part->pos += size;
src->offset = sd->src_ins_end + 1;
+ printk("src offset is now %u\n", src->offset);
} else {
state->info = src;
if (max_copy < size)
size = max_copy;
+ printk("\tstore info: %u %u %u\n", sd->len, src->offset, size);
BUG_ON(size == 0);
mns_mni_init(state, dst, src->offset, size);
src->offset += size;
struct ma_node_info *src, struct ma_node_info *src2,
struct ma_node_part *part, struct split_data *sd)
{
+ printk("sd len is %u\n", sd->len);
sd->insert_end = sd->insert + part->size - 1;
if (!sd->left_store) {
left->min = src2->min;
sd->space = sd->new_end + 1;
sd->states[sd->len].info = src2;
/* The first state to copy is the left node */
+ printk("%d sd len is %u\n", __LINE__, sd->len);
mns_mni_init(&sd->states[sd->len], left, 0, src2->end + 1);
sd->len++;
} else {
} while (src->offset <= src->end);
if (sd->left_store) {
+ unsigned char len = src2->end + 1 - src2->offset;
+
sd->states[sd->len].info = src2;
- mns_mni_init(&sd->states[sd->len], left, 0, src2->end + 1);
+ printk("cp %u node %p offset %u-%u to left too\n", sd->len, src2->node, src2->offset, len);
+ mns_mni_init(&sd->states[sd->len], left, src2->offset, len);
sd->len++;
}
return;
}
+
/*
* mas_wr_spanning_store() - Create a subtree with the store operation completed
* and new nodes where necessary, then place the sub-tree in the actual tree.
* span.
* @wr_mas: The maple write state
*/
-static noinline void mas_wr_spanning_store(struct ma_wr_state *wr_mas)
+static noinline void __mas_wr_spanning_store(struct ma_wr_state *wr_mas)
{
struct maple_subtree_state mast;
struct maple_big_node b_node;
unsigned long last = wr_mas->mas->last;
unsigned long *pivs = wr_mas->pivots;
+ printk("last is %u\n", last);
if (last > pivs[wr_mas->mas->end - 1]) {
wr_mas->offset_end = wr_mas->mas->end;
wr_mas->end_piv = wr_mas->mas->max;
}
offset_end = wr_mas->offset_end;
+ printk("end offset is %u\n", offset_end);
+ printk("pivs at offset is %u\n", pivs[offset_end]);
while (last > pivs[offset_end])
offset_end++;
return;
}
+static void mas_wr_spanning_store(struct ma_wr_state *wr_mas)
+{
+ struct ma_state *mas;
+ MA_STATE(r_mas, NULL, 0, 0);
+ MA_WR_STATE(r_wr_mas, &r_mas, wr_mas->entry);
+ struct ma_node_info src, r_src, left, right, middle;
+ struct ma_node_info parent, r_parent, new_parent;
+ struct ma_node_part part;
+ struct split_data sd;
+ unsigned char height;
+
+ mas = wr_mas->mas;
+ utrace_ma_op(__func__, mas);
+
+ mt_dump(mas->tree, mt_dump_dec);
+ printk("Storing %lu - %lu -> %p\n", mas->index, mas->last, wr_mas->entry);
+
+ if (unlikely(!mas->index && mas->last == ULONG_MAX))
+ return mas_new_root(mas, wr_mas->entry);
+
+ r_mas = *mas;
+ printk("r_wr_mas\n");
+ r_mas.index = r_mas.last;
+ mas_wr_walk_index(&r_wr_mas);
+ r_mas.index = r_mas.min;
+ r_mas.offset = 0;
+ mas_wr_end_piv(&r_wr_mas);
+
+ /* Set up left side. */
+ printk("\nwr_mas\n");
+ mas_wr_walk_index(wr_mas);
+
+
+ printk("At %p and %p\n", mas_mn(mas), mas_mn(&r_mas));
+ printk("r_mas: end piv is %lu\n", r_wr_mas.end_piv);
+
+ wr_mas->end_piv = r_wr_mas.end_piv;
+ mni_mas_init(&src, mas);
+ mni_mas_init(&r_src, &r_mas);
+ printk("offset end is %u\n", r_wr_mas.offset_end);
+ sd.len = 0;
+ sd.offset = 0;
+ sd.left_store = true;
+ sd.insert = mas->offset;
+ sd.src_ins_end = wr_mas->offset_end + mas->end + 1;
+ wr_mas->offset_end += mas->end + part.skip + 1;
+ mns_node_part_leaf_init(&part, wr_mas, &right);
+ do {
+ struct ma_node_state *state;
+
+ for (int i = 0; i < part.size; i++)
+ printk("slot %u is %lu -> %p\n", i, part.pivots[i], part.slots[i]);
+ printk("skip %u\n", part.skip);
+
+ sd.new_end = r_mas.end + mas->end - part.skip;
+ sd.len = 0;
+ r_src.offset = r_wr_mas.offset_end + 1;
+ printk("new end is %u\n", sd.new_end);
+
+ mni_node_init(&left, mas_pop_node(mas), src.type);
+ left.min = src.min;
+ mas_wr_ascend_init(mas, &parent);
+ mas->end = parent.end;
+ mas_wr_ascend_init(&r_mas, &r_parent);
+ r_mas.end = r_parent.end;
+ if (sd.new_end < mt_slots[src.type]) {
+ /* Single node at this level */
+ printk("%d\n", __LINE__);
+ left.max = r_src.max;
+ right.node = NULL;
+ middle.node = NULL;
+ sd.split = mt_slots[src.type];
+ rebalance_reduce(&left, &src, &r_src, &part, &sd);
+ if (ma_is_root(parent.node)) {
+ /* This is wrong...
+ * We have parent.end != 1, but we have
+ * replaced all the data..
+ * */
+ if (parent.end != 1)
+ break;
+
+ src.enode = mas->node;
+ left.node->parent = mas_mn(mas)->parent;
+ mas->node = left.enode;
+ mas->depth = mas_mt_height(mas) - 1;
+ mas_set_height(mas);
+ goto new_root;
+ }
+ } else if (sd.new_end < 2 * mt_slots[src.type]) {
+ printk("%d\n", __LINE__);
+ mni_node_init(&right, mas_pop_node(mas), r_src.type);
+ middle.node = NULL;
+ right.max = r_src.max;
+ } else {
+ printk("%d\n", __LINE__);
+ mni_node_init(&right, mas_pop_node(mas), r_src.type);
+ mni_node_init(&middle, mas_pop_node(mas), src.type);
+ right.max = r_src.max;
+ }
+
+ sd.len = 0;
+ sd.offset = 0;
+ } while ((parent.node != r_parent.node) &&
+ sd.new_end >= mt_slots[parent.type]);
+
+ mas_wr_converged(&parent, &new_parent, &part, mas, &sd);
+ src.enode = parent.enode;
+ mas->node = new_parent.enode;
+ printk("replace %p with %p\n", src.enode, mas->node);
+
+new_root:
+ mas_wmb_replace(mas, src.enode);
+ mtree_range_walk(mas);
+ mt_dump(mas->tree, mt_dump_dec);
+ mt_validate(mas->tree);
+}
+
/*
* mas_wr_store_entry() - Internal call to store a value
* @wr_mas: The maple write state