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