b-tree: fix corruption bug when inserting an entry in the middle of a node

This commit is contained in:
2025-04-26 21:23:50 +01:00
parent 4b790d855f
commit d5df4d593f

View File

@@ -180,8 +180,10 @@ static void node_shift_entries(
unsigned long count = nr_entries - shift_from;
for (unsigned long i = 0; i < count; i++) {
b_tree_node_entry *entry = node_get_entry(tree, node, src + i);
node_set_entry(tree, node, dest + i, entry);
unsigned long from = (src + count - 1) - i;
unsigned long to = (dest + count - 1) - i;
b_tree_node_entry *entry = node_get_entry(tree, node, from);
node_set_entry(tree, node, to, entry);
}
if (shift_by < 0) {
@@ -323,15 +325,28 @@ static int node_put(
}
int insert_at = -1;
bool exact_match = false;
for (unsigned long i = 0; i < nr_entries; i++) {
const b_tree_node_entry *cur = node_get_entry(tree, n, i);
int cmp = entry_compare(tree, cur, e);
if (cmp == 0) {
insert_at = i;
exact_match = true;
break;
}
if (cmp == 1) {
insert_at = i;
break;
}
}
if (exact_match) {
node_set_entry(tree, n, insert_at, e);
return insert_at;
}
if (insert_at != -1) {
node_shift_entries(tree, n, insert_at, 1);
} else {
@@ -443,9 +458,9 @@ int b_tree_put(struct b_tree *tree, const b_tree_node_entry *to_put)
/* this node is full, split it. */
/* half the nodes from `next` will be moved into `n3`. the other
half will stay put. the median entry will be moved to
`current`.
/* half the nodes from `next` will be moved into `n3`.
the other half will stay put. the median entry will
be moved to `current`.
`n3` will become the right sibling of `next` */
b_tree_node *n3 = cache_alloc_node(tree);