From: Liam R. Howlett Date: Fri, 11 Jan 2019 15:46:29 +0000 (-0500) Subject: maple_tree: Refactor coalesce into a separate function. X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=1039559ba6043ee9bf6a114c657c5bbfa2ad7452;p=users%2Fjedix%2Flinux-maple.git maple_tree: Refactor coalesce into a separate function. Reworked logic to have a bit of a cleaner looking function. Supports full nodes now as well. Signed-off-by: Liam R. Howlett --- diff --git a/lib/maple_tree.c b/lib/maple_tree.c index 13958fa73eb9..198ef705a71d 100644 --- a/lib/maple_tree.c +++ b/lib/maple_tree.c @@ -437,58 +437,85 @@ static void mas_update_limits(struct ma_state *ms, unsigned char slot) if (slot < MAPLE_RANGE64_SLOTS - 1) ms->max = mr64->pivot[slot]; } +/* Private + * + * This copies from the start to the specified end of a node into a new node. + * Returns a pointer to the node, encoded node is in mas->node. + * Node: mas->node is overwritten. + */ +static struct maple_range_64 *mas_partial_copy(struct ma_state *mas, + unsigned char end) +{ + struct maple_node *smn = mt_to_node(mas->node); + struct maple_range_64 *src = &smn->mr64; + struct maple_range_64 *dst = NULL; + struct maple_node *dmn; + int i = 0; + /* Allocate a new node */ + mas_node_cnt(mas, 1); + if (mas_is_err(mas)) + return NULL; + dmn = ma_next_alloc(mas); + dst = &dmn->mr64; + dmn->parent = smn->parent; + for (i = 0; i < end;i++) + { + RCU_INIT_POINTER(dst->slot[i], + src->slot[i]); + dst->pivot[i] = src->pivot[i]; + } + mas->node = mt_mk_node(dmn, maple_leaf_64); + return dst; +} /* Private * Combine nulls with the same pivot value + * Note: The mas->node will most likely be changed, so keep track of the old + * mas->node to free it. */ static int mas_coalesce(struct ma_state *mas) { - struct maple_range_64 *src = &mt_to_node(mas->node)->mr64; + struct maple_node *smn = mt_to_node(mas->node); + struct maple_range_64 *src = &smn->mr64; unsigned char s_slot, d_slot = 0; unsigned long last = mas->max; struct maple_range_64 *dst = NULL; - struct maple_node *mn; + int ret = 0; for (s_slot = 0; s_slot < MAPLE_RANGE64_SLOTS; s_slot++) { if (s_slot < MAPLE_RANGE64_SLOTS - 1) { if (last == src->pivot[s_slot]) { if (!dst) { - int i = 0; - /* Allocate a new node */ - mas_node_cnt(mas, 1); + d_slot = s_slot; + dst = mas_partial_copy(mas, s_slot); if (mas_is_err(mas)) return 0; - mn = ma_next_alloc(mas); - dst = &mn->mr64; - mn->parent = src->parent; - for (i = 0; i <= s_slot;i++) - { - RCU_INIT_POINTER(dst->slot[i], - src->slot[i]); - dst->pivot[i] = src->pivot[i]; - } - d_slot = s_slot; - mas->node = mt_mk_node(mn, - maple_leaf_64); } continue; } if (s_slot != 0 && src->pivot[s_slot] == 0) - break; + goto done; last = src->pivot[s_slot]; + if (!dst) + continue; - if (dst) - dst->pivot[d_slot] = src->pivot[s_slot]; - } - if (dst) + dst->pivot[d_slot] = src->pivot[s_slot]; + RCU_INIT_POINTER(dst->slot[d_slot++], + src->slot[s_slot]); + } else if (dst && src->slot[s_slot] != NULL) { + dst->pivot[d_slot] = mas->max; RCU_INIT_POINTER(dst->slot[d_slot++], - src->slot[s_slot]); + src->slot[s_slot]); + } } - return s_slot - d_slot; +done: + if (dst) + ret = s_slot - d_slot; + return ret; } static void ma_adopt_children(struct maple_node *parent)