for (data_end = 0; data_end < MAPLE_RANGE64_SLOTS - 1; data_end++) {
last = mr64->pivot[data_end];
if (last == 0 && data_end > 0)
- return data_end;
+ return data_end - 1;
if (last == ULONG_MAX)
- return data_end;
+ return data_end - 1;
}
- if (mr64->slot[data_end] != NULL)
- data_end++;
+ if (mr64->slot[data_end] == NULL)
+ data_end--;
return data_end;
}
dst64 = &cp->dst->mr64;
while (sloc <= cp->src_end &&
- dloc <= cp->dst_end) {
+ dloc <= cp->dst_end) {
if (sloc != 0 && sloc < MAPLE_RANGE64_SLOTS - 1 &&
src64->pivot[sloc] == 0)
ma_copy(mas, &cp);
cp.dst_start += 1;
cp.src_start = p_slot + 1;
- cp.src_end = p_end;
+ cp.src_end = p_end + 1;
ma_copy(mas, &cp);
// Update encoded slots in children
ma_adopt_children(new_parent);
max = mr64->pivot[slot];
if (slot == MAPLE_NODE_SLOTS)
- slot = o_end;
+ slot = o_end + 1; // Append.
if (slot > 0)
min = mr64->pivot[slot - 1];
if (mas->index && min != mas->index - 1)
n_end++;
- if (n_end > MAPLE_RANGE64_SLOTS - 1) {
+ if (n_end > MAPLE_RANGE64_SLOTS - 1 ||
+ (n_end == MAPLE_RANGE64_SLOTS - 1 && mas->max == ULONG_MAX)) {
unsigned char split = ma_split(mas, slot);
if (mas_is_err(mas))
return 0;
n_end -= split;
mr64 = &mt_to_node(mas->node)->mr64;
o_end = ma_data_end_r64(mr64, mas->max); // Old end is not so old now.
- if (o_end == 1)
- o_end = 0; // This node is empty, append at the start.
}
/* Save the node in case we are not appending. */
p_mr64 = mr64;
/* Figure out if this is an append or not.
* Appending does not need to create a new node. */
- if (slot == o_end) {
+ if (slot - 1 == o_end) {
o_end = n_end; /* Appending */
} else {
/* Not appending */
mr64->pivot[slot] = mas->last;
/* Write NULL entry */
RCU_INIT_POINTER(mr64->slot[--slot], NULL);
- if (o_end == n_end) // Append.
+ if (o_end == n_end + 1) // Append.
wmb();
mr64->pivot[slot] = mas->index - 1;
} else {
/* Write the entry */
RCU_INIT_POINTER(mr64->slot[slot], entry);
- if (o_end == n_end) // Append.
+ if (o_end == n_end + 1) // Append.
wmb();
- mr64->pivot[slot++] = mas->last;
+ if (slot < MAPLE_RANGE64_SLOTS - 1)
+ mr64->pivot[slot++] = mas->last;
}
/* Skip possible duplicate entry that contains a NULL */
mn->mr64.pivot[0] = ms->index - 1;
_ma_insert(ms, entry, 1);
+ if (mas_is_err(ms))
+ return;
/* swap the new root into the tree */
rcu_assign_pointer(ms->tree->ma_root, mt_mk_root(ms->node));
}