unsigned char offset;
void __rcu **slots;
+ printk("%p is root?\n", mas->node);
if (mte_is_root(mas->node)) {
mas_mn(mas)->parent = ma_parent_ptr(mas_tree_parent(mas));
rcu_assign_pointer(mas->tree->ma_root, mte_mk_root(mas->node));
end = ma_data_end(node, mt, pivots, mas->max);
for (offset = mas->offset; offset <= end; offset++) {
entry = mas_slot_locked(mas, slots, offset);
- //printk("check %p[%u/%u] %p\n", mas->node, end, offset, entry);
+ printk("check %p[%u/%u] %p\n", mas->node, end, offset, entry);
+ printk("parent of %p is %p\n", entry, mte_parent(entry));
if (mte_parent(entry) == node) {
- //printk(" found entry at %u\n", offset);
+ printk(" found entry at %u\n", offset);
*child = *mas;
mas->offset = offset + 1;
child->offset = offset;
unsigned long gaps[2];
bool unfinished;
unsigned char skip;
+ bool leaf;
};
struct ma_node_info {
struct ma_node_info *info;
struct ma_node_part *part;
};
- unsigned char start; /* The start offset */
+ unsigned char start; /* The start offset into the source*/
unsigned char size; /* The size to copy or insert */
struct ma_node_info *dst; /* The destination node */
bool use_part;
};
-/*
- * Unsafe from reader side
- */
-static inline void mni_set_end(struct ma_node_info *mni)
-{
- unsigned char offset;
-
- if (mni->type == maple_arange_64) {
- mni->end = ma_meta_end(mni->node, mni->type);
- return;
- }
-
- offset = mt_pivots[mni->type] - 1;
- if (likely(!mni->pivots[offset])) {
- mni->end = ma_meta_end(mni->node, mni->type);
- return;
- }
-
- if (likely(mni->pivots[offset] == mni->max)) {
- mni->end = offset;
- return;
- }
-
- mni->end = mt_pivots[mni->type];
-}
-
/*
* mns_node_part_leaf_init() - Initialize what is being inserted, calculate how
* many slots will be skipped.
{
ma_part->pos = 0;
ma_part->size = 0;
- //printk("%s: %lx - %lx store %lx - %lx\n", __func__, wr_mas->r_min, wr_mas->r_max, wr_mas->mas->index, wr_mas->mas->last);
+ printk("%s: %lx - %lx store %lx - %lx\n", __func__, wr_mas->r_min, wr_mas->r_max, wr_mas->mas->index, wr_mas->mas->last);
if (wr_mas->r_min < wr_mas->mas->index) {
ma_part->pivots[0] = wr_mas->mas->index - 1;
ma_part->slots[0] = wr_mas->content;
ma_part->size++;
- //printk("r_min remains\n");
+ printk("r_min remains\n");
}
ma_part->pivots[ma_part->size] = wr_mas->mas->last;
ma_part->pivots[ma_part->size] = wr_mas->end_piv;
ma_part->slots[ma_part->size] = src->slots[wr_mas->offset_end];
ma_part->size++;
- //printk("r_max remains\n");
+ printk("r_max remains\n");
}
ma_part->unfinished = false;
ma_part->dst_max_off = 255;
ma_part->skip = wr_mas->offset_end - wr_mas->mas->offset + 1;
+ printk("skip %u = %u - %u + 1\n", ma_part->skip, wr_mas->offset_end, wr_mas->mas->offset);
+ printk("ma_part size %u\n", ma_part->size);
+ ma_part->leaf = true;
}
static inline
void mni_node_part_init(struct ma_node_part *ma_part,
struct ma_node_info *left, struct ma_node_info *right)
{
+ printk("set slot 0 to %p\n", left->enode);
ma_part->slots[0] = left->enode;
ma_part->pivots[0] = left->max;
ma_part->gaps[0] = left->max_gap;
{
mni->node = node;
mni->type = type;
+ mni->enode = mt_mk_node(node, type);
_mni_node_init(mni, node, type);
}
+/*
+ * Unsafe from reader side
+ */
+static inline void mni_set_end(struct ma_node_info *ni)
+{
+ unsigned char offset;
+
+ if (ni->type == maple_arange_64) {
+ ni->end = ma_meta_end(ni->node, ni->type);
+ return;
+ }
+
+ offset = mt_pivots[ni->type] - 1;
+ if (likely(!ni->pivots[offset])) {
+ ni->end = ma_meta_end(ni->node, ni->type);
+ return;
+ }
+
+ if (likely(ni->pivots[offset] == ni->max)) {
+ ni->end = offset;
+ return;
+ }
+
+ ni->end = mt_pivots[ni->type];
+}
+
+static inline
+void mni_mas_init(struct ma_node_info *mni, struct ma_state *mas)
+{
+ mni->node = mte_to_node(mas->node);
+ mni->type = mte_node_type(mas->node);
+ _mni_node_init(mni, mni->node, mni->type);
+ mni->enode = mas->node;
+ mni->end = mas->end;
+ mni->max = mas->max;
+ mni->min = mas->min;
+ mni_set_end(mni);
+}
+
static inline
void mns_mas_init(struct ma_node_state *mns, struct ma_node_info *mni,
struct ma_state *mas)
void mns_mni_init(struct ma_node_state *mns, struct ma_node_info *dst,
unsigned char start, unsigned char len)
{
- mns->dst = ni;
+ mns->dst = dst;
mns->start = start;
- mns->size = len + 1;
+ mns->size = len;
+ printk("Dst %p <= [%u] + %u\n", dst, start, len);
}
static inline
-bool mns_ends_in_null(struct ma_node_state *mns)
+bool mns_ends_in_null(struct ma_node_state *ns)
{
void __rcu **s_slots;
- unsigned long *s_piv;
- if (mns->use_part) {
+ if (ns->use_part) {
s_slots = ns->part->slots;
- s_piv = ns->part->pivots;
} else {
s_slots = ns->info->slots;
- s_piv = ns->info->pivots;
}
-
- if (s_slots[mns->start + mns->size - 1])
+
+ if (s_slots[ns->start + ns->size - 1])
return false;
return true;
return new_end;
}
-static inline void mas_wr_converged(struct ma_node_info *src,
- struct ma_node_info *dst, struct ma_node_part *ma_part,
- struct ma_state *mas)
-{
- mni_node_init(dst, mas_pop_node(mas), src->type);
- printk("%s: %p -> %p\n", __func__, src->node, dst->node);
-
- if (mas->offset)
- mni_cp(src, dst, mas->offset);
-
- mni_insert_part(ma_part, dst);
- src->offset += ma_part->skip;
-
- if (src->offset <= mas->end)
- mni_cp(src, dst, mas->end - src->offset + 1);
-
- dst->node->parent = src->node->parent;
- mni_finalise(dst);
- mas_set_height(mas);
-}
-
static void mas_wr_split_no_null(struct ma_node_info *src,
struct ma_node_info *left, struct ma_node_info *right,
unsigned char total, struct ma_node_part *ma_part)
right->min = left->max + 1;
}
-static inline void mni_in_left(struct ma_node_info *src,
- struct ma_node_info *left, struct ma_node_info *right,
- struct ma_state *mas, unsigned char split,
- unsigned char new_end, struct ma_node_part *ma_part)
-{
- ma_part->dst_max_off = split;
- if (mas->offset)
- mni_cp(src, left, mas->offset);
-
- mni_insert_part(ma_part, left);
- src->offset+= ma_part->skip;
- //printk("\t\tsrc L offset adjusted to %u\n", src->offset);
- if (left->offset <= split)
- mni_cp(src, left, split - left->offset + 1);
-
- mas_wr_split_no_null(src, left, right, new_end, ma_part);
- if (ma_part->unfinished)
- mni_insert_part(ma_part, right);
-
- right->min = left->max + 1;
- mni_cp(src, right, mas->end - src->offset + 1);
-}
-
-static inline void mni_in_right(struct ma_node_info *src,
- struct ma_node_info *left, struct ma_node_info *right,
- struct ma_state *mas, unsigned char split,
- unsigned char new_end, struct ma_node_part *ma_part)
-{
- unsigned char cp;
-
- cp = mas->offset - split - 1;
- mni_cp(src, left, split + 1);
- mas_wr_split_no_null(src, left, right, new_end, ma_part);
- right->min = left->max + 1;
- if (cp)
- mni_cp(src, right, cp);
-
- mni_insert_part(ma_part, right);
- src->offset+= ma_part->skip;
- //printk("\t\tsrc offset adjusted to %u\n", src->offset);
- if (src->offset <= mas->end)
- mni_cp(src, right, mas->end - src->offset + 1);
-}
-
/*
* mas_wr_rebalance_calc() - Try to calculate a rebalance that will work
* @data_size: The total data to be written
ni->node = mte_to_node(mas->node);
ni->type = mte_node_type(mas->node);
_mni_node_init(ni, ni->node, ni->type);
+ mni_set_end(ni);
+ ni->insert_off = mas->offset;
}
+#if 0
static void mas_wr_rebalance_nodes(
struct ma_node_info *l_src,
struct ma_node_info *r_src,
}
}
}
+#endif
/*
* Assemble all the states into the dst within those states
*
*/
static inline
-void mns_assemble(struct ma_node_state **states, unsigned char len)
+void mns_assemble(struct ma_node_state *states, unsigned char len)
{
unsigned char i;
unsigned long max;
struct ma_node_info *last_dst;
- last_dst = states[0]->dst;
+ last_dst = states[0].dst;
+ max = 0;
for (i = 0; i < len; i++) {
- struct ma_node_state *ns = states[i];
+ struct ma_node_state *ns = &states[i];
void __rcu **s_slots, **d_slots;
unsigned long *s_piv, *d_piv;
unsigned long *s_gap, *d_gap;
unsigned char size;
unsigned char piv_overflow = 0;
- if (last_dst != ns->dst)
+ if (last_dst != ns->dst) {
+ WARN_ON_ONCE(!max);
ns->dst->min = max + 1;
+ }
d_slots = ns->dst->slots + ns->dst->offset;
+ printk("Store at %p\n", d_slots);
d_piv = ns->dst->pivots + ns->dst->offset;
- d_gap = ns->dst->gaps + ns->dst->offset;
size = ns->size;
+ printk("%u: dst %p [%u] size %lu\n", i, ns->dst, ns->dst->offset, size);
if (ns->use_part) {
s_slots = ns->part->slots + ns->start;
s_piv = ns->part->pivots + ns->start;
s_gap = ns->part->gaps + ns->start;
max = s_piv[size - 1];
+ printk("max from offset %u\n", size -1);
+ if (!ns->part->leaf) {
+ int j = 0;
+
+ printk("not a leaf\n");
+ do {
+ struct maple_enode *child;
+
+ child = ma_enode_ptr(ns->part->slots[j]);
+ printk("set %p %p[%u] parent\n", child,
+ ns->dst->enode, j);
+ mte_set_parent(child, ns->dst->enode,
+ j + ns->dst->offset);
+ } while (++j < ns->part->size);
+ }
} else {
+ printk("Use info %p + %u\n", ns->info->slots, ns->start);
s_slots = ns->info->slots + ns->start;
s_piv = ns->info->pivots + ns->start;
s_gap = ns->info->gaps + ns->start;
- if (ns->start + size >= mt_pivots[ns->info->type]) {
+ if (ns->start + size > mt_pivots[ns->info->type]) {
piv_overflow = 1;
max = ns->info->max;
- } else
+ printk("Use max for pivot\n");
+ } else {
max = s_piv[size - 1];
+ }
}
+ printk("Cp %p + %u to dst %p + %lu\n",
+ s_slots, size,
+ ns->dst->slots, ns->dst->offset);
memcpy(d_slots, s_slots, size * sizeof(void __rcu *));
- if (d_gap)
+ if (ns->dst->gaps) {
+ d_gap = ns->dst->gaps + ns->dst->offset;
memcpy(d_gap, s_gap, size * sizeof(unsigned long));
+ }
if (ns->dst->offset + size >= mt_pivots[ns->dst->type])
piv_overflow = 1;
- else if (piv_overflow) /* Source overflow */
+ else if (piv_overflow) { /* Source overflow */
+ printk("source overflow, set pivot to %lu\n", max);
*(d_piv + size - 1) = max;
+ }
ns->dst->offset += size;
+ ns->dst->end = ns->dst->offset - 1;
+ printk("\t\t set %p end to %u\n", ns->dst->node, ns->dst->end);
size -= piv_overflow;
memcpy(d_piv, s_piv, size * sizeof(unsigned long));
ns->dst->max = max;
}
}
+static inline void mas_wr_converged(struct ma_node_info *src,
+ struct ma_node_info *dst, struct ma_node_part *ma_part,
+ struct ma_state *mas)
+
+{
+ struct ma_node_state converged[3];
+ unsigned char i = 0;
+ unsigned char off = 0;
+
+ mni_node_init(dst, mas_pop_node(mas), src->type);
+ printk("dst node is %p\n", dst->node);
+ printk("%s: %p -> %p\n", __func__, src->node, dst->node);
+
+ if (src->insert_off) {
+ printk("%s: cp start data\n", __func__);
+ mns_mni_init(&converged[i], dst, 0, src->insert_off);
+ converged[i].info = src;
+ off = src->insert_off;
+ i++;
+ }
+
+ printk("%s: insert data\n", __func__);
+ mns_mni_init(&converged[i], dst, 0, ma_part->size);
+ converged[i].part = ma_part;
+ converged[i].use_part = true;
+ off += ma_part->skip;
+ i++;
+
+ if (src->end >= off) {
+ printk ("end %u %u + %u\n", src->end, ma_part->skip,
+ src->insert_off);
+ printk("%s: cp end of data\n", __func__);
+ unsigned char start = off;
+ unsigned char size = src->end - start + 1;
+ mns_mni_init(&converged[i], dst, start, size);
+ converged[i].info = src;
+ i++;
+ off += size - 1;
+ }
+
+ mns_assemble(converged, i);
+ dst->node->parent = src->node->parent;
+ printk("Set parent of %p to %p\n", dst->node, dst->node->parent);
+ mni_finalise(dst);
+}
+
/*
* mas_wr_try_rebalance() - Try to rebalance two nodes, this may not work out.
* @src: The source node state
static bool mas_wr_try_rebalance(struct ma_state *mas,
struct ma_node_info *src, unsigned char new_end,
struct ma_node_info *left, struct ma_node_info *right,
- struct ma_node_part *ma_part)
+ struct ma_node_part *ma_part, unsigned char insert_end)
{
struct ma_state tmp_mas;
- struct ma_node_info src2_info, parent, new_parent;
- struct ma_node_info *l_src, *r_src;
- struct ma_node_state src2;
- unsigned char split, max;
- unsigned char p_end, p_off;
+ struct ma_node_info src2, parent, new_parent;
+ struct ma_node_state state[4];
+ unsigned char split, max, i;
bool left_store = false;
/*
tmp_mas = *mas;
mas_wr_ascend_init(&tmp_mas, &parent);
- p_off = tmp_mas.offset;
- p_end = ma_data_end(parent.node, parent.type, parent.pivots,
- parent.max);
- //printk("parent %p has end %u %p\n", parent.node, p_end, parent.slots[p_end]);
+ //printk("parent %p has end %u %p\n", parent.node, parent.end, parent.slots[parent.end]);
max = mt_slots[src->type] - 1;
if (ma_is_leaf(src->type))
max--;
- if (!p_off)
- goto try_right;
+ src->end = mas->end;
+ if (!parent.insert_off) /* No left sibling */
+ goto try_right; /* There must be a right sibling */
+ /* Check for space in left sibling */
tmp_mas.offset--;
mas_descend(&tmp_mas);
- mns_mas_init(&src2, &src2_info, &tmp_mas);
- src2_info.insert_off = 255;
- src2_info.end = ma_data_end(src2.node, src2.type, src2.pivots,
- src2.max);
+ mni_mas_init(&src2, &tmp_mas);
split = mas_wr_rebalance_calc(src2.end + new_end, src2.type);
if (split) {
- p_off--;
- l_src = &src2;
- r_src = src;
- r_src->end = mas->end;
+ parent.insert_off--;
+ /* Left will be src2, right will be src */
+ left->min = src2.min;
+ right->max = src->max;
} else {
- if (p_end <= p_off)
+ if (parent.end <= parent.insert_off)
return false;
mas_ascend(&tmp_mas);
try_right:
- tmp_mas.offset = p_off + 1;
+ tmp_mas.offset = parent.insert_off + 1;
mas_descend(&tmp_mas);
- mns_mas_init(&src2, &tmp_mas);
- src2.insert = 255;
- src2.end = ma_data_end(src2.node, src2.type,
- src2.pivots, src2.max);
- src->end = mas->end;
+ mni_mas_init(&src2, &tmp_mas);
+ mni_set_end(&src2);
split = mas_wr_rebalance_calc(src2.end + new_end, src2.type);
if (!split)
return false;
split = src2.end + new_end - split;
- l_src = src;
- r_src = &src2;
left_store = true;
+ /* Left will be src, right will be src2 */
+ left->min = src->min;
+ right->max = src2.max;
}
/*
* At this point, the rebalance operation will succeed.
*/
- left->min = l_src->min;
- mas_wr_rebalance_nodes(l_src, r_src, left, right, left_store, split,
- ma_part, mas->offset, new_end);
+ i = 0;
+ if (left_store) {
+ unsigned char space;
+
+ /*
+ * Left pushes data right.
+ * Fill left up to split from l_src and ma_part - Func_1
+ */
+ if (mas->offset) {
+ state[i].info = src;
+ mns_mni_init(&state[i++], left, 0, mas->offset);
+ }
+
+ state[i].part = ma_part;
+ state[i].use_part = true;
+ space = split - mas->offset + 1;
+ if (space >= ma_part->size) {
+ mns_mni_init(&state[i++], left, 0, ma_part->size);
+ } else {
+ /* The insert part spans the left and right */
+ mns_mni_init(&state[i], left, 0, space);
+ if (mns_ends_in_null(&state[i])) {
+ state[i].size--;
+ split--;
+ }
+
+ space = ma_part->size - state[i].size;
+ i++;
+ /*
+ * fill right from ma_part and l_src - Func_1
+ */
+ state[i].part = ma_part;
+ state[i].use_part = true;
+ mns_mni_init(&state[i], right, state[i - 1].size,
+ space);
+ i++;
+ }
+
+ if (split > insert_end) {
+ state[i].info = src;
+ mns_mni_init(&state[i], left, insert_end + 1,
+ split - insert_end + 1);
+
+ if (mns_ends_in_null(&state[i])) {
+ state[i].size--;
+ split--;
+ }
+ i++;
+ }
+
+ /*
+ * fill right with right. - Func_2
+ */
+ state[i].info = &src2;
+ mns_mni_init(&state[i++], right, split + 1, mas->end - split + 1);
+ } else {
+ /*
+ * Right pushes data left
+ * Copy left to new left - Func_2
+ */
+ state[i].info = &src2;
+ mns_mni_init(&state[i], left, 0, split);
+ if (mns_ends_in_null(&state[i])) {
+ state[i].size--;
+ split--;
+ }
+ i++;
+
+ /*
+ * copy from right or ma_part to split to new left - Func_1
+ * fill right from ma_part and r_src - Func_1
+ */
+
+ state[i].info = &src2;
+ mns_mni_init(&state[i++], right, split + 1,
+ src2.end + 1);
+
+ if (mas->offset) {
+ state[i].info = src;
+ mns_mni_init(&state[i++], right, 0, mas->offset);
+ }
+
+ state[i].part = ma_part;
+ mns_mni_init(&state[i], right, 0, ma_part->size);
+ state[i++].use_part = true;
+ if (insert_end > mas->end) {
+ state[i].info = src;
+ mns_mni_init(&state[i++], right, insert_end + 1,
+ mas->end - insert_end + 1);
+ }
+ }
mni_finalise(left);
mni_finalise(right);
mas_ascend(mas);
- mas->end = p_end;
- mas->offset = p_off;
+ mas->end = parent.end;
+ mas->offset = parent.insert_off;
mni_node_part_init(ma_part, left, right);
ma_part->skip = 2;
mas_wr_converged(&parent, &new_parent, ma_part, mas);
return true;
}
+#if 0
/*
* There is insufficient data in the node after a store.
* This rebalance will succeed, not like the split variant that will attempt
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);
* Two possibilities:
* 1. keep two nodes if possible and limit ripple
* 2. make one node if possible and limit memory use
+ *
+ * Case 1:
+ * Left takes data from right.
+ * Fill left up to split from l_src and ma_part - Func_1
+ * Fill left up from l_src remainder - Func_2
+ * Fill left up to split from right. - Func_2
+ * fill right with remainder of right. - Func_2
+ *
+ * Right takes data from left
+ * Copy left to new left up to split - Func_2
+ * Fill right with remainder of left - Func_2
+ * Fill right from old right or ma_part - Func_1
*/
if ((total > 2 * mt_min_slots[l_src.type] ) ||
ma_is_root(parent.node)) {
break;
}
-
printk("consume\n");
/* Reduce two nodes into one */
if (l_store) {
mtree_range_walk(mas);
mt_dump(mas->tree, mt_dump_dec);
}
+#endif
/*
* There is not enough room to contain the store in one node.
trace_ma_op(__func__, mas);
- //printk("\t\t%s\n", __func__);
- //mt_dump(mas->tree, mt_dump_hex);
+ printk("\t\t%s\n", __func__);
+ mt_dump(mas->tree, mt_dump_hex);
+ printk ("Store %lu - %lu => %p\n", mas->index, mas->last, wr_mas->entry);
height = mas_mt_height(mas);
mas->depth = height;
mns_node_part_leaf_init(&ma_part, wr_mas, &src_info);
total = mas->end + ma_part.size - 1;
split = (total + 1) / 2;
+ printk("Splitting leaf at %u store at %u\n", split, mas->offset);
- if (mt_is_alloc(mas->tree))
+ if (mt_is_alloc(mas->tree)) {
right.alloc = left.alloc = true;
+ }
if (height > 1 &&
- mas_wr_try_rebalance(mas, &src, total, &left, &right, &ma_part))
+ mas_wr_try_rebalance(mas, &src_info, total, &left,
+ &right, &ma_part, wr_mas->offset_end))
goto rebalanced;
left.min = mas->min;
right.max = mas->max;
if (split >= mas->offset) {
- unsigned char space; /* size remaining in left */
+ unsigned char space;
+ printk("Store in left\n");
if (mas->offset) {
- state[i]->info = &src;
- mns_mni_init(state[i++], &left, 0, mas->offset);
+ state[i].info = &src_info;
+ printk("src is info %p\n", src_info.node);
+ mns_mni_init(&state[i++], &left, 0, mas->offset);
}
- state[i]->part = &ma_part;
- state[i]->part = true;
+ state[i].part = &ma_part;
+ state[i].use_part = true;
space = split - mas->offset + 1;
- if (space >= ma_part.size)
- mns_mni_init(state[i++], &left, 0, ma_part.size);
+ if (space >= ma_part.size) {
+ mns_mni_init(&state[i++], &left, 0, ma_part.size);
} else {
- mns_mni_init(state[i++], &left, 0, space);
- state[i]->part = &ma_part;
- state[i]->part = true;
- mns_mni_init(state[i++], &right, space - 1, ma_part.size);
+ /* The insert part spans the left and right */
+ mns_mni_init(&state[i], &left, 0, space);
+ if (mns_ends_in_null(&state[i])) {
+ state[i].size--;
+ split--;
+ }
+ space = ma_part.size - state[i].size;
+ i++;
+ state[i].part = &ma_part;
+ state[i].use_part = true;
+ mns_mni_init(&state[i], &right, state[i - 1].size,
+ space);
+ i++;
}
if (split > wr_mas->offset_end) {
- state[i]->info = &src;
- mns_mni_init(state[i++], &left, wr_mas->offset_end + 1,
+ state[i].info = &src_info;
+ printk("src is info %p\n", src_info.node);
+ mns_mni_init(&state[i], &left, wr_mas->offset_end + 1,
split - wr_mas->offset_end + 1);
- }
- if (mns_ends_in_null(state[i - 1])) {
- state[i - 1]->size--;
- split--;
+ if (mns_ends_in_null(&state[i])) {
+ state[i - 1].size--;
+ split--;
+ }
+ i++;
}
- state[i]->info = &src;
- mns_min_init(state[i++], &right, split + 1, mas-end - split + 1);
+ state[i].info = &src_info;
+ printk("src is info %p\n", src_info.node);
+ mns_mni_init(&state[i++], &right, split + 1, mas->end - split + 1);
} else {
- state[i]->info = &src;
- mns_mni_init(state[i++], &left, 0, split);
- if (mns_ends_in_null(state[i - 1])) {
- state[i - 1]->size--;
+ printk("Store in right\n");
+ printk("src is info %p\n", src_info.node);
+ state[i].info = &src_info;
+ split++; /* it's a size */
+ mns_mni_init(&state[i], &left, 0, split);
+ if (mns_ends_in_null(&state[i])) {
+ printk("Ends in null, move split\n");
+ state[i].size--;
split--;
}
+ i++;
- if (mas->offset > split + 1) {
- state[i]->info = &src;
- mns_mni_init(state[i++], &right, split + 1,
- mas->offset - split + 1);
+ if (mas->offset >= split) {
+ state[i].info = &src_info;
+ printk("src is info %p\n", src_info.node);
+ mns_mni_init(&state[i++], &right, split,
+ mas->offset - split);
}
- state[i]->part = &ma_part;
- mns_mni_init(state[i], &right, 0, ma_part.size);
- state[i++]->part = true;
+ printk("Store part next 0 - %u\n", ma_part.size - 1);
+ state[i].part = &ma_part;
+ mns_mni_init(&state[i], &right, 0, ma_part.size);
+ state[i++].use_part = true;
if (wr_mas->offset_end > mas->end) {
- state[i]->info = &src;
- mns_mni_init(state[i++], &right, wr_mas->offset_end + 1,
- mas->end - wr_mas->offset_end + 1);
+ state[i].info = &src_info;
+ printk("src is info %p\n", src_info.node);
+ mns_mni_init(&state[i++], &right, wr_mas->offset_end + 1,
+ mas->end - wr_mas->offset_end + 1);
}
}
- mns_assemble(&state, i);
+ printk("\n\nAssemble %u\n", i);
+ mns_assemble(state, i);
+ printk("\n\n");
mni_finalise(&left);
mni_finalise(&right);
mni_node_part_init(&ma_part, &left, &right);
+ ma_part.leaf = false;
if (height == 1) {
- if (mt_is_alloc(mas->tree))
- src.type = maple_arange_64;
- else
- src.type = maple_range_64;
-
+ printk("src parent is %p\n", src_info.node->parent);
+ printk("New root\n");
goto new_root;
}
//printk("%d height is %d\n", __LINE__, height);
while (--height) {
i = 0;
- mas_wr_ascend_init(mas, &src);
- mas->end = ma_data_end(src.node, src.type, src.pivots,
- src.max);
+ mas_wr_ascend_init(mas, &src_info);
+ mas->end = src_info.end;
total = mas->end + 1;
- if (mas->end + 1 < mt_slots[src.type])
+ if (mas->end + 1 < mt_slots[src_info.type])
goto converged;
//printk("\tConsume %p type %u\n", src.node, src.type);
- mni_node_init(&left, mas_pop_node(mas), src.type);
- mni_node_init(&right, mas_pop_node(mas), src.type);
+ mni_node_init(&left, mas_pop_node(mas), src_info.type);
+ mni_node_init(&right, mas_pop_node(mas), src_info.type);
if ((height > 1) &&
- (mas_wr_try_rebalance(mas, &src, mas->end + 1, &left,
- &right, &ma_part)))
+ (mas_wr_try_rebalance(mas, &src_info, mas->end + 1, &left,
+ &right, &ma_part, src_info.insert_off + 1)))
goto rebalanced;
- left.min = src.min;
- right.max = src.max;
+ left.min = src_info.min;
+ right.max = src_info.max;
split = (total + 1) / 2;
if (split >= mas->offset) {
+ unsigned char space; /* size remaining in left */
+
if (mas->offset) {
- state[i]->info = &src;
- msn_mni_init(state[i++], &left, 0, mas->offset);
+ state[i].info = &src_info;
+ mns_mni_init(&state[i++], &left, 0, mas->offset);
}
- }
+ state[i].part = &ma_part;
+ state[i].use_part = true;
+ space = split - mas->offset + 1;
+ if (space >= ma_part.size) {
+ mns_mni_init(&state[i++], &left, 0, ma_part.size);
+ } else {
+ mns_mni_init(&state[i++], &left, 0, space);
+ state[i].part = &ma_part;
+ state[i].use_part = true;
+ mns_mni_init(&state[i++], &right, space - 1, ma_part.size);
+
+ }
- /* Old
- if (split >= mas->offset)
- mni_in_left(&src, &left, &right, mas, split, total, &ma_part);
- else
- mni_in_right(&src, &left, &right, mas, split, total, &ma_part);
- */
+ if (split > wr_mas->offset_end) {
+ state[i].info = &src_info;
+ mns_mni_init(&state[i++], &left, wr_mas->offset_end + 1,
+ split - wr_mas->offset_end + 1);
+ }
+
+ if (mns_ends_in_null(&state[i - 1])) {
+ state[i - 1].size--;
+ split--;
+ }
+
+ state[i].info = &src_info;
+ mns_mni_init(&state[i++], &right, split + 1, mas->end - split + 1);
+ } else {
+ state[i].info = &src_info;
+ mns_mni_init(&state[i], &left, 0, split);
+ if (mns_ends_in_null(&state[i])) {
+ state[i].size--;
+ split--;
+ }
+ i++;
+
+ if (mas->offset > split + 1) {
+ state[i].info = &src_info;
+ mns_mni_init(&state[i++], &right, split + 1,
+ mas->offset - split + 1);
+ }
+ state[i].part = &ma_part;
+ mns_mni_init(&state[i], &right, 0, ma_part.size);
+ state[i++].use_part = true;
+ if (wr_mas->offset_end > mas->end) {
+ state[i].info = &src_info;
+ mns_mni_init(&state[i++], &right, wr_mas->offset_end + 1,
+ mas->end - wr_mas->offset_end + 1);
+ }
+ }
- mns_assemble(&state, i);
+ mns_assemble(state, i);
mni_finalise(&left);
mni_finalise(&right);
mni_node_part_init(&ma_part, &left, &right);
new_root:
/* Converged on new root */
mas->depth++;
- mas->offset = 0;
+ src_info.insert_off = mas->offset = 0;
mas->end = 0;
mas_set_height(mas);
+ if (mt_is_alloc(mas->tree))
+ src_info.type = maple_arange_64;
+ else
+ src_info.type = maple_range_64;
+ src_info.end = 0; /* Empty node */
+
+ /*
+ * src can only really provide the parent
+ * set the skip to high enough to avoid using any data
+ */
converged:
- mas_wr_converged(&src, &parent, &ma_part, mas);
+ mas_wr_converged(&src_info, &parent, &ma_part, mas);
mas->node = parent.enode;
rebalanced:
- mas_wmb_replace(mas, src.enode);
+ mas_wmb_replace(mas, src_info.enode);
mtree_range_walk(mas);
- //mt_dump(wr_mas->mas->tree, mt_dump_hex);
+ mt_dump(wr_mas->mas->tree, mt_dump_hex);
}
/*
mas_wr_split(wr_mas);
break;
case wr_rebalance:
- mas_wr_rebalance(wr_mas);
+ 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);
MA_WR_STATE(wr_mas, mas, entry);
int ret = 0;
+ printk("store %lu-%lu\n", index, last);
retry:
mas_wr_preallocate(&wr_mas, entry);
if (unlikely(mas_nomem(mas, gfp))) {