} else {
old_parent = mt_parent(mas->node);
p_end = ma_data_end_r64(&old_parent->mr64, UINT_MAX);
-
if (p_end >= MAPLE_RANGE64_SLOTS - 1) {
/* Must split the parent */
- unsigned long max = mas->max;
- unsigned long min = mas->min;
-
ma_encoded_parent(mas);
p_slot = mt_parent_slot(enc_full);
split = ma_split(mas, p_slot, p_end, 1);
mt_free(full);
return split;
}
-/* Private
- *
- * Splitting is done in a lazy-fashion. As such, the parent may not have room
- * for two entries and will require splitting itself. Rinse & repeat.
- *
- *
- * If this is root, increase the branch height.
- * If this is not root, promote the middle item as a pivot to the parent.
- * Copy 1/2 data to each left & right children.
- *
- *
- */
-static int _ma_split(struct ma_state *mas, unsigned char slot,
- unsigned char num, int depth)
-{
- struct maple_node *full = mas->node;
- struct maple_node *mn = mt_to_node(mas->node);
- struct maple_node *old_parent, *new_parent, *left, *right;
- struct maple_range_64 *nparent64;
- unsigned char p_slot;
- unsigned char p_end;
- unsigned char split;
- if (ma_is_root(full)) {
- old_parent = mn;
- mas->node = mt_safe_root(mas->node);
- p_slot = 0;
- p_end = 0;
- } else {
- old_parent = mt_parent(mn);
- p_slot = mt_parent_slot(mn);
- p_end = ma_data_end_r64(&old_parent->mr64, UINT_MAX);
- }
-
-
- if (p_end >= MAPLE_RANGE64_SLOTS - 1) {
- mas->node = mn;
- ma_encoded_parent(mas);
- unsigned char split = ma_split(mas, p_slot, p_end, depth + 1);
- if (mas_is_err(mas))
- return 0;
-
- if (split < slot)
- slot -= split;
-
- mn = mt_to_node(mas->node);
- mas->node = full;
- old_parent = mt_parent(mn);
- p_slot = mt_parent_slot(mn);
- p_end = ma_data_end_r64(&old_parent->mr64, UINT_MAX);
- }
-
- mas_node_cnt(mas, 3);
- if (mas_is_err(mas))
- return 0;
-
- new_parent = ma_next_alloc(mas);
- left = ma_next_alloc(mas);
- right = ma_next_alloc(mas);
-
- split = ma_cp_data_64(mas, left, right, 0);
-
- new_parent->parent = old_parent->parent;
- nparent64 = &new_parent->mr64;
-
- if (!ma_is_root(full)) {
- MA_CP(cp, old_parent, new_parent, 0, p_slot);
- ma_copy(mas, &cp);
- cp.dst_start += 1;
- cp.src_start = p_slot+1;
- cp.src_end = p_end;
- ma_copy(mas, &cp);
- }
-
- mt_set_parent(left, new_parent, p_slot);
- if (split >= MAPLE_RANGE64_SLOTS - 1)
- nparent64->pivot[p_slot] = mn->mr64.pivot[split - 1];
- else
- nparent64->pivot[p_slot] = mn->mr64.pivot[split];
-
- RCU_INIT_POINTER(nparent64->slot[p_slot],
- mt_mk_node(left, mt_node_type(full)));
-
- mt_set_parent(right, new_parent, ++p_slot);
- nparent64->pivot[p_slot] = mas->max;
- RCU_INIT_POINTER(nparent64->slot[p_slot],
- mt_mk_node(right, mt_node_type(full)));
-
- if (ma_is_root(old_parent)) {
- mas->node = mt_mk_node(new_parent, maple_range_64);
- mas->node = mt_mk_root(mas->node);
- if (!mt_is_leaf(left)) {
- ma_adopt_children(left);
- ma_adopt_children(right);
- }
- } else {
- struct maple_node *gparent = mt_parent(old_parent);
- old_parent = gparent->mr64.slot[mt_parent_slot(old_parent)];
- mas->node = mt_mk_node(new_parent, mt_node_type(old_parent));
- }
- mt_replace(mas); // Replace old with new parent & free.
-
- mas->node = nparent64->slot[p_slot-1];
- mas->max = nparent64->pivot[p_slot-1];
- if (split <= slot) {
- mas->node = nparent64->slot[p_slot];
- mas->min = nparent64->pivot[p_slot-1];
- mas->max = nparent64->pivot[p_slot];
- } else {
- }
-
- mt_free(mn); // Free full node.
- return split;
-}
/* Private
*
* Insert entry into a node.