MA_STATE(tmp, mast->orig_r->tree, mast->orig_r->index, mast->orig_r->last);
mas_dup_state(&tmp, mast->orig_r);
- mas_set_offset(mast->orig_r,
- mte_parent_slot(mast->orig_r->node));
mas_next_node(mast->orig_r, ULONG_MAX);
if (!mas_is_none(mast->orig_r)) {
mast_rebalance_next(mast, old_r);
static inline unsigned long mas_next_node(struct ma_state *mas,
unsigned long max)
{
- int level;
- unsigned long start_piv;
+ unsigned long start_piv, prev_piv, pivot;
+ int offset, level = 0;
+ enum maple_type mt;
+ void **slots;
restart_next_node:
level = 0;
- while (1) {
- int offset;
- struct maple_enode *mn;
- unsigned long prev_piv;
- enum maple_type mt;
- void **slots;
-
- if (mte_is_root(mas->node) || mas->node == MAS_NONE)
+ while (!mas_is_none(mas)) {
+ if (mte_is_root(mas->node))
goto no_entry;
- mn = mas->node;
- offset= mas_offset(mas);
- start_piv = mas_safe_pivot(mas, offset);
- level++;
+ offset = mte_parent_slot(mas->node);
mas_ascend(mas);
-
+ start_piv = mas_safe_pivot(mas, offset);
if (mas_dead_node(mas, start_piv))
goto restart_next_node;
+ level++;
mt = mte_node_type(mas->node);
slots = ma_get_slots(mas_mn(mas), mt);
prev_piv = mas_safe_pivot(mas, offset);
- while (++offset< mt_slots[mt]) {
- unsigned long pivot = mas_safe_pivot(mas, offset);
-
- if (prev_piv > max)
- goto no_entry;
-
- if (!pivot && offset)
- break;
-
- mn = rcu_dereference(slots[offset]);
- if (!mn) {
- prev_piv = pivot;
- continue;
- }
+ if (prev_piv > max)
+ goto no_entry;
- mas->min = prev_piv + 1;
- mas->max = pivot;
+ if (prev_piv == mas->max) // last in node.
+ continue;
- if (level == 1) {
- mas_set_offset(mas, offset);
- mas->node = mn;
- if (mas_dead_node(mas, start_piv))
- goto restart_next_node;
+ if (++offset >= mt_slots[mt])
+ continue;
- return pivot;
- }
+ pivot = mas_safe_pivot(mas, offset);
+ // Descend, if necessary.
+ while (level > 1) {
level--;
- mas->node = mn;
- offset = -1;
+ mas->node = rcu_dereference(slots[offset]);
mt = mte_node_type(mas->node);
slots = ma_get_slots(mas_mn(mas), mt);
+ offset = 0;
+ pivot = mas_safe_pivot(mas, offset);
}
- if (mte_is_root(mas->node))
- goto no_entry;
- mas_set_offset(mas, mte_parent_slot(mas->node));
+ mas->node = rcu_dereference(slots[offset]);
+ mas->min = prev_piv + 1;
+ mas->max = pivot;
+ return mas->max;
}
no_entry:
mas->node = MAS_NONE;
return mas->max;
-
}
/*
*range_start = mas->last + 1;
while (!mas_is_none(mas)) {
- unsigned char p_slot = 0;
struct maple_enode *last_node = mas->node;
slot = mas_offset(mas);
}
next_node:
- p_slot = mte_parent_slot(mas->node);
- mas_set_offset(mas, p_slot);
mas_next_node(mas, limit);
mas_set_offset(mas, 0);
}
struct maple_enode *p = MAS_NONE, *mn = mas->node;
unsigned long p_min, p_max;
- mas_set_offset(mas, mte_parent_slot(mas->node));
mas_next_node(mas, max);
if (!mas_is_none(mas))
return;