]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
rebalance starts now
authorLiam R. Howlett <Liam.Howlett@Oracle.com>
Fri, 29 Nov 2024 15:31:43 +0000 (10:31 -0500)
committerLiam R. Howlett <Liam.Howlett@Oracle.com>
Sat, 30 Nov 2024 02:13:12 +0000 (21:13 -0500)
Signed-off-by: Liam R. Howlett <Liam.Howlett@Oracle.com>
lib/maple_tree.c

index 07bacec3d97896c44dede51522febfd4d0e43cb7..ec971af3397b9a3e9cb1590864e8b4f46edc9c08 100644 (file)
@@ -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.
  */