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; goto compact;
} }
// done? goto commit_recurse;
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;
compact:; compact:;
// can't commit, try to 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 // is our compacted size too small? try to merge with one of
// our siblings // our siblings
if (rbyd_.eoff < lfs->cfg->block_size/4 if (rbyd_.eoff < lfs->cfg->block_size/4) {
// no parent? can't merge
&& prid != -1
// only child? can't merge
&& rbyd.weight < parent.weight) {
goto merge; goto merge;
merge_abort:;
} }
merge_abort:;
// finalize commit // finalize commit
err = lfsr_rbyd_appendcksum(lfs, &rbyd_); err = lfsr_rbyd_appendcksum(lfs, &rbyd_);
if (err) { if (err) {
@@ -4064,13 +4025,15 @@ static int lfsr_btree_commit(lfs_t *lfs, lfsr_btree_t *btree,
return err; return err;
} }
commit_recurse:;
// done? // done?
if (prid == -1) { if (prid == -1) {
LFS_ASSERT(bid == 0); LFS_ASSERT(bid == 0);
break; 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) { if (scratch_dsize < 0) {
return scratch_dsize; return scratch_dsize;
} }
@@ -4253,6 +4216,16 @@ static int lfsr_btree_commit(lfs_t *lfs, lfsr_btree_t *btree,
continue; continue;
merge:; 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 srid;
lfs_ssize_t sdelta; lfs_ssize_t sdelta;
lfs_size_t sweight; lfs_size_t sweight;