Added lfsr_rbyd_compact, lfsr_rbyd_appendshrub

Also renamed lfsr_rbyd_compact -> lfsr_rbyd_appendcompaction to make
room for a more high-level lfsr_rbyd_compact and emphasize that this is
an append operation.

lfsr_rbyd_appendshrub was a common pattern emerging in mdir commit
related functions for moving shrubs around. It's just a useful function
to have.

lfsr_rbyd_compact, on the other hand, is only useful for the evicting
bshrubs. Most other rbyd compaction code involves weird corner cases and
doesn't seem to generalize well (or at least I can't see it). But adding
lfsr_rbyd_compact is nice for consistency with the mdir commit/compact
functions. And it can be used by lfsr_bshrub_commit at least...

Code changes minimal:

  before:  31596           2752
  after:   31528 (+0.2%)   2752 (+0.0%)
This commit is contained in:
Christopher Haster
2023-12-06 23:33:40 -06:00
parent 7e9c0fbd88
commit c76ff08f67

171
lfs.c
View File

@@ -3230,14 +3230,14 @@ static int lfsr_rbyd_appendcompactattr(lfs_t *lfs, lfsr_rbyd_t *rbyd,
rbyd->eoff += lfsr_data_size(&data);
// keep track of the total weight, the rbyd is in an unusable
// state until lfsr_rbyd_compact anyways
// state until lfsr_rbyd_appendcompaction anyways
rbyd->weight += weight;
return 0;
}
static int lfsr_rbyd_appendcompactrbyd(lfs_t *lfs, lfsr_rbyd_t *rbyd_,
bool shrub,
static int lfsr_rbyd_appendcompactrbyd(lfs_t *lfs,
lfsr_rbyd_t *rbyd_, bool isshrub,
lfsr_srid_t start_rid, lfsr_srid_t end_rid,
const lfsr_rbyd_t *rbyd) {
// copy over tags in the rbyd in order
@@ -3264,7 +3264,7 @@ static int lfsr_rbyd_appendcompactrbyd(lfs_t *lfs, lfsr_rbyd_t *rbyd_,
// write the tag
err = lfsr_rbyd_appendcompactattr(lfs, rbyd_,
((shrub) ? LFSR_TAG_SHRUB : 0) | tag, weight, data);
((isshrub) ? LFSR_TAG_SHRUB : 0) | tag, weight, data);
if (err) {
return err;
}
@@ -3273,12 +3273,14 @@ static int lfsr_rbyd_appendcompactrbyd(lfs_t *lfs, lfsr_rbyd_t *rbyd_,
return 0;
}
static int lfsr_rbyd_compact(lfs_t *lfs, lfsr_rbyd_t *rbyd,
bool shrub, lfs_size_t off) {
static int lfsr_rbyd_appendcompaction(lfs_t *lfs,
lfsr_rbyd_t *rbyd, bool isshrub,
lfs_size_t off) {
// must fetch before mutating!
LFS_ASSERT(lfsr_rbyd_isfetched(rbyd));
// offset must be after the revision count
LFS_ASSERT(off >= sizeof(uint32_t));
// clamp offset to be after the revision count
off = lfs_max32(off, sizeof(uint32_t));
// make sure every rbyd starts with a revision count
if (rbyd->eoff == 0) {
@@ -3291,7 +3293,7 @@ static int lfsr_rbyd_compact(lfs_t *lfs, lfsr_rbyd_t *rbyd,
// empty rbyd? write a null tag so our trunk can still point to something
if (rbyd->eoff == off) {
lfs_ssize_t d = lfsr_bd_progtag(lfs, rbyd->blocks[0], rbyd->eoff,
shrub ? LFSR_TAG_SHRUB(NULL) : LFSR_TAG_NULL, 0, 0,
(isshrub) ? LFSR_TAG_SHRUB(NULL) : LFSR_TAG_NULL, 0, 0,
&rbyd->cksum);
if (d < 0) {
return d;
@@ -3335,7 +3337,7 @@ static int lfsr_rbyd_compact(lfs_t *lfs, lfsr_rbyd_t *rbyd,
// ignore shrub trunks, unless we are actually compacting
// a shrub tree
if (!shrub && lfsr_tag_isshrub(tag__)) {
if (!isshrub && lfsr_tag_isshrub(tag__)) {
trunk = off;
weight = 0;
continue;
@@ -3378,7 +3380,7 @@ static int lfsr_rbyd_compact(lfs_t *lfs, lfsr_rbyd_t *rbyd,
// terminate with a null tag
lfs_ssize_t d = lfsr_bd_progtag(lfs, rbyd->blocks[0], rbyd->eoff,
shrub ? LFSR_TAG_SHRUB(NULL) : LFSR_TAG_NULL, 0, 0,
(isshrub) ? LFSR_TAG_SHRUB(NULL) : LFSR_TAG_NULL, 0, 0,
&rbyd->cksum);
if (d < 0) {
return d;
@@ -3398,6 +3400,38 @@ done:;
return 0;
}
static int lfsr_rbyd_compact(lfs_t *lfs, lfsr_rbyd_t *rbyd_,
const lfsr_rbyd_t *rbyd,
const lfsr_attr_t *attrs, lfs_size_t attr_count) {
// append rbyd
int err = lfsr_rbyd_appendcompactrbyd(lfs, rbyd_, false,
-1, -1, rbyd);
if (err) {
return err;
}
// compact
err = lfsr_rbyd_appendcompaction(lfs, rbyd_, false, 0);
if (err) {
return err;
}
// append a commit
err = lfsr_rbyd_appendattrs(lfs, rbyd_, -1, -1,
attrs, attr_count);
if (err) {
return err;
}
// append a cksum, finalizing the commit
err = lfsr_rbyd_appendcksum(lfs, rbyd_);
if (err) {
return err;
}
return 0;
}
// append and consume any pending gstate
static int lfsr_rbyd_appendgdelta(lfs_t *lfs, lfsr_rbyd_t *rbyd) {
// need GRM delta?
@@ -3440,6 +3474,28 @@ static int lfsr_rbyd_appendgdelta(lfs_t *lfs, lfsr_rbyd_t *rbyd) {
return 0;
}
// append a secondary "shrub" tree
static int lfsr_rbyd_appendshrub(lfs_t *lfs, lfsr_rbyd_t *rbyd,
const lfsr_rbyd_t *shrub) {
// keep track of the start of the new tree
lfs_size_t off = rbyd->eoff;
// compact our shrub
int err = lfsr_rbyd_appendcompactrbyd(lfs, rbyd, true,
-1, -1, shrub);
if (err) {
return err;
}
err = lfsr_rbyd_appendcompaction(lfs, rbyd, true,
off);
if (err) {
return err;
}
return 0;
}
// the following are mostly btree helpers, but since they operate on rbyds,
// exist in the rbyd namespace
@@ -4180,13 +4236,14 @@ static lfs_ssize_t lfsr_btree_commit_(lfs_t *lfs,
}
// try to compact
err = lfsr_rbyd_appendcompactrbyd(lfs, &rbyd_, false, -1, -1, &rbyd);
err = lfsr_rbyd_appendcompactrbyd(lfs, &rbyd_, false,
-1, -1, &rbyd);
if (err) {
LFS_ASSERT(err != LFS_ERR_RANGE);
return err;
}
err = lfsr_rbyd_compact(lfs, &rbyd_, false, sizeof(uint32_t));
err = lfsr_rbyd_appendcompaction(lfs, &rbyd_, false, 0);
if (err) {
LFS_ASSERT(err != LFS_ERR_RANGE);
return err;
@@ -4234,7 +4291,7 @@ static lfs_ssize_t lfsr_btree_commit_(lfs_t *lfs,
return err;
}
err = lfsr_rbyd_compact(lfs, &rbyd_, false, sizeof(uint32_t));
err = lfsr_rbyd_appendcompaction(lfs, &rbyd_, false, 0);
if (err) {
LFS_ASSERT(err != LFS_ERR_RANGE);
return err;
@@ -4266,7 +4323,7 @@ static lfs_ssize_t lfsr_btree_commit_(lfs_t *lfs,
return err;
}
err = lfsr_rbyd_compact(lfs, &sibling, false, sizeof(uint32_t));
err = lfsr_rbyd_appendcompaction(lfs, &sibling, false, 0);
if (err) {
LFS_ASSERT(err != LFS_ERR_RANGE);
return err;
@@ -4371,7 +4428,7 @@ static lfs_ssize_t lfsr_btree_commit_(lfs_t *lfs,
return err;
}
err = lfsr_rbyd_compact(lfs, &rbyd_, false, sizeof(uint32_t));
err = lfsr_rbyd_appendcompaction(lfs, &rbyd_, false, 0);
if (err) {
LFS_ASSERT(err != LFS_ERR_RANGE);
return err;
@@ -4861,22 +4918,8 @@ evict:;
return err;
}
err = lfsr_rbyd_appendcompactrbyd(lfs, &bshrub->rbyd_, false,
-1, -1, &bshrub->rbyd);
if (err) {
LFS_ASSERT(err != LFS_ERR_RANGE);
return err;
}
err = lfsr_rbyd_compact(lfs, &bshrub->rbyd_, false,
sizeof(uint32_t));
if (err) {
LFS_ASSERT(err != LFS_ERR_RANGE);
return err;
}
err = lfsr_rbyd_commit(lfs, &bshrub->rbyd_,
attrs, attr_count);
err = lfsr_rbyd_compact(lfs, &bshrub->rbyd_,
&bshrub->rbyd, attrs, attr_count);
if (err) {
LFS_ASSERT(err != LFS_ERR_RANGE);
return err;
@@ -5585,17 +5628,8 @@ static int lfsr_mdir_commit__(lfs_t *lfs, lfsr_mdir_t *mdir,
lfs_size_t trunk = rbyd_.trunk;
lfsr_srid_t weight = rbyd_.weight;
// keep track of the start of our new tree
lfs_size_t off = rbyd_.eoff;
// compact our inlined tree
err = lfsr_rbyd_appendcompactrbyd(lfs, &rbyd_, true,
-1, -1, &shrub);
if (err) {
return err;
}
err = lfsr_rbyd_compact(lfs, &rbyd_, true, off);
// compact our shrub
err = lfsr_rbyd_appendshrub(lfs, &rbyd_, &shrub);
if (err) {
return err;
}
@@ -5737,11 +5771,11 @@ static int lfsr_mdir_compact__(lfs_t *lfs, lfsr_mdir_t *mdir_,
lfsr_srid_t start_rid, lfsr_srid_t end_rid,
const lfsr_mdir_t *mdir,
const lfsr_attr_t *attrs, lfs_size_t attr_count) {
// this is basically the same as lfsr_rbyd_appendcompactrbyd +
// lfsr_rbyd_compact, but with special handling for inlined trees.
// this is basically the same as lfsr_rbyd_compact, but with special
// handling for inlined trees.
//
// it's really tempting to deduplicate this via recursion! but we can't
// do that here
// it's really tempting to deduplicate this via recursion! but we
// can't do that here
//
// TODO this true?
// note that any inlined updates here depend on the pre-commit state
@@ -5812,18 +5846,8 @@ static int lfsr_mdir_compact__(lfs_t *lfs, lfsr_mdir_t *mdir_,
return err;
}
// keep track of the start of our new tree
lfs_size_t off = mdir_->rbyd.eoff;
// compact our inlined tree
err = lfsr_rbyd_appendcompactrbyd(lfs, &mdir_->rbyd, true,
-1, -1, &shrub);
if (err) {
LFS_ASSERT(err != LFS_ERR_RANGE);
return err;
}
err = lfsr_rbyd_compact(lfs, &mdir_->rbyd, true, off);
// compact our shrub
err = lfsr_rbyd_appendshrub(lfs, &mdir_->rbyd, &shrub);
if (err) {
LFS_ASSERT(err != LFS_ERR_RANGE);
return err;
@@ -5866,7 +5890,7 @@ static int lfsr_mdir_compact__(lfs_t *lfs, lfsr_mdir_t *mdir_,
}
}
int err = lfsr_rbyd_compact(lfs, &mdir_->rbyd, false, sizeof(uint32_t));
int err = lfsr_rbyd_appendcompaction(lfs, &mdir_->rbyd, false, 0);
if (err) {
LFS_ASSERT(err != LFS_ERR_RANGE);
return err;
@@ -5889,26 +5913,18 @@ static int lfsr_mdir_compact__(lfs_t *lfs, lfsr_mdir_t *mdir_,
const lfsr_bshrubcommit_t *bshrubcommit
= (const lfsr_bshrubcommit_t*)
attrs[i].data.u.buf.buffer;
// save our current off/trunk/weight
lfs_size_t off = mdir_->rbyd.eoff;
// save our current trunk/weight
lfs_size_t trunk = mdir_->rbyd.trunk;
lfsr_srid_t weight = mdir_->rbyd.weight;
// compact our shrub
err = lfsr_rbyd_appendcompactrbyd(lfs, &mdir_->rbyd, true,
-1, -1,
err = lfsr_rbyd_appendshrub(lfs, &mdir_->rbyd,
&bshrubcommit->bshrub->rbyd);
if (err) {
LFS_ASSERT(err != LFS_ERR_RANGE);
return err;
}
err = lfsr_rbyd_compact(lfs, &mdir_->rbyd, true, off);
if (err) {
LFS_ASSERT(err != LFS_ERR_RANGE);
return err;
}
// stage our new trunk and revert to mdir trunk/weight
bshrubcommit->bshrub->rbyd_ = mdir_->rbyd;
mdir_->rbyd.trunk = trunk;
@@ -5947,26 +5963,18 @@ static int lfsr_mdir_compact__(lfs_t *lfs, lfsr_mdir_t *mdir_,
// inlined shrub?
} else if (lfsr_ftree_isbshrub(&file->mdir, &file->ftree)) {
// save our current off/trunk/weight
lfs_size_t off = mdir_->rbyd.eoff;
// save our current trunk/weight
lfs_size_t trunk = mdir_->rbyd.trunk;
lfsr_srid_t weight = mdir_->rbyd.weight;
// compact our shrub
err = lfsr_rbyd_appendcompactrbyd(lfs, &mdir_->rbyd, true,
-1, -1,
err = lfsr_rbyd_appendshrub(lfs, &mdir_->rbyd,
&file->ftree.u.bshrub.rbyd);
if (err) {
LFS_ASSERT(err != LFS_ERR_RANGE);
return err;
}
err = lfsr_rbyd_compact(lfs, &mdir_->rbyd, true, off);
if (err) {
LFS_ASSERT(err != LFS_ERR_RANGE);
return err;
}
// stage our new trunk and revert to mdir trunk/weight
file->ftree.u.bshrub.rbyd_ = mdir_->rbyd;
mdir_->rbyd.trunk = trunk;
@@ -6195,8 +6203,7 @@ static int lfsr_mroot_commit(lfs_t *lfs,
}
}
err = lfsr_rbyd_compact(lfs, &mrootanchor_.rbyd, false,
sizeof(uint32_t));
err = lfsr_rbyd_appendcompaction(lfs, &mrootanchor_.rbyd, false, 0);
if (err) {
LFS_ASSERT(err != LFS_ERR_RANGE);
return err;