*/
static inline void mas_descend(struct ma_state *mas)
{
+ enum maple_type type;
+ unsigned long *pivots;
+ struct maple_node *node;
+ void **slots;
+
+ node = mas_mn(mas);
+ type = mte_node_type(mas->node);
+ pivots = ma_pivots(node, type);
+ slots = ma_slots(node, type);
+
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);
+ mas->min = pivots[mas->offset - 1] + 1;
+ mas->max = _mas_safe_pivot(mas, pivots, mas->offset, type);
+ mas->node = mas_slot(mas, slots, mas->offset);
}
static inline void mte_set_gap(const struct maple_enode *mn,
{
void *entry = NULL;
- if (mas_is_err(mas))
+ if (unlikely(mas_is_err(mas)))
return NULL;
- if (mas_is_start(mas)) {
+ if (likely(mas_is_start(mas))) {
struct maple_enode *root;
mas->node = MAS_NONE;
mas->max = ULONG_MAX;
mas->depth = 0;
mas->offset = 0;
- if (!mas_root(mas)) // empty tree.
+ if (unlikely(!mas_root(mas))) // empty tree.
goto done;
root = mte_safe_root(mas_root(mas));
- if (xa_is_node(mas_root(mas))) {
+ if (unlikely(xa_is_node(mas_root(mas)))) {
mas->node = root;
} else {
// Single entry tree.
}
static inline unsigned long
ma_max_gap(struct maple_node *node, unsigned long *gaps, enum maple_type mt,
- unsigned char *offset)
+ unsigned char *off)
{
- unsigned char i = ma_meta_end(node, mt);
+ unsigned char offset, i;
unsigned long max_gap = 0;
+ i = offset = ma_meta_end(node, mt);
do {
if (gaps[i] > max_gap) {
max_gap = gaps[i];
- *offset = i;
+ offset = i;
}
} while (i--);
+ *off = offset;
return max_gap;
}
unsigned long limit)
{
void **slots, *entry;
- unsigned long range_start = mas->min;
+ unsigned long max = mas->max, range_start = mas->min;
+ unsigned char offset;
- while (!mte_is_leaf(mas->node)) {
- mas->max = mte_pivot(mas->node, 0);
- slots = ma_slots(mte_to_node(mas->node),
- mte_node_type(mas->node));
- mas->node = slots[0];
+ while (likely(!mte_is_leaf(mas->node))) {
+ max = mte_pivot(mas->node, 0);
+ mas->node = mas_get_slot(mas, 0);
}
+ mas->max = max;
slots = ma_slots(mte_to_node(mas->node), mte_node_type(mas->node));
- mas->offset = 0;
- while ((range_start < limit) && (mas->offset < mt_slot_count(mas->node))) {
- entry = mas_slot(mas, slots, mas->offset);
+ offset = 0;
+ while ((range_start < limit) &&
+ (offset < mt_slot_count(mas->node))) {
+ entry = mas_slot(mas, slots, offset);
if (entry)
- return range_start;
- range_start = mas_safe_pivot(mas, mas->offset) + 1;
- mas->offset++;
+ goto done;
+ range_start = mas_safe_pivot(mas, offset) + 1;
+ offset++;
}
mas->node = MAS_NONE;
+done:
+ mas->offset = offset;
return range_start;
}
for (offset = 0; offset < mt_slots[type]; offset++) {
child = slots[offset];
- if (!child)
+ if (unlikely(!child))
break;
mte_set_parent(child, parent, offset);
}
*
*/
static inline bool mas_new_child(struct ma_state *mas, struct ma_state *child)
+ __must_hold(mas->tree->lock)
{
- enum maple_type mt = mte_node_type(mas->node);
- unsigned char offset;
+ enum maple_type mt;
+ unsigned char offset, count;
struct maple_enode *entry;
- void **slots = ma_slots(mte_to_node(mas->node), mt);
+ struct maple_node *node;
+ void **slots;
- for (offset = mas->offset; offset < mt_slots[mt]; offset++) {
+ mt = mte_node_type(mas->node);
+ node = mas_mn(mas);
+ slots = ma_slots(node, mt);
+ count = mt_slots[mt];
+ for (offset = mas->offset; offset < count; offset++) {
entry = slots[offset];
- if (!entry) // end of node data.
+ if (unlikely(!entry)) // end of node data.
break;
- if (mte_parent(entry) == mas_mn(mas)) {
+ if (mte_parent(entry) == node) {
mas->offset = offset;
mas_dup_state(child, mas);
mas->offset = offset + 1;
unsigned long *range_min, unsigned long *range_max)
{
unsigned long *pivots = ma_pivots(mas_mn(mas), type);
- unsigned char offset;
+ unsigned char offset, count;
unsigned long min, max;
if (unlikely(ma_is_dense(type))) {
offset = mas->offset;
min = mas_safe_min(mas, pivots, offset);
- if (unlikely(offset == mt_pivots[type]))
+ count = mt_pivots[type];
+ if (unlikely(offset == count))
goto max;
- while (offset < mt_pivots[type]) {
+ while (offset < count) {
max = pivots[offset];
if (unlikely(!max && offset)) {
mas->depth++;
mas_node_walk(mas, type, range_min, range_max);
- if (unlikely(ma_is_leaf(type)))
+ if (ma_is_leaf(type))
return true;
next = mas_get_slot(mas, mas->offset);
enum maple_type type = mte_node_type(mas->node);
unsigned long pivot = mas->min;
unsigned long r_start;
- unsigned char offset = mas->offset;
+ unsigned char count, offset = mas->offset;
unsigned long *pivots = ma_pivots(mas_mn(mas), type);
void **slots = ma_slots(mas_mn(mas), type);
+ count = mt_slots[type];
r_start = mas_safe_min(mas, pivots, offset);
- while (offset < mt_slots[type]) {
+ while (offset < count) {
pivot = _mas_safe_pivot(mas, pivots, offset, type);
if (!pivot && offset)
goto no_entry;
unsigned char offset = mas->offset;
unsigned long index = mas->index;
enum maple_type mt = mte_node_type(mas->node);
+ unsigned long r_start;
mas->offset++;
retry:
- *range_start = mas->last + 1;
+ r_start = mas->last + 1;
while (!mas_is_none(mas)) {
if (mas->offset >= mt_slots[mt])
if (!ma_is_leaf(mt) || !mas->offset) {
prev_node = mas->node;
- *range_start = mas_first_entry(mas, limit);
+ r_start = mas_first_entry(mas, limit);
if (mas_is_none(mas)) {
mas->node = prev_node;
goto next_node;
}
}
- if (mas_next_nentry(mas, limit, range_start))
+ if (mas_next_nentry(mas, limit, &r_start))
break;
- if (*range_start > limit) {
+ if (r_start > limit) {
*range_start = limit;
mas->index = mas->last = limit;
mas->offset = offset;
if (mas_dead_node(mas, index))
goto retry;
+ *range_start = r_start;
return entry;
}