mas->offset--;
not_found:
mas->index = mas->last = min;
+ mas->node = MAS_NONE;
return NULL;
}
*/
void *mas_prev(struct ma_state *mas, unsigned long min)
{
- if (!mas->index) {
- /* Nothing comes before 0 */
- mas->last = 0;
- mas->node = MAS_NONE;
- return NULL;
- }
+ if (mas->index <= min)
+ goto none;
if (unlikely(mas_is_ptr(mas)))
- return NULL;
+ goto none;
if (mas_is_none(mas) || mas_is_paused(mas))
mas->node = MAS_START;
if (mas_is_start(mas)) {
mas_walk(mas);
if (!mas->index)
- return NULL;
+ goto none;
}
if (mas_is_ptr(mas)) {
- if (!mas->index) {
- mas->last = 0;
- return NULL;
- }
-
mas->index = mas->last = 0;
- return mas_root_locked(mas);
+ return mas_root(mas);
}
return mas_prev_entry(mas, min);
+
+none:
+ mas->last = mas->index = min;
+ mas->node = MAS_NONE;
+ return NULL;
}
EXPORT_SYMBOL_GPL(mas_prev);
*/
void *mas_find_rev(struct ma_state *mas, unsigned long min)
{
+ if (unlikely(mas_is_none(mas))) {
+ if (mas->index <= min)
+ goto none;
+
+ mas->last = mas->index;
+ mas->node = MAS_PAUSE;
+ }
+
if (unlikely(mas_is_paused(mas))) {
- if (unlikely(mas->last == ULONG_MAX)) {
+ if (unlikely(mas->index <= min)) {
mas->node = MAS_NONE;
return NULL;
}
mas->last = --mas->index;
}
+ if (unlikely(mas_is_ptr(mas)))
+ goto none;
+
if (unlikely(mas_is_start(mas))) {
/* First run or continue */
void *entry;
return entry;
}
- if (unlikely(!mas_searchable(mas)))
- return NULL;
+ if (unlikely(!mas_searchable(mas))) {
+ if (mas_is_ptr(mas)) {
+ /*
+ * Walked to the location, and there was nothing so the
+ * previous location is 0.
+ */
+ mas->last = mas->index = 0;
+ return mas_root(mas);
+ }
+ goto none;
+ }
if (mas->index < min)
return NULL;
/* Retries on dead nodes handled by mas_prev_entry */
return mas_prev_entry(mas, min);
+
+none:
+ mas->node = MAS_NONE;
+ return NULL;
}
EXPORT_SYMBOL_GPL(mas_find_rev);