unsigned char offset; /* Current operating offset */
unsigned char insert;
enum maple_type type;
+ unsigned char end;
};
static inline
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
* 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)
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);
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.
*/