Use sign bit of rbyd.trunk to indicate shrubness of rbyds

Shrubness should have always been a property of lfsr_rbyd_t.

You know you've made a good design decision when things just sort of
fall into place and the code somehow becomes cleaner.

The downside of this change is accessing rbyd trunks requires a mask,
which is annoying, but the upside is we don't need to signal shrubness
via extra booleans in internal functions anymore.

The funny thing is, the actual motivation for this change is was just to
free up a bit in our tag encoding. Simplifying some of the internal
functions was just a nice side effect.

            code          stack
  before:  33940           2928
  after:   33928 (-0.0%)   2912 (-0.5%)
This commit is contained in:
Christopher Haster
2024-01-21 00:06:36 -06:00
parent 4ce582bf9b
commit bea13dcf8e
6 changed files with 125 additions and 101 deletions
+116 -99
View File
@@ -722,14 +722,6 @@ static inline lfsr_tag_t lfsr_tag_subkey(lfsr_tag_t tag) {
return tag & 0x00ff;
}
static inline lfsr_tag_t lfsr_tag_shrubmode(lfsr_tag_t tag) {
return tag & 0xe000;
}
static inline lfsr_tag_t lfsr_tag_shrubkey(lfsr_tag_t tag) {
return tag & 0x1fff;
}
static inline bool lfsr_tag_isalt(lfsr_tag_t tag) {
return tag & LFSR_TAG_ALT;
}
@@ -1993,9 +1985,23 @@ static void lfs_alloc_ckpoint(lfs_t *lfs);
/// Red-black-yellow Dhara tree operations ///
#define LFSR_RBYD_SHRUB 0x80000000
// helper functions
static inline bool lfsr_rbyd_isshrub(const lfsr_rbyd_t *rbyd) {
return rbyd->trunk & LFSR_RBYD_SHRUB;
}
static inline lfs_size_t lfsr_rbyd_trunk(const lfsr_rbyd_t *rbyd) {
return rbyd->trunk & ~LFSR_RBYD_SHRUB;
}
static inline bool lfsr_rbyd_hastrunk(const lfsr_rbyd_t *rbyd) {
return lfsr_rbyd_trunk(rbyd) != 0;
}
static inline bool lfsr_rbyd_isfetched(const lfsr_rbyd_t *rbyd) {
return !(rbyd->eoff == 0 && rbyd->trunk > 0);
return !(lfsr_rbyd_hastrunk(rbyd) && rbyd->eoff == 0);
}
static inline int lfsr_rbyd_cmp(
@@ -2027,7 +2033,7 @@ static int lfsr_rbyd_alloc(lfs_t *lfs, lfsr_rbyd_t *rbyd) {
}
static int lfsr_rbyd_fetch(lfs_t *lfs, lfsr_rbyd_t *rbyd,
lfs_block_t block, lfs_size_t trunk) {
lfs_block_t block, lfs_ssize_t trunk) {
// checksum the revision count to get the cksum started
uint32_t cksum = 0;
int err = lfsr_bd_cksum(lfs, block, 0, lfs->cfg->block_size,
@@ -2038,7 +2044,8 @@ static int lfsr_rbyd_fetch(lfs_t *lfs, lfsr_rbyd_t *rbyd,
rbyd->blocks[0] = block;
rbyd->eoff = 0;
rbyd->trunk = 0;
rbyd->trunk = (trunk & LFSR_RBYD_SHRUB) | 0;
trunk &= ~LFSR_RBYD_SHRUB;
// temporary state until we validate a cksum
lfs_size_t off = sizeof(uint32_t);
@@ -2052,7 +2059,8 @@ static int lfsr_rbyd_fetch(lfs_t *lfs, lfsr_rbyd_t *rbyd,
lfsr_ecksum_t ecksum = {.size=-1};
// scan tags, checking valid bits, cksums, etc
while (off < lfs->cfg->block_size && (!trunk || rbyd->eoff <= trunk)) {
while (off < lfs->cfg->block_size
&& (!trunk || rbyd->eoff <= (lfs_size_t)trunk)) {
lfsr_tag_t tag;
lfsr_rid_t weight__;
lfs_size_t size;
@@ -2133,12 +2141,13 @@ static int lfsr_rbyd_fetch(lfs_t *lfs, lfsr_rbyd_t *rbyd,
// save what we've found so far
rbyd->eoff = off_ + size;
rbyd->cksum = cksum;
rbyd->trunk = trunk_;
rbyd->trunk = (LFSR_RBYD_SHRUB & rbyd->trunk) | trunk_;
rbyd->weight = weight;
}
// found a trunk of a tree?
if (lfsr_tag_istrunk(tag) && (!trunk || trunk >= off || wastrunk)) {
if (lfsr_tag_istrunk(tag)
&& (!trunk || (lfs_size_t)trunk >= off || wastrunk)) {
// start of trunk?
if (!wastrunk) {
wastrunk = true;
@@ -2177,7 +2186,7 @@ static int lfsr_rbyd_fetch(lfs_t *lfs, lfsr_rbyd_t *rbyd,
}
// no valid commits?
if (!rbyd->trunk) {
if (!lfsr_rbyd_hastrunk(rbyd)) {
return LFS_ERR_CORRUPT;
}
@@ -2202,7 +2211,7 @@ static int lfsr_rbyd_fetch(lfs_t *lfs, lfsr_rbyd_t *rbyd,
// a more aggressive fetch when checksum is known
static int lfsr_rbyd_fetchvalidate(lfs_t *lfs, lfsr_rbyd_t *rbyd,
lfs_block_t block, lfs_size_t trunk, lfsr_rid_t weight,
lfs_block_t block, lfs_ssize_t trunk, lfsr_rid_t weight,
uint32_t cksum) {
int err = lfsr_rbyd_fetch(lfs, rbyd, block, trunk);
if (err) {
@@ -2222,13 +2231,13 @@ static int lfsr_rbyd_fetchvalidate(lfs_t *lfs, lfsr_rbyd_t *rbyd,
if (rbyd->cksum != cksum) {
LFS_ERROR("Found rbyd cksum mismatch rbyd 0x%"PRIx32".%"PRIx32", "
"cksum 0x%08"PRIx32" (!= 0x%08"PRIx32")",
rbyd->blocks[0], rbyd->trunk, rbyd->cksum, cksum);
rbyd->blocks[0], lfsr_rbyd_trunk(rbyd), rbyd->cksum, cksum);
return LFS_ERR_CORRUPT;
}
// if trunk/weight mismatch _after_ cksums match, that's not a storage
// error, that's a programming error
LFS_ASSERT(rbyd->trunk == trunk);
LFS_ASSERT(lfsr_rbyd_trunk(rbyd) == (lfs_size_t)trunk);
LFS_ASSERT((lfsr_rid_t)rbyd->weight == weight);
return 0;
}
@@ -2246,12 +2255,12 @@ static int lfsr_rbyd_lookupnext(lfs_t *lfs, const lfsr_rbyd_t *rbyd,
tag = lfs_max16(tag, 0x1);
// out of bounds? no trunk yet?
if (rid >= rbyd->weight || !rbyd->trunk) {
if (rid >= rbyd->weight || !lfsr_rbyd_hastrunk(rbyd)) {
return LFS_ERR_NOENT;
}
// keep track of bounds as we descend down the tree
lfs_size_t branch = rbyd->trunk;
lfs_size_t branch = lfsr_rbyd_trunk(rbyd);
lfsr_srid_t lower = 0;
lfsr_srid_t upper = rbyd->weight;
@@ -2281,7 +2290,6 @@ static int lfsr_rbyd_lookupnext(lfs_t *lfs, const lfsr_rbyd_t *rbyd,
// found end of tree?
} else {
// update the tag rid
LFS_ASSERT(lfsr_tag_shrubmode(alt) == 0x0000);
lfsr_srid_t rid__ = upper-1;
lfsr_tag_t tag__ = lfsr_tag_key(alt);
@@ -2574,7 +2582,7 @@ static int lfsr_rbyd_appendattr(lfs_t *lfs, lfsr_rbyd_t *rbyd,
// this gets a bit confusing as we also may need to keep
// track of both the lower and upper bounds of diverging paths
// in the case of range deletions
lfs_size_t branch = rbyd->trunk;
lfs_size_t branch = lfsr_rbyd_trunk(rbyd);
lfsr_srid_t lower_rid = 0;
lfsr_srid_t upper_rid = rbyd->weight;
lfsr_tag_t lower_tag = 0;
@@ -2599,7 +2607,7 @@ static int lfsr_rbyd_appendattr(lfs_t *lfs, lfsr_rbyd_t *rbyd,
rbyd->weight += delta;
// assume we'll update our trunk
rbyd->trunk = rbyd->eoff;
rbyd->trunk = (rbyd->trunk & LFSR_RBYD_SHRUB) | rbyd->eoff;
// no trunk yet?
if (!branch) {
@@ -2826,7 +2834,6 @@ static int lfsr_rbyd_appendattr(lfs_t *lfs, lfsr_rbyd_t *rbyd,
// note we:
// - clear valid bit, marking the tag as found
// - preserve diverged state
LFS_ASSERT(lfsr_tag_shrubmode(alt) == 0x0000);
tag_ = lfsr_tag_mode(tag_ & ~LFSR_TAG_RM) | alt;
// done?
@@ -2958,10 +2965,12 @@ leaf:;
// note we always need a non-alt to terminate the trunk, otherwise we
// can't find trunks during fetch
lfs_ssize_t d = lfsr_bd_progtag(lfs, rbyd->blocks[0], rbyd->eoff,
// rm => null or shrubnull, otherwise strip off control bits
(lfsr_tag_isrm(tag))
? lfsr_tag_mode(lfsr_tag_shrubkey(tag))
: lfsr_tag_shrubkey(tag),
// mark as shrub if we are a shrub
(lfsr_rbyd_isshrub(rbyd) ? LFSR_TAG_SHRUB : 0)
// rm => null, otherwise strip off control bits
| ((lfsr_tag_isrm(tag))
? LFSR_TAG_NULL
: lfsr_tag_key(tag)),
upper_rid - lower_rid + delta,
lfsr_data_size(&data),
&rbyd->cksum);
@@ -3286,7 +3295,10 @@ static int lfsr_rbyd_appendcompactattr(lfs_t *lfs, lfsr_rbyd_t *rbyd,
// write the tag
lfs_ssize_t d = lfsr_bd_progtag(lfs, rbyd->blocks[0], rbyd->eoff,
tag, weight, lfsr_data_size(&data),
// mark as shrub if we are a shrub
(lfsr_rbyd_isshrub(rbyd) ? LFSR_TAG_SHRUB : 0)
| tag,
weight, lfsr_data_size(&data),
&rbyd->cksum);
if (d < 0) {
return d;
@@ -3308,8 +3320,7 @@ static int lfsr_rbyd_appendcompactattr(lfs_t *lfs, lfsr_rbyd_t *rbyd,
return 0;
}
static int lfsr_rbyd_appendcompactrbyd(lfs_t *lfs,
lfsr_rbyd_t *rbyd_, bool isshrub,
static int lfsr_rbyd_appendcompactrbyd(lfs_t *lfs, lfsr_rbyd_t *rbyd_,
lfsr_srid_t start_rid, lfsr_srid_t end_rid,
const lfsr_rbyd_t *rbyd) {
// copy over tags in the rbyd in order
@@ -3335,8 +3346,7 @@ static int lfsr_rbyd_appendcompactrbyd(lfs_t *lfs,
}
// write the tag
err = lfsr_rbyd_appendcompactattr(lfs, rbyd_,
((isshrub) ? LFSR_TAG_SHRUB : 0) | tag, weight, data);
err = lfsr_rbyd_appendcompactattr(lfs, rbyd_, tag, weight, data);
if (err) {
return err;
}
@@ -3345,8 +3355,7 @@ static int lfsr_rbyd_appendcompactrbyd(lfs_t *lfs,
return 0;
}
static int lfsr_rbyd_appendcompaction(lfs_t *lfs,
lfsr_rbyd_t *rbyd, bool isshrub,
static int lfsr_rbyd_appendcompaction(lfs_t *lfs, lfsr_rbyd_t *rbyd,
lfs_size_t off) {
// must fetch before mutating!
LFS_ASSERT(lfsr_rbyd_isfetched(rbyd));
@@ -3365,14 +3374,17 @@ static int lfsr_rbyd_appendcompaction(lfs_t *lfs,
// 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,
(isshrub) ? LFSR_TAG_SHRUB(NULL) : LFSR_TAG_NULL, 0, 0,
// mark as shrub if we are a shrub
(lfsr_rbyd_isshrub(rbyd) ? LFSR_TAG_SHRUB : 0)
| LFSR_TAG_NULL,
0, 0,
&rbyd->cksum);
if (d < 0) {
return d;
}
rbyd->eoff += d;
rbyd->trunk = off;
rbyd->trunk = (rbyd->trunk & LFSR_RBYD_SHRUB) | off;
rbyd->weight = 0;
return 0;
}
@@ -3409,7 +3421,8 @@ static int lfsr_rbyd_appendcompaction(lfs_t *lfs,
// ignore shrub trunks, unless we are actually compacting
// a shrub tree
if (!isshrub && lfsr_tag_isshrub(tag__)) {
if (!lfsr_rbyd_isshrub(rbyd)
&& lfsr_tag_isshrub(tag__)) {
trunk = off;
weight = 0;
continue;
@@ -3452,7 +3465,10 @@ static int lfsr_rbyd_appendcompaction(lfs_t *lfs,
// terminate with a null tag
lfs_ssize_t d = lfsr_bd_progtag(lfs, rbyd->blocks[0], rbyd->eoff,
(isshrub) ? LFSR_TAG_SHRUB(NULL) : LFSR_TAG_NULL, 0, 0,
// mark as shrub if we are a shrub
(lfsr_rbyd_isshrub(rbyd) ? LFSR_TAG_SHRUB : 0)
| LFSR_TAG_NULL,
0, 0,
&rbyd->cksum);
if (d < 0) {
return d;
@@ -3466,7 +3482,7 @@ static int lfsr_rbyd_appendcompaction(lfs_t *lfs,
done:;
// done! just need to update our trunk. Note we could have no trunks
// after compaction. Leave this to upper layers to take care of this.
rbyd->trunk = layer;
rbyd->trunk = (rbyd->trunk & LFSR_RBYD_SHRUB) | layer;
rbyd->weight = weight;
return 0;
@@ -3476,14 +3492,14 @@ static int lfsr_rbyd_compact(lfs_t *lfs, lfsr_rbyd_t *rbyd_,
lfsr_srid_t start_rid, lfsr_srid_t end_rid,
const lfsr_rbyd_t *rbyd) {
// append rbyd
int err = lfsr_rbyd_appendcompactrbyd(lfs, rbyd_, false,
start_rid, end_rid, rbyd);
int err = lfsr_rbyd_appendcompactrbyd(lfs, rbyd_, start_rid, end_rid,
rbyd);
if (err) {
return err;
}
// compact
err = lfsr_rbyd_appendcompaction(lfs, rbyd_, false, 0);
err = lfsr_rbyd_appendcompaction(lfs, rbyd_, 0);
if (err) {
return err;
}
@@ -3542,16 +3558,17 @@ static int lfsr_rbyd_appendshrub(lfs_t *lfs, lfsr_rbyd_t *rbyd,
const lfsr_shrub_t *shrub) {
// keep track of the start of the new tree
lfs_size_t off = rbyd->eoff;
// mark as shrub
rbyd->trunk |= LFSR_RBYD_SHRUB;
// compact our shrub
int err = lfsr_rbyd_appendcompactrbyd(lfs, rbyd, true,
-1, -1, lfsr_shrub_rbyd(shrub));
int err = lfsr_rbyd_appendcompactrbyd(lfs, rbyd, -1, -1,
lfsr_shrub_rbyd(shrub));
if (err) {
return err;
}
err = lfsr_rbyd_appendcompaction(lfs, rbyd, true,
off);
err = lfsr_rbyd_appendcompaction(lfs, rbyd, off);
if (err) {
return err;
}
@@ -3697,7 +3714,7 @@ static lfsr_data_t lfsr_data_frombranch(const lfsr_rbyd_t *branch,
LFS_ASSERT(d_ >= 0);
d += d_;
d_ = lfs_toleb128(branch->trunk, &buffer[d], 5);
d_ = lfs_toleb128(lfsr_rbyd_trunk(branch), &buffer[d], 5);
LFS_ASSERT(d_ >= 0);
d += d_;
@@ -3720,7 +3737,7 @@ static int lfsr_data_readbranch(lfs_t *lfs, lfsr_data_t *data,
return err;
}
err = lfsr_data_readleb128(lfs, data, (int32_t*)&branch->trunk);
err = lfsr_data_readleb128(lfs, data, &branch->trunk);
if (err) {
return err;
}
@@ -3922,8 +3939,7 @@ static int lfsr_btree_parent(lfs_t *lfs, const lfsr_btree_t *btree,
}
// found our child?
if (branch_.blocks[0] == child->blocks[0]
&& branch_.trunk == child->trunk) {
if (lfsr_rbyd_cmp(&branch_, child) == 0) {
// TODO how many of these should be conditional?
if (rbyd_) {
*rbyd_ = branch;
@@ -3943,10 +3959,9 @@ static int lfsr_btree_parent(lfs_t *lfs, const lfsr_btree_t *btree,
//
// this commits up to the root, but stops if:
// 1. we need a new root
// 2. shrub=true, which means we have a shrub root
// 2. we have a shrub root
//
static int lfsr_btree_commit_(lfs_t *lfs,
lfsr_btree_t *btree, bool shrub,
static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree,
const lfsr_attr_t **attrs_, lfs_size_t *attr_count_,
lfsr_attr_t attrs__[static 4],
uint8_t buf__[static 2*LFSR_BRANCH_DSIZE]) {
@@ -3988,13 +4003,15 @@ static int lfsr_btree_commit_(lfs_t *lfs,
lfsr_rbyd_t parent = {.trunk=0, .weight=0};
lfsr_srid_t rid = -1;
// are we root?
if (rbyd.blocks[0] == btree->blocks[0] || rbyd.trunk == 0) {
if (rbyd.blocks[0] == btree->blocks[0]
|| !lfsr_rbyd_hastrunk(&rbyd)) {
// new root? shrub root? yield the final root commit to
// higher-level btree/bshrub logic
if (rbyd.trunk == 0 || shrub) {
if (!lfsr_rbyd_hastrunk(&rbyd)
|| lfsr_rbyd_isshrub(btree)) {
*attrs_ = attrs;
*attr_count_ = attr_count;
return (rbyd.trunk == 0) ? LFS_ERR_RANGE : 0;
return (!lfsr_rbyd_hastrunk(&rbyd)) ? LFS_ERR_RANGE : 0;
}
// mark btree as unerased in case of failure, our btree rbyd and
@@ -4020,7 +4037,8 @@ static int lfsr_btree_commit_(lfs_t *lfs,
// a funny benefit is we cache the root of our btree this way
if (!lfsr_rbyd_isfetched(&rbyd)) {
int err = lfsr_rbyd_fetchvalidate(lfs, &rbyd,
rbyd.blocks[0], rbyd.trunk, rbyd.weight, rbyd.cksum);
rbyd.blocks[0], lfsr_rbyd_trunk(&rbyd), rbyd.weight,
rbyd.cksum);
if (err) {
return err;
}
@@ -4051,7 +4069,7 @@ static int lfsr_btree_commit_(lfs_t *lfs,
finalize:;
// done?
if (parent.trunk == 0) {
if (!lfsr_rbyd_hastrunk(&parent)) {
LFS_ASSERT(bid == 0);
*btree = rbyd_;
*attr_count_ = 0;
@@ -4109,7 +4127,7 @@ static int lfsr_btree_commit_(lfs_t *lfs,
lfsr_rbyd_t sibling;
if ((lfs_size_t)estimate <= lfs->cfg->block_size/4
// no parent? can't merge
&& parent.trunk != 0) {
&& !lfsr_rbyd_hastrunk(&parent)) {
// try the right sibling
if (rid+1 < parent.weight) {
// try looking up the sibling
@@ -4344,7 +4362,7 @@ static int lfsr_btree_commit_(lfs_t *lfs,
attr_count = 0;
buf_size = 0;
// new root?
if (parent.trunk == 0) {
if (!lfsr_rbyd_hastrunk(&parent)) {
attrs__[attr_count++] = LFSR_ATTR(0,
BRANCH, +rbyd_.weight,
FROMBRANCH(&rbyd_, &buf__[buf_size]));
@@ -4393,21 +4411,19 @@ static int lfsr_btree_commit_(lfs_t *lfs,
}
// merge the siblings together
err = lfsr_rbyd_appendcompactrbyd(lfs, &rbyd_, false,
-1, -1, &rbyd);
err = lfsr_rbyd_appendcompactrbyd(lfs, &rbyd_, -1, -1, &rbyd);
if (err) {
LFS_ASSERT(err != LFS_ERR_RANGE);
return err;
}
err = lfsr_rbyd_appendcompactrbyd(lfs, &rbyd_, false,
-1, -1, &sibling);
err = lfsr_rbyd_appendcompactrbyd(lfs, &rbyd_, -1, -1, &sibling);
if (err) {
LFS_ASSERT(err != LFS_ERR_RANGE);
return err;
}
err = lfsr_rbyd_appendcompaction(lfs, &rbyd_, false, 0);
err = lfsr_rbyd_appendcompaction(lfs, &rbyd_, 0);
if (err) {
LFS_ASSERT(err != LFS_ERR_RANGE);
return err;
@@ -4430,7 +4446,7 @@ static int lfsr_btree_commit_(lfs_t *lfs,
// we must have a parent at this point, but is our parent the root
// and is the root degenerate?
LFS_ASSERT(parent.trunk != 0);
LFS_ASSERT(lfsr_rbyd_hastrunk(&parent) != 0);
if (rbyd.weight+sibling.weight == btree->weight) {
// collapse the root, decreasing the height of the tree
*btree = rbyd_;
@@ -4467,7 +4483,7 @@ static int lfsr_btree_commit(lfs_t *lfs, lfsr_btree_t *btree,
uint8_t buffer[2*LFSR_BRANCH_DSIZE];
// try to commit to the btree
int err = lfsr_btree_commit_(lfs, btree, false,
int err = lfsr_btree_commit_(lfs, btree,
&attrs, &attr_count,
attrs__, buffer);
if (err && err != LFS_ERR_RANGE) {
@@ -4493,7 +4509,7 @@ static int lfsr_btree_commit(lfs_t *lfs, lfsr_btree_t *btree,
*btree = rbyd;
}
LFS_ASSERT(btree->trunk != 0);
LFS_ASSERT(lfsr_rbyd_hastrunk(btree));
return 0;
}
@@ -4582,16 +4598,15 @@ typedef struct lfsr_btraversal {
.branch.trunk=0, \
.branch.weight=0})
static int lfsr_btree_traverse_(lfs_t *lfs,
const lfsr_btree_t *btree, bool shrub,
static int lfsr_btree_traverse_(lfs_t *lfs, const lfsr_btree_t *btree,
lfsr_btraversal_t *btraversal,
lfsr_bid_t *bid_, lfsr_tinfo_t *tinfo_) {
// explicitly traverse the root even if weight=0
if (btraversal->branch.trunk == 0
// unless we don't even have a root yet
&& btree->trunk != 0
&& lfsr_rbyd_trunk(btree) != 0
// or are a shrub
&& !shrub) {
&& !lfsr_rbyd_isshrub(btree)) {
btraversal->rid = btraversal->bid;
btraversal->branch = *btree;
@@ -4688,8 +4703,7 @@ static int lfsr_btree_traverse_(lfs_t *lfs,
static int lfsr_btree_traverse(lfs_t *lfs, const lfsr_btree_t *btree,
lfsr_btraversal_t *btraversal,
lfsr_bid_t *bid_, lfsr_tinfo_t *tinfo_) {
return lfsr_btree_traverse_(lfs, btree, false,
btraversal,
return lfsr_btree_traverse_(lfs, btree, btraversal,
bid_, tinfo_);
}
@@ -4784,6 +4798,14 @@ static int lfsr_sprout_compact(lfs_t *lfs, const lfsr_rbyd_t *rbyd_,
// shrub things
static inline lfs_size_t lfsr_shrub_trunk(const lfsr_shrub_t *shrub) {
return shrub->trunk & ~LFSR_RBYD_SHRUB;
}
static inline bool lfsr_shrub_hastrunk(const lfsr_shrub_t *shrub) {
return lfsr_shrub_trunk(shrub) != 0;
}
static inline const lfsr_rbyd_t *lfsr_shrub_rbyd(const lfsr_shrub_t *shrub) {
return (const lfsr_rbyd_t*)shrub;
}
@@ -4805,7 +4827,7 @@ static inline int lfsr_shrub_cmp(
static lfsr_data_t lfsr_data_fromshrub(const lfsr_shrub_t *shrub,
uint8_t buffer[static LFSR_SHRUB_DSIZE]) {
// shrub trunks should never be null
LFS_ASSERT(shrub->trunk != 0);
LFS_ASSERT(lfsr_shrub_trunk(shrub) != 0);
lfs_ssize_t d = 0;
// just write the trunk and weight, the rest of the rbyd is contextual
@@ -4813,7 +4835,7 @@ static lfsr_data_t lfsr_data_fromshrub(const lfsr_shrub_t *shrub,
LFS_ASSERT(d_ >= 0);
d += d_;
d_ = lfs_toleb128(shrub->trunk, &buffer[d], 5);
d_ = lfs_toleb128(lfsr_shrub_trunk(shrub), &buffer[d], 5);
LFS_ASSERT(d_ >= 0);
d += d_;
@@ -4833,13 +4855,15 @@ static int lfsr_data_readshrub(lfs_t *lfs, lfsr_data_t *data,
return err;
}
err = lfsr_data_readleb128(lfs, data, (int32_t*)&shrub->trunk);
err = lfsr_data_readleb128(lfs, data, &shrub->trunk);
if (err) {
return err;
}
// shrub trunks should never be null
LFS_ASSERT(shrub->trunk != 0);
LFS_ASSERT(lfsr_shrub_hastrunk(shrub));
// set the shrub bit in our trunk
shrub->trunk |= LFSR_RBYD_SHRUB;
return 0;
}
@@ -4869,7 +4893,7 @@ static lfs_ssize_t lfsr_shrub_estimate(lfs_t *lfs,
static int lfsr_shrub_compact(lfs_t *lfs, lfsr_rbyd_t *rbyd_,
lfsr_shrub_t *shrub_, const lfsr_shrub_t *shrub) {
// save our current trunk/weight
lfs_size_t trunk = rbyd_->trunk;
lfs_ssize_t trunk = rbyd_->trunk;
lfsr_srid_t weight = rbyd_->weight;
// compact our bshrub
@@ -4919,21 +4943,16 @@ static int lfsr_shrub_commit(lfs_t *lfs, lfsr_rbyd_t *rbyd_,
// things up too much
//
// it is important that these rbyds share eoff/cksum/etc
lfs_size_t trunk = rbyd_->trunk;
lfs_ssize_t trunk = rbyd_->trunk;
lfsr_srid_t weight = rbyd_->weight;
rbyd_->trunk = shrub->trunk;
rbyd_->weight = shrub->weight;
// append any bshrub attributes
for (lfs_size_t j = 0; j < attr_count; j++) {
int err = lfsr_rbyd_appendattr(lfs, rbyd_,
attrs[j].rid,
LFSR_TAG_SHRUB | attrs[j].tag,
attrs[j].delta,
attrs[j].data);
if (err) {
return err;
}
int err = lfsr_rbyd_appendattrs(lfs, rbyd_, -1, -1,
attrs, attr_count);
if (err) {
return err;
}
// restore mdir to the main trunk/weight
@@ -5604,7 +5623,7 @@ static int lfsr_mdir_commit__(lfs_t *lfs, lfsr_mdir_t *mdir,
// extensions are atomic
if (attrs[i].tag == LFSR_TAG_SHRUBALLOC) {
bshrubcommit->shrub->blocks[0] = rbyd_.blocks[0];
bshrubcommit->shrub->trunk = 0;
bshrubcommit->shrub->trunk = LFSR_RBYD_SHRUB | 0;
bshrubcommit->shrub->weight = 0;
}
@@ -5929,7 +5948,7 @@ static int lfsr_mdir_compact__(lfs_t *lfs, lfsr_mdir_t *mdir_,
}
}
int err = lfsr_rbyd_appendcompaction(lfs, &mdir_->rbyd, false, 0);
int err = lfsr_rbyd_appendcompaction(lfs, &mdir_->rbyd, 0);
if (err) {
LFS_ASSERT(err != LFS_ERR_RANGE);
return err;
@@ -6203,7 +6222,7 @@ static int lfsr_mroot_commit_(lfs_t *lfs,
}
}
err = lfsr_rbyd_appendcompaction(lfs, &mrootanchor_.rbyd, false, 0);
err = lfsr_rbyd_appendcompaction(lfs, &mrootanchor_.rbyd, 0);
if (err) {
LFS_ASSERT(err != LFS_ERR_RANGE);
return err;
@@ -8037,7 +8056,7 @@ int lfsr_mount(lfs_t *lfs, const struct lfs_config *cfg) {
lfs->cfg->block_count,
lfs->mroot.rbyd.blocks[0],
lfs->mroot.rbyd.blocks[1],
lfs->mroot.rbyd.trunk,
lfsr_rbyd_trunk(&lfs->mroot.rbyd),
lfsr_mtree_weight(lfs) / lfsr_mweight(lfs),
lfsr_mweight(lfs));
@@ -9594,7 +9613,6 @@ static int lfsr_bshrub_traverse(lfs_t *lfs, const lfsr_file_t *file,
} else if (lfsr_bshrub_isbshruborbtree(&file->bshrub)) {
int err = lfsr_btree_traverse_(lfs,
lfsr_shrub_rbyd(&file->bshrub.u.bshrub),
lfsr_bshrub_isbshrub(&file->m.mdir, &file->bshrub),
btraversal,
bid_, tinfo_);
if (err) {
@@ -9713,7 +9731,6 @@ static int lfsr_bshrub_commit(lfs_t *lfs, lfsr_file_t *file,
// try to commit to the btree
int err = lfsr_btree_commit_(lfs, &file->bshrub.u.btree,
lfsr_bshrub_isbshrub(&file->m.mdir, &file->bshrub),
&attrs, &attr_count,
attrs__, buffer);
if (err && err != LFS_ERR_RANGE) {
@@ -9803,7 +9820,7 @@ static int lfsr_bshrub_commit(lfs_t *lfs, lfsr_file_t *file,
return 0;
}
LFS_ASSERT(file->bshrub.u.bshrub.trunk != 0);
LFS_ASSERT(lfsr_shrub_hastrunk(&file->bshrub.u.bshrub));
return 0;
evict:;
@@ -9880,7 +9897,7 @@ static int lfsr_file_carve(lfs_t *lfs, lfsr_file_t *file,
}
file->bshrub.u.bshrub.blocks[0] = file->m.mdir.rbyd.blocks[0];
file->bshrub.u.bshrub.trunk = 0;
file->bshrub.u.bshrub.trunk = LFSR_RBYD_SHRUB | 0;
file->bshrub.u.bshrub.weight = 0;
// force estimate recalculation
file->bshrub.u.bshrub.estimate = -1;
+5 -2
View File
@@ -339,12 +339,15 @@ typedef struct lfs_cache {
// TODO do we get ram savings with a lfsr_rorbyd_t substruct? need to measure
typedef struct lfsr_rbyd {
// note this lines up with weight in lfsr_btree_t
// sign(weight)=0 => rbyd
lfsr_srid_t weight;
lfs_block_t blocks[2];
// sign(trunk)=0 => normal rbyd
// sign(trunk)=1 => shrub rbyd
// eoff=0, trunk=0 => not yet committed
// eoff=0, trunk>0 => not yet fetched
// eoff>=block_size => rbyd not erased/needs compaction
lfs_size_t trunk;
lfs_ssize_t trunk;
lfs_size_t eoff;
uint32_t cksum;
} lfsr_rbyd_t;
@@ -493,7 +496,7 @@ typedef struct lfsr_shrub {
// this all lines up with lfsr_rbyd_t
lfsr_srid_t weight;
lfs_block_t blocks[2];
lfs_size_t trunk;
lfs_ssize_t trunk;
lfs_size_t eoff;
// an upper-bound estimate on the on-disk shrub size
lfs_size_t estimate;
+1
View File
@@ -696,6 +696,7 @@ class Rbyd:
# keep track of eoff for best matching trunk
if trunk and j_ + size > trunk:
trunkeoff = j_ + size
eoff = trunkeoff
cksum = cksum_
trunk_ = trunk__
weight = weight_
+1
View File
@@ -363,6 +363,7 @@ class Rbyd:
# keep track of eoff for best matching trunk
if trunk and j_ + size > trunk:
trunkeoff = j_ + size
eoff = trunkeoff
cksum = cksum_
trunk_ = trunk__
weight = weight_
+1
View File
@@ -394,6 +394,7 @@ class Rbyd:
# keep track of eoff for best matching trunk
if trunk and j_ + size > trunk:
trunkeoff = j_ + size
eoff = trunkeoff
cksum = cksum_
trunk_ = trunk__
weight = weight_
+1
View File
@@ -378,6 +378,7 @@ class Rbyd:
# keep track of eoff for best matching trunk
if trunk and j_ + size > trunk:
trunkeoff = j_ + size
eoff = trunkeoff
cksum = cksum_
trunk_ = trunk__
weight = weight_