return false;
}
+/* Private
+ * Replace mn with mas->node in the tree
+ */
+void mt_replace(struct ma_state *mas, void *p_entry, bool leaf)
+{
+ struct maple_node *mn = mt_to_node(mas->node);
+ mn->parent = mt_to_node(p_entry)->parent;
+ if (!leaf)
+ ma_adopt_children(mn);
+
+ if (ma_is_root(p_entry)) {
+ mn->parent = (struct maple_node *)
+ ((unsigned long)mas->tree | MA_ROOT_PARENT);
+ rcu_assign_pointer(mas->tree->ma_root, mt_mk_root(mas->node));
+ } else {
+ struct maple_node *parent = mt_parent(mn->parent);
+ unsigned char slot = mt_parent_slot(mn);
+
+ RCU_INIT_POINTER(parent->slot[slot], mas->node);
+ }
+ mt_free(mt_to_node(p_entry));
+
+}
void *ma_insert(struct ma_state *mas, void *entry)
{
void *p_entry; // Previous entry.
if (mas_is_err(mas))
goto error;
- /* Insert into tree */
- mn->parent = mas->node->parent;
- if (!leaf)
- ma_adopt_children(mn);
-
- if (ma_is_root(p_entry)) {
- mn->parent = (struct maple_node *)
- ((unsigned long)mas->tree | MA_ROOT_PARENT);
- rcu_assign_pointer(mas->tree->ma_root, mt_mk_root(mas->node));
- } else {
- struct maple_node *parent = mt_parent(mn->parent);
-
- slot = mt_parent_slot(mn);
- RCU_INIT_POINTER(parent->slot[slot], mas->node);
- }
- mt_free(mt_to_node(p_entry));
+ /* Replace the node in the tree */
+ mt_replace(mas, p_entry, leaf);
return NULL;
error:
*/
int ma_erase(struct ma_state *mas)
{
- //bool leaf = _mas_walk(mas);
- return -EINVAL;
+ bool leaf = _mas_walk(mas);
+ int slot = ma_get_slot(mas);
+ struct maple_range_64 *mr64 = &mt_to_node(mas->node)->mr64;
+ unsigned long piv_val;
+ int cnt = -EINVAL;
+ void *p_entry; // Previous entry.
+ struct maple_node *mn;
+
+ if (slot == MAPLE_NODE_SLOTS)
+ return cnt;
+ rcu_assign_pointer(mr64->slot[slot], NULL);
+ if ((slot >= MAPLE_RANGE64_SLOTS - 1))
+ return 1;
+
+ if ((slot < MAPLE_RANGE64_SLOTS - 2) &&
+ ((mr64->pivot[slot + 1] == 0) ||
+ (mr64->slot[slot + 1] == NULL))) {
+ piv_val = mr64->pivot[++slot];
+ } else {
+ piv_val = mr64->pivot[slot];
+ }
+
+ cnt = 1;
+ /* Walk down and set all the previous pivots with NULLs to piv_val */
+ while(--slot >= 0 && mr64->slot[slot] == NULL) {
+ mr64->pivot[slot] = piv_val;
+ cnt++;
+ }
+
+ mn = mas_coalesce(mas);
+ if (mas_is_err(mas))
+ goto error;
+ p_entry = mas->node;
+ mas->node = mt_mk_node(mn, maple_leaf_64);
+ mt_replace(mas, p_entry, leaf);
+
+error:
+ return cnt;
}
void ma_destroy_walk(struct ma_state *mas)
return mtree_load(mt, index);
}
+static int mtree_test_erase(struct maple_tree *mt, unsigned long index)
+{
+ return mtree_erase(mt, index);
+}
+
static noinline void check_insert_range(struct maple_tree *mt,
unsigned long start, unsigned long end, void *ptr)
MT_BUG_ON(mt, ret != 0);
}
+static noinline void check_erase(struct maple_tree *mt, unsigned long index)
+{
+ int ret = -EINVAL;
+ ret = mtree_test_erase(mt, index);
+ MT_BUG_ON(mt, ret < 0);
+}
static noinline void check_dup_insert(struct maple_tree *mt,
unsigned long index, void *ptr)
{
check_insert(&tree, set[1], &tree); // 14
check_insert(&tree, set[2], ptr); // 17
check_insert(&tree, set[3], &tree); // 25
+ check_load(&tree, set[0], ptr);
+ check_load(&tree, set[1], &tree);
+ check_load(&tree, set[2], ptr);
+ check_load(&tree, set[3], &tree);
+ check_erase(&tree, set[1]);
+ check_load(&tree, set[1], NULL);
return 0;
check_insert(&tree, set[4], ptr); // 1000 < Should split.
check_load(&tree, set[0], ptr);