call_rcu(&node->rcu, mt_free_rcu);
}
+static unsigned int mt_height(const struct maple_tree *mt)
+{
+ return (mt->ma_flags & MAPLE_HEIGHT) >> MAPLE_HEIGHT_OFFSET;
+}
+
+static void mas_set_height(struct ma_state *mas)
+{
+ unsigned int new_flags = mas->tree->ma_flags;
+ new_flags &= ~MAPLE_HEIGHT;
+ new_flags |= mas->depth << MAPLE_HEIGHT_OFFSET;
+ mas->tree->ma_flags = new_flags;
+}
+
+static unsigned int mas_mt_height(struct ma_state *mas)
+{
+ return mt_height(mas->tree);
+}
static inline enum maple_type mte_node_type(const struct maple_enode *entry)
{
mn->parent = ma_parent_ptr(
((unsigned long)mas->tree | MA_ROOT_PARENT));
rcu_assign_pointer(mas->tree->ma_root, mte_mk_root(mas->node));
- mas->tree->ma_height = mas->depth;
+ mas_set_height(mas);
} else {
mte_set_rcu_slot(parent, slot, mas->node);
}
mast_topiary(mast);
} while (!mte_is_root(mast->orig_l->node));
} else if ((mast->orig_l->node != mas->node) &&
- (mast->l->depth > mas->tree->ma_height)) {
+ (mast->l->depth > mas_mt_height(mas))) {
mat_add(mast->free, mas->node);
}
struct ma_state *mas, int height)
{
struct maple_enode *ancestor;
+ unsigned int mas_height = mas_mt_height(mas);
if (height <= mas->full_cnt)
return false;
mte_set_parent(mast->r->node, ancestor, mas_get_slot(mast->r));
mte_to_node(ancestor)->parent = mas_mn(mas)->parent;
// New root requires a new height.
- if (mas->full_cnt >= mas->tree->ma_height)
- mas->tree->ma_height++;
+ if (mas->full_cnt >= mas_height) {
+ mas->depth = mas_height + 1;
+ mas_set_height(mas);
+ }
mast->l->node = ancestor;
mab_mas_cp(mast->bn, 0, mt_slots[mast->bn->type] - 1, mast->l);
if ((b_node->b_end < mt_min_slot_cnt(mas->node)) &&
(!mte_is_root(mas->node)) &&
- (mas->tree->ma_height > 1))
+ (mas_mt_height(mas) > 1))
return mas_rebalance(mas, b_node);
#endif
/* swap the new root into the tree */
rcu_assign_pointer(mas->tree->ma_root, mte_mk_root(mas->node));
- mas->tree->ma_height = 1;
+ mas->depth = 1;
+ mas_set_height(mas);
return slot;
}
static inline int ma_root_ptr(struct ma_state *mas, void *entry,
/* Node rebalancing may occur due to this store, so there may be two new
* entries per level plus a new root.
*/
- node_cnt += 1 + mas->tree->ma_height * 2;
+ node_cnt += 1 + mas_mt_height(mas) * 2;
mas_node_cnt(mas, node_cnt);
if (mas_is_err(mas))
return 0;
l_mas.index = l_mas.last = mas->index;
// Calc the number of iterations of combining and splitting that will
// need to occur.
- count = mas_cnt_positive(mas) + mas->tree->ma_height - mas->depth + 1;
+ count = mas_cnt_positive(mas) + mas_mt_height(mas) - mas->depth + 1;
// Combine l_mas and r_mas and split them up evenly again.
return mas_spanning_rebalance(mas, &mast, count);
if (!mte_is_leaf(oldmas->node)) {
*node_cnt += mas_data_end(oldmas) + 1;
- *node_cnt *= 1 << (4 * (oldmas->tree->ma_height - 2)); // assume all other levels full.
+ *node_cnt *= 1 << (4 * (mas_mt_height(oldmas) - 2)); // assume all other levels full.
}
mas_dup_alloc(mas, node_cnt);
}
mt->ma_flags = 0;
- mt->ma_height = 0;
mt->ma_root = NULL;
mtree_unlock(mt);
}
mte_destroy_walk(mt->ma_root, mt);
mt->ma_flags = 0;
- mt->ma_height = 0;
rcu_assign_pointer(mt->ma_root, NULL);
mtree_unlock(mt);
}
void *entry = mt->ma_root;
pr_info("maple_tree("MA_PTR") flags %X, height %u root "MA_PTR"\n",
- mt, mt->ma_flags, mt->ma_height, entry);
+ mt, mt->ma_flags, mt_height(mt), entry);
if (!xa_is_node(entry))
mt_dump_entry(entry, 0, 0, 0);
else if (entry)