From a49e13b992f7f2be9aab11b2eab739355b1739b8 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Sat, 24 May 2025 11:20:05 -0500 Subject: [PATCH] Attempted to implement per-btree leaf caches The idea here, is we give each lfsr_btree_t an optional leaf rbyd, in addition to the root rbyd. This leaf rbyd acts as a cache for the most recent leaf, allowing nearby btree lookups to skip the full btree walk. Unfortunately, this failed on pretty much every measurable metric... --- The motivation for this is that we often do a bunch of nearby btree lookups: - Btree iteration via lfsr_btree_lookupnext is a bit naive, walking from the root every step. - Our crystallization algorithm requires a bunch of nearby lookups to figure out our crystallization heuristic. Currently at most 4, when you need to lookup both crystal neighbors and then _also_ both fragment neighbors for coalescing. - Checksum collision resolution for dids and (FUTURE) ddkeys can require an unbounded number of sequential lookups. Though to be fair, this is an exceptional case if our checksum is any good. - Bids with multiple rattrs require nearby lookups to resolve. Though currently this can be explicitly avoided via lfsr_btree_lookupleaf + lfsr_rbyd_lookup. The theory was that cases like these could explicitly keep track of the leaf rbyd to avoid full btree walks, but in practice this never really worked out. Tracking if we're still in the relevant leaf rbyd just adds too much logic/code cost. But if this leaf tracking logic was implemented once in the btree layer... The other theoretical benefit was being able to move more rbyds off the stack. Sure our btrees take up more RAM, but if that results in stack savings, that may be a win. Oh, and this would let our btree API and rbyd API converge without performance concerns. Internal users could in theory call lfsr_btree_lookupnext + lfsr_btree_lookup with the same performance as explicitly tracking the rbyd. --- But this was a complete failure! First the good news: There was a modest speedup of around ~2x to linear reads. And that's the good news. Now the bad news: 1. There was no noticeable performance gain in any other benchmarks. To be fair, we're at the early stages of benchmarking, so the benchmarks may not be the most thorough, but thinking about it, there are some explanations: - In any benchmark that writes, fetch + erase + prog dominates. Being able to skip fetches during lookups makes our btree lookups surprisingly cheap! - Any random read heavy benchmark is likely thrashing this cache, which is to be expected. - For small 1-block btrees, the leaf cache is useless because the entire btree is cache in the root rbyd. And keep in mind, our blocks are BIG. "Small" here could be on the order of ~128KiB-1MiB for NAND flash. - For the mtree, fetched mdirs actually already act as a sort of leaf cache. The extra btree leaf cache isn't doing _nothing_, but each layer of the mtree has diminishing returns due to btree's ridiculous branching factor. - For file btrees, we're explicitly caching the leaf fragments/ blocks, so the extra btree leaf cache has diminishing returns for the same reason. 2. Code cost was bad, stack cost was worse: code stack ctx before: 37172 2288 636 after: 38068 (+2.4%) 2416 (+5.6%) 664 (+4.4%) Tracking the leaf required more code, that's expected. And, to be fair, the current code has had a lot more time to congeal. What wasn't expected was the stack cost. Unfortunately these caches didn't really take any rbyds off the stack hot-path: - We _can_ get rid of the rbyd in lfsr_btree_lookup/namelookup, but we were already hacking our way around the critical one in lfsr_mtree_lookup/namelookup by reusing the mdir's rbyd! - We can't even abuse the leaf rbyd in the commit logic, since the target btree can end up iterated/traversed by lfs_alloc. That was a fun bug. And the addition of a second rbyd to lfsr_btree_t increases both ctx and stack anywhere btrees are allocated. Maybe this will make more sense when we add the auxiliary btrees, or after more benchmarking, but for now the theoretical performance improvements just aren't worth it. Will probably revert this, but I wanted to commit it in case the idea is worth resurrecting in the future, if in the future nearby btree lookups are a bigger penalty than they are now. --- lfs.c | 645 +++++++++++++++++++++----------------- lfs.h | 13 +- tests/test_badblocks.toml | 24 +- tests/test_btree.toml | 610 +++++++++++++++++------------------ tests/test_files.toml | 6 +- tests/test_mtree.toml | 122 +++---- tests/test_traversal.toml | 90 +++--- 7 files changed, 783 insertions(+), 727 deletions(-) diff --git a/lfs.c b/lfs.c index 13ead2ec..c58cd461 100644 --- a/lfs.c +++ b/lfs.c @@ -2611,6 +2611,10 @@ static inline bool lfsr_bptr_isbptr(const lfsr_bptr_t *bptr) { return bptr->data.size & LFSR_BPTR_ISBPTR; } +static inline lfs_size_t lfsr_bptr_size(const lfsr_bptr_t *bptr) { + return bptr->data.size & ~LFSR_BPTR_ONDISK & ~LFSR_BPTR_ISBPTR; +} + static inline lfs_block_t lfsr_bptr_block(const lfsr_bptr_t *bptr) { return bptr->data.u.disk.block; } @@ -2619,10 +2623,6 @@ static inline lfs_size_t lfsr_bptr_off(const lfsr_bptr_t *bptr) { return bptr->data.u.disk.off; } -static inline lfs_size_t lfsr_bptr_size(const lfsr_bptr_t *bptr) { - return bptr->data.size & ~LFSR_BPTR_ONDISK & ~LFSR_BPTR_ISBPTR; -} - // checked reads adds ck info to lfsr_data_t that we don't want to // unnecessarily duplicate, this makes accessing ck info annoyingly // messy... @@ -5133,20 +5133,47 @@ static lfs_scmp_t lfsr_rbyd_namelookup(lfs_t *lfs, const lfsr_rbyd_t *rbyd, // create an empty btree static void lfsr_btree_init(lfsr_btree_t *btree) { - btree->weight = 0; - btree->blocks[0] = -1; - btree->trunk = 0; + btree->root.weight = 0; + btree->root.blocks[0] = -1; + btree->root.trunk = 0; + // weight=0 indicates no leaf + btree->leaf.rbyd.weight = 0; } // convenience operations static inline void lfsr_btree_claim(lfsr_btree_t *btree) { - lfsr_rbyd_claim(btree); + lfsr_rbyd_claim(&btree->root); + lfsr_rbyd_claim(&btree->leaf.rbyd); +} + +static inline void lfsr_btree_discardleaf(lfsr_btree_t *btree) { + btree->leaf.rbyd.weight = 0; +} + +static inline lfsr_bid_t lfsr_btree_weight(const lfsr_btree_t *btree) { + return btree->root.weight; +} + +static inline lfs_block_t lfsr_btree_block(const lfsr_btree_t *btree) { + return btree->root.blocks[0]; +} + +static inline bool lfsr_btree_isbshrub(const lfsr_btree_t *btree) { + return lfsr_rbyd_isshrub(&btree->root); +} + +static inline lfs_size_t lfsr_btree_trunk(const lfsr_btree_t *btree) { + return lfsr_rbyd_trunk(&btree->root); +} + +static inline uint32_t lfsr_btree_cksum(const lfsr_btree_t *btree) { + return btree->root.cksum; } static inline int lfsr_btree_cmp( const lfsr_btree_t *a, const lfsr_btree_t *b) { - return lfsr_rbyd_cmp(a, b); + return lfsr_rbyd_cmp(&a->root, &b->root); } @@ -5257,16 +5284,16 @@ static int lfsr_data_fetchbranch(lfs_t *lfs, static lfsr_data_t lfsr_data_frombtree(const lfsr_btree_t *btree, uint8_t buffer[static LFSR_BTREE_DSIZE]) { // weight should not exceed 31-bits - LFS_ASSERT(btree->weight <= 0x7fffffff); + LFS_ASSERT(lfsr_btree_weight(btree) <= 0x7fffffff); lfs_ssize_t d = 0; - lfs_ssize_t d_ = lfs_toleb128(btree->weight, &buffer[d], 5); + lfs_ssize_t d_ = lfs_toleb128(lfsr_btree_weight(btree), &buffer[d], 5); if (d_ < 0) { LFS_UNREACHABLE(); } d += d_; - lfsr_data_t data = lfsr_data_frombranch(btree, &buffer[d]); + lfsr_data_t data = lfsr_data_frombranch(&btree->root, &buffer[d]); d += lfsr_data_size(data); return LFSR_DATA_BUF(buffer, d); @@ -5280,11 +5307,12 @@ static int lfsr_data_readbtree(lfs_t *lfs, lfsr_data_t *data, return err; } - err = lfsr_data_readbranch(lfs, data, weight, btree); + err = lfsr_data_readbranch(lfs, data, weight, &btree->root); if (err) { return err; } + lfsr_btree_discardleaf(btree); return 0; } @@ -5295,7 +5323,7 @@ static int lfsr_btree_fetch(lfs_t *lfs, lfsr_btree_t *btree, lfs_block_t block, lfs_size_t trunk, lfsr_bid_t weight, uint32_t cksum) { // btree/branch fetch really are the same once we know the weight - int err = lfsr_branch_fetch(lfs, btree, + int err = lfsr_branch_fetch(lfs, &btree->root, block, trunk, weight, cksum); if (err) { @@ -5305,9 +5333,9 @@ static int lfsr_btree_fetch(lfs_t *lfs, lfsr_btree_t *btree, #ifdef LFS_DBGBTREEFETCHES LFS_DEBUG("Fetched btree 0x%"PRIx32".%"PRIx32" w%"PRId32", " "cksum %"PRIx32, - btree->blocks[0], lfsr_rbyd_trunk(btree), - btree->weight, - btree->cksum); + lfsr_btree_block(btree), lfsr_btree_trunk(btree), + lfsr_btree_weight(btree), + lfsr_btree_cksum(btree)); #endif return 0; } @@ -5322,52 +5350,62 @@ static int lfsr_data_fetchbtree(lfs_t *lfs, lfsr_data_t *data, } return lfsr_btree_fetch(lfs, btree, - btree->blocks[0], btree->trunk, btree->weight, - btree->cksum); + lfsr_btree_block(btree), lfsr_btree_trunk(btree), + lfsr_btree_weight(btree), + lfsr_btree_cksum(btree)); } // lookup rbyd/rid containing a given bid -static int lfsr_btree_lookupleaf(lfs_t *lfs, const lfsr_btree_t *btree, +static int lfsr_btree_lookupnext(lfs_t *lfs, lfsr_btree_t *btree, lfsr_bid_t bid, - lfsr_bid_t *bid_, lfsr_rbyd_t *rbyd_, lfsr_srid_t *rid_, - lfsr_tag_t *tag_, lfsr_bid_t *weight_, lfsr_data_t *data_) { - // descend down the btree looking for our bid - *rbyd_ = *btree; - lfsr_srid_t rid = bid; - while (true) { - // each branch is a pair of optional name + on-disk structure + lfsr_bid_t *bid_, lfsr_tag_t *tag_, lfsr_bid_t *weight_, + lfsr_data_t *data_) { + // is our bid in the leaf? can we skip the btree walk? + // + // if not we need to restart from the root + if (!(bid >= btree->leaf.bid-(btree->leaf.rbyd.weight-1) + && bid < btree->leaf.bid+1)) { + btree->leaf.bid = lfsr_btree_weight(btree)-1; + btree->leaf.rbyd = btree->root; + } + // descend down the btree looking for our bid + lfsr_srid_t rid = bid - (btree->leaf.bid-(btree->leaf.rbyd.weight-1)); + int err; + while (true) { // lookup our bid in the rbyd lfsr_srid_t rid__; lfsr_tag_t tag__; lfsr_rid_t weight__; lfsr_data_t data__; - int err = lfsr_rbyd_lookupnext(lfs, rbyd_, rid, 0, + err = lfsr_rbyd_lookupnext(lfs, &btree->leaf.rbyd, rid, 0, &rid__, &tag__, &weight__, &data__); if (err) { - return err; + goto failed; } // if we found a bname, lookup the branch if (tag__ == LFSR_TAG_BNAME) { - err = lfsr_rbyd_lookup(lfs, rbyd_, rid__, LFSR_TAG_BRANCH, + err = lfsr_rbyd_lookup(lfs, &btree->leaf.rbyd, rid__, + LFSR_TAG_BRANCH, &tag__, &data__); if (err) { LFS_ASSERT(err != LFS_ERR_NOENT); - return err; + goto failed; } } // found another branch if (tag__ == LFSR_TAG_BRANCH) { - // adjust rid with subtree's weight + // adjust bid/rid with subtree's weight + btree->leaf.bid = bid + (rid__ - rid); rid -= (rid__ - (weight__-1)); // fetch the next branch err = lfsr_data_fetchbranch(lfs, &data__, weight__, - rbyd_); + &btree->leaf.rbyd); if (err) { - return err; + goto failed; } // found our bid @@ -5376,9 +5414,6 @@ static int lfsr_btree_lookupleaf(lfs_t *lfs, const lfsr_btree_t *btree, if (bid_) { *bid_ = bid + (rid__ - rid); } - if (rid_) { - *rid_ = rid__; - } if (tag_) { *tag_ = tag__; } @@ -5391,43 +5426,42 @@ static int lfsr_btree_lookupleaf(lfs_t *lfs, const lfsr_btree_t *btree, return 0; } } -} -// non-leaf lookups discard the rbyd info, which can be a bit more -// convenient, but may make commits more costly -static int lfsr_btree_lookupnext(lfs_t *lfs, const lfsr_btree_t *btree, - lfsr_bid_t bid, - lfsr_bid_t *bid_, lfsr_tag_t *tag_, lfsr_bid_t *weight_, - lfsr_data_t *data_) { - lfsr_rbyd_t rbyd; - return lfsr_btree_lookupleaf(lfs, btree, bid, - bid_, &rbyd, NULL, tag_, weight_, data_); +failed:; + // we need to discard the leaf if it's not a true leaf, otherwise + // this breaks lfsr_btree_lookup + lfsr_btree_discardleaf(btree); + return err; } // lfsr_btree_lookup assumes a known bid, matching lfsr_rbyd_lookup's // behavior, if you don't care about the exact bid either first call -// lfsr_btree_lookupnext, or lfsr_btree_lookupleaf + lfsr_rbyd_lookup -static int lfsr_btree_lookup(lfs_t *lfs, const lfsr_btree_t *btree, +// lfsr_btree_lookupnext +// +// note that leaf caching makes this pretty efficient +static int lfsr_btree_lookup(lfs_t *lfs, lfsr_btree_t *btree, lfsr_bid_t bid, lfsr_tag_t tag, lfsr_tag_t *tag_, lfsr_data_t *data_) { - // lookup rbyd in btree - lfsr_bid_t bid__; - lfsr_rbyd_t rbyd__; - lfsr_srid_t rid__; - int err = lfsr_btree_lookupleaf(lfs, btree, bid, - &bid__, &rbyd__, &rid__, NULL, NULL, NULL); - if (err) { - return err; - } + if (!(bid >= btree->leaf.bid-(btree->leaf.rbyd.weight-1) + && bid < btree->leaf.bid+1)) { + // lookup rbyd in btree + lfsr_bid_t bid__; + int err = lfsr_btree_lookupnext(lfs, btree, bid, + &bid__, NULL, NULL, NULL); + if (err) { + return err; + } - // lookup finds the next-smallest bid, all we need to do is fail if it - // picks up the wrong bid - if (bid__ != bid) { - return LFS_ERR_NOENT; + // lookup finds the next-smallest bid, all we need to do is fail + // if it picks up the wrong bid + if (bid__ != bid) { + return LFS_ERR_NOENT; + } } // lookup tag in rbyd - return lfsr_rbyd_lookup(lfs, &rbyd__, rid__, tag, + lfsr_srid_t rid__ = bid - (btree->leaf.bid-(btree->leaf.rbyd.weight-1)); + return lfsr_rbyd_lookup(lfs, &btree->leaf.rbyd, rid__, tag, tag_, data_); } @@ -5436,11 +5470,13 @@ static int lfsr_btree_parent(lfs_t *lfs, const lfsr_btree_t *btree, lfsr_bid_t bid, const lfsr_rbyd_t *child, lfsr_rbyd_t *rbyd_, lfsr_srid_t *rid_) { // we should only call this when we actually have parents - LFS_ASSERT(bid < (lfsr_bid_t)btree->weight); - LFS_ASSERT(lfsr_rbyd_cmp(btree, child) != 0); + LFS_ASSERT(bid < lfsr_btree_weight(btree)); + LFS_ASSERT(lfsr_rbyd_cmp(&btree->root, child) != 0); + + // note we don't bother with leaf here // descend down the btree looking for our rid - *rbyd_ = *btree; + *rbyd_ = btree->root; lfsr_srid_t rid = bid; while (true) { // each branch is a pair of optional name + on-disk structure @@ -5457,7 +5493,8 @@ static int lfsr_btree_parent(lfs_t *lfs, const lfsr_btree_t *btree, // if we found a bname, lookup the branch if (tag__ == LFSR_TAG_BNAME) { - err = lfsr_rbyd_lookup(lfs, rbyd_, rid__, LFSR_TAG_BRANCH, + err = lfsr_rbyd_lookup(lfs, rbyd_, rid__, + LFSR_TAG_BRANCH, &tag__, &data__); if (err) { LFS_ASSERT(err != LFS_ERR_NOENT); @@ -5550,29 +5587,28 @@ static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree, lfsr_bid_t *bid, const lfsr_rattr_t **rattrs, lfs_size_t *rattr_count) { lfsr_bid_t bid_ = *bid; - LFS_ASSERT(bid_ <= (lfsr_bid_t)btree->weight); + LFS_ASSERT(bid_ <= lfsr_btree_weight(btree)); const lfsr_rattr_t *rattrs_ = *rattrs; lfs_size_t rattr_count_ = *rattr_count; // lookup which leaf our bid resides - // - // for lfsr_btree_commit_ operations to work out, we need to - // limit our bid to an rid in the tree, which is what this min - // is doing - lfsr_rbyd_t rbyd_ = *btree; + lfsr_rbyd_t child = btree->root; lfsr_srid_t rid_ = bid_; - if (btree->weight > 0) { - lfsr_srid_t rid__; - int err = lfsr_btree_lookupleaf(lfs, btree, - lfs_min(bid_, btree->weight-1), - &bid_, &rbyd_, &rid__, NULL, NULL, NULL); + if (lfsr_btree_weight(btree) > 0) { + int err = lfsr_btree_lookupnext(lfs, btree, + // for lfsr_btree_commit_ operations to work out, we + // need to limit our bid to an rid in the tree, which + // is what this min is doing + lfs_min(bid_, lfsr_btree_weight(btree)-1), + &bid_, NULL, NULL, NULL); if (err) { LFS_ASSERT(err != LFS_ERR_NOENT); return err; } // adjust rid - rid_ -= (bid_-rid__); + child = btree->leaf.rbyd; + rid_ -= (btree->leaf.bid-(btree->leaf.rbyd.weight-1)); } // tail-recursively commit to btree @@ -5581,16 +5617,16 @@ static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree, lfsr_rbyd_t parent = {.trunk=0, .weight=0}; lfsr_srid_t pid = 0; // are we root? - if (!lfsr_rbyd_trunk(&rbyd_) - || rbyd_.blocks[0] == btree->blocks[0]) { + if (!lfsr_rbyd_trunk(&child) + || child.blocks[0] == lfsr_btree_block(btree)) { // new root? shrub root? yield the final root commit to // higher-level btree/bshrub logic - if (!lfsr_rbyd_trunk(&rbyd_) - || lfsr_rbyd_isshrub(btree)) { + if (!lfsr_rbyd_trunk(&child) + || lfsr_btree_isbshrub(btree)) { *bid = rid_; *rattrs = rattrs_; *rattr_count = rattr_count_; - return (!lfsr_rbyd_trunk(&rbyd_)) ? LFS_ERR_RANGE : 0; + return (!lfsr_rbyd_trunk(&child)) ? LFS_ERR_RANGE : 0; } // mark btree as unerased in case of failure, our btree rbyd and @@ -5599,7 +5635,7 @@ static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree, lfsr_btree_claim(btree); } else { - int err = lfsr_btree_parent(lfs, btree, bid_, &rbyd_, + int err = lfsr_btree_parent(lfs, btree, bid_, &child, &parent, &pid); if (err) { LFS_ASSERT(err != LFS_ERR_NOENT); @@ -5614,10 +5650,10 @@ static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree, // unfetched // // a funny benefit is we cache the root of our btree this way - if (!lfsr_rbyd_isfetched(&rbyd_)) { - int err = lfsr_rbyd_fetchck(lfs, &rbyd_, - rbyd_.blocks[0], lfsr_rbyd_trunk(&rbyd_), - rbyd_.cksum); + if (!lfsr_rbyd_isfetched(&child)) { + int err = lfsr_rbyd_fetchck(lfs, &child, + child.blocks[0], lfsr_rbyd_trunk(&child), + child.cksum); if (err) { return err; } @@ -5626,8 +5662,8 @@ static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree, // is rbyd erased? can we sneak our commit into any remaining // erased bytes? note that the btree trunk field prevents this from // interacting with other references to the rbyd - lfsr_rbyd_t rbyd__ = rbyd_; - int err = lfsr_rbyd_commit(lfs, &rbyd__, rid_, + lfsr_rbyd_t child_ = child; + int err = lfsr_rbyd_commit(lfs, &child_, rid_, rattrs_, rattr_count_); if (err) { if (err == LFS_ERR_RANGE || err == LFS_ERR_CORRUPT) { @@ -5641,7 +5677,7 @@ static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree, compact:; // estimate our compacted size lfsr_srid_t split_rid; - lfs_ssize_t estimate = lfsr_rbyd_estimate(lfs, &rbyd_, -1, -1, + lfs_ssize_t estimate = lfsr_rbyd_estimate(lfs, &child, -1, -1, &split_rid); if (estimate < 0) { return estimate; @@ -5707,13 +5743,13 @@ static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree, } // try the left sibling - if (pid-(lfsr_srid_t)rbyd_.weight >= 0) { + if (pid-(lfsr_srid_t)child.weight >= 0) { // try looking up the sibling lfsr_srid_t sibling_rid; lfsr_tag_t sibling_tag; lfsr_rid_t sibling_weight; lfsr_data_t sibling_data; - err = lfsr_rbyd_lookupnext(lfs, &parent, pid-rbyd_.weight, 0, + err = lfsr_rbyd_lookupnext(lfs, &parent, pid-child.weight, 0, &sibling_rid, &sibling_tag, &sibling_weight, &sibling_data); if (err) { @@ -5754,11 +5790,11 @@ static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree, // so our sibling is on the right bid_ -= sibling.weight; rid_ += sibling.weight; - pid -= rbyd_.weight; + pid -= child.weight; - rbyd__ = sibling; - sibling = rbyd_; - rbyd_ = rbyd__; + child_ = sibling; + sibling = child; + child = child_; goto merge; } @@ -5767,14 +5803,14 @@ static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree, relocate:; // allocate a new rbyd - err = lfsr_rbyd_alloc(lfs, &rbyd__); + err = lfsr_rbyd_alloc(lfs, &child_); if (err) { return err; } #if defined(LFS_REVDBG) || defined(LFS_REVNOISE) // append a revision count? - err = lfsr_rbyd_appendrev(lfs, &rbyd__, lfsr_rev_btree(lfs)); + err = lfsr_rbyd_appendrev(lfs, &child_, lfsr_rev_btree(lfs)); if (err) { // bad prog? try another block if (err == LFS_ERR_CORRUPT) { @@ -5785,7 +5821,7 @@ static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree, #endif // try to compact - err = lfsr_rbyd_compact(lfs, &rbyd__, &rbyd_, -1, -1); + err = lfsr_rbyd_compact(lfs, &child_, &child, -1, -1); if (err) { LFS_ASSERT(err != LFS_ERR_RANGE); // bad prog? try another block @@ -5797,7 +5833,7 @@ static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree, // append any pending rattrs, it's up to upper // layers to make sure these always fit - err = lfsr_rbyd_commit(lfs, &rbyd__, rid_, + err = lfsr_rbyd_commit(lfs, &child_, rid_, rattrs_, rattr_count_); if (err) { LFS_ASSERT(err != LFS_ERR_RANGE); @@ -5813,18 +5849,18 @@ static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree, split:; // we should have something to split here LFS_ASSERT(split_rid > 0 - && split_rid < (lfsr_srid_t)rbyd_.weight); + && split_rid < (lfsr_srid_t)child.weight); split_relocate_l:; // allocate a new rbyd - err = lfsr_rbyd_alloc(lfs, &rbyd__); + err = lfsr_rbyd_alloc(lfs, &child_); if (err) { return err; } #if defined(LFS_REVDBG) || defined(LFS_REVNOISE) // append a revision count? - err = lfsr_rbyd_appendrev(lfs, &rbyd__, lfsr_rev_btree(lfs)); + err = lfsr_rbyd_appendrev(lfs, &child_, lfsr_rev_btree(lfs)); if (err) { // bad prog? try another block if (err == LFS_ERR_CORRUPT) { @@ -5835,7 +5871,7 @@ static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree, #endif // copy over tags < split_rid - err = lfsr_rbyd_compact(lfs, &rbyd__, &rbyd_, -1, split_rid); + err = lfsr_rbyd_compact(lfs, &child_, &child, -1, split_rid); if (err) { LFS_ASSERT(err != LFS_ERR_RANGE); // bad prog? try another block @@ -5849,7 +5885,7 @@ static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree, // // upper layers should make sure this can't fail by limiting the // maximum commit size - err = lfsr_rbyd_appendrattrs(lfs, &rbyd__, rid_, -1, split_rid, + err = lfsr_rbyd_appendrattrs(lfs, &child_, rid_, -1, split_rid, rattrs_, rattr_count_); if (err) { LFS_ASSERT(err != LFS_ERR_RANGE); @@ -5861,7 +5897,7 @@ static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree, } // finalize commit - err = lfsr_rbyd_appendcksum(lfs, &rbyd__); + err = lfsr_rbyd_appendcksum(lfs, &child_); if (err) { LFS_ASSERT(err != LFS_ERR_RANGE); // bad prog? try another block @@ -5891,7 +5927,7 @@ static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree, #endif // copy over tags >= split_rid - err = lfsr_rbyd_compact(lfs, &sibling, &rbyd_, split_rid, -1); + err = lfsr_rbyd_compact(lfs, &sibling, &child, split_rid, -1); if (err) { LFS_ASSERT(err != LFS_ERR_RANGE); // bad prog? try another block @@ -5929,9 +5965,9 @@ static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree, // did one of our siblings drop to zero? yes this can happen! revert // to a normal commit in that case - if (rbyd__.weight == 0 || sibling.weight == 0) { - if (rbyd__.weight == 0) { - rbyd__ = sibling; + if (child_.weight == 0 || sibling.weight == 0) { + if (child_.weight == 0) { + child_ = sibling; } goto commit; } @@ -5949,15 +5985,15 @@ static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree, } // prepare commit to parent, tail recursing upwards - LFS_ASSERT(rbyd__.weight > 0); + LFS_ASSERT(child_.weight > 0); LFS_ASSERT(sibling.weight > 0); rattr_count_ = 0; // new root? if (!lfsr_rbyd_trunk(&parent)) { lfsr_data_t branch_l = lfsr_data_frombranch( - &rbyd__, &bctx->buf[0*LFSR_BRANCH_DSIZE]); + &child_, &bctx->buf[0*LFSR_BRANCH_DSIZE]); bctx->rattrs[rattr_count_++] = LFSR_RATTR_BUF( - LFSR_TAG_BRANCH, +rbyd__.weight, + LFSR_TAG_BRANCH, +child_.weight, branch_l.u.buffer, lfsr_data_size(branch_l)); lfsr_data_t branch_r = lfsr_data_frombranch( &sibling, &bctx->buf[1*LFSR_BRANCH_DSIZE]); @@ -5971,15 +6007,15 @@ static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree, } // split root? } else { - bid_ -= pid - (rbyd_.weight-1); + bid_ -= pid - (child.weight-1); lfsr_data_t branch_l = lfsr_data_frombranch( - &rbyd__, &bctx->buf[0*LFSR_BRANCH_DSIZE]); + &child_, &bctx->buf[0*LFSR_BRANCH_DSIZE]); bctx->rattrs[rattr_count_++] = LFSR_RATTR_BUF( LFSR_TAG_BRANCH, 0, branch_l.u.buffer, lfsr_data_size(branch_l)); - if (rbyd__.weight != rbyd_.weight) { + if (child_.weight != child.weight) { bctx->rattrs[rattr_count_++] = LFSR_RATTR( - LFSR_TAG_GROW, -rbyd_.weight + rbyd__.weight); + LFSR_TAG_GROW, -child.weight + child_.weight); } lfsr_data_t branch_r = lfsr_data_frombranch( &sibling, &bctx->buf[1*LFSR_BRANCH_DSIZE]); @@ -5994,21 +6030,21 @@ static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree, } rattrs_ = bctx->rattrs; - rbyd_ = parent; + child = parent; rid_ = pid; continue; merge:; merge_relocate:; // allocate a new rbyd - err = lfsr_rbyd_alloc(lfs, &rbyd__); + err = lfsr_rbyd_alloc(lfs, &child_); if (err) { return err; } #if defined(LFS_REVDBG) || defined(LFS_REVNOISE) // append a revision count? - err = lfsr_rbyd_appendrev(lfs, &rbyd__, lfsr_rev_btree(lfs)); + err = lfsr_rbyd_appendrev(lfs, &child_, lfsr_rev_btree(lfs)); if (err) { // bad prog? try another block if (err == LFS_ERR_CORRUPT) { @@ -6019,7 +6055,7 @@ static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree, #endif // merge the siblings together - err = lfsr_rbyd_appendcompactrbyd(lfs, &rbyd__, &rbyd_, -1, -1); + err = lfsr_rbyd_appendcompactrbyd(lfs, &child_, &child, -1, -1); if (err) { LFS_ASSERT(err != LFS_ERR_RANGE); // bad prog? try another block @@ -6029,7 +6065,7 @@ static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree, return err; } - err = lfsr_rbyd_appendcompactrbyd(lfs, &rbyd__, &sibling, -1, -1); + err = lfsr_rbyd_appendcompactrbyd(lfs, &child_, &sibling, -1, -1); if (err) { LFS_ASSERT(err != LFS_ERR_RANGE); // bad prog? try another block @@ -6039,7 +6075,7 @@ static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree, return err; } - err = lfsr_rbyd_appendcompaction(lfs, &rbyd__, 0); + err = lfsr_rbyd_appendcompaction(lfs, &child_, 0); if (err) { LFS_ASSERT(err != LFS_ERR_RANGE); // bad prog? try another block @@ -6051,7 +6087,7 @@ static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree, // append any pending rattrs, it's up to upper // layers to make sure these always fit - err = lfsr_rbyd_commit(lfs, &rbyd__, rid_, + err = lfsr_rbyd_commit(lfs, &child_, rid_, rattrs_, rattr_count_); if (err) { LFS_ASSERT(err != LFS_ERR_RANGE); @@ -6065,47 +6101,51 @@ static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree, // we must have a parent at this point, but is our parent the root // and is the root degenerate? LFS_ASSERT(lfsr_rbyd_trunk(&parent)); - if (rbyd_.weight+sibling.weight == btree->weight) { + if (child.weight+sibling.weight == lfsr_btree_weight(btree)) { // collapse the root, decreasing the height of the tree - *btree = rbyd__; + btree->root = child_; + // no new root needed *rattr_count = 0; return 0; } // prepare commit to parent, tail recursing upwards - LFS_ASSERT(rbyd__.weight > 0); + LFS_ASSERT(child_.weight > 0); rattr_count_ = 0; // build attr list - bid_ -= pid - (rbyd_.weight-1); + bid_ -= pid - (child.weight-1); bctx->rattrs[rattr_count_++] = LFSR_RATTR( LFSR_TAG_RM, -sibling.weight); lfsr_data_t branch = lfsr_data_frombranch( - &rbyd__, &bctx->buf[0*LFSR_BRANCH_DSIZE]); + &child_, &bctx->buf[0*LFSR_BRANCH_DSIZE]); bctx->rattrs[rattr_count_++] = LFSR_RATTR_BUF( LFSR_TAG_BRANCH, 0, branch.u.buffer, lfsr_data_size(branch)); - if (rbyd__.weight != rbyd_.weight) { + if (child_.weight != child.weight) { bctx->rattrs[rattr_count_++] = LFSR_RATTR( - LFSR_TAG_GROW, -rbyd_.weight + rbyd__.weight); + LFSR_TAG_GROW, -child.weight + child_.weight); } rattrs_ = bctx->rattrs; - rbyd_ = parent; + child = parent; rid_ = pid + sibling.weight; continue; commit:; // done? if (!lfsr_rbyd_trunk(&parent)) { - *btree = rbyd__; + // update the root + btree->root = child_; + // no new root needed *rattr_count = 0; return 0; } // is our parent the root and is the root degenerate? - if (rbyd_.weight == btree->weight) { + if (child.weight == lfsr_btree_weight(btree)) { // collapse the root, decreasing the height of the tree - *btree = rbyd__; + btree->root = child_; + // no new root needed *rattr_count = 0; return 0; } @@ -6115,24 +6155,24 @@ static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree, // note that since we defer merges to compaction time, we can // end up removing an rbyd here rattr_count_ = 0; - bid_ -= pid - (rbyd_.weight-1); - if (rbyd__.weight == 0) { + bid_ -= pid - (child.weight-1); + if (child_.weight == 0) { bctx->rattrs[rattr_count_++] = LFSR_RATTR( - LFSR_TAG_RM, -rbyd_.weight); + LFSR_TAG_RM, -child.weight); } else { lfsr_data_t branch = lfsr_data_frombranch( - &rbyd__, &bctx->buf[0*LFSR_BRANCH_DSIZE]); + &child_, &bctx->buf[0*LFSR_BRANCH_DSIZE]); bctx->rattrs[rattr_count_++] = LFSR_RATTR_BUF( LFSR_TAG_BRANCH, 0, branch.u.buffer, lfsr_data_size(branch)); - if (rbyd__.weight != rbyd_.weight) { + if (child_.weight != child.weight) { bctx->rattrs[rattr_count_++] = LFSR_RATTR( - LFSR_TAG_GROW, -rbyd_.weight + rbyd__.weight); + LFSR_TAG_GROW, -child.weight + child_.weight); } } rattrs_ = bctx->rattrs; - rbyd_ = parent; + child = parent; rid_ = pid; continue; } @@ -6182,81 +6222,83 @@ static int lfsr_btree_commit(lfs_t *lfs, lfsr_btree_t *btree, return err; } - *btree = rbyd_; + // update the root + btree->root = rbyd_; } - LFS_ASSERT(lfsr_rbyd_trunk(btree)); + // discard the leaf + lfsr_btree_discardleaf(btree); + + LFS_ASSERT(lfsr_btree_trunk(btree)); #ifdef LFS_DBGBTREECOMMITS LFS_DEBUG("Committed btree 0x%"PRIx32".%"PRIx32" w%"PRId32", " "cksum %"PRIx32, - btree->blocks[0], lfsr_rbyd_trunk(btree), - btree->weight, - btree->cksum); + lfsr_btree_block(btree), lfsr_btree_trunk(btree), + lfsr_btree_weight(btree), + lfsr_btree_cksum(btree)); #endif return 0; } // lookup in a btree by name -static lfs_scmp_t lfsr_btree_namelookupleaf(lfs_t *lfs, - const lfsr_btree_t *btree, +static lfs_scmp_t lfsr_btree_namelookup(lfs_t *lfs, + lfsr_btree_t *btree, lfsr_did_t did, const char *name, lfs_size_t name_len, - lfsr_bid_t *bid_, lfsr_rbyd_t *rbyd_, lfsr_srid_t *rid_, - lfsr_tag_t *tag_, lfsr_bid_t *weight_, lfsr_data_t *data_) { + lfsr_bid_t *bid_, lfsr_tag_t *tag_, lfsr_bid_t *weight_, + lfsr_data_t *data_) { // an empty tree? - if (btree->weight == 0) { + if (lfsr_btree_weight(btree) == 0) { return LFS_ERR_NOENT; } // descend down the btree looking for our name - *rbyd_ = *btree; - lfsr_bid_t bid = 0; + btree->leaf.bid = lfsr_btree_weight(btree)-1; + btree->leaf.rbyd = btree->root; + int err; while (true) { - // each branch is a pair of optional name + on-disk structure - // lookup our name in the rbyd via binary search lfsr_srid_t rid__; lfsr_tag_t tag__; lfsr_rid_t weight__; lfsr_data_t data__; - lfs_scmp_t cmp = lfsr_rbyd_namelookup(lfs, rbyd_, + lfs_scmp_t cmp = lfsr_rbyd_namelookup(lfs, &btree->leaf.rbyd, did, name, name_len, &rid__, &tag__, &weight__, &data__); if (cmp < 0) { LFS_ASSERT(cmp != LFS_ERR_NOENT); - return cmp; + err = cmp; + goto failed; } // if we found a bname, lookup the branch if (tag__ == LFSR_TAG_BNAME) { - int err = lfsr_rbyd_lookup(lfs, rbyd_, rid__, + err = lfsr_rbyd_lookup(lfs, &btree->leaf.rbyd, rid__, LFSR_TAG_MASK8 | LFSR_TAG_STRUCT, &tag__, &data__); if (err < 0) { LFS_ASSERT(err != LFS_ERR_NOENT); - return err; + goto failed; } } // found another branch if (tag__ == LFSR_TAG_BRANCH) { - // update our bid - bid += rid__ - (weight__-1); + // adjust bid/rid with subtree's weight + btree->leaf.bid -= (btree->leaf.rbyd.weight-1) - rid__; // fetch the next branch - int err = lfsr_data_fetchbranch(lfs, &data__, weight__, - rbyd_); + err = lfsr_data_fetchbranch(lfs, &data__, weight__, + &btree->leaf.rbyd); if (err < 0) { - return err; + goto failed; } // found our rid } else { // TODO how many of these should be conditional? if (bid_) { - *bid_ = bid + rid__; - } - if (rid_) { - *rid_ = rid__; + *bid_ = btree->leaf.bid + - ((btree->leaf.rbyd.weight-1) - rid__); } if (tag_) { *tag_ = tag__; @@ -6270,17 +6312,12 @@ static lfs_scmp_t lfsr_btree_namelookupleaf(lfs_t *lfs, return cmp; } } -} -static lfs_scmp_t lfsr_btree_namelookup(lfs_t *lfs, - const lfsr_btree_t *btree, - lfsr_did_t did, const char *name, lfs_size_t name_len, - lfsr_bid_t *bid_, - lfsr_tag_t *tag_, lfsr_bid_t *weight_, lfsr_data_t *data_) { - lfsr_rbyd_t rbyd; - return lfsr_btree_namelookupleaf(lfs, btree, - did, name, name_len, - bid_, &rbyd, NULL, tag_, weight_, data_); +failed:; + // we need to discard the leaf if it's not a true leaf, otherwise + // this breaks lfsr_btree_lookup + lfsr_btree_discardleaf(btree); + return err; } // incremental btree traversal @@ -6299,17 +6336,17 @@ static int lfsr_btree_traverse(lfs_t *lfs, const lfsr_btree_t *btree, lfsr_bid_t *bid_, lfsr_tag_t *tag_, lfsr_data_t *data_) { // explicitly traverse the root even if weight=0 if (!bt->branch) { - bt->branch = btree; + bt->branch = &btree->root; bt->rid = bt->bid; // traverse the root if (bt->bid == 0 // unless we don't even have a root yet - && lfsr_rbyd_trunk(btree) != 0 + && lfsr_btree_trunk(btree) != 0 // or are a shrub - && !lfsr_rbyd_isshrub(btree)) { + && !lfsr_btree_isbshrub(btree)) { if (bid_) { - *bid_ = btree->weight-1; + *bid_ = lfsr_btree_weight(btree)-1; } if (tag_) { *tag_ = LFSR_TAG_BRANCH; @@ -6323,7 +6360,7 @@ static int lfsr_btree_traverse(lfs_t *lfs, const lfsr_btree_t *btree, // need to restart from the root? if (bt->rid >= (lfsr_srid_t)bt->branch->weight) { - bt->branch = btree; + bt->branch = &btree->root; bt->rid = bt->bid; } @@ -6486,9 +6523,9 @@ static lfs_ssize_t lfsr_shrub_estimate(lfs_t *lfs, for (lfsr_omdir_t *o = lfs->omdirs; o; o = o->next) { if (lfsr_o_isbshrub(o->flags) && lfsr_shrub_cmp( - &((lfsr_bshrub_t*)o)->shrub, + &((lfsr_bshrub_t*)o)->shrub.root, shrub) == 0) { - last = &((lfsr_bshrub_t*)o)->shrub; + last = &((lfsr_bshrub_t*)o)->shrub.root; } } if (last && shrub != last) { @@ -6518,7 +6555,7 @@ static int lfsr_shrub_compact(lfs_t *lfs, lfsr_rbyd_t *rbyd_, for (lfsr_omdir_t *o = lfs->omdirs; o; o = o->next) { if (lfsr_o_isbshrub(o->flags) && lfsr_shrub_cmp( - &((lfsr_bshrub_t*)o)->shrub, + &((lfsr_bshrub_t*)o)->shrub.root, shrub) == 0) { ((lfsr_bshrub_t*)o)->shrub_.blocks[0] = rbyd_->blocks[0]; ((lfsr_bshrub_t*)o)->shrub_.trunk = rbyd_->trunk; @@ -6577,29 +6614,65 @@ static int lfsr_shrub_commit(lfs_t *lfs, lfsr_rbyd_t *rbyd_, // create a non-existant bshrub static void lfsr_bshrub_init(lfsr_bshrub_t *bshrub) { // set up a null bshrub - bshrub->shrub.weight = 0; - bshrub->shrub.blocks[0] = -1; - bshrub->shrub.trunk = 0; + bshrub->shrub.root.weight = 0; + bshrub->shrub.root.blocks[0] = -1; + bshrub->shrub.root.trunk = 0; // force estimate recalculation - bshrub->shrub.eoff = -1; + bshrub->shrub.root.eoff = -1; + // weight=0 indicates no leaf + bshrub->shrub.leaf.rbyd.weight = 0; +} + +static inline void lfsr_bshrub_discardleaf(lfsr_bshrub_t *bshrub) { + lfsr_btree_discardleaf(&bshrub->shrub); } static inline bool lfsr_bshrub_isbnull(const lfsr_bshrub_t *bshrub) { - return !bshrub->shrub.trunk; + return !bshrub->shrub.root.trunk; } static inline bool lfsr_bshrub_isbshrub(const lfsr_bshrub_t *bshrub) { - return lfsr_shrub_isshrub(&bshrub->shrub); + return lfsr_btree_isbshrub(&bshrub->shrub); } static inline bool lfsr_bshrub_isbtree(const lfsr_bshrub_t *bshrub) { - return !lfsr_shrub_isshrub(&bshrub->shrub); + return !lfsr_btree_isbshrub(&bshrub->shrub); +} + +static inline lfsr_bid_t lfsr_bshrub_weight(const lfsr_bshrub_t *bshrub) { + return lfsr_btree_weight(&bshrub->shrub); +} + +static inline lfs_block_t lfsr_bshrub_block(const lfsr_bshrub_t *bshrub) { + return lfsr_btree_block(&bshrub->shrub); +} + +static inline lfs_size_t lfsr_bshrub_trunk(const lfsr_bshrub_t *bshrub) { + return lfsr_btree_trunk(&bshrub->shrub); +} + +static inline uint32_t lfsr_bshrub_cksum(const lfsr_bshrub_t *bshrub) { + return lfsr_btree_cksum(&bshrub->shrub); } static inline int lfsr_bshrub_cmp( const lfsr_bshrub_t *a, const lfsr_bshrub_t *b) { - return lfsr_rbyd_cmp(&a->shrub, &b->shrub); + return lfsr_btree_cmp(&a->shrub, &b->shrub); +} + +static lfsr_data_t lfsr_data_frombshrub(const lfsr_bshrub_t *bshrub, + uint8_t buffer[static LFSR_SHRUB_DSIZE]) { + return lfsr_data_fromshrub(&bshrub->shrub.root, buffer); +} + +static int lfsr_data_readbshrub(lfs_t *lfs, lfsr_data_t *data, + const lfsr_mdir_t *mdir, + lfsr_bshrub_t *bshrub) { + // we just need to make sure to discard the leaf here + lfsr_bshrub_discardleaf(bshrub); + + return lfsr_data_readshrub(lfs, data, mdir, &bshrub->shrub.root); } // needed in lfsr_bshrub_estimate @@ -6644,7 +6717,7 @@ static lfs_ssize_t lfsr_bshrub_estimate(lfs_t *lfs, && o->mdir.mid == bshrub->o.mdir.mid && lfsr_bshrub_isbshrub((lfsr_bshrub_t*)o)) { lfs_ssize_t dsize = lfsr_shrub_estimate(lfs, - &((lfsr_bshrub_t*)o)->shrub); + &((lfsr_bshrub_t*)o)->shrub.root); if (dsize < 0) { return dsize; } @@ -6656,15 +6729,7 @@ static lfs_ssize_t lfsr_bshrub_estimate(lfs_t *lfs, } // bshrub lookup functions -static int lfsr_bshrub_lookupleaf(lfs_t *lfs, const lfsr_bshrub_t *bshrub, - lfsr_bid_t bid, - lfsr_bid_t *bid_, lfsr_rbyd_t *rbyd_, lfsr_srid_t *rid_, - lfsr_tag_t *tag_, lfsr_bid_t *weight_, lfsr_data_t *data_) { - return lfsr_btree_lookupleaf(lfs, &bshrub->shrub, bid, - bid_, rbyd_, rid_, tag_, weight_, data_); -} - -static int lfsr_bshrub_lookupnext(lfs_t *lfs, const lfsr_bshrub_t *bshrub, +static int lfsr_bshrub_lookupnext(lfs_t *lfs, lfsr_bshrub_t *bshrub, lfsr_bid_t bid, lfsr_bid_t *bid_, lfsr_tag_t *tag_, lfsr_bid_t *weight_, lfsr_data_t *data_) { @@ -6672,7 +6737,7 @@ static int lfsr_bshrub_lookupnext(lfs_t *lfs, const lfsr_bshrub_t *bshrub, bid_, tag_, weight_, data_); } -static int lfsr_bshrub_lookup(lfs_t *lfs, const lfsr_bshrub_t *bshrub, +static int lfsr_bshrub_lookup(lfs_t *lfs, lfsr_bshrub_t *bshrub, lfsr_bid_t bid, lfsr_tag_t tag, lfsr_tag_t *tag_, lfsr_data_t *data_) { return lfsr_btree_lookup(lfs, &bshrub->shrub, bid, tag, @@ -6699,8 +6764,8 @@ static int lfsr_bshrub_commit(lfs_t *lfs, lfsr_bshrub_t *bshrub, for (lfsr_omdir_t *o = lfs->omdirs; o; o = o->next) { if (lfsr_o_isbshrub(o->flags) && o != &bshrub->o - && ((lfsr_bshrub_t*)o)->shrub.blocks[0] - == bshrub->shrub.blocks[0]) { + && lfsr_bshrub_block((lfsr_bshrub_t*)o) + == lfsr_bshrub_block(bshrub)) { // mark as unerased lfsr_btree_claim(&((lfsr_bshrub_t*)o)->shrub); } @@ -6739,7 +6804,9 @@ static int lfsr_bshrub_commit(lfs_t *lfs, lfsr_bshrub_t *bshrub, // does our estimate exceed our inline_size? need to recalculate an // accurate estimate - lfs_ssize_t estimate = (alloc) ? (lfs_size_t)-1 : bshrub->shrub.eoff; + lfs_ssize_t estimate = (alloc) + ? (lfs_size_t)-1 + : bshrub->shrub.root.eoff; // this double condition avoids overflow issues if ((lfs_size_t)estimate > lfs->cfg->inline_size || estimate + commit_estimate > lfs->cfg->inline_size) { @@ -6766,7 +6833,7 @@ static int lfsr_bshrub_commit(lfs_t *lfs, lfsr_bshrub_t *bshrub, estimate += commit_estimate; // commit to shrub - int err = lfsr_mdir_commit(lfs, &bshrub->o.mdir, LFSR_RATTRS( + err = lfsr_mdir_commit(lfs, &bshrub->o.mdir, LFSR_RATTRS( LFSR_RATTR_SHRUBCOMMIT( (&(lfsr_shrubcommit_t){ .bshrub=bshrub, @@ -6776,33 +6843,36 @@ static int lfsr_bshrub_commit(lfs_t *lfs, lfsr_bshrub_t *bshrub, if (err) { return err; } - LFS_ASSERT(bshrub->shrub.blocks[0] == bshrub->o.mdir.rbyd.blocks[0]); + LFS_ASSERT(lfsr_bshrub_block(bshrub) == bshrub->o.mdir.rbyd.blocks[0]); // update _all_ shrubs with the new estimate for (lfsr_omdir_t *o = lfs->omdirs; o; o = o->next) { if (lfsr_o_isbshrub(o->flags) && o->mdir.mid == bshrub->o.mdir.mid && lfsr_bshrub_isbshrub((lfsr_bshrub_t*)o)) { - ((lfsr_bshrub_t*)o)->shrub.eoff = estimate; + ((lfsr_bshrub_t*)o)->shrub.root.eoff = estimate; } } - LFS_ASSERT(bshrub->shrub.eoff == (lfs_size_t)estimate); + LFS_ASSERT(bshrub->shrub.root.eoff == (lfs_size_t)estimate); } - LFS_ASSERT(lfsr_shrub_trunk(&bshrub->shrub)); + // discard the leaf + lfsr_bshrub_discardleaf(bshrub); + + LFS_ASSERT(lfsr_bshrub_trunk(bshrub)); #ifdef LFS_DBGBTREECOMMITS if (lfsr_bshrub_isbshrub(bshrub)) { LFS_DEBUG("Committed bshrub " "0x{%"PRIx32",%"PRIx32"}.%"PRIx32" w%"PRId32, bshrub->o.mdir.rbyd.blocks[0], bshrub->o.mdir.rbyd.blocks[1], - lfsr_shrub_trunk(&bshrub->shrub), - bshrub->shrub.weight); + lfsr_bshrub_trunk(bshrub), + lfsr_bshrub_weight(bshrub)); } else { LFS_DEBUG("Committed btree 0x%"PRIx32".%"PRIx32" w%"PRId32", " "cksum %"PRIx32, - bshrub->shrub.blocks[0], lfsr_shrub_trunk(&bshrub->shrub), - bshrub->shrub.weight, - bshrub->shrub.cksum); + lfsr_bshrub_block(bshrub), lfsr_bshrub_trunk(bshrub), + lfsr_bshrub_weight(bshrub), + lfsr_bshrub_cksum(bshrub)); } #endif return 0; @@ -6828,7 +6898,8 @@ relocate:; // note this may be a new root if (!alloc) { - err = lfsr_rbyd_compact(lfs, &bshrub->shrub_, &bshrub->shrub, -1, -1); + err = lfsr_rbyd_compact(lfs, &bshrub->shrub_, + &bshrub->shrub.root, -1, -1); if (err) { LFS_ASSERT(err != LFS_ERR_RANGE); // bad prog? try another block @@ -6849,15 +6920,19 @@ relocate:; return err; } - bshrub->shrub = bshrub->shrub_; + // update the root + bshrub->shrub.root = bshrub->shrub_; - LFS_ASSERT(lfsr_rbyd_trunk(&bshrub->shrub)); + // discard the leaf + lfsr_bshrub_discardleaf(bshrub); + + LFS_ASSERT(lfsr_bshrub_trunk(bshrub)); #ifdef LFS_DBGBTREECOMMITS LFS_DEBUG("Committed btree 0x%"PRIx32".%"PRIx32" w%"PRId32", " "cksum %"PRIx32, - bshrub->shrub.blocks[0], lfsr_shrub_trunk(&bshrub->shrub), - bshrub->shrub.weight, - bshrub->shrub.cksum); + lfsr_bshrub_block(bshrub), lfsr_bshrub_trunk(bshrub), + lfsr_bshrub_weight(bshrub), + lfsr_bshrub_cksum(bshrub)); #endif return 0; } @@ -6882,7 +6957,7 @@ static inline lfsr_srid_t lfsr_mrid(const lfs_t *lfs, lfsr_smid_t mid) { // these should only be used for logging static inline lfsr_sbid_t lfsr_dbgmbid(const lfs_t *lfs, lfsr_smid_t mid) { - if (lfs->mtree.weight == 0) { + if (lfsr_btree_weight(&lfs->mtree) == 0) { return -1; } else { return mid >> lfs->mbits; @@ -7747,7 +7822,7 @@ static int lfsr_mdir_lookup(lfs_t *lfs, const lfsr_mdir_t *mdir, static inline lfsr_mid_t lfsr_mtree_weight(lfs_t *lfs) { return lfs_max( - lfs->mtree.weight, + lfsr_btree_weight(&lfs->mtree), 1 << lfs->mbits); } @@ -7763,7 +7838,7 @@ static int lfsr_mtree_lookup(lfs_t *lfs, lfsr_smid_t mid, } // looking up mroot? - if (lfs->mtree.weight == 0) { + if (lfsr_btree_weight(&lfs->mtree) == 0) { // treat inlined mdir as mid=0 mdir_->mid = mid; lfsr_mdir_sync(mdir_, &lfs->mroot); @@ -7772,12 +7847,11 @@ static int lfsr_mtree_lookup(lfs_t *lfs, lfsr_smid_t mid, // look up mdir in actual mtree } else { lfsr_bid_t bid; - lfsr_srid_t rid; lfsr_tag_t tag; lfsr_bid_t weight; lfsr_data_t data; - int err = lfsr_btree_lookupleaf(lfs, &lfs->mtree, mid, - &bid, &mdir_->rbyd, &rid, &tag, &weight, &data); + int err = lfsr_btree_lookupnext(lfs, &lfs->mtree, mid, + &bid, &tag, &weight, &data); if (err) { LFS_ASSERT(err != LFS_ERR_NOENT); return err; @@ -7789,7 +7863,7 @@ static int lfsr_mtree_lookup(lfs_t *lfs, lfsr_smid_t mid, // if we found an mname, lookup the mdir if (tag == LFSR_TAG_MNAME) { - err = lfsr_rbyd_lookup(lfs, &mdir_->rbyd, rid, LFSR_TAG_MDIR, + err = lfsr_btree_lookup(lfs, &lfs->mtree, bid, LFSR_TAG_MDIR, NULL, &data); if (err) { LFS_ASSERT(err != LFS_ERR_NOENT); @@ -8062,7 +8136,7 @@ static int lfsr_mdir_commit__(lfs_t *lfs, lfsr_mdir_t *mdir, != mdir->rbyd.blocks[0]) { int err = lfsr_shrub_compact(lfs, &mdir->rbyd, &((lfsr_bshrub_t*)o)->shrub_, - &((lfsr_bshrub_t*)o)->shrub); + &((lfsr_bshrub_t*)o)->shrub.root); if (err) { return err; } @@ -8279,7 +8353,7 @@ static lfs_ssize_t lfsr_mdir_estimate__(lfs_t *lfs, const lfsr_mdir_t *mdir, // is a bshrub? && lfsr_bshrub_isbshrub((lfsr_bshrub_t*)o)) { lfs_ssize_t dsize__ = lfsr_shrub_estimate(lfs, - &((lfsr_bshrub_t*)o)->shrub); + &((lfsr_bshrub_t*)o)->shrub.root); if (dsize__ < 0) { return dsize__; } @@ -8405,7 +8479,7 @@ static int lfsr_mdir_compact__(lfs_t *lfs, lfsr_mdir_t *mdir_, != mdir_->rbyd.blocks[0]) { int err = lfsr_shrub_compact(lfs, &mdir_->rbyd, &((lfsr_bshrub_t*)o)->shrub_, - &((lfsr_bshrub_t*)o)->shrub); + &((lfsr_bshrub_t*)o)->shrub.root); if (err) { LFS_ASSERT(err != LFS_ERR_RANGE); return err; @@ -8653,9 +8727,9 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, // a bshrub outside of its mdir means something has gone // horribly wrong LFS_ASSERT(!lfsr_bshrub_isbshrub((lfsr_bshrub_t*)o) - || ((lfsr_bshrub_t*)o)->shrub.blocks[0] + || lfsr_bshrub_block((lfsr_bshrub_t*)o) == o->mdir.rbyd.blocks[0]); - ((lfsr_bshrub_t*)o)->shrub_ = ((lfsr_bshrub_t*)o)->shrub; + ((lfsr_bshrub_t*)o)->shrub_ = ((lfsr_bshrub_t*)o)->shrub.root; } } @@ -8696,7 +8770,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, if (err == LFS_ERR_RANGE) { // this should not happen unless we can't fit our mroot's metadata LFS_ASSERT(lfsr_mdir_cmp(mdir, &lfs->mroot) != 0 - || lfs->mtree.weight == 0); + || lfsr_btree_weight(&lfs->mtree) == 0); // if we're not the mroot, we need to consume the gstate so // we don't lose any info during the split @@ -8813,7 +8887,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, } // new mtree? - if (lfs->mtree.weight == 0) { + if (lfsr_btree_weight(&lfs->mtree) == 0) { lfsr_btree_init(&mtree_); err = lfsr_mtree_commit(lfs, &mtree_, @@ -8870,7 +8944,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, mdelta = -(1 << lfs->mbits); // how can we drop if we have no mtree? - LFS_ASSERT(lfs->mtree.weight != 0); + LFS_ASSERT(lfsr_btree_weight(&lfs->mtree) > 0); // mark as unerased in case of failure lfsr_btree_claim(&lfs->mtree); @@ -8895,7 +8969,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, relocated:; // new mtree? - if (lfs->mtree.weight == 0) { + if (lfsr_btree_weight(&lfs->mtree) == 0) { lfsr_btree_init(&mtree_); err = lfsr_mtree_commit(lfs, &mtree_, @@ -8941,7 +9015,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, // need to update mtree? if (lfsr_btree_cmp(&mtree_, &lfs->mtree) != 0) { // mtree should never go to zero since we always have a root bookmark - LFS_ASSERT(mtree_.weight > 0); + LFS_ASSERT(lfsr_btree_weight(&mtree_) > 0); // make sure mtree/mroot changes are on-disk before committing // metadata @@ -9177,15 +9251,16 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, // leaves that moved if (lfsr_o_type(o->flags) == LFS_TYPE_REG && lfsr_bptr_block(&((lfsr_file_t*)o)->leaf.bptr) - == ((lfsr_bshrub_t*)o)->shrub.blocks[0] + == lfsr_bshrub_block((lfsr_bshrub_t*)o) && ((lfsr_bshrub_t*)o)->shrub_.blocks[0] - != ((lfsr_bshrub_t*)o)->shrub.blocks[0]) { + != lfsr_bshrub_block((lfsr_bshrub_t*)o)) { lfsr_file_discardleaf((lfsr_file_t*)o); } // update the shrub if (lfsr_o_isbshrub(o->flags)) { - ((lfsr_bshrub_t*)o)->shrub = ((lfsr_bshrub_t*)o)->shrub_; + ((lfsr_bshrub_t*)o)->shrub.root = ((lfsr_bshrub_t*)o)->shrub_; + lfsr_bshrub_discardleaf((lfsr_bshrub_t*)o); } } @@ -9281,7 +9356,7 @@ static int lfsr_mtree_namelookup(lfs_t *lfs, lfsr_did_t did, const char *name, lfs_size_t name_len, lfsr_mdir_t *mdir_, lfsr_tag_t *tag_, lfsr_data_t *data_) { // do we only have mroot? - if (lfs->mtree.weight == 0) { + if (lfsr_btree_weight(&lfs->mtree) == 0) { // treat inlined mdir as mid=0 mdir_->mid = 0; lfsr_mdir_sync(mdir_, &lfs->mroot); @@ -9289,13 +9364,12 @@ static int lfsr_mtree_namelookup(lfs_t *lfs, // lookup name in actual mtree } else { lfsr_bid_t bid; - lfsr_srid_t rid; lfsr_tag_t tag; lfsr_bid_t weight; lfsr_data_t data; - lfs_scmp_t cmp = lfsr_btree_namelookupleaf(lfs, &lfs->mtree, + lfs_scmp_t cmp = lfsr_btree_namelookup(lfs, &lfs->mtree, did, name, name_len, - &bid, &mdir_->rbyd, &rid, &tag, &weight, &data); + &bid, &tag, &weight, &data); if (cmp < 0) { LFS_ASSERT(cmp != LFS_ERR_NOENT); return cmp; @@ -9306,7 +9380,7 @@ static int lfsr_mtree_namelookup(lfs_t *lfs, // if we found an mname, lookup the mdir if (tag == LFSR_TAG_MNAME) { - int err = lfsr_rbyd_lookup(lfs, &mdir_->rbyd, rid, LFSR_TAG_MDIR, + int err = lfsr_btree_lookup(lfs, &lfs->mtree, bid, LFSR_TAG_MDIR, NULL, &data); if (err) { LFS_ASSERT(err != LFS_ERR_NOENT); @@ -9681,8 +9755,8 @@ static int lfsr_mtree_traverse_(lfs_t *lfs, lfsr_traversal_t *t, || tag == LFSR_TAG_BTREE)) { // found a bshrub (inlined btree)? if (tag == LFSR_TAG_BSHRUB) { - err = lfsr_data_readshrub(lfs, &data, &t->b.o.mdir, - &t->b.shrub); + err = lfsr_data_readbshrub(lfs, &data, &t->b.o.mdir, + &t->b); if (err) { return err; } @@ -11298,7 +11372,7 @@ static inline lfs_size_t lfsr_file_cachesize(lfs_t *lfs, static inline lfs_off_t lfsr_file_weight(const lfsr_file_t *file) { return lfs_max( file->leaf.pos + file->leaf.weight, - file->b.shrub.weight); + lfsr_bshrub_weight(&file->b)); } static inline lfs_off_t lfsr_file_size_(const lfsr_file_t *file) { @@ -11331,17 +11405,16 @@ static int lfsr_file_fetch(lfs_t *lfs, lfsr_file_t *file, bool trunc) { return err; } - // note many of these functions leave bshrub undefined if - // there is an error, so we first read into the staging - // bshrub - file->b.shrub_ = file->b.shrub; + // note many of these functions leave bshrub undefined if there + // is an error, so we first read into a temporary bshrub/btree + lfsr_bshrub_t b = file->b; // found a bshrub/btree? if (err != LFS_ERR_NOENT) { // may be a bshrub (inlined btree) if (tag == LFSR_TAG_BSHRUB) { - err = lfsr_data_readshrub(lfs, &data, &file->b.o.mdir, - &file->b.shrub_); + err = lfsr_data_readbshrub(lfs, &data, &file->b.o.mdir, + &b); if (err) { return err; } @@ -11349,7 +11422,7 @@ static int lfsr_file_fetch(lfs_t *lfs, lfsr_file_t *file, bool trunc) { // or a btree } else if (tag == LFSR_TAG_BTREE) { err = lfsr_data_fetchbtree(lfs, &data, - &file->b.shrub_); + &b.shrub); if (err) { return err; } @@ -11359,8 +11432,8 @@ static int lfsr_file_fetch(lfs_t *lfs, lfsr_file_t *file, bool trunc) { } } - // update the bshrub - file->b.shrub = file->b.shrub_; + // update the bshrub/btree + file->b = b; // mark as in-sync file->b.o.flags &= ~LFS_o_UNSYNC; @@ -11638,7 +11711,7 @@ int lfsr_file_close(lfs_t *lfs, lfsr_file_t *file) { // low-level file reading -static int lfsr_file_lookup_(lfs_t *lfs, const lfsr_file_t *file, +static int lfsr_file_lookup_(lfs_t *lfs, lfsr_file_t *file, lfsr_bid_t bid, lfsr_bid_t *bid_, lfsr_bid_t *weight_, lfsr_bptr_t *bptr_) { lfsr_tag_t tag; @@ -11672,7 +11745,7 @@ static int lfsr_file_lookup_(lfs_t *lfs, const lfsr_file_t *file, return 0; } -static int lfsr_file_lookup(lfs_t *lfs, const lfsr_file_t *file, +static int lfsr_file_lookup(lfs_t *lfs, lfsr_file_t *file, lfsr_bid_t bid, lfsr_bid_t *bid_, lfsr_bid_t *weight_, lfsr_bptr_t *bptr_) { // hits our leaf? @@ -11690,12 +11763,12 @@ static int lfsr_file_lookup(lfs_t *lfs, const lfsr_file_t *file, // in between bshrub/btree and ungrafted leaf? pretend there's a // hole here - if (bid >= file->b.shrub.weight && bid < file->leaf.pos) { + if (bid >= lfsr_bshrub_weight(&file->b) && bid < file->leaf.pos) { if (bid_) { *bid_ = file->leaf.pos-1; } if (weight_) { - *weight_ = file->leaf.pos - file->b.shrub.weight; + *weight_ = file->leaf.pos - lfsr_bshrub_weight(&file->b); } lfsr_bptr_discard(bptr_); return 0; @@ -11938,38 +12011,38 @@ static int lfsr_file_graft(lfs_t *lfs, lfsr_file_t *file, // carving the entire tree? revert to no bshrub/btree if (pos == 0 - && weight >= file->b.shrub.weight + && weight >= lfsr_bshrub_weight(&file->b) && delta == -(lfs_soff_t)weight) { lfsr_file_discardbshrub(file); return 0; } // try to merge commits where possible - lfsr_bid_t bid = file->b.shrub.weight; + lfsr_bid_t bid = lfsr_bshrub_weight(&file->b); lfsr_rattr_t rattrs[3]; lfs_size_t rattr_count = 0; lfsr_bptr_t l; lfsr_bptr_t r; // need a hole? - if (pos > file->b.shrub.weight) { + if (pos > lfsr_bshrub_weight(&file->b)) { // can we coalesce? - if (file->b.shrub.weight > 0) { - bid = lfs_min(bid, file->b.shrub.weight-1); + if (lfsr_bshrub_weight(&file->b) > 0) { + bid = lfs_min(bid, lfsr_bshrub_weight(&file->b)-1); rattrs[rattr_count++] = LFSR_RATTR( - LFSR_TAG_GROW, +(pos - file->b.shrub.weight)); + LFSR_TAG_GROW, +(pos - lfsr_bshrub_weight(&file->b))); // new hole } else { - bid = lfs_min(bid, file->b.shrub.weight); + bid = lfs_min(bid, lfsr_bshrub_weight(&file->b)); rattrs[rattr_count++] = LFSR_RATTR( - LFSR_TAG_DATA, +(pos - file->b.shrub.weight)); + LFSR_TAG_DATA, +(pos - lfsr_bshrub_weight(&file->b))); } } // try to carve any existing data lfsr_rattr_t r_rattr_ = {.tag=0}; - while (pos < file->b.shrub.weight) { + while (pos < lfsr_bshrub_weight(&file->b)) { lfsr_bid_t weight_; lfsr_bptr_t bptr_; int err = lfsr_file_lookup_(lfs, file, pos, @@ -12148,26 +12221,26 @@ static int lfsr_file_graft(lfs_t *lfs, lfsr_file_t *file, // can we coalesce a hole? if (dsize == 0 && pos > 0) { - bid = lfs_min(bid, file->b.shrub.weight-1); + bid = lfs_min(bid, lfsr_bshrub_weight(&file->b)-1); rattrs[rattr_count++] = LFSR_RATTR( LFSR_TAG_GROW, +(weight + delta)); // need a new hole? } else if (dsize == 0) { - bid = lfs_min(bid, file->b.shrub.weight); + bid = lfs_min(bid, lfsr_bshrub_weight(&file->b)); rattrs[rattr_count++] = LFSR_RATTR( LFSR_TAG_DATA, +(weight + delta)); // append a new fragment? } else if (data_count >= 0) { - bid = lfs_min(bid, file->b.shrub.weight); + bid = lfs_min(bid, lfsr_bshrub_weight(&file->b)); rattrs[rattr_count++] = LFSR_RATTR_CAT_( LFSR_TAG_DATA, +(weight + delta), datas, data_count); // append a new bptr? } else { - bid = lfs_min(bid, file->b.shrub.weight); + bid = lfs_min(bid, lfsr_bshrub_weight(&file->b)); rattrs[rattr_count++] = LFSR_RATTR_BPTR( LFSR_TAG_BLOCK, +(weight + delta), (const lfsr_bptr_t*)datas); @@ -12662,7 +12735,7 @@ static int lfsr_file_flush_(lfs_t *lfs, lfsr_file_t *file, // block alignment, we use the entry immediately to the left of // our crystal for this if (crystal_start > 0 - && file->b.shrub.weight > 0 + && lfsr_bshrub_weight(&file->b) > 0 // don't bother to lookup left after the first block && !aligned) { lfsr_bid_t bid; @@ -12671,7 +12744,7 @@ static int lfsr_file_flush_(lfs_t *lfs, lfsr_file_t *file, int err = lfsr_file_lookup(lfs, file, lfs_min( crystal_start-1, - file->b.shrub.weight-1), + lfsr_bshrub_weight(&file->b)-1), &bid, &weight, &bptr); if (err) { LFS_ASSERT(err != LFS_ERR_NOENT); @@ -14519,8 +14592,8 @@ static int lfsr_mountinited(lfs_t *lfs) { } else if (tag == LFSR_TAG_BRANCH) { lfsr_rbyd_t *rbyd = (lfsr_rbyd_t*)bptr.data.u.buffer; // found the root of the mtree? keep track of this - if (lfs->mtree.weight == 0) { - lfs->mtree = *rbyd; + if (lfsr_btree_weight(&lfs->mtree) == 0) { + lfs->mtree.root = *rbyd; } } else { @@ -14725,7 +14798,7 @@ int lfsr_mount(lfs_t *lfs, uint32_t flags, lfs->mroot.rbyd.blocks[0], lfs->mroot.rbyd.blocks[1], lfsr_rbyd_trunk(&lfs->mroot.rbyd), - lfs->mtree.weight >> lfs->mbits, + lfsr_btree_weight(&lfs->mtree) >> lfs->mbits, 1 << lfs->mbits, lfs->gcksum); diff --git a/lfs.h b/lfs.h index 0aa407c0..b885f36f 100644 --- a/lfs.h +++ b/lfs.h @@ -681,8 +681,15 @@ typedef struct lfsr_rbyd { uint32_t cksum; } lfsr_rbyd_t; -// a btree is represented by the root rbyd -typedef lfsr_rbyd_t lfsr_btree_t; +// all we need for btrees is the root rbyd, but tracking the most recent +// leaf helps speed up iteration/attr lookup/etc +typedef struct lfsr_btree { + lfsr_rbyd_t root; + struct { + lfsr_bid_t bid; + lfsr_rbyd_t rbyd; + } leaf; +} lfsr_btree_t; // littlefs's atomic metadata log type typedef struct lfsr_mdir { @@ -709,7 +716,7 @@ typedef struct lfsr_bshrub { // trunk=0 => no bshrub/btree // sign(trunk)=1 => bshrub // sign(trunk)=0 => btree - lfsr_shrub_t shrub; + lfsr_btree_t shrub; lfsr_shrub_t shrub_; } lfsr_bshrub_t; diff --git a/tests/test_badblocks.toml b/tests/test_badblocks.toml index 01f23a08..17fdd384 100644 --- a/tests/test_badblocks.toml +++ b/tests/test_badblocks.toml @@ -98,10 +98,10 @@ code = ''' } printf("]\n"); printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == sim_size); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == sim_size); uint8_t buffer[4]; lfsr_bid_t bid_; @@ -2053,10 +2053,10 @@ code = ''' } printf("]\n"); printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == sim_size); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == sim_size); uint8_t buffer[4]; lfsr_bid_t bid_; @@ -4010,10 +4010,10 @@ code = ''' } printf("]\n"); printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == sim_size); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == sim_size); uint8_t buffer[4]; lfsr_bid_t bid_; diff --git a/tests/test_btree.toml b/tests/test_btree.toml index 82826b81..49092c60 100644 --- a/tests/test_btree.toml +++ b/tests/test_btree.toml @@ -23,10 +23,10 @@ code = ''' lfsr_btree_t btree; lfsr_btree_init(&btree); printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == 0); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == 0); // try looking up tags lfsr_bid_t bid_; @@ -58,10 +58,10 @@ code = ''' lfsr_btree_commit(&lfs, &btree, 0, LFSR_RATTRS( LFSR_RATTR_BUF(LFSR_TAG_DATA, +1, "a", 1))) => 0; printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == 1); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == 1); // try looking up tags uint8_t buffer[4]; @@ -104,10 +104,10 @@ code = ''' lfsr_btree_commit(&lfs, &btree, 1, LFSR_RATTRS( LFSR_RATTR_BUF(LFSR_TAG_DATA, +1, "b", 1))) => 0; printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == 2); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == 2); // try looking up tags uint8_t buffer[4]; @@ -155,10 +155,10 @@ code = ''' lfsr_btree_commit(&lfs, &btree, 0, LFSR_RATTRS( LFSR_RATTR_BUF(LFSR_TAG_DATA, +1, "a", 1))) => 0; printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == 2); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == 2); // try looking up tags uint8_t buffer[4]; @@ -209,10 +209,10 @@ code = ''' lfsr_btree_commit(&lfs, &btree, 2, LFSR_RATTRS( LFSR_RATTR_BUF(LFSR_TAG_DATA, +1, "c", 1))) => 0; printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == 3); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == 3); // try looking up tags uint8_t buffer[4]; @@ -269,10 +269,10 @@ code = ''' lfsr_btree_commit(&lfs, &btree, 0, LFSR_RATTRS( LFSR_RATTR_BUF(LFSR_TAG_DATA, +1, "a", 1))) => 0; printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == 3); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == 3); // try looking up tags uint8_t buffer[4]; @@ -334,10 +334,10 @@ code = ''' n += 1; } printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == n); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == n); // check that the elements are in the tree uint8_t buffer[4]; @@ -386,10 +386,10 @@ code = ''' n += 1; } printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == n); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == n); // check that the elements are in the tree uint8_t buffer[4]; @@ -469,10 +469,10 @@ code = ''' } printf("]\n"); printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == sim_size); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == sim_size); uint8_t buffer[4]; lfsr_bid_t bid_; @@ -524,10 +524,10 @@ code = ''' n += 1; } printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == n*W); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == n*W); // check that the elements are in the tree uint8_t buffer[4]; @@ -643,15 +643,15 @@ code = ''' } printf("]\n"); printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); lfs_size_t total_weight = 0; for (lfs_size_t j = 0; j < sim_size; j++) { total_weight += sim_weights[j]; } - assert(btree.weight == total_weight); + assert(lfsr_btree_weight(&btree) == total_weight); uint8_t buffer[4]; lfsr_bid_t bid_; @@ -730,10 +730,10 @@ code = ''' LFSR_TAG_MASK8 | LFSR_TAG_DATA, 0, "A", 1))) => 0; printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == 1); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == 1); // try looking up tags uint8_t buffer[4]; @@ -783,10 +783,10 @@ code = ''' LFSR_TAG_MASK8 | LFSR_TAG_DATA, 0, "B", 1))) => 0; printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == 2); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == 2); // try looking up tags uint8_t buffer[4]; @@ -849,10 +849,10 @@ code = ''' LFSR_TAG_MASK8 | LFSR_TAG_DATA, 0, "C", 1))) => 0; printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == 3); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == 3); // try looking up tags uint8_t buffer[4]; @@ -917,10 +917,10 @@ code = ''' &(uint8_t){'A'+(i % 26)}, 1))) => 0; } printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == N); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == N); // check that the elements are in the tree uint8_t buffer[4]; @@ -1005,10 +1005,10 @@ code = ''' } printf("]\n"); printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == N); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == N); uint8_t buffer[4]; lfsr_bid_t bid_; @@ -1064,10 +1064,10 @@ code = ''' &(uint8_t){'A'+(i % 26)}, 1))) => 0; } printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == N*W); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == N*W); // check that the elements are in the tree uint8_t buffer[4]; @@ -1189,15 +1189,15 @@ code = ''' } printf("]\n"); printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); lfs_size_t total_weight = 0; for (lfs_size_t j = 0; j < N; j++) { total_weight += sim_weights[j]; } - assert(btree.weight == total_weight); + assert(lfsr_btree_weight(&btree) == total_weight); uint8_t buffer[4]; lfsr_bid_t bid_; @@ -1275,10 +1275,10 @@ code = ''' lfsr_btree_commit(&lfs, &btree, 0, LFSR_RATTRS( LFSR_RATTR(LFSR_TAG_RM, -1))) => 0; printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == 0); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == 0); // try looking up tags uint8_t buffer[4]; @@ -1294,10 +1294,10 @@ code = ''' lfsr_btree_commit(&lfs, &btree, 0, LFSR_RATTRS( LFSR_RATTR_BUF(LFSR_TAG_DATA, +1, "A", 1))) => 0; printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == 1); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == 1); // try looking up tags lfsr_btree_lookupnext(&lfs, &btree, 0, @@ -1335,10 +1335,10 @@ code = ''' lfsr_btree_commit(&lfs, &btree, 1, LFSR_RATTRS( LFSR_RATTR(LFSR_TAG_RM, -1))) => 0; printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == 1); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == 1); // try looking up tags uint8_t buffer[4]; @@ -1361,10 +1361,10 @@ code = ''' lfsr_btree_commit(&lfs, &btree, 1, LFSR_RATTRS( LFSR_RATTR_BUF(LFSR_TAG_DATA, +1, "B", 1))) => 0; printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == 2); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == 2); // try looking up tags lfsr_btree_lookupnext(&lfs, &btree, 0, @@ -1409,10 +1409,10 @@ code = ''' lfsr_btree_commit(&lfs, &btree, 0, LFSR_RATTRS( LFSR_RATTR(LFSR_TAG_RM, -1))) => 0; printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == 1); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == 1); // try looking up tags uint8_t buffer[4]; @@ -1435,10 +1435,10 @@ code = ''' lfsr_btree_commit(&lfs, &btree, 0, LFSR_RATTRS( LFSR_RATTR_BUF(LFSR_TAG_DATA, +1, "A", 1))) => 0; printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == 2); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == 2); // try looking up tags lfsr_btree_lookupnext(&lfs, &btree, 0, @@ -1485,10 +1485,10 @@ code = ''' lfsr_btree_commit(&lfs, &btree, 2, LFSR_RATTRS( LFSR_RATTR(LFSR_TAG_RM, -1))) => 0; printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == 2); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == 2); // try looking up tags uint8_t buffer[4]; @@ -1518,10 +1518,10 @@ code = ''' lfsr_btree_commit(&lfs, &btree, 2, LFSR_RATTRS( LFSR_RATTR_BUF(LFSR_TAG_DATA, +1, "C", 1))) => 0; printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == 3); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == 3); // try looking up tags lfsr_btree_lookupnext(&lfs, &btree, 0, @@ -1581,10 +1581,10 @@ code = ''' } printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == REMAINING); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == REMAINING); // check that the elements are in the tree uint8_t buffer[4]; @@ -1661,10 +1661,10 @@ code = ''' LFSR_RATTR(LFSR_TAG_RM, -1))) => 0; } printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == REMAINING); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == REMAINING); // check that the elements are in the tree uint8_t buffer[4]; @@ -1776,10 +1776,10 @@ code = ''' } printf("]\n"); printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == sim_size); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == sim_size); uint8_t buffer[4]; lfsr_bid_t bid_; @@ -1835,10 +1835,10 @@ code = ''' LFSR_RATTR(LFSR_TAG_RM, -W))) => 0; } printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == REMAINING*W); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == REMAINING*W); // check that the elements are in the tree uint8_t buffer[4]; @@ -2004,15 +2004,15 @@ code = ''' } printf("]\n"); printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); lfs_size_t total_weight = 0; for (lfs_size_t j = 0; j < sim_size; j++) { total_weight += sim_weights[j]; } - assert(btree.weight == total_weight); + assert(lfsr_btree_weight(&btree) == total_weight); uint8_t buffer[4]; lfsr_bid_t bid_; @@ -2098,10 +2098,10 @@ code = ''' n += 1; } printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == n); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == n); // check that the elements are in the tree uint8_t buffer[4]; @@ -2188,10 +2188,10 @@ code = ''' } printf("]\n"); printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == sim_size); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == sim_size); uint8_t buffer[4]; lfsr_bid_t bid_; @@ -2250,10 +2250,10 @@ code = ''' n += 1; } printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == n*W); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == n*W); // check that the elements are in the tree uint8_t buffer[4]; @@ -2352,7 +2352,7 @@ code = ''' for (lfs_size_t j = 0; j < sim_size; j++) { total_weight += sim_weights[j]; } - assert(btree.weight == total_weight); + assert(lfsr_btree_weight(&btree) == total_weight); uint8_t buffer[4]; lfsr_bid_t bid_; @@ -2394,15 +2394,15 @@ code = ''' } printf("]\n"); printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); lfs_size_t total_weight = 0; for (lfs_size_t j = 0; j < sim_size; j++) { total_weight += sim_weights[j]; } - assert(btree.weight == total_weight); + assert(lfsr_btree_weight(&btree) == total_weight); uint8_t buffer[4]; lfsr_bid_t bid_; @@ -2488,13 +2488,13 @@ code = ''' LFSR_RATTR_BUF(LFSR_TAG_DATA, 0, buf1, SIZE), LFSR_RATTR_BUF(LFSR_TAG_DATA, +1, buf2, SIZE))) => 0; // force compaction - btree.eoff = -1; + lfsr_btree_claim(&btree); memset(buf2, 'b', SIZE); lfsr_btree_commit(&lfs, &btree, 1, LFSR_RATTRS( LFSR_RATTR_BUF( LFSR_TAG_MASK8 | LFSR_TAG_DATA, 0, buf2, SIZE))) => 0; - assert(btree.weight == 2); + assert(lfsr_btree_weight(&btree) == 2); // now remove one entry, since this brings the rbyd down to zero, // this should force one of the blocks to drop @@ -2502,10 +2502,10 @@ code = ''' LFSR_RATTR(LFSR_TAG_RM, -1))) => 0; printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == 1); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == 1); // check that our other entry is fine lfsr_bid_t bid_; @@ -2557,27 +2557,27 @@ code = ''' LFSR_RATTR_BUF(LFSR_TAG_DATA, 0, buf1, SIZE), LFSR_RATTR_BUF(LFSR_TAG_DATA, +1, buf2, SIZE))) => 0; // force compaction - btree.eoff = -1; + lfsr_btree_claim(&btree); memset(buf2, 'b', SIZE); lfsr_btree_commit(&lfs, &btree, 1, LFSR_RATTRS( LFSR_RATTR_BUF( LFSR_TAG_MASK8 | LFSR_TAG_DATA, 0, buf2, SIZE))) => 0; - assert(btree.weight == 2); + assert(lfsr_btree_weight(&btree) == 2); // now remove one entry, since this brings the rbyd down this zero, // this should force one of the blocks to drop // // do this while forcing a compaction - btree.eoff = -1; + lfsr_btree_claim(&btree); lfsr_btree_commit(&lfs, &btree, SIBLING, LFSR_RATTRS( LFSR_RATTR(LFSR_TAG_RM, -1))) => 0; printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == 1); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == 1); // check that our other entry is fine lfsr_bid_t bid_; @@ -2634,15 +2634,15 @@ code = ''' // // messy, isn't it? this is why we need an explicit test // - btree.eoff = -1; + lfsr_btree_claim(&btree); lfsr_btree_commit(&lfs, &btree, SIBLING, LFSR_RATTRS( LFSR_RATTR(LFSR_TAG_RM, -1))) => 0; printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == 1); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == 1); // check that our other entry is fine lfsr_bid_t bid_; @@ -2694,13 +2694,13 @@ code = ''' LFSR_RATTR_BUF(LFSR_TAG_DATA, 0, buf1, SIZE), LFSR_RATTR_BUF(LFSR_TAG_DATA, +1, buf2, SIZE))) => 0; // force compaction - btree.eoff = -1; + lfsr_btree_claim(&btree); memset(buf2, 'b', SIZE); lfsr_btree_commit(&lfs, &btree, 1, LFSR_RATTRS( LFSR_RATTR_BUF( LFSR_TAG_MASK8 | LFSR_TAG_DATA, 0, buf2, SIZE))) => 0; - assert(btree.weight == 2); + assert(lfsr_btree_weight(&btree) == 2); // now make both entries small so they should be merged if either compacts lfsr_btree_commit(&lfs, &btree, 0, LFSR_RATTRS( @@ -2714,15 +2714,15 @@ code = ''' // force compaction, while removing one entry, this drops the rbyd // down to zero while also triggering a merge - btree.eoff = -1; + lfsr_btree_claim(&btree); lfsr_btree_commit(&lfs, &btree, SIBLING, LFSR_RATTRS( LFSR_RATTR(LFSR_TAG_RM, -1))) => 0; printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == 1); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == 1); // check that our other entry is fine lfsr_bid_t bid_; @@ -2823,10 +2823,10 @@ code = ''' } printf("]\n"); printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == sim_size); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == sim_size); uint8_t buffer[4]; lfsr_bid_t bid_; @@ -2959,15 +2959,15 @@ code = ''' } printf("]\n"); printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); lfs_size_t total_weight = 0; for (lfs_size_t j = 0; j < sim_size; j++) { total_weight += sim_weights[j]; } - assert(btree.weight == total_weight); + assert(lfsr_btree_weight(&btree) == total_weight); uint8_t buffer[4]; lfsr_bid_t bid_; @@ -3037,19 +3037,17 @@ code = ''' lfsr_btree_t btree; lfsr_btree_init(&btree); printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == 0); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == 0); // try to find tags lfsr_bid_t bid_; - lfsr_rbyd_t rbyd_; - lfsr_srid_t rid_; lfs_size_t weight_; - lfsr_btree_namelookupleaf(&lfs, &btree, 0, "aaa", 3, - &bid_, &rbyd_, &rid_, NULL, &weight_, NULL) => LFS_ERR_NOENT; + lfsr_btree_namelookup(&lfs, &btree, 0, "aaa", 3, + &bid_, NULL, &weight_, NULL) => LFS_ERR_NOENT; ''' [cases.test_btree_find_one] @@ -3076,23 +3074,21 @@ code = ''' 0, "aaa", 3), LFSR_RATTR_BUF(LFSR_TAG_DATA, 0, "0", 1))) => 0; printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == 1); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == 1); // try to find tags uint8_t buffer[4]; lfsr_bid_t bid_; - lfsr_rbyd_t rbyd_; - lfsr_srid_t rid_; lfsr_tag_t tag_; lfs_size_t weight_; lfsr_data_t data_; - lfsr_btree_namelookupleaf(&lfs, &btree, 0*DID, "aaa", 3, - &bid_, &rbyd_, &rid_, NULL, &weight_, NULL) => LFS_CMP_EQ; - lfsr_rbyd_lookup(&lfs, &rbyd_, rid_, LFSR_TAG_MASK8 | LFSR_TAG_STRUCT, + lfsr_btree_namelookup(&lfs, &btree, 0*DID, "aaa", 3, + &bid_, NULL, &weight_, NULL) => LFS_CMP_EQ; + lfsr_btree_lookup(&lfs, &btree, bid_, LFSR_TAG_MASK8 | LFSR_TAG_STRUCT, &tag_, &data_) => 0; assert(tag_ == LFSR_TAG_DATA); assert(bid_ == 0); @@ -3100,9 +3096,9 @@ code = ''' lfsr_data_read(&lfs, &data_, buffer, 4) => 1; assert(memcmp(buffer, "0", 1) == 0); - lfsr_btree_namelookupleaf(&lfs, &btree, 1*DID, "aab", 3, - &bid_, &rbyd_, &rid_, NULL, &weight_, NULL) => LFS_CMP_LT; - lfsr_rbyd_lookup(&lfs, &rbyd_, rid_, LFSR_TAG_MASK8 | LFSR_TAG_STRUCT, + lfsr_btree_namelookup(&lfs, &btree, 1*DID, "aab", 3, + &bid_, NULL, &weight_, NULL) => LFS_CMP_LT; + lfsr_btree_lookup(&lfs, &btree, bid_, LFSR_TAG_MASK8 | LFSR_TAG_STRUCT, &tag_, &data_) => 0; assert(tag_ == LFSR_TAG_DATA); assert(bid_ == 0); @@ -3141,23 +3137,21 @@ code = ''' 0, "aab", 3), LFSR_RATTR_BUF(LFSR_TAG_DATA, 0, "1", 1))) => 0; printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == 2); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == 2); // try to find tags uint8_t buffer[4]; lfsr_bid_t bid_; - lfsr_rbyd_t rbyd_; - lfsr_srid_t rid_; lfsr_tag_t tag_; lfs_size_t weight_; lfsr_data_t data_; - lfsr_btree_namelookupleaf(&lfs, &btree, 0, "aaa", 3, - &bid_, &rbyd_, &rid_, NULL, &weight_, NULL) => LFS_CMP_EQ; - lfsr_rbyd_lookup(&lfs, &rbyd_, rid_, LFSR_TAG_MASK8 | LFSR_TAG_STRUCT, + lfsr_btree_namelookup(&lfs, &btree, 0, "aaa", 3, + &bid_, NULL, &weight_, NULL) => LFS_CMP_EQ; + lfsr_btree_lookup(&lfs, &btree, bid_, LFSR_TAG_MASK8 | LFSR_TAG_STRUCT, &tag_, &data_) => 0; assert(tag_ == LFSR_TAG_DATA); assert(bid_ == 0); @@ -3165,9 +3159,9 @@ code = ''' lfsr_data_read(&lfs, &data_, buffer, 4) => 1; assert(memcmp(buffer, "0", 1) == 0); - lfsr_btree_namelookupleaf(&lfs, &btree, 0, "aab", 3, - &bid_, &rbyd_, &rid_, NULL, &weight_, NULL) => LFS_CMP_EQ; - lfsr_rbyd_lookup(&lfs, &rbyd_, rid_, LFSR_TAG_MASK8 | LFSR_TAG_STRUCT, + lfsr_btree_namelookup(&lfs, &btree, 0, "aab", 3, + &bid_, NULL, &weight_, NULL) => LFS_CMP_EQ; + lfsr_btree_lookup(&lfs, &btree, bid_, LFSR_TAG_MASK8 | LFSR_TAG_STRUCT, &tag_, &data_) => 0; assert(tag_ == LFSR_TAG_DATA); assert(bid_ == 1); @@ -3175,9 +3169,9 @@ code = ''' lfsr_data_read(&lfs, &data_, buffer, 4) => 1; assert(memcmp(buffer, "1", 1) == 0); - lfsr_btree_namelookupleaf(&lfs, &btree, 0, "aac", 3, - &bid_, &rbyd_, &rid_, NULL, &weight_, NULL) => LFS_CMP_LT; - lfsr_rbyd_lookup(&lfs, &rbyd_, rid_, LFSR_TAG_MASK8 | LFSR_TAG_STRUCT, + lfsr_btree_namelookup(&lfs, &btree, 0, "aac", 3, + &bid_, NULL, &weight_, NULL) => LFS_CMP_LT; + lfsr_btree_lookup(&lfs, &btree, bid_, LFSR_TAG_MASK8 | LFSR_TAG_STRUCT, &tag_, &data_) => 0; assert(tag_ == LFSR_TAG_DATA); assert(bid_ == 1); @@ -3222,23 +3216,21 @@ code = ''' 2*DID, "aac", 3), LFSR_RATTR_BUF(LFSR_TAG_DATA, 0, "2", 1))) => 0; printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == 3); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == 3); // try to find tags uint8_t buffer[4]; lfsr_bid_t bid_; - lfsr_rbyd_t rbyd_; - lfsr_srid_t rid_; lfsr_tag_t tag_; lfs_size_t weight_; lfsr_data_t data_; - lfsr_btree_namelookupleaf(&lfs, &btree, 0*DID, "aaa", 3, - &bid_, &rbyd_, &rid_, NULL, &weight_, NULL) => LFS_CMP_EQ; - lfsr_rbyd_lookup(&lfs, &rbyd_, rid_, LFSR_TAG_MASK8 | LFSR_TAG_STRUCT, + lfsr_btree_namelookup(&lfs, &btree, 0*DID, "aaa", 3, + &bid_, NULL, &weight_, NULL) => LFS_CMP_EQ; + lfsr_btree_lookup(&lfs, &btree, bid_, LFSR_TAG_MASK8 | LFSR_TAG_STRUCT, &tag_, &data_) => 0; assert(tag_ == LFSR_TAG_DATA); assert(bid_ == 0); @@ -3246,9 +3238,9 @@ code = ''' lfsr_data_read(&lfs, &data_, buffer, 4) => 1; assert(memcmp(buffer, "0", 1) == 0); - lfsr_btree_namelookupleaf(&lfs, &btree, 1*DID, "aab", 3, - &bid_, &rbyd_, &rid_, NULL, &weight_, NULL) => LFS_CMP_EQ; - lfsr_rbyd_lookup(&lfs, &rbyd_, rid_, LFSR_TAG_MASK8 | LFSR_TAG_STRUCT, + lfsr_btree_namelookup(&lfs, &btree, 1*DID, "aab", 3, + &bid_, NULL, &weight_, NULL) => LFS_CMP_EQ; + lfsr_btree_lookup(&lfs, &btree, bid_, LFSR_TAG_MASK8 | LFSR_TAG_STRUCT, &tag_, &data_) => 0; assert(tag_ == LFSR_TAG_DATA); assert(bid_ == 1); @@ -3256,9 +3248,9 @@ code = ''' lfsr_data_read(&lfs, &data_, buffer, 4) => 1; assert(memcmp(buffer, "1", 1) == 0); - lfsr_btree_namelookupleaf(&lfs, &btree, 2*DID, "aac", 3, - &bid_, &rbyd_, &rid_, NULL, &weight_, NULL) => LFS_CMP_EQ; - lfsr_rbyd_lookup(&lfs, &rbyd_, rid_, LFSR_TAG_MASK8 | LFSR_TAG_STRUCT, + lfsr_btree_namelookup(&lfs, &btree, 2*DID, "aac", 3, + &bid_, NULL, &weight_, NULL) => LFS_CMP_EQ; + lfsr_btree_lookup(&lfs, &btree, bid_, LFSR_TAG_MASK8 | LFSR_TAG_STRUCT, &tag_, &data_) => 0; assert(tag_ == LFSR_TAG_DATA); assert(bid_ == 2); @@ -3266,9 +3258,9 @@ code = ''' lfsr_data_read(&lfs, &data_, buffer, 4) => 1; assert(memcmp(buffer, "2", 1) == 0); - lfsr_btree_namelookupleaf(&lfs, &btree, 3*DID, "aad", 3, - &bid_, &rbyd_, &rid_, NULL, &weight_, NULL) => LFS_CMP_LT; - lfsr_rbyd_lookup(&lfs, &rbyd_, rid_, LFSR_TAG_MASK8 | LFSR_TAG_STRUCT, + lfsr_btree_namelookup(&lfs, &btree, 3*DID, "aad", 3, + &bid_, NULL, &weight_, NULL) => LFS_CMP_LT; + lfsr_btree_lookup(&lfs, &btree, bid_, LFSR_TAG_MASK8 | LFSR_TAG_STRUCT, &tag_, &data_) => 0; assert(tag_ == LFSR_TAG_DATA); assert(bid_ == 2); @@ -3313,23 +3305,21 @@ code = ''' 1*DID, "aab", 3), LFSR_RATTR_BUF(LFSR_TAG_DATA, 0, "1", 1))) => 0; printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == 3); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == 3); // try to find tags uint8_t buffer[4]; lfsr_bid_t bid_; - lfsr_rbyd_t rbyd_; - lfsr_srid_t rid_; lfsr_tag_t tag_; lfs_size_t weight_; lfsr_data_t data_; - lfsr_btree_namelookupleaf(&lfs, &btree, 0*DID, "aaa", 3, - &bid_, &rbyd_, &rid_, NULL, &weight_, NULL) => LFS_CMP_EQ; - lfsr_rbyd_lookup(&lfs, &rbyd_, rid_, LFSR_TAG_MASK8 | LFSR_TAG_STRUCT, + lfsr_btree_namelookup(&lfs, &btree, 0*DID, "aaa", 3, + &bid_, NULL, &weight_, NULL) => LFS_CMP_EQ; + lfsr_btree_lookup(&lfs, &btree, bid_, LFSR_TAG_MASK8 | LFSR_TAG_STRUCT, &tag_, &data_) => 0; assert(tag_ == LFSR_TAG_DATA); assert(bid_ == 0); @@ -3337,9 +3327,9 @@ code = ''' lfsr_data_read(&lfs, &data_, buffer, 4) => 1; assert(memcmp(buffer, "0", 1) == 0); - lfsr_btree_namelookupleaf(&lfs, &btree, 1*DID, "aab", 3, - &bid_, &rbyd_, &rid_, NULL, &weight_, NULL) => LFS_CMP_EQ; - lfsr_rbyd_lookup(&lfs, &rbyd_, rid_, LFSR_TAG_MASK8 | LFSR_TAG_STRUCT, + lfsr_btree_namelookup(&lfs, &btree, 1*DID, "aab", 3, + &bid_, NULL, &weight_, NULL) => LFS_CMP_EQ; + lfsr_btree_lookup(&lfs, &btree, bid_, LFSR_TAG_MASK8 | LFSR_TAG_STRUCT, &tag_, &data_) => 0; assert(tag_ == LFSR_TAG_DATA); assert(bid_ == 1); @@ -3347,9 +3337,9 @@ code = ''' lfsr_data_read(&lfs, &data_, buffer, 4) => 1; assert(memcmp(buffer, "1", 1) == 0); - lfsr_btree_namelookupleaf(&lfs, &btree, 2*DID, "aac", 3, - &bid_, &rbyd_, &rid_, NULL, &weight_, NULL) => LFS_CMP_EQ; - lfsr_rbyd_lookup(&lfs, &rbyd_, rid_, LFSR_TAG_MASK8 | LFSR_TAG_STRUCT, + lfsr_btree_namelookup(&lfs, &btree, 2*DID, "aac", 3, + &bid_, NULL, &weight_, NULL) => LFS_CMP_EQ; + lfsr_btree_lookup(&lfs, &btree, bid_, LFSR_TAG_MASK8 | LFSR_TAG_STRUCT, &tag_, &data_) => 0; assert(tag_ == LFSR_TAG_DATA); assert(bid_ == 2); @@ -3357,9 +3347,9 @@ code = ''' lfsr_data_read(&lfs, &data_, buffer, 4) => 1; assert(memcmp(buffer, "2", 1) == 0); - lfsr_btree_namelookupleaf(&lfs, &btree, 3*DID, "aad", 3, - &bid_, &rbyd_, &rid_, NULL, &weight_, NULL) => LFS_CMP_LT; - lfsr_rbyd_lookup(&lfs, &rbyd_, rid_, LFSR_TAG_MASK8 | LFSR_TAG_STRUCT, + lfsr_btree_namelookup(&lfs, &btree, 3*DID, "aad", 3, + &bid_, NULL, &weight_, NULL) => LFS_CMP_LT; + lfsr_btree_lookup(&lfs, &btree, bid_, LFSR_TAG_MASK8 | LFSR_TAG_STRUCT, &tag_, &data_) => 0; assert(tag_ == LFSR_TAG_DATA); assert(bid_ == 2); @@ -3415,16 +3405,14 @@ code = ''' n += 1; } printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == n); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == n); // try to find tags uint8_t buffer[4]; lfsr_bid_t bid_; - lfsr_rbyd_t rbyd_; - lfsr_srid_t rid_; lfsr_tag_t tag_; lfs_size_t weight_; lfsr_data_t data_; @@ -3434,9 +3422,9 @@ code = ''' 'a'+((i/26/26) % 26), 'a'+((i/26) % 26), 'a'+(i % 26) }; - lfsr_btree_namelookupleaf(&lfs, &btree, i*DID, name, 3, - &bid_, &rbyd_, &rid_, NULL, &weight_, NULL) => LFS_CMP_EQ; - lfsr_rbyd_lookup(&lfs, &rbyd_, rid_, LFSR_TAG_MASK8 | LFSR_TAG_STRUCT, + lfsr_btree_namelookup(&lfs, &btree, i*DID, name, 3, + &bid_, NULL, &weight_, NULL) => LFS_CMP_EQ; + lfsr_btree_lookup(&lfs, &btree, bid_, LFSR_TAG_MASK8 | LFSR_TAG_STRUCT, &tag_, &data_) => 0; assert(tag_ == LFSR_TAG_DATA); assert(bid_ == i); @@ -3534,22 +3522,20 @@ code = ''' } printf("]\n"); printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == sim_size); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == sim_size); uint8_t buffer[4]; lfsr_bid_t bid_; - lfsr_rbyd_t rbyd_; - lfsr_srid_t rid_; lfsr_tag_t tag_; lfs_size_t weight_; lfsr_data_t data_; for (lfs_size_t i = 0; i < sim_size; i++) { - lfsr_btree_namelookupleaf(&lfs, &btree, 0, sim_names[i], 3, - &bid_, &rbyd_, &rid_, NULL, &weight_, NULL) => LFS_CMP_EQ; - lfsr_rbyd_lookup(&lfs, &rbyd_, rid_, LFSR_TAG_MASK8 | LFSR_TAG_STRUCT, + lfsr_btree_namelookup(&lfs, &btree, 0, sim_names[i], 3, + &bid_, NULL, &weight_, NULL) => LFS_CMP_EQ; + lfsr_btree_lookup(&lfs, &btree, bid_, LFSR_TAG_MASK8 | LFSR_TAG_STRUCT, &tag_, &data_) => 0; assert(tag_ == LFSR_TAG_DATA); assert(bid_ == i); @@ -3612,16 +3598,14 @@ code = ''' n += 1; } printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == n*W); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == n*W); // try to find tags uint8_t buffer[4]; lfsr_bid_t bid_; - lfsr_rbyd_t rbyd_; - lfsr_srid_t rid_; lfsr_tag_t tag_; lfs_size_t weight_; lfsr_data_t data_; @@ -3631,9 +3615,9 @@ code = ''' 'a'+((i/26/26) % 26), 'a'+((i/26) % 26), 'a'+(i % 26) }; - lfsr_btree_namelookupleaf(&lfs, &btree, i*DID, name, 3, - &bid_, &rbyd_, &rid_, NULL, &weight_, NULL) => LFS_CMP_EQ; - lfsr_rbyd_lookup(&lfs, &rbyd_, rid_, LFSR_TAG_MASK8 | LFSR_TAG_STRUCT, + lfsr_btree_namelookup(&lfs, &btree, i*DID, name, 3, + &bid_, NULL, &weight_, NULL) => LFS_CMP_EQ; + lfsr_btree_lookup(&lfs, &btree, bid_, LFSR_TAG_MASK8 | LFSR_TAG_STRUCT, &tag_, &data_) => 0; assert(tag_ == LFSR_TAG_DATA); assert(bid_ == i*W+W-1); @@ -3761,20 +3745,18 @@ code = ''' } printf("]\n"); printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); lfs_size_t total_weight = 0; for (lfs_size_t j = 0; j < sim_size; j++) { total_weight += sim_weights[j]; } - assert(btree.weight == total_weight); + assert(lfsr_btree_weight(&btree) == total_weight); uint8_t buffer[4]; lfsr_bid_t bid_; - lfsr_rbyd_t rbyd_; - lfsr_srid_t rid_; lfsr_tag_t tag_; lfs_size_t weight_; lfsr_data_t data_; @@ -3785,9 +3767,9 @@ code = ''' weighted_bid += sim_weights[j]; } - lfsr_btree_namelookupleaf(&lfs, &btree, 0, sim_names[i], 3, - &bid_, &rbyd_, &rid_, NULL, &weight_, NULL) => LFS_CMP_EQ; - lfsr_rbyd_lookup(&lfs, &rbyd_, rid_, LFSR_TAG_MASK8 | LFSR_TAG_STRUCT, + lfsr_btree_namelookup(&lfs, &btree, 0, sim_names[i], 3, + &bid_, NULL, &weight_, NULL) => LFS_CMP_EQ; + lfsr_btree_lookup(&lfs, &btree, bid_, LFSR_TAG_MASK8 | LFSR_TAG_STRUCT, &tag_, &data_) => 0; assert(tag_ == LFSR_TAG_DATA); assert(bid_ == weighted_bid+sim_weights[i]-1); @@ -3889,10 +3871,9 @@ code = ''' // a c d g h i k // ^ lfsr_bid_t split_bid; - lfsr_rbyd_t split_rbyd; - lfs_scmp_t cmp = lfsr_btree_namelookupleaf(&lfs, &btree, + lfs_scmp_t cmp = lfsr_btree_namelookup(&lfs, &btree, 0, name, 3, - &split_bid, &split_rbyd, NULL, NULL, NULL, NULL); + &split_bid, NULL, NULL, NULL); assert(cmp >= 0); assert(cmp != LFS_CMP_EQ); if (cmp > LFS_CMP_EQ) { @@ -3956,22 +3937,20 @@ code = ''' } printf("]\n"); printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == sim_size); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == sim_size); uint8_t buffer[4]; lfsr_bid_t bid_; - lfsr_rbyd_t rbyd_; - lfsr_srid_t rid_; lfsr_tag_t tag_; lfs_size_t weight_; lfsr_data_t data_; for (lfs_size_t i = 0; i < sim_size; i++) { - lfsr_btree_namelookupleaf(&lfs, &btree, 0, sim_names[i], 3, - &bid_, &rbyd_, &rid_, NULL, &weight_, NULL) => LFS_CMP_EQ; - lfsr_rbyd_lookup(&lfs, &rbyd_, rid_, LFSR_TAG_MASK8 | LFSR_TAG_STRUCT, + lfsr_btree_namelookup(&lfs, &btree, 0, sim_names[i], 3, + &bid_, NULL, &weight_, NULL) => LFS_CMP_EQ; + lfsr_btree_lookup(&lfs, &btree, bid_, LFSR_TAG_MASK8 | LFSR_TAG_STRUCT, &tag_, &data_) => 0; assert(tag_ == LFSR_TAG_DATA); assert(bid_ == i); @@ -4083,11 +4062,10 @@ code = ''' // a c d g h i k // ^ lfsr_bid_t split_bid; - lfsr_rbyd_t split_rbyd; lfsr_bid_t split_weight; - lfs_scmp_t cmp = lfsr_btree_namelookupleaf(&lfs, &btree, + lfs_scmp_t cmp = lfsr_btree_namelookup(&lfs, &btree, 0, name, 3, - &split_bid, &split_rbyd, NULL, NULL, &split_weight, NULL); + &split_bid, NULL, &split_weight, NULL); assert(cmp >= 0); assert(cmp != LFS_CMP_EQ); if (cmp > LFS_CMP_EQ) { @@ -4173,20 +4151,18 @@ code = ''' } printf("]\n"); printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); lfs_size_t total_weight = 0; for (lfs_size_t j = 0; j < sim_size; j++) { total_weight += sim_weights[j]; } - assert(btree.weight == total_weight); + assert(lfsr_btree_weight(&btree) == total_weight); uint8_t buffer[4]; lfsr_bid_t bid_; - lfsr_rbyd_t rbyd_; - lfsr_srid_t rid_; lfsr_tag_t tag_; lfs_size_t weight_; lfsr_data_t data_; @@ -4197,9 +4173,9 @@ code = ''' weighted_bid += sim_weights[j]; } - lfsr_btree_namelookupleaf(&lfs, &btree, 0, sim_names[i], 3, - &bid_, &rbyd_, &rid_, NULL, &weight_, NULL) => LFS_CMP_EQ; - lfsr_rbyd_lookup(&lfs, &rbyd_, rid_, LFSR_TAG_MASK8 | LFSR_TAG_STRUCT, + lfsr_btree_namelookup(&lfs, &btree, 0, sim_names[i], 3, + &bid_, NULL, &weight_, NULL) => LFS_CMP_EQ; + lfsr_btree_lookup(&lfs, &btree, bid_, LFSR_TAG_MASK8 | LFSR_TAG_STRUCT, &tag_, &data_) => 0; assert(tag_ == LFSR_TAG_DATA); assert(bid_ == weighted_bid+sim_weights[i]-1); @@ -4244,10 +4220,10 @@ code = ''' n += 1; } printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == n); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == n); // check that the elements are in the tree uint8_t buffer[4]; @@ -4399,10 +4375,10 @@ code = ''' } printf("]\n"); printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == sim_size); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == sim_size); uint8_t buffer[4]; lfsr_bid_t bid_; @@ -4493,10 +4469,10 @@ code = ''' } printf("]\n"); printf("btree: w%d 0x%x.%x\n", - btree.weight, - btree.blocks[0], - btree.trunk); - assert(btree.weight == sim_size); + lfsr_btree_weight(&btree), + lfsr_btree_block(&btree), + lfsr_btree_trunk(&btree)); + assert(lfsr_btree_weight(&btree) == sim_size); for (lfs_size_t i = 0; i < sim_size; i++) { lfsr_btree_lookupnext(&lfs, &btree, i, diff --git a/tests/test_files.toml b/tests/test_files.toml index b6a8d8b7..94f10337 100644 --- a/tests/test_files.toml +++ b/tests/test_files.toml @@ -1227,10 +1227,10 @@ code = ''' // create an empty btree lfs_alloc_ckpoint(&lfs); - lfsr_rbyd_alloc(&lfs, &file.b.shrub) => 0; - lfsr_rbyd_commit(&lfs, &file.b.shrub, 0, LFSR_RATTRS( + lfsr_rbyd_alloc(&lfs, &file.b.shrub.root) => 0; + lfsr_rbyd_commit(&lfs, &file.b.shrub.root, 0, LFSR_RATTRS( LFSR_RATTR_BUF(LFSR_TAG_DATA, +1, "?", 1))) => 0; - lfsr_rbyd_commit(&lfs, &file.b.shrub, 0, LFSR_RATTRS( + lfsr_rbyd_commit(&lfs, &file.b.shrub.root, 0, LFSR_RATTRS( LFSR_RATTR(LFSR_TAG_RM, -1))) => 0; lfsr_mdir_commit(&lfs, &file.b.o.mdir, LFSR_RATTRS( LFSR_RATTR_BTREE( diff --git a/tests/test_mtree.toml b/tests/test_mtree.toml index be796f8d..9ce99887 100644 --- a/tests/test_mtree.toml +++ b/tests/test_mtree.toml @@ -196,7 +196,7 @@ code = ''' LFSR_RATTR_BUF(LFSR_TAG_ATTR(3), 0, "c", 1))) => 0; // assert mdirs were unininlined - assert(lfs.mtree.weight == (1 << lfs.mbits)); + assert(lfs.mtree.root.weight == (1 << lfs.mbits)); // assert mroot now has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -220,7 +220,7 @@ code = ''' lfsr_mount(&lfs, LFS_M_RDWR | M_FLAGS, CFG) => 0; // assert mdirs were unininlined - assert(lfs.mtree.weight == (1 << lfs.mbits)); + assert(lfs.mtree.root.weight == (1 << lfs.mbits)); // assert mroot now has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -281,7 +281,7 @@ code = ''' LFSR_RATTR_BUF(LFSR_TAG_ATTR(1), 0, "c", 1))) => 0; // assert mdirs were unininlined and split - assert(lfs.mtree.weight == (2 << lfs.mbits)); + assert(lfs.mtree.root.weight == (2 << lfs.mbits)); // assert mroot now has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -307,7 +307,7 @@ code = ''' lfsr_mount(&lfs, LFS_M_RDWR | M_FLAGS, CFG) => 0; // assert mdirs were unininlined and split - assert(lfs.mtree.weight == (2 << lfs.mbits)); + assert(lfs.mtree.root.weight == (2 << lfs.mbits)); // assert mroot now has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -370,7 +370,7 @@ code = ''' LFSR_RATTR_BUF(LFSR_TAG_ATTR(1), 0, "c", 1))) => 0; // assert mdirs were unininlined and split - assert(lfs.mtree.weight == (2 << lfs.mbits)); + assert(lfs.mtree.root.weight == (2 << lfs.mbits)); // assert mroot now has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -390,7 +390,7 @@ code = ''' LFSR_RATTR_BUF(LFSR_TAG_ATTR(2), 0, "e", 1))) => 0; // assert mdir was split correctly - assert(lfs.mtree.weight == (3 << lfs.mbits)); + assert(lfs.mtree.root.weight == (3 << lfs.mbits)); // assert mroot still has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -426,7 +426,7 @@ code = ''' lfsr_mount(&lfs, LFS_M_RDWR | M_FLAGS, CFG) => 0; // assert mdir was split correctly - assert(lfs.mtree.weight == (3 << lfs.mbits)); + assert(lfs.mtree.root.weight == (3 << lfs.mbits)); // assert mroot still has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -687,7 +687,7 @@ code = ''' LFSR_RATTR_BUF(LFSR_TAG_ATTR(1), 0, "c", 1))) => 0; // assert mdirs were unininlined and split - assert(lfs.mtree.weight == (2 << lfs.mbits)); + assert(lfs.mtree.root.weight == (2 << lfs.mbits)); // assert mroot now has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -700,7 +700,7 @@ code = ''' assert(mdir.rbyd.weight == 0); // assert mdir was dropped - assert(lfs.mtree.weight == (1 << lfs.mbits)); + assert(lfs.mtree.root.weight == (1 << lfs.mbits)); // assert mroot still has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -720,7 +720,7 @@ code = ''' lfsr_mount(&lfs, LFS_M_RDWR | M_FLAGS, CFG) => 0; // assert mdir was dropped - assert(lfs.mtree.weight == (1 << lfs.mbits)); + assert(lfs.mtree.root.weight == (1 << lfs.mbits)); // assert mroot still has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -777,7 +777,7 @@ code = ''' LFSR_RATTR_BUF(LFSR_TAG_ATTR(1), 0, "c", 1))) => 0; // assert mdirs were unininlined and split - assert(lfs.mtree.weight == (2 << lfs.mbits)); + assert(lfs.mtree.root.weight == (2 << lfs.mbits)); // assert mroot now has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -792,7 +792,7 @@ code = ''' assert(mdir.rbyd.weight == 0); // assert mdir was dropped - assert(lfs.mtree.weight == (1 << lfs.mbits)); + assert(lfs.mtree.root.weight == (1 << lfs.mbits)); // assert mroot still has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -812,7 +812,7 @@ code = ''' lfsr_mount(&lfs, LFS_M_RDWR | M_FLAGS, CFG) => 0; // assert mdir was dropped - assert(lfs.mtree.weight == (1 << lfs.mbits)); + assert(lfs.mtree.root.weight == (1 << lfs.mbits)); // assert mroot still has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -875,7 +875,7 @@ code = ''' assert(mdir.rbyd.weight == 2); // assert split/drop worked out - assert(lfs.mtree.weight == (1 << lfs.mbits)); + assert(lfs.mtree.root.weight == (1 << lfs.mbits)); // assert mroot still has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -891,7 +891,7 @@ code = ''' lfsr_mount(&lfs, LFS_M_RDWR | M_FLAGS, CFG) => 0; // assert mdir was dropped - assert(lfs.mtree.weight == (1 << lfs.mbits)); + assert(lfs.mtree.root.weight == (1 << lfs.mbits)); // assert mroot still has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -944,7 +944,7 @@ code = ''' LFSR_RATTR_BUF(LFSR_TAG_ATTR(1), 0, "c", 1))) => 0; // assert mdirs were unininlined and split - assert(lfs.mtree.weight == (2 << lfs.mbits)); + assert(lfs.mtree.root.weight == (2 << lfs.mbits)); // assert mroot now has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -969,7 +969,7 @@ code = ''' assert(mdir.rbyd.weight == 1); // assert split/drop worked out - assert(lfs.mtree.weight == (2 << lfs.mbits)); + assert(lfs.mtree.root.weight == (2 << lfs.mbits)); // assert mroot still has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -995,7 +995,7 @@ code = ''' lfsr_mount(&lfs, LFS_M_RDWR | M_FLAGS, CFG) => 0; // assert split/drop worked out - assert(lfs.mtree.weight == (2 << lfs.mbits)); + assert(lfs.mtree.root.weight == (2 << lfs.mbits)); // assert mroot still has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -1058,7 +1058,7 @@ code = ''' LFSR_RATTR_BUF(LFSR_TAG_ATTR(1), 0, "c", 1))) => 0; // assert mdirs were unininlined and split - assert(lfs.mtree.weight == (2 << lfs.mbits)); + assert(lfs.mtree.root.weight == (2 << lfs.mbits)); // assert mroot now has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -1083,7 +1083,7 @@ code = ''' assert(mdir.rbyd.weight == 1); // assert split/drop worked out - assert(lfs.mtree.weight == (2 << lfs.mbits)); + assert(lfs.mtree.root.weight == (2 << lfs.mbits)); // assert mroot still has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -1109,7 +1109,7 @@ code = ''' lfsr_mount(&lfs, LFS_M_RDWR | M_FLAGS, CFG) => 0; // assert split/drop worked out - assert(lfs.mtree.weight == (2 << lfs.mbits)); + assert(lfs.mtree.root.weight == (2 << lfs.mbits)); // assert mroot still has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -1296,7 +1296,7 @@ code = ''' LFSR_RATTR_BUF(LFSR_TAG_ATTR(3), 0, "c", 1))) => 0; // assert mdirs were unininlined - assert(lfs.mtree.weight == (1 << lfs.mbits)); + assert(lfs.mtree.root.weight == (1 << lfs.mbits)); // assert mroot now has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -1313,7 +1313,7 @@ code = ''' assert(lfsr_mdir_cmp(&old_mdir, &mdir) != 0); // assert mdirs were unininlined - assert(lfs.mtree.weight == (1 << lfs.mbits)); + assert(lfs.mtree.root.weight == (1 << lfs.mbits)); // assert mroot now has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -1347,7 +1347,7 @@ code = ''' lfsr_mount(&lfs, LFS_M_RDWR | M_FLAGS, CFG) => 0; // assert mdirs were unininlined - assert(lfs.mtree.weight == (1 << lfs.mbits)); + assert(lfs.mtree.root.weight == (1 << lfs.mbits)); // assert mroot now has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -1420,7 +1420,7 @@ code = ''' LFSR_RATTR_BUF(LFSR_TAG_ATTR(1), 0, "c", 1))) => 0; // assert mdirs were unininlined and split - assert(lfs.mtree.weight == (2 << lfs.mbits)); + assert(lfs.mtree.root.weight == (2 << lfs.mbits)); // assert mroot now has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -1439,7 +1439,7 @@ code = ''' assert(lfsr_mdir_cmp(&old_mdir, &mdir) != 0); // assert mdirs were unininlined and split - assert(lfs.mtree.weight == (2 << lfs.mbits)); + assert(lfs.mtree.root.weight == (2 << lfs.mbits)); // assert mroot now has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -1475,7 +1475,7 @@ code = ''' lfsr_mount(&lfs, LFS_M_RDWR | M_FLAGS, CFG) => 0; // assert mdirs were unininlined and split - assert(lfs.mtree.weight == (2 << lfs.mbits)); + assert(lfs.mtree.root.weight == (2 << lfs.mbits)); // assert mroot now has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -1550,7 +1550,7 @@ code = ''' LFSR_RATTR_BUF(LFSR_TAG_ATTR(1), 0, "c", 1))) => 0; // assert mdirs were unininlined and split - assert(lfs.mtree.weight == (2 << lfs.mbits)); + assert(lfs.mtree.root.weight == (2 << lfs.mbits)); // assert mroot now has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -1569,7 +1569,7 @@ code = ''' assert(lfsr_mdir_cmp(&old_mdir, &mdir) != 0); // assert mdirs were unininlined and split - assert(lfs.mtree.weight == (2 << lfs.mbits)); + assert(lfs.mtree.root.weight == (2 << lfs.mbits)); // assert mroot now has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -1605,7 +1605,7 @@ code = ''' lfsr_mount(&lfs, LFS_M_RDWR | M_FLAGS, CFG) => 0; // assert mdirs were unininlined and split - assert(lfs.mtree.weight == (2 << lfs.mbits)); + assert(lfs.mtree.root.weight == (2 << lfs.mbits)); // assert mroot now has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -1982,7 +1982,7 @@ code = ''' LFSR_RATTR_BUF(LFSR_TAG_ATTR(1), 0, "c", 1))) => 0; // assert mdirs were unininlined and split - assert(lfs.mtree.weight == (2 << lfs.mbits)); + assert(lfs.mtree.root.weight == (2 << lfs.mbits)); // assert mroot now has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -2006,7 +2006,7 @@ code = ''' assert(lfsr_mdir_cmp(&old_mroot, &lfs.mroot) != 0); // assert mdirs were unininlined and split - assert(lfs.mtree.weight == (2 << lfs.mbits)); + assert(lfs.mtree.root.weight == (2 << lfs.mbits)); // assert mroot now has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -2042,7 +2042,7 @@ code = ''' lfsr_mount(&lfs, LFS_M_RDWR | M_FLAGS, CFG) => 0; // assert mdirs were unininlined and split - assert(lfs.mtree.weight == (2 << lfs.mbits)); + assert(lfs.mtree.root.weight == (2 << lfs.mbits)); // assert mroot now has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -2117,7 +2117,7 @@ code = ''' LFSR_RATTR_BUF(LFSR_TAG_ATTR(1), 0, "c", 1))) => 0; // assert mdirs were unininlined and split - assert(lfs.mtree.weight == (2 << lfs.mbits)); + assert(lfs.mtree.root.weight == (2 << lfs.mbits)); // assert mroot now has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -2148,7 +2148,7 @@ code = ''' assert(lfsr_mdir_cmp(&old_mroot, &lfs.mroot) != 0); // assert mdir was split correctly - assert(lfs.mtree.weight == (3 << lfs.mbits)); + assert(lfs.mtree.root.weight == (3 << lfs.mbits)); // assert mroot still has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -2188,7 +2188,7 @@ code = ''' lfsr_mount(&lfs, LFS_M_RDWR | M_FLAGS, CFG) => 0; // assert mdir was split correctly - assert(lfs.mtree.weight == (3 << lfs.mbits)); + assert(lfs.mtree.root.weight == (3 << lfs.mbits)); // assert mroot still has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -2267,7 +2267,7 @@ code = ''' LFSR_RATTR_BUF(LFSR_TAG_ATTR(1), 0, "c", 1))) => 0; // assert mdirs were unininlined and split - assert(lfs.mtree.weight == (2 << lfs.mbits)); + assert(lfs.mtree.root.weight == (2 << lfs.mbits)); // assert mroot now has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -2291,7 +2291,7 @@ code = ''' assert(lfsr_mdir_cmp(&old_mroot, &lfs.mroot) != 0); // assert mdir was dropped - assert(lfs.mtree.weight == (1 << lfs.mbits)); + assert(lfs.mtree.root.weight == (1 << lfs.mbits)); // assert mroot still has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -2311,7 +2311,7 @@ code = ''' lfsr_mount(&lfs, LFS_M_RDWR | M_FLAGS, CFG) => 0; // assert mdir was dropped - assert(lfs.mtree.weight == (1 << lfs.mbits)); + assert(lfs.mtree.root.weight == (1 << lfs.mbits)); // assert mroot still has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -2368,7 +2368,7 @@ code = ''' assert(lfsr_mdir_cmp(&old_mroot, &lfs.mroot) != 0); // assert mdirs were unininlined - assert(lfs.mtree.weight == (1 << lfs.mbits)); + assert(lfs.mtree.root.weight == (1 << lfs.mbits)); // assert mroot now has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -2392,7 +2392,7 @@ code = ''' lfsr_mount(&lfs, LFS_M_RDWR | M_FLAGS, CFG) => 0; // assert mdirs were unininlined - assert(lfs.mtree.weight == (1 << lfs.mbits)); + assert(lfs.mtree.root.weight == (1 << lfs.mbits)); // assert mroot now has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -2463,7 +2463,7 @@ code = ''' assert(lfsr_mdir_cmp(&old_mroot, &lfs.mroot) != 0); // assert mdirs were unininlined and split - assert(lfs.mtree.weight == (2 << lfs.mbits)); + assert(lfs.mtree.root.weight == (2 << lfs.mbits)); // assert mroot now has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -2489,7 +2489,7 @@ code = ''' lfsr_mount(&lfs, LFS_M_RDWR | M_FLAGS, CFG) => 0; // assert mdirs were unininlined and split - assert(lfs.mtree.weight == (2 << lfs.mbits)); + assert(lfs.mtree.root.weight == (2 << lfs.mbits)); // assert mroot now has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -2888,7 +2888,7 @@ code = ''' lfsr_mdir_commit(&lfs, &lfs.mroot, NULL, 0) => 0; // assert mdirs were unininlined and split - assert(lfs.mtree.weight == (2 << lfs.mbits)); + assert(lfs.mtree.root.weight == (2 << lfs.mbits)); // assert mroot now has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -2979,7 +2979,7 @@ code = ''' lfsr_mdir_commit(&lfs, &mdir, NULL, 0) => 0; // assert mdir was split correctly - assert(lfs.mtree.weight == (3 << lfs.mbits)); + assert(lfs.mtree.root.weight == (3 << lfs.mbits)); // assert mroot still has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -3114,7 +3114,7 @@ code = ''' lfsr_mdir_commit(&lfs, &lfs.mroot, NULL, 0) => 0; // assert mdirs were unininlined and split - assert(lfs.mtree.weight == (2 << lfs.mbits)); + assert(lfs.mtree.root.weight == (2 << lfs.mbits)); // assert mroot now has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -3211,7 +3211,7 @@ code = ''' lfsr_mdir_commit(&lfs, &lfs.mroot, NULL, 0) => 0; // assert mdirs were unininlined and split - assert(lfs.mtree.weight == (2 << lfs.mbits)); + assert(lfs.mtree.root.weight == (2 << lfs.mbits)); // assert mroot now has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -3320,7 +3320,7 @@ code = ''' lfsr_mdir_commit(&lfs, &mdir, NULL, 0) => 0; // assert mdir was split correctly - assert(lfs.mtree.weight == (3 << lfs.mbits)); + assert(lfs.mtree.root.weight == (3 << lfs.mbits)); // assert mroot still has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -3339,7 +3339,7 @@ code = ''' lfsr_mdir_commit(&lfs, &mdir, NULL, 0) => 0; // assert mdir was split correctly - assert(lfs.mtree.weight == (4 << lfs.mbits)); + assert(lfs.mtree.root.weight == (4 << lfs.mbits)); // assert mroot still has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -3430,7 +3430,7 @@ code = ''' lfsr_mdir_commit(&lfs, &mdir, NULL, 0) => 0; // assert mdir was split correctly - assert(lfs.mtree.weight == (3 << lfs.mbits)); + assert(lfs.mtree.root.weight == (3 << lfs.mbits)); // assert mroot still has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -3440,7 +3440,7 @@ code = ''' assert(mdir.rbyd.weight == 0); // assert mdir was dropped correctly - assert(lfs.mtree.weight == (2 << lfs.mbits)); + assert(lfs.mtree.root.weight == (2 << lfs.mbits)); // assert mroot still has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -3597,7 +3597,7 @@ code = ''' lfsr_mdir_commit(&lfs, &lfs.mroot, NULL, 0) => 0; // assert mdirs were unininlined - assert(lfs.mtree.weight == (1 << lfs.mbits)); + assert(lfs.mtree.root.weight == (1 << lfs.mbits)); // assert mroot now has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -3663,7 +3663,7 @@ code = ''' // and the tree should still work // assert mdirs were unininlined - assert(lfs.mtree.weight == (1 << lfs.mbits)); + assert(lfs.mtree.root.weight == (1 << lfs.mbits)); // assert mroot now has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -3683,7 +3683,7 @@ code = ''' lfsr_mount(&lfs, LFS_M_RDWR | M_FLAGS, CFG) => 0; // assert mdirs were unininlined - assert(lfs.mtree.weight == (1 << lfs.mbits)); + assert(lfs.mtree.root.weight == (1 << lfs.mbits)); // assert mroot now has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -3740,7 +3740,7 @@ code = ''' lfsr_mdir_commit(&lfs, &lfs.mroot, NULL, 0) => 0; // assert mdirs were unininlined and split - assert(lfs.mtree.weight == (2 << lfs.mbits)); + assert(lfs.mtree.root.weight == (2 << lfs.mbits)); // assert mroot now has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -3806,7 +3806,7 @@ code = ''' // and the tree should still work // assert mdirs were unininlined and split - assert(lfs.mtree.weight == (2 << lfs.mbits)); + assert(lfs.mtree.root.weight == (2 << lfs.mbits)); // assert mroot now has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -3828,7 +3828,7 @@ code = ''' lfsr_mount(&lfs, LFS_M_RDWR | M_FLAGS, CFG) => 0; // assert mdirs were unininlined and split - assert(lfs.mtree.weight == (2 << lfs.mbits)); + assert(lfs.mtree.root.weight == (2 << lfs.mbits)); // assert mroot now has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -3887,7 +3887,7 @@ code = ''' lfsr_mdir_commit(&lfs, &lfs.mroot, NULL, 0) => 0; // assert mdirs were unininlined and split - assert(lfs.mtree.weight == (2 << lfs.mbits)); + assert(lfs.mtree.root.weight == (2 << lfs.mbits)); // assert mroot now has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -3906,7 +3906,7 @@ code = ''' lfsr_mdir_commit(&lfs, &mdir, NULL, 0) => 0; // assert mdir was split correctly - assert(lfs.mtree.weight == (3 << lfs.mbits)); + assert(lfs.mtree.root.weight == (3 << lfs.mbits)); // assert mroot still has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -3972,7 +3972,7 @@ code = ''' // and the tree should still work // assert mdir was split correctly - assert(lfs.mtree.weight == (3 << lfs.mbits)); + assert(lfs.mtree.root.weight == (3 << lfs.mbits)); // assert mroot still has no entries assert(lfs.mroot.rbyd.weight == 0); @@ -4000,7 +4000,7 @@ code = ''' lfsr_mount(&lfs, LFS_M_RDWR | M_FLAGS, CFG) => 0; // assert mdir was split correctly - assert(lfs.mtree.weight == (3 << lfs.mbits)); + assert(lfs.mtree.root.weight == (3 << lfs.mbits)); // assert mroot still has no entries assert(lfs.mroot.rbyd.weight == 0); diff --git a/tests/test_traversal.toml b/tests/test_traversal.toml index fe4f2f66..fce42424 100644 --- a/tests/test_traversal.toml +++ b/tests/test_traversal.toml @@ -3416,7 +3416,7 @@ code = ''' // create enough files for mroot to split lfs_size_t i = 0; - while (lfs.mtree.weight == 0) { + while (lfs.mtree.root.weight == 0) { char name[256]; sprintf(name, "uloborus%03x", i); lfsr_file_open(&lfs, &file, name, @@ -3535,7 +3535,7 @@ code = ''' // create enough files for mroot to split lfs_size_t i = 0; - while (lfs.mtree.weight == 0) { + while (lfs.mtree.root.weight == 0) { char name[256]; sprintf(name, "uloborus%03x", i); lfsr_file_open(&lfs, &file, name, @@ -3662,7 +3662,7 @@ code = ''' // create enough files for mroot to split lfs_size_t i = 0; - while (lfs.mtree.weight == 0) { + while (lfs.mtree.root.weight == 0) { char name[256]; sprintf(name, "uloborus%03x", i); lfsr_file_open(&lfs, &file, name, @@ -4186,7 +4186,7 @@ code = ''' // create enough files for mroot to split twice lfs_size_t i = 0; - while (lfs.mtree.weight == 0) { + while (lfs.mtree.root.weight == 0) { char name[256]; sprintf(name, "tarantula%03x", i); lfsr_file_open(&lfs, &file, name, @@ -4196,8 +4196,8 @@ code = ''' } i = 0; - lfs_size_t orig = lfs.mtree.weight; - while (lfs.mtree.weight == orig) { + lfs_size_t orig = lfs.mtree.root.weight; + while (lfs.mtree.root.weight == orig) { char name[256]; sprintf(name, "xnotata%03x", i); lfsr_file_open(&lfs, &file, name, @@ -4221,8 +4221,8 @@ code = ''' // create enough files for mdir to split again i = 0; - orig = lfs.mtree.weight; - while (lfs.mtree.weight == orig) { + orig = lfs.mtree.root.weight; + while (lfs.mtree.root.weight == orig) { char name[256]; sprintf(name, "vulsor%03x", i); lfsr_file_open(&lfs, &file, name, @@ -4361,7 +4361,7 @@ code = ''' // create enough files for mroot to split twice lfs_size_t i = 0; - while (lfs.mtree.weight == 0) { + while (lfs.mtree.root.weight == 0) { char name[256]; sprintf(name, "tarantula%03x", i); lfsr_file_open(&lfs, &file, name, @@ -4371,8 +4371,8 @@ code = ''' } i = 0; - lfs_size_t orig = lfs.mtree.weight; - while (lfs.mtree.weight == orig) { + lfs_size_t orig = lfs.mtree.root.weight; + while (lfs.mtree.root.weight == orig) { char name[256]; sprintf(name, "xnotata%03x", i); lfsr_file_open(&lfs, &file, name, @@ -4420,8 +4420,8 @@ code = ''' // create enough files for mdir to split again i = 0; - orig = lfs.mtree.weight; - while (lfs.mtree.weight == orig) { + orig = lfs.mtree.root.weight; + while (lfs.mtree.root.weight == orig) { char name[256]; sprintf(name, "vulsor%03x", i); lfsr_file_open(&lfs, &file, name, @@ -4543,7 +4543,7 @@ code = ''' // create enough files for mroot to split twice lfs_size_t i = 0; - while (lfs.mtree.weight == 0) { + while (lfs.mtree.root.weight == 0) { char name[256]; sprintf(name, "tarantula%03x", i); lfsr_file_open(&lfs, &file, name, @@ -4553,8 +4553,8 @@ code = ''' } i = 0; - lfs_size_t orig = lfs.mtree.weight; - while (lfs.mtree.weight == orig) { + lfs_size_t orig = lfs.mtree.root.weight; + while (lfs.mtree.root.weight == orig) { char name[256]; sprintf(name, "xnotata%03x", i); lfsr_file_open(&lfs, &file, name, @@ -4607,8 +4607,8 @@ code = ''' // create enough files for mdir to split again i = 0; - orig = lfs.mtree.weight; - while (lfs.mtree.weight == orig) { + orig = lfs.mtree.root.weight; + while (lfs.mtree.root.weight == orig) { char name[256]; sprintf(name, "vulsor%03x", i); lfsr_file_open(&lfs, &file, name, @@ -4719,7 +4719,7 @@ code = ''' // create enough files for mroot to split twice lfs_size_t i = 0; - while (lfs.mtree.weight == 0) { + while (lfs.mtree.root.weight == 0) { char name[256]; sprintf(name, "tarantula%03x", i); lfsr_file_open(&lfs, &file, name, @@ -4729,8 +4729,8 @@ code = ''' } i = 0; - lfs_size_t orig = lfs.mtree.weight; - while (lfs.mtree.weight == orig) { + lfs_size_t orig = lfs.mtree.root.weight; + while (lfs.mtree.root.weight == orig) { char name[256]; sprintf(name, "xnotata%03x", i); lfsr_file_open(&lfs, &file, name, @@ -4892,7 +4892,7 @@ code = ''' // create enough files for mroot to split twice lfs_size_t i = 0; - while (lfs.mtree.weight == 0) { + while (lfs.mtree.root.weight == 0) { char name[256]; sprintf(name, "tarantula%03x", i); lfsr_file_open(&lfs, &file, name, @@ -4902,8 +4902,8 @@ code = ''' } i = 0; - lfs_size_t orig = lfs.mtree.weight; - while (lfs.mtree.weight == orig) { + lfs_size_t orig = lfs.mtree.root.weight; + while (lfs.mtree.root.weight == orig) { char name[256]; sprintf(name, "xnotata%03x", i); lfsr_file_open(&lfs, &file, name, @@ -5083,7 +5083,7 @@ code = ''' // create enough files for mroot to split twice lfs_size_t i = 0; - while (lfs.mtree.weight == 0) { + while (lfs.mtree.root.weight == 0) { char name[256]; sprintf(name, "tarantula%03x", i); lfsr_file_open(&lfs, &file, name, @@ -5093,8 +5093,8 @@ code = ''' } i = 0; - lfs_size_t orig = lfs.mtree.weight; - while (lfs.mtree.weight == orig) { + lfs_size_t orig = lfs.mtree.root.weight; + while (lfs.mtree.root.weight == orig) { char name[256]; sprintf(name, "xnotata%03x", i); lfsr_file_open(&lfs, &file, name, @@ -5262,7 +5262,7 @@ code = ''' // create enough files for mroot to split twice lfs_size_t i = 0; - while (lfs.mtree.weight == 0) { + while (lfs.mtree.root.weight == 0) { char name[256]; sprintf(name, "tarantula%03x", i); lfsr_file_open(&lfs, &file, name, @@ -5272,8 +5272,8 @@ code = ''' } i = 0; - lfs_size_t orig = lfs.mtree.weight; - while (lfs.mtree.weight == orig) { + lfs_size_t orig = lfs.mtree.root.weight; + while (lfs.mtree.root.weight == orig) { char name[256]; sprintf(name, "xnotata%03x", i); lfsr_file_open(&lfs, &file, name, @@ -5795,7 +5795,7 @@ code = ''' lfs_size_t i = 0; while (true) { // we should not have split yet - assert(lfs.mtree.weight == 0); + assert(lfs.mtree.root.weight == 0); // we need internals to check this lfs_ssize_t estimate = lfsr_mdir_estimate__(&lfs, &file1.b.o.mdir, -1, -1, @@ -5964,7 +5964,7 @@ code = ''' // create enough files for mroot to split twice lfs_size_t i = 0; - while (lfs.mtree.weight == 0) { + while (lfs.mtree.root.weight == 0) { char name[256]; sprintf(name, "hydroid%03x", i); lfsr_file_t file; @@ -5975,8 +5975,8 @@ code = ''' } i = 0; - lfs_size_t orig = lfs.mtree.weight; - while (lfs.mtree.weight == orig) { + lfs_size_t orig = lfs.mtree.root.weight; + while (lfs.mtree.root.weight == orig) { char name[256]; sprintf(name, "medusa%03x", i); lfsr_file_t file; @@ -6198,7 +6198,7 @@ code = ''' // create enough files for mroot to split twice lfs_size_t i = 0; - while (lfs.mtree.weight == 0) { + while (lfs.mtree.root.weight == 0) { char name[256]; sprintf(name, "hydroid%03x", i); lfsr_file_t file; @@ -6209,8 +6209,8 @@ code = ''' } i = 0; - lfs_size_t orig = lfs.mtree.weight; - while (lfs.mtree.weight == orig) { + lfs_size_t orig = lfs.mtree.root.weight; + while (lfs.mtree.root.weight == orig) { char name[256]; sprintf(name, "polyp%03x", i); lfsr_file_t file; @@ -6222,10 +6222,10 @@ code = ''' // create enough files to both compact and split i = 0; - orig = lfs.mtree.weight; + orig = lfs.mtree.root.weight; while (true) { // we should not have split yet - assert(lfs.mtree.weight == orig); + assert(lfs.mtree.root.weight == orig); // we need internals to check this lfs_ssize_t estimate = lfsr_mdir_estimate__(&lfs, &file2.b.o.mdir, -1, -1, @@ -6482,7 +6482,7 @@ code = ''' assert(!(lfs.flags & LFS_I_MKCONSISTENT)); // which means there shouldn't be that many files left - assert(lfs.mtree.weight <= (2 << lfs.mbits)); + assert(lfs.mtree.root.weight <= (2 << lfs.mbits)); assert(file1.b.o.mdir.rbyd.weight <= 3); assert(file2.b.o.mdir.rbyd.weight <= 3); @@ -6783,7 +6783,7 @@ code = ''' assert(!(lfs.flags & LFS_I_MKCONSISTENT)); // which means there shouldn't be that many files left - assert(lfs.mtree.weight <= (2 << lfs.mbits)); + assert(lfs.mtree.root.weight <= (2 << lfs.mbits)); assert(file1.b.o.mdir.rbyd.weight <= 3); assert(file2.b.o.mdir.rbyd.weight <= 3); @@ -6943,7 +6943,7 @@ code = ''' assert(!(lfs.flags & LFS_I_MKCONSISTENT)); // which means there shouldn't be that many files left - assert(lfs.mtree.weight <= (2 << lfs.mbits)); + assert(lfs.mtree.root.weight <= (2 << lfs.mbits)); assert(file1.b.o.mdir.rbyd.weight <= 3); assert(file2.b.o.mdir.rbyd.weight <= 3); @@ -7112,7 +7112,7 @@ code = ''' assert(!(lfs.flags & LFS_I_MKCONSISTENT)); // which means there shouldn't be that many files left - assert(lfs.mtree.weight <= (2 << lfs.mbits)); + assert(lfs.mtree.root.weight <= (2 << lfs.mbits)); assert(file1.b.o.mdir.rbyd.weight <= 3); assert(file2.b.o.mdir.rbyd.weight <= 3); @@ -7281,7 +7281,7 @@ code = ''' assert(!(lfs.flags & LFS_I_MKCONSISTENT)); // which means there shouldn't be that many files left - assert(lfs.mtree.weight <= (2 << lfs.mbits)); + assert(lfs.mtree.root.weight <= (2 << lfs.mbits)); assert(file1.b.o.mdir.rbyd.weight <= 3); assert(file2.b.o.mdir.rbyd.weight <= 3); @@ -7446,7 +7446,7 @@ code = ''' assert(!(lfs.flags & LFS_I_MKCONSISTENT)); // which means there shouldn't be that many files left - assert(lfs.mtree.weight <= (2 << lfs.mbits)); + assert(lfs.mtree.root.weight <= (2 << lfs.mbits)); assert(file1.b.o.mdir.rbyd.weight <= 3); assert(file2.b.o.mdir.rbyd.weight <= 3);