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:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user