break;
}
- //printk("\t\t\tset %p -> parent %p\n", enode, parent);
val &= ~MAPLE_NODE_MASK; /* Clear all node metadata in parent */
val |= (slot << shift) | type;
mte_to_node(enode)->parent = ma_parent_ptr(val);
if (mte_is_root(mas->node))
return;
- //printk("Updating gap for %p\n", mas->node);
max_gap = mas_max_gap(mas);
penode = mas->node;
do {
unsigned char offset;
void __rcu **slots;
- printk("%p is root?\n", mas->node);
if (mte_is_root(mas->node)) {
- printk("yes\n");
mas_mn(mas)->parent = ma_parent_ptr(mas_tree_parent(mas));
rcu_assign_pointer(mas->tree->ma_root, mte_mk_root(mas->node));
mas_set_height(mas);
} else {
- printk("no\n");
-
offset = mte_parent_slot(mas->node);
slots = ma_slots(mte_parent(mas->node),
mas_parent_type(mas, 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("parent of %p is %p\n", entry, mte_parent(entry));
if (mte_parent(entry) == node) {
- printk(" found entry at %u\n", offset);
*child = *mas;
mas->offset = offset + 1;
child->offset = offset;
tmp[i] = tmp_next[i];
}
- //printk("Collect discarded\n");
/* Collect the old nodes that need to be discarded */
if (mte_is_leaf(old_enode))
return mas_free(mas, old_enode);
mast->r = &r_mas;
l_mas.status = r_mas.status = m_mas.status = ma_none;
- printk("%d\n", __LINE__);
/* Check if this is not root and has sufficient data. */
if (((mast->orig_l->min != 0) || (mast->orig_r->max != ULONG_MAX)) &&
- unlikely(mast->bn->b_end <= mt_min_slots[mast->bn->type])) {
+ unlikely(mast->bn->b_end <= mt_min_slots[mast->bn->type]))
mast_spanning_rebalance(mast);
- printk("%d\n", __LINE__);
- }
l_mas.depth = 0;
mast->bn->type = mte_node_type(left);
l_mas.depth++;
- printk("%d\n", __LINE__);
/* Root already stored in l->node. */
if (mas_is_root_limits(mast->l))
goto new_root;
- printk("%d\n", __LINE__);
mast_ascend(mast);
mast_combine_cp_left(mast);
l_mas.offset = mast->bn->b_end;
if (!count)
count++;
}
- printk("%d\n", __LINE__);
l_mas.node = mt_mk_node(ma_mnode_ptr(mas_pop_node(mas)),
mte_node_type(mast->orig_l->node));
if (mas_is_root_limits(mast->l)) {
new_root:
- printk("%d\n", __LINE__);
mas_mn(mast->l)->parent = ma_parent_ptr(mas_tree_parent(mas));
while (!mte_is_root(mast->orig_l->node))
mast_ascend(mast);
MA_STATE(l_mas, mas->tree, mas->index, mas->last);
MA_STATE(r_mas, mas->tree, mas->index, mas->last);
- //printk("Rebalance\n");
trace_ma_op(__func__, mas);
/*
{
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);
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");
}
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 as %lx\n", wr_mas->end_piv);
}
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;
}
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;
- printk("pivot 0 is %lu\n", left->max);
ma_part->gaps[0] = left->max_gap;
- printk("set slot 1 to %p\n", right->enode);
ma_part->slots[1] = right->enode;
ma_part->pivots[1] = right->max;
- printk("pivot 1 is %lu\n", right->max);
ma_part->gaps[1] = right->max_gap;
ma_part->pos = 0;
void mni_insert_part(struct ma_node_part *part,
struct ma_node_info *dst)
{
- 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]);
dst->slots[dst->offset] = part->slots[part->pos];
if (dst->gaps)
dst->gaps[dst->offset] = part->gaps[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]);
dst->offset++;
dst->max = part->pivots[part->pos];
- printk("Offset is %u, use max for pivot\n", dst->offset);
part->pos++;
- printk("dst offset is %u\n", dst->offset);
if (part->pos >= part->size) {
- 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");
/* push to next node */
part->unfinished = true;
return;
}
- printk("dst offset is %u max is %u\n", dst->offset, part->dst_max_off);
}
- printk("OUT OF ROOM??\n");
/* Out of room.. */
//WARN_ON_ONCE(1);
part->unfinished = true;
mns->start = start;
mns->size = len;
mns->use_part = false;
- printk("Dst %p <= [%u] + %u\n", dst->node, start, len);
}
static inline
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);
size = len * sizeof(void *);
- 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);
} else {
size = len;
max = src->pivots[src->offset + len - 1];
- 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);
} else {
- printk("Set piv %u to %lx\n", dst->offset + len - 1, max);
dst->pivots[dst->offset + len - 1] = max;
}
unsigned long max_gap;
unsigned char len;
- printk("%s: offset is %u range %lx - %lx\n", __func__, p->offset, p->min, p->max);
len = mt_slots[p->type] - p->offset;
-
- //printk("len is %u %u - %u\n", len, mt_slots[p->type], p->offset);
-
if (len) {
- //printk("zero slots %u to %u\n", p->offset, len + p->offset - 1);
memset(p->slots + p->offset, 0, len * sizeof(void *));
if (p->pivots && len > 1)
(len - 1) * sizeof(unsigned long));
}
- //printk("check %p %u gaps\n", p->node, p->type);
max_gap = 0;
if (ma_is_leaf(p->type)) {
unsigned char offset;
if (!p->alloc)
goto finalise_leaf;
- //printk("check gaps for %p\n", p->node);
i = 0;
offset = p->offset - 2;
/*
* Check the end pivot which can only exist at the left most
* node
*/
- //printk("max is %lx last slot %u\n", p->max, offset + 2);
- //printk("last slot is %p\n", p->slots[offset + 1]);
if (unlikely(p->max == ULONG_MAX) &&
!p->slots[offset + 1]) {
- //printk("last slot\n");
max_gap = ULONG_MAX - p->pivots[offset];
- //printk("set max gap to %lu\n", max_gap);
if (max_gap > p->pivots[offset] - p->min)
goto finalise_leaf;
}
pivs = p->pivots;
/* Special case the first slot before the loop */
if (likely(!slots[0])) {
- //printk("slot 0 is %p\n", p->slots[0]);
- //printk("first slot check (%lu - %lu + 1\n", p->pivots[0], p->min);
gap = pivs[0] - p->min + 1;
if (gap > max_gap)
max_gap = gap;
- //printk("gap is now %lu\n", max_gap);
i = 2;
} else {
i = 1;
for (; i <= offset; i++) {
/* data == no gap. */
- printk("gap check %u\n", i);
if (slots[i])
continue;
- //printk("empty slot at %u\n", i);
pstart = pivs[i - 1];
gap = pivs[i] - pstart;
- //printk("gap is %lu vs %lu\n", gap, max_gap);
if (gap > max_gap)
max_gap = gap;
finalise_leaf:
p->max_gap = max_gap;
if (p->offset <= mt_pivots[p->type]) {
- //printk("%s: set meta %u\n", __func__, p->offset - 1);
ma_set_meta(p->node, p->type, 0, p->offset - 1);
}
} else {
unsigned long gap_off = 0;
- //printk("gaps is %p\n", p->gaps);
if (p->gaps) {
unsigned char offset = p->offset - 1;
- //printk("go through offset %u to 0\n", offset);
memset(p->gaps + p->offset, 0,
len * sizeof(unsigned long));
do {
} while (offset--);
p->max_gap = max_gap;
- //printk("max gap is %lx\n", max_gap);
- //printk("%s: set meta %u\n", __func__, p->offset - 1);
ma_set_meta(p->node, p->type, gap_off, p->offset - 1);
} else if (p->offset <= mt_pivots[p->type]) {
- //printk("%s: set meta %u\n", __func__, p->offset - 1);
ma_set_meta(p->node, p->type, 0, p->offset - 1);
}
}
node_size = mt_slots[mt];
space = node_size * 2 - 2;
- printk("space is %u data size is %u\n", space, data_size);
/* Greedy rebalance */
if (space <= data_size)
return 0;
unsigned long max;
struct ma_node_info *last_dst;
- printk("\n\n%s %u\n", __func__, len);
last_dst = states[0].dst;
max = 0;
for (i = 0; i < len; i++) {
unsigned char size;
unsigned char piv_overflow = 0;
- printk("%d: cp to %p + %u\n", i, ns->dst->node, ns->dst->offset);
if (last_dst != ns->dst) {
WARN_ON_ONCE(!max);
ns->dst->min = max + 1;
- printk("Set min %lu\n", ns->dst->min);
}
last_dst = ns->dst;
d_slots = ns->dst->slots + ns->dst->offset;
- printk("Store at %p\n", d_slots);
d_piv = ns->dst->pivots + 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) {
- printk("Use part\n");
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;
/* Set parent of _new_ children */
- 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]) {
piv_overflow = 1;
max = ns->info->max;
- 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 (ns->dst->gaps) {
d_gap = ns->dst->gaps + ns->dst->offset;
}
if (ns->dst->offset + size > mt_pivots[ns->dst->type]) {
- printk("dst overflow\n");
piv_overflow = 1;
} else if (piv_overflow) { /* Source overflow */
- printk("source overflow, set pivot to %lu\n", max);
*(d_piv + size - 1) = max;
}
ns->dst->offset += size;
- printk("offset advances by %u to %u\n", size, ns->dst->offset);
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;
}
- printk("\n\n");
}
static inline void mas_wr_converged(struct ma_node_info *src,
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;
- printk("converged use_part is %s\n",
- converged[i].use_part ? "a part" : "not a part");
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;
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);
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);
}
to = left;
node_off = 0; /* src */
part_off = 0;
- printk("offset is %u insert %u insert end %u total data %u\n",
- offset, insert, insert_end, total_data);
- printk("split %u\n", split);
do {
unsigned char copied = 0;
- printk("offset is %u insert %u - %u\n", insert, insert_end);
if (offset >= insert && offset <= insert_end) {
copied = min(ma_part->size - part_off, size);
- printk("B: (part) Insert at %u/%u size %u (out of %u)\n", offset, total_data, copied,
- ma_part->size);
state[i].part = ma_part;
mns_mni_init(&state[i], to, part_off, copied);
state[i].use_part = true;
part_off += copied;
- printk("copy part size %u\n", copied);
- printk("node_off is %u insert end is %u\n", node_off, node_ins_end);
node_off = node_ins_end + 1;
} else {
state[i].info = src;
* First part of node, may split across node
* boundaries though
*/
- printk("A: min of %u and %u (%u - %u)\n", size, insert - offset, insert, offset);
copied = min(size, insert - offset);
- printk("\tcopied = %u\n", copied);
} else {
- printk("C: min of %u and %u\n", size, src->end - node_off + 1);
copied = min(size, (src->end - node_off + 1));
- printk("\tcopied = %u\n", copied);
}
BUG_ON(copied == 0);
-
- printk("size is %u split %u\n", size, split);
- printk("cp at %u/%u size %u\n", offset, total_data, copied);
mns_mni_init(&state[i], to, node_off, copied);
-
node_off += copied;
}
offset += copied;
size -= copied;
- printk("next offset %u\n", offset);
if ((to == left) && (offset >= split)) {
if (ma_is_leaf(src->type) &&
mns_ends_in_null(&state[i])) {
- printk("Check null\n");
if (!state[i].use_part && offset != insert) {
/* Setting up a copy from a normal node */
- printk("\t!use_part: expand cp a space\n");
- printk("offset %u insert %u\n", offset, insert);
state[i].size++;
split++;
offset++;
size--;
node_off++;
} else {
- printk("\tuse_part!!\n");
- printk("\t\t split (%u) - 1\n", split);
- printk("\t\t offset (%u) - 1\n", offset);
- printk("\t\t size (%u) + 1\n", size);
split--;
offset--;
size++;
if (state[i].use_part) {
- printk("\t\t part_off (%u) - 1\n", part_off);
part_off--;
} else {
- printk("\t\t node_off %u --\n", node_off);
node_off--;
}
- printk("\t\t state size (%u) - 1\n", state[i].size);
if (state[i].size == 1)
i--;
else
state[i].size--;
}
- printk("offset %u node_off %u\n", offset, node_off);
}
- //printk("Last pivot in left is %lu\n", to->pivots[node_off - 1]);
- printk("Switch to right\n");
size = mt_slots[right->type];
- printk("size is %u\n", size);
to = right;
split = 255;
}
i++;
- printk("\tnode %p off is %u vs %u\n", src->node, node_off, src->end);
} while (node_off <= src->end);
- printk("Last pivot in right is %lu\n", to->pivots[node_off - 1]);
-
return i;
}
tmp_mas = *mas;
mas_wr_ascend_init(&tmp_mas, &parent);
- 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--;
src->end = mas->end;
- if (!parent.insert_off) /* No left sibling */ {
- printk("no left, try right\n");
+ 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);
mni_mas_init(&src2, &tmp_mas);
- printk("data size is calculated as %u\n", src2.end + new_end);
split = mas_wr_rebalance_calc(src2.end + new_end, src2.type);
- printk("Split calc to %u\n", split);
if (split) {
parent.insert_off--;
/* Left will be src2, right will be src */
left->min = src2.min;
right->max = src->max;
- printk("left will be rebalanced against this one.\n");
} else {
if (parent.end <= parent.insert_off)
return false;
mas_ascend(&tmp_mas);
try_right:
tmp_mas.offset = parent.insert_off + 1;
- printk("check parent offset %u\n", tmp_mas.offset);
mas_descend(&tmp_mas);
mni_mas_init(&src2, &tmp_mas);
mni_set_end(&src2);
/* Left will be src, right will be src2 */
left->min = src->min;
right->max = src2.max;
- printk("right will be rebalanced against this one.\n");
- printk("ma part %p and %p\n", ma_part->slots[0], ma_part->slots[1]);
}
/* The rebalance operation will succeed. */
- printk("\t\t%s\n", __func__);
- //mt_dump(mas->tree, mt_dump_dec);
-
i = 0;
offset = 0;
total_data = src2.end + new_end + 1;
if (left_store) {
/* Left pushes data right. */
insert = mas->offset;
- printk("left store at %u\n", insert);
size = split;
} else {
- printk("right store (into %p)\n", src2.node);
/* Right pushes data left */
insert = mas->offset + src2.end + 1;
offset += src2.end + 1;
- printk("insert %u offset %u\n", insert, offset);
size = split - src2.end;
- printk("size is %u = %u - %u\n", size, split, src2.end);
-
- printk("first store %p\n", src2.node);
state[i].info = &src2;
mns_mni_init(&state[i], left, 0, src2.end + 1);
i++;
* There can also be a split between nodes that may happen at these
* boundaries, or elsewhere.
*/
- printk("do the splitting of data %u - node ins end %u\n", offset, node_ins_end);
i = mt_wr_split_data(src, left, right, ma_part, split, insert, size,
offset, node_ins_end, total_data, state, i);
if (left_store) {
- printk("Cp right %p 0 - %u\n", src2.node, src2.end);
state[i].info = &src2;
mns_mni_init(&state[i++], right, 0, src2.end + 1);
}
mas_wr_converged(&parent, &new_parent, ma_part, mas);
src->enode = parent.enode;
mas->node = new_parent.enode;
- printk("Replace %p with %p\n", mas->node, src->enode);
-
-#if 0
- mas_wmb_replace(mas, src->enode);
- mtree_range_walk(mas);
- mt_dump(mas->tree, mt_dump_hex);
- exit(0);
-#endif
return true;
}