index = mas->index;
max = pivots[offset];
- if (index <= max)
+ if (unlikely(index <= max))
goto done;
+
if (unlikely(!max && offset))
goto max;
+
offset++;
min = max + 1;
while (offset < count) {
pivots = ma_pivots(node, type);
slots = ma_slots(node, type);
- offset = mas->offset;
- if (!ma_is_leaf(type))
+ if (ma_is_leaf(type))
+ gaps = NULL;
+ else
gaps = ma_gaps(node, type);
+ offset = mas->offset;
min = mas_safe_min(mas, pivots, offset);
while (mas->last < min) // Skip out of bounds.
min = mas_safe_min(mas, pivots, --offset);
index = mas->index;
while (index <= max) {
gap = 0;
- if (!ma_is_leaf(type))
+ if (gaps)
gap = gaps[offset];
else if (!mas_slot(mas, slots, offset))
gap = max - min + 1;
if ((size <= gap) && (size <= mas->last - min + 1))
break;
- if (ma_is_leaf(type)) {
+ if (!gaps) {
// Skip the next slot, it cannot be a gap.
if (offset < 2)
goto ascend;
offset -= 2;
max = pivots[offset];
- goto next;
+ min = mas_safe_min(mas, pivots, offset);
+ continue;
}
}
offset--;
max = min - 1;
-next:
min = mas_safe_min(mas, pivots, offset);
}
static inline bool mas_search_cont(struct ma_state *mas, unsigned long index,
unsigned long max, void *entry)
{
- if (mas_is_start(mas))
- return true;
-
if (index >= max)
return false;
if (mas_is_err(mas))
return false;
+ if (mas_is_start(mas))
+ return true;
+
if (entry)
return false;
return true;
}
-static void mas_rev_awalk(struct ma_state *mas, unsigned long size)
+static bool mas_rev_awalk(struct ma_state *mas, unsigned long size)
{
struct maple_enode *last = NULL;
* found the gap. (return, slot != MAPLE_NODE_SLOTS)
*/
while (!_mas_rev_awalk(mas, size)) {
- if (last == mas->node)
- mas_rewind_node(mas);
- else
+ if (last == mas->node) {
+ if (!mas_rewind_node(mas))
+ return false;
+ } else {
last = mas->node;
+ }
}
+ return true;
}
/* Skip this slot in the parent. */
// The start of the window can only be within these values.
mas->index = min;
mas->last = max;
- mas_rev_awalk(mas, size);
-
-
- if (unlikely(mas_is_err(mas)))
+ if (unlikely(!mas_rev_awalk(mas, size)))
return xa_err(mas->node);
if (unlikely(mas->offset == MAPLE_NODE_SLOTS))
static inline void *mas_range_load(struct ma_state *mas,
unsigned long *range_min, unsigned long *range_max)
{
- void *entry = NULL;
+ unsigned long index = mas->index;
+ if (mas_is_none(mas))
+ mas->node = MAS_START;
+
+ if (_mas_walk(mas, range_min, range_max))
+ if (unlikely(mas->node == MAS_ROOT))
+ return mas_root(mas);
retry:
- if (_mas_walk(mas, range_min, range_max)) {
- if (mas->last == 0 && mas_is_ptr(mas))
- return mte_safe_root(mas->tree->ma_root);
+ if (mas_dead_node(mas, index))
+ goto retry;
- if (mas->offset >= MAPLE_NODE_SLOTS)
- return NULL;
+ if (mas->offset == MAPLE_NODE_SLOTS)
+ return NULL; // Not found.
- entry = mas_get_slot(mas, mas->offset);
- if (mte_dead_node(mas->node))
- goto retry;
- }
+ return mas_get_slot(mas, mas->offset);
- return entry;
}
void *mas_load(struct ma_state *mas)
mas->index = *range_start;
if (entry)
return entry;
- } else if (!mas_searchable(mas))
+ }
+
+ if (unlikely(!mas_searchable(mas)))
return NULL;
entry = __mas_next(mas, limit, range_start);