Added generalize fuzz testing for B-trees, fixed single-child bug

A single child is just another condition to watch out for during B-tree
merge, since a single-child obviously can't have a sibling.

This is a good safety to have, but I was surprised this can happen. But
it turns out to be quite easy since our rbyds defer the B-tree
operations until compaction. A merge down to a single child won't
propagate the merge until the parent compacts.
This commit is contained in:
Christopher Haster
2023-03-13 13:21:32 -05:00
parent c55cc4d010
commit dd5af724fd
2 changed files with 285 additions and 10 deletions
+6 -2
View File
@@ -2232,6 +2232,7 @@ static int lfsr_rbyd_append(lfs_t *lfs, lfsr_rbyd_t *rbyd,
other_id_ = id_;
} else if (tag == LFSR_TAG_SHRINK) {
LFS_ASSERT(id < rbyd->weight);
LFS_ASSERT(lfsr_data_len(data) <= rbyd->weight);
// noop?
if (lfsr_data_len(data) == 0) {
return 0;
@@ -3320,8 +3321,6 @@ static lfs_ssize_t lfsr_btree_get(lfs_t *lfs,
buffer, size);
}
// TODO drop the root during merges
// TODO inline?
static int lfsr_btree_commit(lfs_t *lfs,
lfsr_btree_t *btree, lfs_size_t id,
lfsr_rbyd_t *rbyd, const struct lfsr_attr *attrs) {
@@ -3821,6 +3820,11 @@ static int lfsr_btree_commit(lfs_t *lfs,
goto abort;
}
// only child? can't merge
if (pweight == parent.weight) {
goto abort;
}
// last child? try the left sibling
lfs_ssize_t sid;
lfs_ssize_t sdelta;