From: Liam R. Howlett Date: Fri, 11 Dec 2020 03:01:16 +0000 (-0500) Subject: maple_tree: mas_mab_cp() rework attempt 2 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=ee17bcdbb39d69165fb588b022794fc175b29d49;p=users%2Fjedix%2Flinux-maple.git maple_tree: mas_mab_cp() rework attempt 2 Signed-off-by: Liam R. Howlett --- diff --git a/lib/maple_tree.c b/lib/maple_tree.c index 21e40d390951..b7fed38722e1 100644 --- a/lib/maple_tree.c +++ b/lib/maple_tree.c @@ -1561,29 +1561,42 @@ static inline void mas_mab_cp(struct ma_state *mas, unsigned char mas_start, unsigned char mas_end, struct maple_big_node *b_node, unsigned char mab_start) { - enum maple_type mt = mte_node_type(mas->node); - struct maple_node *node = mte_to_node(mas->node); - void **slots = ma_slots(node, mt); - unsigned long *pivots = ma_pivots(node, mt); - unsigned long *gaps = NULL; + enum maple_type mt; + struct maple_node *node; + void **slots; + unsigned long *pivots, *gaps; int i = mas_start, j = mab_start; + unsigned char piv_end; - for (; i <= mas_end; i++, j++) { - b_node->pivot[j] = _mas_safe_pivot(mas, pivots, i, mt); + node = mas_mn(mas); + mt = mte_node_type(mas->node); + pivots = ma_pivots(node, mt); + if (!i) { + b_node->pivot[j] = pivots[i++]; + if (unlikely(i > mas_end)) + goto complete; + j++; + } - if ((mas->max == b_node->pivot[j]) || - (j && !b_node->pivot[j])) { // end of node. - j++; + piv_end = min(mas_end, mt_pivots[mt]); + for (; i < piv_end; i++, j++) { + b_node->pivot[j] = pivots[i]; + if (unlikely(!b_node->pivot[j])) break; - } + + if (unlikely(mas->max == b_node->pivot[j])) + goto complete; } - b_node->b_end = j; - j -= mab_start; + if (likely(i <= mas_end)) + b_node->pivot[j] = _mas_safe_pivot(mas, pivots, i, mt); +complete: + b_node->b_end = ++j; + j -= mab_start; + slots = ma_slots(node, mt); memcpy(b_node->slot + mab_start, slots + mas_start, sizeof(void *) * j); - - if (!mte_is_leaf(mas->node) && mt_is_alloc(mas->tree)) { + if (!ma_is_leaf(mt) && mt_is_alloc(mas->tree)) { gaps = ma_gaps(node, mt); memcpy(b_node->gap + mab_start, gaps + mas_start, sizeof(unsigned long) * j);