From: Liam R. Howlett Date: Fri, 29 Nov 2024 15:31:43 +0000 (-0500) Subject: rebalance starts now X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=5a01c065b7d2d0444ca01c7d309dc85e5a795c00;p=users%2Fjedix%2Flinux-maple.git rebalance starts now Signed-off-by: Liam R. Howlett --- diff --git a/lib/maple_tree.c b/lib/maple_tree.c index 07bacec3d978..ec971af3397b 100644 --- a/lib/maple_tree.c +++ b/lib/maple_tree.c @@ -3177,6 +3177,7 @@ struct ma_node_state { unsigned char offset; /* Current operating offset */ unsigned char insert; enum maple_type type; + unsigned char end; }; static inline @@ -3627,92 +3628,20 @@ void mas_wr_ascend_init(struct ma_state *mas, ns->max = mas->max; } -/* - * mas_wr_try_rebalance() - Try to rebalance two nodes, this may not work out. - * @src: The source node state - * @new_end: The size of the src after the insert - * @left: The new left child - * @right: The new right child - * @ma_part: The node part that will be inserted - * - * Returns: True on rebalance, false otherwise. - */ -static bool mas_wr_try_rebalance(struct ma_state *mas, - struct ma_node_state *src, unsigned char new_end, - struct ma_node_state *left, struct ma_node_state *right, - struct ma_node_part *ma_part) +static void mas_wr_rebalance_nodes( + struct ma_node_state *l_src, + struct ma_node_state *r_src, + struct ma_node_state *left, + struct ma_node_state *right, + bool left_store, + unsigned char split, + struct ma_node_part *ma_part, + unsigned char mas_off, + unsigned char new_end + ) { - struct ma_state tmp_mas; - struct ma_node_state src2, parent, new_parent; - struct ma_node_state *l_src, *r_src; - unsigned char l_end, r_end, mas_off; - unsigned char split, max; - unsigned char p_end, p_off; - bool left_store = false; - - /* - * It is currently not known if the rebalance can work, so this is to - * try and determine if a rebalance operation will succeed - */ - - tmp_mas = *mas; - mas_wr_ascend_init(&tmp_mas, &parent); - p_off = tmp_mas.offset; - p_end = ma_data_end(parent.node, parent.type, parent.pivots, - parent.max); - //printk("parent %p has end %u %p\n", parent.node, p_end, parent.slots[p_end]); - max = mt_slots[src->type] - 1; - if (ma_is_leaf(src->type)) - max--; - - if (!p_off) - goto try_right; - - tmp_mas.offset--; - mas_descend(&tmp_mas); - mns_mas_init(&src2, &tmp_mas); - src2.max = tmp_mas.max; - src2.min = tmp_mas.min; - src2.insert = 255; - l_end = ma_data_end(src2.node, src2.type, src2.pivots, - src2.max); - split = mas_wr_rebalance_calc(l_end + new_end, src2.type); - if (split) { - p_off--; - l_src = &src2; - r_src = src; - r_end = mas->end; - } else { - if (p_end <= p_off) - return false; - - mas_ascend(&tmp_mas); -try_right: - tmp_mas.offset = p_off + 1; - mas_descend(&tmp_mas); - mns_mas_init(&src2, &tmp_mas); - src2.min = tmp_mas.min; - src2.max = tmp_mas.max; - src2.insert = 255; - r_end = ma_data_end(src2.node, src2.type, - src2.pivots, src2.max); - l_end = mas->end; - split = mas_wr_rebalance_calc(r_end + new_end, src2.type); - if (!split) - return false; - - split = r_end + new_end - split; - l_src = src; - r_src = &src2; - left_store = true; - } + unsigned char l_end, r_end; - /* - * At this point, the rebalance operation will succeed. - */ - - left->min = l_src->min; - mas_off = mas->offset; /* * l_src, ma_part, and r_src will be split between the new left and * right nodes. Depending on where the split and the store offset @@ -3727,6 +3656,9 @@ try_right: * which means the new data going to the left will have to come from the * ma_part. This is all taken care of in mas_wr_split_no_null(). */ + + l_end = l_src->end; + r_end = r_src->end; if (left_store) { /* Store is targeting l_src */ if (mas_off <= split) { /* Store will end up in left */ if (mas_off) @@ -3811,6 +3743,94 @@ try_right: mns_cp(r_src, right, r_end - r_src->offset + 1); } } +} + +/* + * mas_wr_try_rebalance() - Try to rebalance two nodes, this may not work out. + * @src: The source node state + * @new_end: The size of the src after the insert + * @left: The new left child + * @right: The new right child + * @ma_part: The node part that will be inserted + * + * Returns: True on rebalance, false otherwise. + */ +static bool mas_wr_try_rebalance(struct ma_state *mas, + struct ma_node_state *src, unsigned char new_end, + struct ma_node_state *left, struct ma_node_state *right, + struct ma_node_part *ma_part) +{ + struct ma_state tmp_mas; + struct ma_node_state src2, parent, new_parent; + struct ma_node_state *l_src, *r_src; + unsigned char split, max; + unsigned char p_end, p_off; + bool left_store = false; + + /* + * It is currently not known if the rebalance can work, so this is to + * try and determine if a rebalance operation will succeed + */ + + tmp_mas = *mas; + mas_wr_ascend_init(&tmp_mas, &parent); + p_off = tmp_mas.offset; + p_end = ma_data_end(parent.node, parent.type, parent.pivots, + parent.max); + //printk("parent %p has end %u %p\n", parent.node, p_end, parent.slots[p_end]); + max = mt_slots[src->type] - 1; + if (ma_is_leaf(src->type)) + max--; + + if (!p_off) + goto try_right; + + tmp_mas.offset--; + mas_descend(&tmp_mas); + mns_mas_init(&src2, &tmp_mas); + src2.max = tmp_mas.max; + src2.min = tmp_mas.min; + src2.insert = 255; + src2.end = ma_data_end(src2.node, src2.type, src2.pivots, + src2.max); + split = mas_wr_rebalance_calc(src2.end + new_end, src2.type); + if (split) { + p_off--; + l_src = &src2; + r_src = src; + r_src->end = mas->end; + } else { + if (p_end <= p_off) + return false; + + mas_ascend(&tmp_mas); +try_right: + tmp_mas.offset = p_off + 1; + mas_descend(&tmp_mas); + mns_mas_init(&src2, &tmp_mas); + src2.min = tmp_mas.min; + src2.max = tmp_mas.max; + src2.insert = 255; + src2.end = ma_data_end(src2.node, src2.type, + src2.pivots, src2.max); + src->end = mas->end; + split = mas_wr_rebalance_calc(src2.end + new_end, src2.type); + if (!split) + return false; + + split = src2.end + new_end - split; + l_src = src; + r_src = &src2; + left_store = true; + } + + /* + * At this point, the rebalance operation will succeed. + */ + + left->min = l_src->min; + mas_wr_rebalance_nodes(l_src, r_src, left, right, left_store, split, + ma_part, mas->offset, new_end); mns_finalise(left); mns_finalise(right); @@ -3824,6 +3844,14 @@ try_right: return true; } +/* + * There is insufficient data in the node after a store. + */ +static void mas_wr_rebalance(struct ma_wr_state *wr_mas) +{ + +} + /* * There is not enough room to contain the store in one node. */