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