return entry;
}
-short ma_data_end_r64(const struct ma_state *ms)
+unsigned char ma_data_end_r64(const struct ma_state *ms)
{
struct maple_range_64 *mr64 = &ms->node->mr64;
- short data_end = 0;
+ unsigned char data_end = 0;
+ unsigned long last = ms->max;
for (data_end = 0; data_end < MAPLE_RANGE64_SLOTS - 1; data_end++) {
- if (mr64->pivot[data_end] == 0 ||
- mr64->pivot[data_end] == ms->max)
+ last = mr64->pivot[data_end];
+ if (last == 0 && data_end > 0)
return data_end;
}
- if (mr64->slot[data_end+1] != NULL)
+ if (mr64->slot[data_end + 1] != NULL)
data_end++;
return data_end;
}
+
static void ma_append(struct ma_state *ms, void *entry)
{
- short idx = ma_data_end_r64(ms) + 2;
+ short idx = ma_data_end_r64(ms) + 1;
struct maple_range_64 *mr64 = &ms->node->mr64;
- if ((ms->index - 1 != mr64->pivot[idx - 1]) ||
+ if ((ms->index - 1 != mr64->pivot[idx - 2]) ||
(ms->index != ms->last))
idx++;
printk("Split this node\n");
/* zero the new end */
- mr64->pivot[idx] = 0;
- RCU_INIT_POINTER(mr64->slot[idx], NULL);
- idx--;
+ mr64->pivot[idx--] = 0;
/* Set the entry value */
RCU_INIT_POINTER(mr64->slot[idx], entry);
- mr64->pivot[idx] = ms->last;
- idx--;
+ mr64->pivot[idx--] = ms->last;
/* Create a NULL gap, if necessary */
if ((ms->index - 1 != mr64->pivot[idx - 1]) ||
mr64->pivot[idx] = ms->index - 1;
}
}
+
static void ma_root_expand(struct ma_state *ms, void *entry)
{
void *r_entry = ms->tree->ma_root; // root entry
mn->parent = (struct maple_node*)
((unsigned long)ms->tree | MA_ROOT_PARENT);
+ /* Assign the old entry to slot 0, or set it to null. */
+ RCU_INIT_POINTER(mn->mr64.slot[0], r_entry);
+ if (!r_entry)
+ mn->mr64.pivot[0] = ms->index - 1;
- /*
- * Insert the existing entry into the new node
- * rcu_assign is not necessary as readers are not able to access this
- * node.
- */
- if (r_entry != NULL) {
- RCU_INIT_POINTER(mn->mr64.slot[0], r_entry);
- mn->mr64.pivot[0] = 0;
- }
ma_append(ms, entry);
-
/* swap the new root into the tree */
rcu_assign_pointer(ms->tree->ma_root, mt_mk_node(mn, maple_leaf_64));
}
break;
} while (i++ < MAPLE_RANGE64_SLOTS - 1);
- ms_update_limits(ms, i);
ms->node = rcu_dereference(mr64->slot[i]);
return i;
}
do {
ms->node = mt_to_node(e_entry);
p_entry = ms->node;
+ ms_update_limits(ms, slot);
slot = mas_walk_r64(ms, ms->index);
e_entry = ms->node;
} while (xa_is_node(e_entry));
void *mas_walk(struct ma_state *ms)
{
void *entry = mas_start(ms);
+ unsigned char slot;
/* Outside this nodes range, it doesn't exist. */
if (ms->min > ms->index ||
while (xa_is_node(entry)) {
ms->node = mt_to_node(entry);
- mas_walk_r64(ms, ms->index);
+ ms_update_limits(ms, slot);
+ slot = mas_walk_r64(ms, ms->index);
entry = ms->node;
}
return entry;
}
-void *ma_destroy_walk(struct ma_state *mas)
+void ma_destroy_walk(struct ma_state *mas)
{
struct maple_node *mn = mas->node;
unsigned int type = mt_node_type(mas->node);