(*slot)++;
}
+
+static inline void mas_wmb_replace(struct ma_state *mas,
+ struct ma_topiary *free,
+ struct ma_topiary *destroy)
+{
+ smp_wmb();
+
+ // Insert the new data in the tree
+ mas_replace(mas, true);
+
+ if (!mte_is_leaf(mas->node))
+ mas_descend_adopt(mas);
+
+ mat_free(free, false);
+
+ if (destroy)
+ mat_free(destroy, true);
+
+ if (mte_is_leaf(mas->node))
+ return;
+
+ if (mt_is_alloc(mas->tree))
+ mas_update_gap(mas, false);
+}
+
/* Private
*
* mas_combine_separate() - Follow the tree upwards from @l_mas and @r_mas for
mte_set_node_dead(mas->node);
// Set up mas for insertion.
mas_dup_state(mas, orig_l_mas);
- smp_wmb();
-
- // Insert new sub-tree
- mas_replace(mas, true);
- if (!mte_is_leaf(mas->node))
- mas_descend_adopt(mas);
-
- mat_free(&free, false);
- mat_free(&destroy, true);
-
- if (mte_is_leaf(mas->node))
- return b_node->b_end;
-
- if (mt_is_alloc(mas->tree))
- mas_update_gap(mas, false);
-
+ mas_wmb_replace(mas, &free, &destroy);
return b_node->b_end;
}
struct maple_enode *ancestor = MAS_NONE;
unsigned char split = 0;
- int j, i = 0, height = 0;
- struct maple_enode *list[15]; // Enough for an 8 level tree.
+ int j, height = 0;
MA_STATE(l_mas, mas->tree, mas->index, mas->last);
MA_STATE(r_mas, mas->tree, mas->index, mas->last);
MA_STATE(orig_l_mas, mas->tree, mas->index, mas->last);
MA_STATE(orig_r_mas, mas->tree, mas->index, mas->last);
+ MA_TOPIARY(mat, mas->tree);
+
// Allocation failures will happen early.
// TODO: Increase this by one when optimizing with a rebalance.
* into the highest common ancestor necessary to be modified (which may
* be a new root).
*/
- list[i++] = mas->node;
+ //list[i++] = mas->node;
while (height++ <= mas->full_cnt) {
struct maple_node *l, *r;
enum maple_type type = mte_node_type(mas->node);
if (mte_is_root(mas->node))
cp = false;
else {
+ struct maple_enode *old = mas->node;
+
mas_ascend(mas);
+ mat_add(&mat, old);
mas_set_slot(mas, mte_parent_slot(mas->node));
- list[i++] = mas->node;
}
if (cp && mas_get_slot(&l_mas))
j + 1);
}
-
- mas->node = ancestor;
- BUG_ON(mas_is_none(mas));
// Set the original node as dead
- mte_set_node_dead(list[0]);
- smp_wmb();
-
- // Insert the new data in the tree
- mas_replace(mas, true);
-
- mas_descend_adopt(mas);
- do {
- mte_free(list[--i]);
- } while (i);
-
- if (mt_is_alloc(mas->tree))
- mas_update_gap(mas, false);
-
+ mat_add(&mat, mas->node);
+ mas->node = ancestor;
+ mas_wmb_replace(mas, &mat, NULL);
return 1;
}