return ((unsigned long)node->parent & MA_ROOT_PARENT);
}
-static inline bool mte_is_root(struct maple_enode *node)
+static inline bool mte_is_root(const struct maple_enode *node)
{
return _ma_is_root(mte_to_node(node));
}
static inline struct maple_enode *mas_start(struct ma_state *mas)
{
- if (mas->node == MAS_START) {
+ if (mas_is_start(mas)) {
+ struct maple_enode *root;
+
mas->min = 0;
+ if (!mas->tree->ma_root) // empty tree.
+ return NULL;
+
if (!xa_is_node(mas->tree->ma_root)) {
if (mas->index > 0)
return NULL;
mas->node = MAS_ROOT;
mas_set_slot(mas, MAPLE_NODE_SLOTS);
- return NULL;
+ return mas->node;
}
- struct maple_enode *root = mte_safe_root(
- mas->tree->ma_root);
+ root = mte_safe_root(mas->tree->ma_root);
mas->max = mt_node_max(root);
return root;
}
if (mas_next_nentry(mas, max, &pivot))
break;
+ if (mte_is_root(mas->node)) {
+ mas->node = MAS_NONE;
+ break;
+ }
+
p_slot = mte_parent_slot(mas->node);
mas_set_slot(mas, p_slot);
mas_next_node(mas, max);
static inline bool _mas_walk(struct ma_state *mas)
{
mas->node = mas_start(mas);
+ if (!mas->node) {
+ mas_set_slot(mas, MAPLE_NODE_SLOTS);
+ return false;
+ }
+
+ if (mas->node == MAS_ROOT)
+ return true;
+
mas_set_slot(mas, 0);
return __mas_walk(mas);
}
{
if (!mas->node)
return 0;
+
if (!mte_dead_node(mas->node))
return 0;
unsigned char slot = 0;
if (!mas->node)
- return MAS_NONE;
+ goto not_found;
- if (mas->node == MAS_START) {
+ if (mas_is_start(mas)) {
_mas_walk(mas);
+ if (!mas->node)
+ return NULL;
+
+ if (mas->node == MAS_ROOT)
+ return mas->tree->ma_root;
+
do {} while (mas_dead_node(mas, mas->index));
slot = mas_get_slot(mas);
goto done;
}
}
+ if (mas->node == MAS_ROOT)
+ goto not_found;
last_piv = mas_safe_next_entry(mas, max);
if (mas->node == MAS_NONE)
rcu_read_lock();
_mas_walk(&mas);
+ if (!mas.node)
+ goto done;
+
+ if (mas.node == MAS_ROOT) {
+ entry = mas.tree->ma_root;
+ goto done;
+ }
+
do {} while (mas_dead_node(&mas, mas.index));
slot = mas_get_slot(&mas);
rcu_read_lock();
_mas_walk(&mas);
+ if (!mas.node)
+ goto done;
+
+ if (mas.node == MAS_ROOT) {
+ entry = mas.tree->ma_root;
+ goto done;
+ }
retry:
mas_set_slot(&mas, mas_get_slot(&mas) + 1);
mas_safe_next_entry(&mas, max);
unsigned char slot, coalesce;
mas->node = mas_start(mas);
+ if (!mas->node) {
+ mas_set_slot(mas, MAPLE_NODE_SLOTS);
+ return;
+ }
slot = mas_data_end(mas, mte_node_type(mas->node), &last_piv, &coalesce);
mas_set_slot(mas, slot);
struct maple_enode *last = NULL;
mas->node = mas_start(mas);
+ if (!mas->node)
+ return;
+
mas_set_slot(mas, 0);
/* There are 4 options:
unsigned long min;
mas->node = mas_start(mas);
+ if (!mas->node) {
+ slot = 0;
+ goto empty_tree;
+ }
+
if (!xa_is_node(rcu_dereference(mas->tree->ma_root))) {
ma_root_expand(mas, entry);
if (!mas->index)
}
mas_awalk(mas, size);
+ // cannot be an empty tree here.
+
if (mas_is_err(mas))
return xa_err(mas->node);
if (mas->index < min)
mas->index = min;
+empty_tree:
return mas_fill_gap(mas, entry, slot, size, index);
no_gap:
unsigned char slot = MAPLE_NODE_SLOTS;
mas->node = mas_start(mas);
+ if (!mas->node) {
+ slot = 0;
+ goto empty_tree;
+ }
+
if (!xa_is_node(rcu_dereference(mas->tree->ma_root))) {
ma_root_expand(mas, entry);
if (!mas->index)
}
mas_rev_awalk(mas, size);
+ // cannot be empty tree.
+
if (mas_is_err(mas))
return xa_err(mas->node);
mas->last = mas->index + size - 1;
+empty_tree:
return mas_fill_gap(mas, entry, slot, size, index);
no_gap: