* @entry: Entry retrieved from the tree
* @max: maximum index to retrieve from the tree
*
+ * When returned, mas->index and mas->last will hold the entire range for the
+ * entry.
+ *
* Note: may return the zero entry.
*
*/
while ((entry = mas_find(mas, max)) != NULL)
/**
- * mt_for_each - Iterate over a range of the tree.
+ * mt_for_each - Searches for an entry starting at index until max.
*
*
*
*
*
*/
-#define mt_for_each(tree, entry, index, last, max) \
+#define mt_for_each(tree, entry, index, max) \
+ for (entry = mt_find(mt, index, max); \
+ entry; entry = mt_find_after(mt, &index, max))
unsigned char slot = ma_get_slot(mas);
unsigned char count = mt_slot_count(mas->node);
void *entry;
+ bool ret = false;
while (slot < count) {
pivot = ma_get_safe_pivot(mas, slot);
/* Valid pivot */;
entry = ma_get_rcu_slot(mas->node, slot);
- if (entry)
+ if (entry) {
+ ret = true;
break;
+ }
/* Ran over the limit, this is was the last slot to try */
if (pivot >= max)
slot++;
}
ma_set_slot(mas, slot);
- return true;
+ return ret;
no_entry:
return false;
}
-void *mt_find_after(struct ma_state *mas, unsigned long max)
+/* mt_find() - Search from start up until an entry is found.
+ *
+ * Note: Does not return the zero entry.
+ * returns an entry.
+ */
+static inline void *mt_find(struct maple_tree *mt, unsigned long start,
+ unsigned long max)
{
- void *entry = mas_find(mas, max);
+ MA_STATE(mas, mt, start, start);
+ unsigned char slot;
+ void *entry = NULL;
+
+ rcu_read_lock();
+ _mas_walk(&mas);
+ slot = ma_get_slot(&mas);
+ if (slot != MAPLE_NODE_SLOTS)
+ entry = ma_get_rcu_slot(mas.node, slot);
+
if (xa_is_zero(entry))
- return NULL;
+ entry = NULL;
+
+ if (entry)
+ goto done;
+
+retry:
+ mas_next_entry(&mas, max);
+ if (mas.node == MAS_NONE)
+ goto done;
+
+ slot = ma_get_slot(&mas);
+ entry = ma_get_rcu_slot(mas.node, slot);
+ if (xa_is_zero(entry))
+ goto retry;
+
+done:
+ rcu_read_unlock();
+
+ return entry;
+}
+
+/* mt_find_after() - Search up from the entry of index until an entry is
+ * found.
+ *
+ * Modifies index and last to point to the newly found range.
+ */
+static inline void *mt_find_after(struct maple_tree *mt, unsigned long *index,
+ unsigned long max)
+{
+ MA_STATE(mas, mt, *index, *index);
+ unsigned char slot;
+ void *entry = NULL;
+
+ rcu_read_lock();
+ _mas_walk(&mas);
+retry:
+ ma_set_slot(&mas, ma_get_slot(&mas) + 1);
+ mas_next_entry(&mas, max);
+ if (mas.node == MAS_NONE)
+ goto done;
+
+ slot = ma_get_slot(&mas);
+ entry = ma_get_rcu_slot(mas.node, slot);
+ if (xa_is_zero(entry))
+ goto retry;
+
+ *index = ma_get_safe_pivot(&mas, slot);
+done:
+ rcu_read_unlock();
return entry;
+
}
static inline void ma_inactive_insert(struct ma_state *mas, void *entry);
static inline int mas_replace_tree(struct ma_state *mas, void *new_entry)