Tried to deduplicate tail-end of rbyd commits in btree commit

This gets a bit ugly with all of the gotos (which is always a great
thing to hear in a C codebase), but with both our normal commit and
compact code paths obviously sharing the same commit logic when we
tail-recurse to our parent, it is really nice to deduplicate these
two paths.

merge_abort is also still there, annoyingly it needs a slightly
different label since merge_abort still needs to append the cksum that
finalizes the commit.

            code          stack
  before:  20874           1752
  after:   20830 (-0.2%)   1752 (+0.0%)

In theory, both commit/compact/merge _could_ share the cksum append,
because compact and merge can't error with LFS_ERR_RANGE (which
might risk an infinite loop?), but that's a level of spaghetti code I'm
not ready to take on yet.
This commit is contained in:
Christopher Haster
2023-08-15 14:12:59 -05:00
parent d039c58acd
commit a5260aa290
+16 -43
View File
@@ -3964,42 +3964,7 @@ static int lfsr_btree_commit(lfs_t *lfs, lfsr_btree_t *btree,
goto compact;
}
// done?
if (prid == -1) {
LFS_ASSERT(bid == 0);
break;
}
lfs_ssize_t scratch_dsize = lfsr_branch_todisk(lfs, &rbyd_,
scratch_buf);
if (scratch_dsize < 0) {
return scratch_dsize;
}
// prepare commit to parent, tail recursing upwards
//
// note that since we defer merges to compaction time, we can
// end up removing an rbyd here
bid -= prid - (rbyd.weight-1);
if (rbyd_.weight == 0) {
scratch_attrs[0] = LFSR_ATTR(
bid+prid, RM, +rbyd_.weight-rbyd.weight,
BUF(scratch_buf, scratch_dsize));
attrs = scratch_attrs;
attr_count = 1;
} else {
scratch_attrs[0] = LFSR_ATTR(
bid+prid, GROW(RM), +rbyd_.weight-rbyd.weight,
NULL);
scratch_attrs[1] = LFSR_ATTR(
bid+prid+rbyd_.weight-rbyd.weight, BRANCH, 0,
BUF(scratch_buf, scratch_dsize));
attrs = scratch_attrs;
attr_count = 2;
}
rbyd = parent;
continue;
goto commit_recurse;
compact:;
// can't commit, try to compact
@@ -4048,15 +4013,11 @@ static int lfsr_btree_commit(lfs_t *lfs, lfsr_btree_t *btree,
// is our compacted size too small? try to merge with one of
// our siblings
if (rbyd_.eoff < lfs->cfg->block_size/4
// no parent? can't merge
&& prid != -1
// only child? can't merge
&& rbyd.weight < parent.weight) {
if (rbyd_.eoff < lfs->cfg->block_size/4) {
goto merge;
merge_abort:;
}
merge_abort:;
// finalize commit
err = lfsr_rbyd_appendcksum(lfs, &rbyd_);
if (err) {
@@ -4064,13 +4025,15 @@ static int lfsr_btree_commit(lfs_t *lfs, lfsr_btree_t *btree,
return err;
}
commit_recurse:;
// done?
if (prid == -1) {
LFS_ASSERT(bid == 0);
break;
}
scratch_dsize = lfsr_branch_todisk(lfs, &rbyd_, scratch_buf);
lfs_ssize_t scratch_dsize = lfsr_branch_todisk(lfs, &rbyd_,
scratch_buf);
if (scratch_dsize < 0) {
return scratch_dsize;
}
@@ -4253,6 +4216,16 @@ static int lfsr_btree_commit(lfs_t *lfs, lfsr_btree_t *btree,
continue;
merge:;
// no parent? can't merge
if (prid == -1) {
goto merge_abort;
}
// only child? can't merge
if (rbyd.weight >= parent.weight) {
goto merge_abort;
}
lfs_ssize_t srid;
lfs_ssize_t sdelta;
lfs_size_t sweight;