return 0;
}
-/*
- * mas_offset() - get the offset into a given node (slot/pivot number)
- * @mas: The maple state
- *
- * Returns: The offset into the @mas node of interest.
- */
-static inline unsigned char mas_offset(const struct ma_state *mas)
-{
- return mas->offset;
-}
-
-/*
- * mas_set_offset() - set the offset into a give node (slot/pivot number)
- * @mas: The maple state
- * @offset: The offset
- *
- */
-static inline void mas_set_offset(struct ma_state *mas, unsigned char offset)
-{
- mas->offset = offset;
-}
-
/*
* ma_pivots() - Get the pivot of a node.
* @node - the maple node.
*/
static inline void mas_descend(struct ma_state *mas)
{
- unsigned char slot = mas_offset(mas);
-
- if (slot)
- mas->min = mas_safe_pivot(mas, slot - 1) + 1;
- mas->max = mas_safe_pivot(mas, slot);
- mas->node = mas_get_slot(mas, mas_offset(mas));
+ if (mas->offset)
+ mas->min = mas_safe_pivot(mas, mas->offset - 1) + 1;
+ mas->max = mas_safe_pivot(mas, mas->offset);
+ mas->node = mas_get_slot(mas, mas->offset);
}
static inline void mte_set_gap(const struct maple_enode *mn,
mas->min = 0;
mas->max = ULONG_MAX;
mas->depth = 0;
- mas_set_offset(mas, 0);
+ mas->offset = 0;
if (!mas_root(mas)) // empty tree.
goto done;
entry = mas_root(mas);
mas->node = MAS_ROOT;
- mas_set_offset(mas, MAPLE_NODE_SLOTS);
+ mas->offset = MAPLE_NODE_SLOTS;
}
}
while ((range_start < limit) && (offset < mt_slot_count(mas->node))) {
entry = mas_slot(mas, slots, offset);
if (entry) {
- mas_set_offset(mas, offset);
+ mas->offset = offset;
return range_start;
}
range_start = mas_safe_pivot(mas, offset) + 1;
struct maple_enode *entry;
void **slots = ma_slots(mte_to_node(mas->node), mt);
- for (offset = mas_offset(mas); offset < mt_slots[mt]; offset++) {
+ for (offset = mas->offset; offset < mt_slots[mt]; offset++) {
entry = slots[offset];
if (!entry) // end of node data.
break;
if (mte_parent(entry) == mas_mn(mas)) {
- mas_set_offset(mas, offset);
+ mas->offset = offset;
mas_dup_state(child, mas);
- mas_set_offset(mas, offset + 1);
+ mas->offset = offset + 1;
mas_descend(child);
return true;
}
for (i = 0; i < 3; i++) {
mas_dup_state(&list[i], mas);
- mas_set_offset(&list[i], 0);
- mas_set_offset(&next[i], 0);
+ list[i].offset = 0;
+ next[i].offset = 0;
}
mas_dup_state(&next[0], mas);
next[n++].node = MAS_NONE;
for (i = 0; i < 3; i++) { // descend.
- mas_set_offset(&next[i], 0);
+ next[i].offset = 0;
mas_dup_state(&list[i], &next[i]);
}
}
struct maple_big_node *b_node,
void *entry, unsigned char end)
{
- unsigned char slot = mas_offset(mas);
+ unsigned char slot = mas->offset;
void *contents = mas_get_slot(mas, slot);
unsigned char b_end = 0;
// Possible underflow of piv will wrap back to 0 before use.
}
// Store the new entry.
- mas_set_offset(mas, b_end);
+ mas->offset = b_end;
b_node->slot[b_end] = entry;
b_node->pivot[b_end] = mas->last;
return false;
mas_ascend(mas);
- mas_set_offset(mas, p_slot - 1);
+ mas->offset = p_slot - 1;
mas_descend(mas);
return true;
}
return false;
mas_dup_state(mas, &parent);
- mas_set_offset(mas, p_slot);
+ mas->offset = p_slot;
mas_descend(mas);
return true;
}
mas_node_walk(mast->orig_l, mte_node_type(mast->orig_l->node),
&range_min, &range_max);
mast->orig_l->index = l_index;
- l_off = mas_offset(mast->orig_l);
- r_off = mas_offset(mast->orig_r);
+ l_off = mast->orig_l->offset;
+ r_off = mast->orig_r->offset;
if (mast->orig_l->node == mast->orig_r->node) {
slots = ma_slots(mte_to_node(mast->orig_l->node),
mte_node_type(mast->orig_l->node));
mast->l->min = mast->orig_l->min;
mast->orig_l->index = mast->orig_l->min;
mast->bn->b_end = end + 1 + b_end;
- mas_set_offset(mast->l, mas_offset(mast->l) + end + 1);
+ mast->l->offset += end + 1;
}
static inline bool mast_sibling_rebalance_left(struct maple_subtree_state *mast)
return false;
}
- mas_set_offset(mast->orig_l, 0);
+ mast->orig_l->offset = 0;
mast_rebalance_prev(mast, old_l);
return true;
}
if (left != right)
mat_add(mast->free, right);
- mas_set_offset(mast->orig_r, 0);
+ mast->orig_r->offset = 0;
mast->orig_r->index = mast->r->max;
/* last should be larger than or equal to index */
if (mast->orig_r->last < mast->orig_r->index)
if (!mas_node_walk(mast->orig_r,
mte_node_type(mast->orig_r->node),
&range_min, &range_max)) {
- mas_set_offset(mast->orig_r, mas_data_end(mast->orig_r) + 1);
+ mast->orig_r->offset = mas_data_end(mast->orig_r) + 1;
}
/* Set up the left side of things */
- mas_set_offset(mast->orig_l, 0);
+ mast->orig_l->offset = 0;
mast->orig_l->index = mast->l->min;
mas_node_walk(mast->orig_l, mte_node_type(mast->orig_l->node),
&range_min, &range_max);
if (middle)
r = middle;
- slot = mas_offset(mast->l);
+ slot = mast->l->offset;
mte_mid_split_check(&l, &r, right, slot, &split, mid_split);
// Set left parent.
*/
static inline void mast_combine_cp_left(struct maple_subtree_state *mast)
{
- unsigned char l_slot = mas_offset(mast->orig_l);
+ unsigned char l_slot = mast->orig_l->offset;
if (!l_slot)
return;
if (mast->bn->pivot[mast->bn->b_end - 1] >= mast->orig_r->max)
return;
- mas_mab_cp(mast->orig_r, mas_offset(mast->orig_r) + 1,
+ mas_mab_cp(mast->orig_r, mast->orig_r->offset + 1,
mt_slot_count(mast->orig_r->node), mast->bn,
mast->bn->b_end);
mast->orig_r->last = mast->orig_r->max;
mast_ascend_free(mast);
mast_combine_cp_left(mast);
- mas_set_offset(&l_mas, mast->bn->b_end);
+ l_mas.offset = mast->bn->b_end;
mab_set_b_end(mast->bn, &l_mas, left);
mab_set_b_end(mast->bn, &m_mas, middle);
mab_set_b_end(mast->bn, &r_mas, right);
* Big_node should just fit in a single node.
*/
ancestor = mas_new_ma_node(mas, mast->bn);
- mte_set_parent(mast->l->node, ancestor, mas_offset(mast->l));
- mte_set_parent(mast->r->node, ancestor, mas_offset(mast->r));
+ mte_set_parent(mast->l->node, ancestor, mast->l->offset);
+ mte_set_parent(mast->r->node, ancestor, mast->r->offset);
mte_to_node(ancestor)->parent = mas_mn(mas)->parent;
mast->l->node = ancestor;
mab_mas_cp(mast->bn, 0, mt_slots[mast->bn->type] - 1, mast->l);
- mas_set_offset(mas, mast->bn->b_end - 1);
+ mas->offset = mast->bn->b_end - 1;
return true;
}
} else {
mas_ascend(mas);
mat_add(mast->free, old);
- mas_set_offset(mas, mte_parent_slot(mas->node));
+ mas->offset = mte_parent_slot(mas->node);
}
mast->bn->min = mas->min;
- if (cp && mas_offset(mast->l))
- mas_mab_cp(mas, 0, mas_offset(mast->l) - 1, mast->bn, 0);
+ if (cp && mast->l->offset)
+ mas_mab_cp(mas, 0, mast->l->offset - 1, mast->bn, 0);
split = mast->bn->b_end;
mab_set_b_end(mast->bn, mast->l, mast->l->node);
- mas_set_offset(mast->r, mast->bn->b_end);
+ mast->r->offset = mast->bn->b_end;
mab_set_b_end(mast->bn, mast->r, mast->r->node);
if (mast->bn->pivot[mast->bn->b_end - 1] == mas->max)
cp = false;
mab_mas_cp(mast->bn, 0, split, mast->l);
mte_set_pivot(mast->r->node, 0, mast->r->max);
mab_mas_cp(mast->bn, split + 1, mast->bn->b_end, mast->r);
- mas_set_offset(mast->l, mte_parent_slot(mas->node));
+ mast->l->offset = mte_parent_slot(mas->node);
mast->l->max = mast->bn->pivot[split];
mast->r->min = mast->l->max + 1;
if (!mte_is_leaf(mas->node)) {
- p_slot = mas_offset(mast->orig_l);
+ p_slot = mast->orig_l->offset;
mas_set_split_parent(mast->orig_l, mast->l->node,
mast->r->node, &p_slot, split);
mas_set_split_parent(mast->orig_r, mast->l->node,
split = mab_no_null_split(mast->bn, split, mt_slots[mast->bn->type]);
// Update parent slot for split calculation.
if (left)
- mas_set_offset(mast->orig_l,
- mas_offset(mast->orig_l) + end + 1);
+ mast->orig_l->offset += end + 1;
mast_split_data(mast, mas, split);
mast_fill_bnode(mast, mas, 2);
{
unsigned long *pivots = ma_pivots(mas_mn(mas), type);
unsigned long min, pivot = 0;
- unsigned char i = mas_offset(mas);
+ unsigned char i = mas->offset;
min = mas_safe_min(mas, pivots, i);
if (ma_is_dense(type)) {
if (!pivot && i) {
if (mas->max < mas->index) {
- mas_set_offset(mas, MAPLE_NODE_SLOTS);
+ mas->offset = MAPLE_NODE_SLOTS;
return false;
}
pivot = mas->max;
dense:
*range_min = min;
*range_max = pivot;
- mas_set_offset(mas, i);
+ mas->offset = i;
return true;
}
// Traverse.
mas->max = *range_max;
mas->min = *range_min;
- mas->node = mas_get_slot(mas, mas_offset(mas));
- mas_set_offset(mas, 0);
+ mas->node = mas_get_slot(mas, mas->offset);
+ mas->offset = 0;
}
return true;
}
static inline void mas_extend_null(struct ma_state *l_mas, struct ma_state *r_mas)
{
- unsigned char l_slot = mas_offset(l_mas);
- unsigned char r_slot = mas_offset(r_mas);
+ unsigned char l_slot = l_mas->offset;
+ unsigned char r_slot = r_mas->offset;
unsigned char cp_r_slot = r_slot;
unsigned long range_max = mas_safe_pivot(r_mas, r_slot);
unsigned long range_min = l_mas->min;
l_mas->index = mas_safe_pivot(l_mas, l_slot - 2) + 1;
else
l_mas->index = l_mas->min;
- mas_set_offset(l_mas, l_slot - 1);
+ l_mas->offset = l_slot - 1;
}
slots = ma_slots(mte_to_node(r_mas->node),
r_mas->last = r_mas->max;
if (l_mas != r_mas)
- mas_set_offset(r_mas, cp_r_slot);
+ r_mas->offset = cp_r_slot;
}
/*
if (ma_is_leaf(type)) // Leaf.
return true;
- next = mas_get_slot(mas, mas_offset(mas));
+ next = mas_get_slot(mas, mas->offset);
if (!next)
return false;
mas->max = *range_max;
mas->min = *range_min;
mas->node = next;
- mas_set_offset(mas, 0);
+ mas->offset = 0;
}
return ret;
}
r_mas.last++;
r_mas.index = r_mas.last;
- mas_set_offset(&r_mas, 0);
+ r_mas.offset = 0;
__mas_walk(&r_mas, &range_min, &range_max);
r_mas.last = r_mas.index = mas->last;
// Set up left side.
mas_dup_state(&l_mas, mas);
l_mas.depth = mas->depth;
- mas_set_offset(&l_mas, 0);
+ l_mas.offset = 0;
__mas_walk(&l_mas, &range_min, &range_max);
MT_BUG_ON(mas->tree, l_mas.depth != r_mas.depth);
mas_extend_null(&l_mas, &r_mas);
mas->index = l_mas.index;
mas->last = l_mas.last = r_mas.index = r_mas.last;
- mas_set_offset(mas, mas_offset(&l_mas));
+ mas->offset = l_mas.offset;
}
b_node.b_end = mas_store_b_node(&l_mas, &b_node, entry,
mas_data_end(&l_mas));
// Copy r_mas into b_node.
- mas_mab_cp(&r_mas, mas_offset(&r_mas), mt_slot_count(r_mas.node),
+ mas_mab_cp(&r_mas, r_mas.offset, mt_slot_count(r_mas.node),
&b_node, b_node.b_end + 1);
// Stop spanning searches by searching for just index.
l_mas.index = l_mas.last = mas->index;
if (offset + 1 < mt_pivots[mt])
pivots[offset + 1] = mas->last;
slots[offset + 1] = entry;
- mas_set_offset(mas, offset + 1);
+ mas->offset = offset + 1;
pivots[offset] = mas->index - 1;
goto done;
}
/* At this point, we are at the leaf node that needs to be altered. */
/* Calculate needed space */
- offset = mas_offset(mas);
+ offset = mas->offset;
content = mas_get_slot(mas, offset);
if (!overwrite && ((mas->last > r_max) || content)) {
mas_set_err(mas, -EEXIST);
MA_STATE(r_mas, mas->tree, mas->last, mas->last);
- mas_set_offset(&r_mas, offset);
+ r_mas.offset = offset;
r_mas.node = mas->node;
mas_node_walk(&r_mas, mte_node_type(r_mas.node), &rmin,
&rmax);
mas_extend_null(mas, &r_mas);
mas->last = r_mas.last;
- offset = mas_offset(mas);
+ offset = mas->offset;
r_min = mas_safe_min(mas, pivots, offset);
r_max = _mas_safe_pivot(mas, pivots, offset, mt);
}
static inline int mas_dead_node(struct ma_state *mas, unsigned long index);
/*
* mas_prev_node() - Find the prev non-null entry at the same level in the
- * tree. The prev value will be mas->node[mas_offset(mas)] or MAS_NONE.
+ * tree. The prev value will be mas->node[mas->offset] or MAS_NONE.
*/
static inline void mas_prev_node(struct ma_state *mas, unsigned long limit)
{
mas->max = mas_safe_pivot(mas, offset);
}
- mas_set_offset(mas, offset);
+ mas->offset = offset;
mas->min = mas_safe_min(mas, ma_pivots(mas_mn(mas),
mte_node_type(mas->node)),
offset);
* @mas: The maple state
* @max: The maximum pivot value to check.
*
- * Returns: The next value will be mas->node[mas_offset(mas)] or MAS_NONE.
+ * Returns: The next value will be mas->node[mas->offset] or MAS_NONE.
*
* Finds the next non-null entry at the same level in the tree. Slot is passed
- * in the maple state offset, eg: mas_set_offset(mas, offset)
+ * in the maple state offset, eg: mas->offset
*/
static inline unsigned long mas_next_node(struct ma_state *mas,
unsigned long *max)
{
unsigned long pivot = mas->max;
- unsigned char slot = mas_offset(mas);
+ unsigned char slot = mas->offset;
void *entry;
if (!slot)
return false;
*max = pivot;
- mas_set_offset(mas, slot);
+ mas->offset = slot;
return true;
}
enum maple_type type = mte_node_type(mas->node);
unsigned long pivot = mas->min;
unsigned long r_start = *range_start;
- unsigned char offset = mas_offset(mas);
+ unsigned char offset = mas->offset;
unsigned long *pivots = ma_pivots(mas_mn(mas), type);
void **slots = ma_slots(mas_mn(mas), type);
found:
mas->last = pivot;
*range_start = r_start;
- mas_set_offset(mas, offset);
+ mas->offset = offset;
return true;
}
prev_min = mas->min;
prev_max = mas->max;
while (range_start < limit) {
- mas_set_offset(mas, slot);
+ mas->offset = slot;
if (!mas_next_nentry(mas, limit, &range_start)) {
entry = mas_get_slot(mas, slot - 1);
if (mte_is_leaf(mas->node)) {
mas->node = entry;
slot = 0;
} else {
- slot = mas_offset(mas) + 1;
+ slot = mas->offset + 1;
prev_min = prev_max + 1;
if (range_start > prev_min)
prev_min = range_start;
{
void *entry = NULL;
unsigned long index = mas->index;
- unsigned char slot = mas_offset(mas);
+ unsigned char slot = mas->offset;
- mas_set_offset(mas, slot + 1);
+ mas->offset = slot + 1;
retry:
*range_start = mas->last + 1;
while (!mas_is_none(mas)) {
struct maple_enode *last_node = mas->node;
- slot = mas_offset(mas);
+ slot = mas->offset;
if (slot >= mt_slot_count(mas->node))
goto next_node;
- if (!mte_is_leaf(mas->node) || !mas_offset(mas)) {
+ if (!mte_is_leaf(mas->node) || !mas->offset) {
*range_start = mas_first_entry(mas, limit);
if (mas_is_none(mas)) {
mas->node = last_node;
next_node:
mas_next_node(mas, limit);
- mas_set_offset(mas, 0);
+ mas->offset = 0;
}
if (mas_is_none(mas))
return NULL;
- entry = mas_get_slot(mas, mas_offset(mas));
+ entry = mas_get_slot(mas, mas->offset);
if (mas_dead_node(mas, index))
goto retry;
static inline void *_mas_prev(struct ma_state *mas, unsigned long limit)
{
unsigned long max = mas->max;
- unsigned char offset;
+ unsigned long *pivots;
while (!mas_is_none(mas)) {
if (mas_prev_nentry(mas, limit, &max))
break;
mas_prev_node(mas, limit);
- mas_set_offset(mas, mt_slot_count(mas->node));
+ mas->offset = mt_slot_count(mas->node);
}
if (mas_is_none(mas)) {
return NULL;
}
+ pivots = ma_pivots(mas_mn(mas), mte_node_type(mas->node));
mas->last = max;
- offset = mas_offset(mas);
- mas->index = mas_safe_min(mas, ma_pivots(mas_mn(mas),
- mte_node_type(mas->node)),
- offset);
- return mas_get_slot(mas, mas_offset(mas));
+ mas->index = mas_safe_min(mas, pivots, mas->offset);
+ return mas_get_slot(mas, mas->offset);
}
/*
enum maple_type type = mte_node_type(mas->node);
unsigned long *pivots, *gaps;
void **slots;
- unsigned char offset = mas_offset(mas);
+ unsigned char offset = mas->offset;
unsigned long max;
unsigned long gap, min;
if (ma_is_dense(type)) { // dense nodes.
- mas_set_offset(mas, (unsigned char)(mas->index - mas->min));
+ mas->offset = (unsigned char)(mas->index - mas->min);
return true;
}
if (ma_is_leaf(type)) {
mas->min = min;
mas->max = min + gap - 1;
- mas_set_offset(mas, offset);
+ mas->offset = offset;
return true;
}
break;
mas->node = mas_slot(mas, slots, offset);
mas->min = min;
mas->max = max;
- mas_set_offset(mas, mt_pivot_count(mas->node));
+ mas->offset = mt_pivot_count(mas->node);
return false;
ascend:
if (mte_is_root(mas->node))
mas_set_err(mas, -EBUSY);
- mas_set_offset(mas, offset);
+ mas->offset = offset;
return false;
}
bool found = false;
if (ma_is_dense(type)) {
- mas_set_offset(mas, mas->index - mas->min);
+ mas->offset = (unsigned char)(mas->index - mas->min);
return true;
}
if (!ma_is_leaf(type)) {
- offset = mas_offset(mas);
+ offset = mas->offset;
gaps = ma_gaps(mte_to_node(mas->node), type);
}
if (mte_is_root(mas->node))
found = true;
done:
- mas_set_offset(mas, offset);
+ mas->offset = offset;
return found;
}
return true;
if (mas_is_none(mas)) {
- mas_set_offset(mas, MAPLE_NODE_SLOTS);
+ mas->offset = MAPLE_NODE_SLOTS;
return false;
}
*range_max = 0;
if (!mas->index)
return true;
- mas_set_offset(mas, MAPLE_NODE_SLOTS);
+ mas->offset = MAPLE_NODE_SLOTS;
return false;
}
- mas_set_offset(mas, 0);
+ mas->offset = 0;
return __mas_walk(mas, range_min, range_max);
}
if (mas_dead_node(mas, index))
goto retry;
- offset = mas_offset(mas);
+ offset = mas->offset;
if (offset == MAPLE_NODE_SLOTS)
return NULL; // Not found.
do {
if (mte_is_root(mas->node)) {
- slot = mas_offset(mas);
+ slot = mas->offset;
if (!slot) {
mas_set_err(mas, -EBUSY);
return false;
}
} while (!slot);
- mas_set_offset(mas, --slot);
+ mas->offset = --slot;
return true;
}
{
struct maple_enode *last = NULL;
- mas_set_offset(mas, mt_pivot_count(mas->node));
+ mas->offset = mt_pivot_count(mas->node);
/* There are 4 options:
* go to child (descend)
do {
if (mte_is_root(mas->node)) {
- slot = mas_offset(mas);
+ slot = mas->offset;
if (slot > mt_slot_count(mas->node) - 1) {
mas_set_err(mas, -EBUSY);
return false;
}
} while (slot > mt_slot_count(mas->node) - 1);
- mas_set_offset(mas, ++slot);
+ mas->offset = ++slot;
if (slot > 0)
mas->min = mte_pivot(mas->node, slot - 1) + 1;
mas->max = _mas_safe_pivot(mas, pivots, pslot, ptype);
mas->min = mas_safe_min(mas, pivots, pslot);
mas->node = mn;
- mas_set_offset(mas, slot);
+ mas->offset = slot;
_mas_store(mas, entry, false);
return 0;
}
void mas_set_fwd_index(struct ma_state *mas, unsigned long size)
{
unsigned long min = mas->min;
- unsigned char slot = mas_offset(mas);
+ unsigned char slot = mas->offset;
// At this point, mas->node points to the right node and we have a
// slot that has a sufficient gap.
if (slot)
if (mas_is_err(mas))
return xa_err(mas->node);
- if (mas_offset(mas) == MAPLE_NODE_SLOTS)
+ if (mas->offset == MAPLE_NODE_SLOTS)
return -EBUSY;
if (forward)
if (mas_is_err(mas))
return xa_err(mas->node);
- slot = mas_offset(mas);
+ slot = mas->offset;
if (slot == MAPLE_NODE_SLOTS)
goto no_gap;
if (mas_is_err(mas))
return xa_err(mas->node);
- slot = mas_offset(mas);
+ slot = mas->offset;
if (slot == MAPLE_NODE_SLOTS)
goto no_gap;
if (mas_is_ptr(mas) && mas->last == 0)
return mte_safe_root(mas->tree->ma_root);
- offset = mas_offset(mas);
+ offset = mas->offset;
if (offset >= MAPLE_NODE_SLOTS)
return NULL;
rcu_read_lock();
leaf = _mas_walk(&mas, &range_start, &range_end);
- slot = mas_offset(&mas);
+ slot = mas.offset;
if (leaf == true && slot != MAPLE_NODE_SLOTS)
entry = mas_get_slot(&mas, slot);
mtree_lock(mas.tree);
retry:
- mas_set_offset(&mas, 0);
+ mas.offset = 0;
mas.index = min;
mas.last = max - size;
ret = mas_alloc(&mas, entry, size, startp);