Reworked ftree/bshrub/shrub relationship, staging in ftree now

This is an attempt to simplify things a bit by moving more logic into
the ftree layer, instead of spreading things around between the
bshrub/bsprout functions.

Now, functionality is organized into high-level ftree operations and
low-level shrub/sprout operations, which only care about the inlined
portion of the shrub/sprout. No more lfsr_bshrub_commit/
lfsr_bshrub_commit__ which were mostly unrelated.

This also adds a lfsr_shrub_t type, which, by taking advantage of the
unused write-related rbyd fields to store the shrub estimate, has the
same size as lfsr_rbyd_t, but can still be casted to an rbyd/btree for
use in readonly rbyd/btree functions.

I considered merging shrub/sprout esimate and shrub/sprout compact into
some sort of ftree_estimate/compact, but it's not obvious what the
benefit would be, so leaving that on the table for now.

---

One nice change is our staging copies are now at the ftree level
(ftree.u and ftree.u_, maybe not the best names, but this is what I've
been using for unions where the name doesn't really matter, god I want
unnamed unions). This simplifies staging, and avoids staging issues
where the underlying type changes.

---

A bit unrelated, but necessary to integrate lfsr_ftree_traverse, a
generalized lfsr_tinfo_t type for all traversal functions was added
(adopted from lfsr_traversal_t really). This is a straightforward tagged
union with relevant traversal types.

The benefit of a generalized tinfo type is better chance we can just
pass the tinfo pointer through multiple layers.

Code changes:

            code          stack
  before:  33368           2984
  after:   33260 (-0.3%)   3024 (+1.3%)
This commit is contained in:
Christopher Haster
2024-01-09 09:45:02 -06:00
parent f209c95dad
commit b0bd026b87
3 changed files with 801 additions and 830 deletions
+38 -40
View File
@@ -4294,37 +4294,36 @@ code = '''
// a bit hacky, but this catches infinite loops
assert(i <= 2*N);
lfsr_binfo_t binfo;
int err = lfsr_btree_traverse(&lfs, &btree, &traversal, &binfo);
lfsr_bid_t bid;
lfsr_tinfo_t tinfo;
int err = lfsr_btree_traverse(&lfs, &btree, &traversal,
&bid, &tinfo);
assert(!err || err == LFS_ERR_NOENT);
if (err == LFS_ERR_NOENT) {
break;
}
if (binfo.tag == LFSR_TAG_BRANCH) {
printf("traversal: %d 0x%x w%d btree 0x%x.%x\n",
binfo.bid,
binfo.tag,
binfo.weight,
binfo.u.rbyd.blocks[0], binfo.u.rbyd.trunk);
if (tinfo.tag == LFSR_TAG_BRANCH) {
printf("traversal: %d 0x%x btree 0x%x.%x\n",
bid,
tinfo.tag,
tinfo.u.rbyd.blocks[0], tinfo.u.rbyd.trunk);
// keep track of seen blocks
seen[binfo.u.rbyd.blocks[0] / 8]
|= 1 << (binfo.u.rbyd.blocks[0] % 8);
seen[tinfo.u.rbyd.blocks[0] / 8]
|= 1 << (tinfo.u.rbyd.blocks[0] % 8);
} else if (binfo.tag == LFSR_TAG_DATA) {
printf("traversal: %d 0x%x w%d data %d\n",
binfo.bid,
binfo.tag,
binfo.weight,
lfsr_data_size(&binfo.u.data));
} else if (tinfo.tag == LFSR_TAG_DATA) {
printf("traversal: %d 0x%x data %d\n",
bid,
tinfo.tag,
lfsr_data_size(&tinfo.u.data));
} else {
// well this shouldn't happen
printf("traversal: %d 0x%x w%d\n",
binfo.bid,
binfo.tag,
binfo.weight);
printf("traversal: %d 0x%x\n",
bid,
tinfo.tag);
assert(false);
}
}
@@ -4447,37 +4446,36 @@ code = '''
// a bit hacky, but this catches infinite loops
assert(i <= 2*N);
lfsr_binfo_t binfo;
int err = lfsr_btree_traverse(&lfs, &btree, &traversal, &binfo);
lfsr_bid_t bid;
lfsr_tinfo_t tinfo;
int err = lfsr_btree_traverse(&lfs, &btree, &traversal,
&bid, &tinfo);
assert(!err || err == LFS_ERR_NOENT);
if (err == LFS_ERR_NOENT) {
break;
}
if (binfo.tag == LFSR_TAG_BRANCH) {
printf("traversal: %d 0x%x w%d btree 0x%x.%x\n",
binfo.bid,
binfo.tag,
binfo.weight,
binfo.u.rbyd.blocks[0], binfo.u.rbyd.trunk);
if (tinfo.tag == LFSR_TAG_BRANCH) {
printf("traversal: %d 0x%x btree 0x%x.%x\n",
bid,
tinfo.tag,
tinfo.u.rbyd.blocks[0], tinfo.u.rbyd.trunk);
// keep track of seen blocks
seen[binfo.u.rbyd.blocks[0] / 8]
|= 1 << (binfo.u.rbyd.blocks[0] % 8);
seen[tinfo.u.rbyd.blocks[0] / 8]
|= 1 << (tinfo.u.rbyd.blocks[0] % 8);
} else if (binfo.tag == LFSR_TAG_DATA) {
printf("traversal: %d 0x%x w%d data %d\n",
binfo.bid,
binfo.tag,
binfo.weight,
lfsr_data_size(&binfo.u.data));
} else if (tinfo.tag == LFSR_TAG_DATA) {
printf("traversal: %d 0x%x data %d\n",
bid,
tinfo.tag,
lfsr_data_size(&tinfo.u.data));
} else {
// well this shouldn't happen
printf("traversal: %d 0x%x w%d\n",
binfo.bid,
binfo.tag,
binfo.weight);
printf("traversal: %d 0x%x\n",
bid,
tinfo.tag);
assert(false);
}
}