From 2835b17d141b8cececea4f1b39376e7599e63a6e Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Wed, 2 Aug 2023 14:27:35 -0500 Subject: [PATCH] Attempted to merge the mid's bid and rid into a single integer This didn't really work out as well as I had hoped. There were a few ideas on how to encode the bid/rid tuple without sacrificing the (currently 31-bit) integer limit, but these just introduced too much complexity. Ideas: 1. In theory, as the mdirs increase in size, the quantity of mdirs needed for a given number of files decreases. If we say the number of files fits in an integer of a given size, than we can model the mapping to mdirs and rids roughly as the number of bits in that integer split between the two. Since the block_size is known, the we can find a rather conservative, yet useful, estimate of the upper bound of rids, which ends up being ~16 bytes ((2 alts + 1 null + 1 tag) * 4 bytes). And since our btrees are perfectly balanced, this encoding should only waste 1 or 2 bits due to rounding to rounding and sign encoding for special values. bbbbbbbb bbbbbbbb bbbbbbbr rrrrrrrr '-----------+-----------''----+---' | '-- log2(block_size/32)-bit rid '-------------------- remaining-bit bid Unfortunately, while this works ok on paper, and maximize the use of the bits we have available for the mid, the implementation ended up awkward and difficult to use. We need to either calculate the relatively complciated log2 of the block_size on the fly, or cache the value, and use it to shift the mid around to extract the bid/rid when needed. Unfortunately, perhaps due to the it being easy to use the bid/rid directly, we use and mutate the bid/rid quite a bit. We mutate when updating the mdirs, when decoding grms, when seeking mdirs, etc. If anything, updating the mid in total is rarer than updating the bid/rid component in complicated situations. Note to mention this required access to the lfs config to even begin decoding, complicating the API and making the result less efficient. Initial (unoptimized, and not even tested) code size showed ~+800 bytes. So I decided to scrap this. Maybe it will be worth investigating dynamic rid sizes later, to increase the possible mtree size for a given mid width. Not sure. 2. Probably one of the worst ideas I've had so far, but it would solve the mid encoding problem, is to use some form a floating point to encode the bid/rid pair: .----------. v .+-. bbbbbbbb bbbbbbbb bbbrrrrr rrrrssss '-----------+-------''----+---''-+' | | '-- rid bits | '--------- variable rid '----------------------- variable bid An even worse idea would be to use IEEE floating point here. Yes it would work, and probably work annoyingly well, but we it risk bringing in a lot of standard conforming backbending that we really don't care about. The idea here is to sacrifice some bits to encode the ratio of rid bits to bid bits. The value of this over the using the block_size is that we can decode the bid and rid using all of the bits in the integer alone. Avoiding memory access (and worse debugging) to load any external constants. As a plus, all mids in the system would have the same exponent, simplifying comparisons and other operations. But this is just trying to solve complexity by adding more complexity, so I'm not even going to try implementing it. Still, it's an interesting idea... In the end I've gone with the KISS implementation. Use half-width integers, in this case uint16s, for both the bid and rid: bbbbbbbb bbbbbbbb rrrrrrrr rrrrrrrr '-------+-------' '-------+-------' | '-- 16-bit rid '-------------------- 16-bit bid This suffers from weakened limits around the number of rids in a block and number of mdirs in the mtree, which is unfortunate. Still it is probably worth the tradeoff for the RAM savings and encoding simplicity. If the mdir is reasonably sized, this does probably approach a decent distribution of rids and bids in 32-bits. But for outlier cases with very small and very large mdirs, it risks premature out of bounds errors. To protect against mtree errors, we will probably need an additional configuration option in the form of an mdir limit. Conveniently this would also provide a way to enforce 2-block mode. rid errors, on the other hand, depend on block_size/32, so we may not need another configuration option and can rely on the block_size to determine if the rids can overflow. This is probably worth revisiting in the future. Fortunately, with mdir_limit and block_size configuration options, it should be possible to increase these limits in the future if this mid bid/rid design changes. code stack before: 22126 2136 after: 22326 (+0.9%) 2088 (-2.2%) This code size increase was unexpected. Maybe non-32-bit-aligned integers cost more to load in thumb? Unsure. --- lfs.c | 430 +++++++++++++++-------------- lfs.h | 31 ++- tests/t3_mtree.toml | 639 +++++++++++++++++++++++--------------------- tests/t4_alloc.toml | 21 +- 4 files changed, 591 insertions(+), 530 deletions(-) diff --git a/lfs.c b/lfs.c index 7d7071a6..8a0a8a2f 100644 --- a/lfs.c +++ b/lfs.c @@ -1257,11 +1257,8 @@ typedef struct lfsr_attr { union { // data, either on-disk or in-device lfsr_data_t data; - // a move of all attrs from an rbyd+rid - struct { - const lfsr_rbyd_t *rbyd; - lfs_ssize_t rid; - } move; + // a move of all attrs from an mdir entry + const lfsr_mdir_t *mdir; // a grm update, note this is mutable! we may update // the grm during mdir commits lfsr_grm_t *grm; @@ -1274,11 +1271,11 @@ typedef struct lfsr_attr { #define LFSR_ATTR_DATA(_id, _type, _delta, _data) \ LFSR_ATTR_DATA_(_id, LFSR_TAG_##_type, _delta, _data) -#define LFSR_ATTR_MOVE_(_new_id, _type, _delta, _rbyd, _old_id) \ - ((const lfsr_attr_t){_new_id, _type, _delta, {.move={_rbyd, _old_id}}}) +#define LFSR_ATTR_MOVE_(_new_id, _type, _delta, _mdir) \ + ((const lfsr_attr_t){_new_id, _type, _delta, {.mdir=_mdir}}) -#define LFSR_ATTR_MOVE(_new_id, _type, _delta, _rbyd, _old_id) \ - LFSR_ATTR_MOVE_(_new_id, LFSR_TAG_##_type, _delta, _rbyd, _old_id) +#define LFSR_ATTR_MOVE(_new_id, _type, _delta, _mdir) \ + LFSR_ATTR_MOVE_(_new_id, LFSR_TAG_##_type, _delta, _mdir) #define LFSR_ATTR_GRM_(_new_id, _type, _delta, _grm) \ ((const lfsr_attr_t){_new_id, _type, _delta, {.grm=_grm}}) @@ -1531,6 +1528,9 @@ static lfs_ssize_t lfsr_fcrc_fromdisk(lfs_t *lfs, lfsr_fcrc_t *fcrc, // lfs->mlist = mlist; //} +/// Metadata-id things /// + +#define LFSR_MID(_bid, _rid) ((lfsr_mid_t){_bid, _rid}) /// Global-state things /// @@ -1581,25 +1581,22 @@ static int lfsr_gdelta_xor(lfs_t *lfs, // GRM (global remove) things static inline bool lfsr_grm_hasrm(const lfsr_grm_t *grm) { - return grm->rms[0].rid != -1; + return grm->mids[0].rid != -1; } static inline uint8_t lfsr_grm_count(const lfsr_grm_t *grm) { - return (grm->rms[0].rid != -1) + (grm->rms[1].rid != -1); + return (grm->mids[0].rid != -1) + (grm->mids[1].rid != -1); } -static inline void lfsr_grm_pushrm(lfsr_grm_t *grm, - lfs_size_t mid, lfs_size_t rid) { - LFS_ASSERT(grm->rms[1].rid == -1); - grm->rms[1] = grm->rms[0]; - grm->rms[0].mid = mid; - grm->rms[0].rid = rid; +static inline void lfsr_grm_pushrm(lfsr_grm_t *grm, lfsr_mid_t mid) { + LFS_ASSERT(grm->mids[1].rid == -1); + grm->mids[1] = grm->mids[0]; + grm->mids[0] = mid; } static inline void lfsr_grm_poprm(lfsr_grm_t *grm) { - grm->rms[0] = grm->rms[1]; - grm->rms[1].mid = -1; - grm->rms[1].rid = -1; + grm->mids[0] = grm->mids[1]; + grm->mids[1] = LFSR_MID(-1, -1); } static int lfsr_grm_todisk(lfs_t *lfs, const lfsr_grm_t *grm, @@ -1619,13 +1616,13 @@ static int lfsr_grm_todisk(lfs_t *lfs, const lfsr_grm_t *grm, for (uint8_t i = 0; i < count; i++) { // map mid=-1 (mroot) to mid=0 lfs_ssize_t d_ = lfs_toleb128( - lfs_smax32(grm->rms[i].mid, 0), &buffer[d], 5); + lfs_smax32(grm->mids[i].bid, 0), &buffer[d], 3); if (d_ < 0) { return d_; } d += d_; - d_ = lfs_toleb128(grm->rms[i].rid, &buffer[d], 5); + d_ = lfs_toleb128(grm->mids[i].rid, &buffer[d], 3); if (d_ < 0) { return d_; } @@ -1647,21 +1644,19 @@ static int lfsr_grm_fromdisk(lfs_t *lfs, lfsr_grm_t *grm, d += 1; // clear first - grm->rms[0].mid = -1; - grm->rms[0].rid = -1; - grm->rms[1].mid = -1; - grm->rms[1].rid = -1; + grm->mids[0] = LFSR_MID(-1, -1); + grm->mids[1] = LFSR_MID(-1, -1); LFS_ASSERT(count <= 2); for (uint8_t i = 0; i < count; i++) { - lfs_size_t mid; - lfs_ssize_t d_ = lfs_fromleb128(&mid, &buffer[d], LFSR_GRM_DSIZE-d); + lfs_size_t bid; + lfs_ssize_t d_ = lfs_fromleb128(&bid, &buffer[d], LFSR_GRM_DSIZE-d); if (d_ < 0) { return d_; } d += d_; // TODO should these checks be in lfsr_data_readleb128? - LFS_ASSERT(mid < 0x7fffffff); + LFS_ASSERT(bid <= 0x7fff); lfs_size_t rid; d_ = lfs_fromleb128(&rid, &buffer[d], LFSR_GRM_DSIZE-d); @@ -1670,12 +1665,13 @@ static int lfsr_grm_fromdisk(lfs_t *lfs, lfsr_grm_t *grm, } d += d_; // TODO should these checks be in lfsr_data_readleb128? - LFS_ASSERT(rid < 0x7fffffff); + LFS_ASSERT(rid < 0x7fff); // adjust mid if mtree is inlined - LFS_ASSERT(lfsr_mtree_isinlined(lfs) || mid < lfsr_mtree_weight(lfs)); - grm->rms[i].mid = lfs_smin32(mid, lfsr_mtree_weight(lfs)-1); - grm->rms[i].rid = rid; + LFS_ASSERT(lfsr_mtree_isinlined(lfs) || bid < lfsr_mtree_weight(lfs)); + grm->mids[i] = LFSR_MID( + lfs_smin32(bid, lfsr_mtree_weight(lfs)-1), + rid); } return 0; @@ -2746,13 +2742,15 @@ static int lfsr_rbyd_appendall(lfs_t *lfs, lfsr_rbyd_t *rbyd, while (true) { lfs_ssize_t rid; lfsr_data_t data; - int err = lfsr_rbyd_lookupnext(lfs, attrs[i].d.move.rbyd, - attrs[i].d.move.rid, lfsr_tag_next(tag), + int err = lfsr_rbyd_lookupnext(lfs, + &attrs[i].d.mdir->m.rbyd, + attrs[i].d.mdir->mid.rid, lfsr_tag_next(tag), &rid, &tag, NULL, &data); if (err && err != LFS_ERR_NOENT) { return err; } - if (err == LFS_ERR_NOENT || rid != attrs[i].d.move.rid) { + if (err == LFS_ERR_NOENT + || rid != attrs[i].d.mdir->mid.rid) { break; } @@ -5084,7 +5082,7 @@ static bool lfsr_mdir_isopened(lfs_t *lfs, // actual mdir functions -static int lfsr_mdir_alloc(lfs_t *lfs, lfsr_mdir_t *mdir, lfs_ssize_t mid) { +static int lfsr_mdir_alloc(lfs_t *lfs, lfsr_mdir_t *mdir, lfsr_mid_t mid) { // allocate two blocks lfs_block_t blocks[2]; for (int i = 0; i < 2; i++) { @@ -5127,7 +5125,7 @@ static int lfsr_mdir_alloc(lfs_t *lfs, lfsr_mdir_t *mdir, lfs_ssize_t mid) { } static int lfsr_mdir_fetch(lfs_t *lfs, lfsr_mdir_t *mdir, - lfsr_mptr_t mptr, lfs_ssize_t mid, lfs_ssize_t rid) { + lfsr_mptr_t mptr, lfsr_mid_t mid) { // read both revision counts, try to figure out which block // has the most recent revision uint32_t revs[2] = {0, 0}; @@ -5156,7 +5154,6 @@ static int lfsr_mdir_fetch(lfs_t *lfs, lfsr_mdir_t *mdir, if (!err) { mdir->mid = mid; - mdir->rid = rid; // keep track of other block for compactions mdir->m.redund_block = mptr.blocks[1]; return 0; @@ -5224,16 +5221,14 @@ static inline lfs_size_t lfsr_mtree_weight(lfs_t *lfs) { return lfsr_btree_weight(&lfs->mtree); } -static int lfsr_mtree_lookup(lfs_t *lfs, lfs_ssize_t mid, lfs_ssize_t rid, - lfsr_mdir_t *mdir_) { +static int lfsr_mtree_lookup(lfs_t *lfs, lfsr_mid_t mid, lfsr_mdir_t *mdir_) { // TODO should we really allow -1=>mroot lookup? - LFS_ASSERT(mid >= -1); - LFS_ASSERT(mid < (lfs_ssize_t)lfsr_mtree_weight(lfs)); + LFS_ASSERT(mid.bid >= -1); + LFS_ASSERT(mid.bid < (lfs_ssize_t)lfsr_mtree_weight(lfs)); // looking up mroot? - if (mid < 0) { + if (mid.bid < 0) { mdir_->mid = mid; - mdir_->rid = rid; mdir_->m = lfs->mroot.m; return 0; @@ -5241,7 +5236,7 @@ static int lfsr_mtree_lookup(lfs_t *lfs, lfs_ssize_t mid, lfs_ssize_t rid, } else { lfsr_tag_t tag; lfsr_data_t data; - int err = lfsr_btree_lookup(lfs, &lfs->mtree, mid, + int err = lfsr_btree_lookup(lfs, &lfs->mtree, mid.bid, &tag, NULL, &data); if (err) { return err; @@ -5256,7 +5251,7 @@ static int lfsr_mtree_lookup(lfs_t *lfs, lfs_ssize_t mid, lfs_ssize_t rid, } // fetch mdir - return lfsr_mdir_fetch(lfs, mdir_, mptr, mid, rid); + return lfsr_mdir_fetch(lfs, mdir_, mptr, mid); } } @@ -5272,7 +5267,7 @@ static int lfsr_mtree_parent(lfs_t *lfs, lfsr_mptr_t mchild, lfsr_mdir_t mdir; while (true) { // fetch next possible superblock - int err = lfsr_mdir_fetch(lfs, &mdir, mptr, -1, -1); + int err = lfsr_mdir_fetch(lfs, &mdir, mptr, LFSR_MID(-1, -1)); if (err) { return err; } @@ -5302,28 +5297,28 @@ static int lfsr_mtree_parent(lfs_t *lfs, lfsr_mptr_t mchild, static int lfsr_mtree_seek(lfs_t *lfs, lfsr_mdir_t *mdir, lfs_off_t off) { // calculate new rid - lfs_ssize_t rid_ = mdir->rid + off; + lfs_ssize_t rid_ = mdir->mid.rid + off; // lookup mdirs until we find our rid, we need to do this because // we don't know how many rids are in each mdir until we fetch while (rid_ >= (lfs_ssize_t)mdir->m.rbyd.weight) { - lfs_ssize_t mid_ = mdir->mid + 1; + lfsr_smbid_t bid_ = mdir->mid.bid + 1; // end of mtree? - if (mid_ >= (lfs_ssize_t)lfsr_mtree_weight(lfs)) { + if (bid_ >= (lfs_ssize_t)lfsr_mtree_weight(lfs)) { // TODO is this needed? // make sure to update rid even if we error so seek will always // return noent after the first noent - mdir->rid = rid_; + mdir->mid.rid = rid_; return LFS_ERR_NOENT; } rid_ -= mdir->m.rbyd.weight; - int err = lfsr_mtree_lookup(lfs, mid_, rid_, mdir); + int err = lfsr_mtree_lookup(lfs, LFSR_MID(bid_, rid_), mdir); if (err) { return err; } } - mdir->rid = rid_; + mdir->mid.rid = rid_; return 0; } @@ -5360,8 +5355,8 @@ static int lfsr_mdir_compact_(lfs_t *lfs, lfsr_mdir_t *mdir_, // TODO rev things && (rev + 1) % lfs->cfg->block_cycles == 0))) { // allocate a new mdir for relocation - err = lfsr_mdir_alloc(lfs, mdir_, - (reason >= 0 ? reason : mdir_->mid)); + err = lfsr_mdir_alloc(lfs, mdir_, LFSR_MID( + (reason >= 0 ? reason : mdir->mid.bid), -1)); if (err) { return err; } @@ -5443,7 +5438,7 @@ static int lfsr_mdir_compact_(lfs_t *lfs, lfsr_mdir_t *mdir_, // drop commit if weight goes to zero - if (mdir_->mid >= 0 && mdir_->m.rbyd.weight == 0) { + if (mdir_->mid.bid >= 0 && mdir_->m.rbyd.weight == 0) { // TODO should we just make our pcache not assert? // drop our pcache, we're not going to complete this commit lfs_cache_zero(lfs, &lfs->pcache); @@ -5455,7 +5450,7 @@ static int lfsr_mdir_compact_(lfs_t *lfs, lfsr_mdir_t *mdir_, // // this pushes gstate up into the mroot when relocating, and // helps avoid corner case issues when splitting/dropping - if (mdir_->mid == -1 || lfsr_mdir_cmp(mdir_, mdir) == 0) { + if (mdir_->mid.bid == -1 || lfsr_mdir_cmp(mdir_, mdir) == 0) { err = lfsr_rbyd_appendgdelta(lfs, &mdir_->m.rbyd); if (err) { LFS_ASSERT(err != LFS_ERR_RANGE); @@ -5477,7 +5472,7 @@ static int lfsr_mdir_compact_(lfs_t *lfs, lfsr_mdir_t *mdir_, // TODO avoid duplicate conditions somehow? // success? gstate is committed - if (mdir_->mid == -1 || lfsr_mdir_cmp(mdir_, mdir) == 0) { + if (mdir_->mid.bid == -1 || lfsr_mdir_cmp(mdir_, mdir) == 0) { lfsr_fs_flushgdelta(lfs); } } @@ -5506,7 +5501,7 @@ static int lfsr_mdir_commit_(lfs_t *lfs, lfsr_mdir_t *mdir, } // drop commit if weight goes to zero - if (mdir_.mid >= 0 && mdir_.m.rbyd.weight == 0) { + if (mdir_.mid.bid >= 0 && mdir_.m.rbyd.weight == 0) { // TODO move this up into lfsr_mdir_commit? // consume gstate so we don't lose any info int err = lfsr_fs_consumegdelta(lfs, mdir); @@ -5582,7 +5577,7 @@ compact:; static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, const lfsr_attr_t *attrs, lfs_size_t attr_count) { LFS_ASSERT(!lfsr_mdir_isdropped(mdir)); - LFS_ASSERT(mdir->mid == -1 || mdir->m.rbyd.weight > 0); + LFS_ASSERT(mdir->mid.bid == -1 || mdir->m.rbyd.weight > 0); // parse out any pending gstate, these will get automatically xored // with on-disk gdeltas in lower-level functions @@ -5620,8 +5615,8 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, // // TODO wait, do we need to update lfs->mroot and mdir eagerly // for the same reason? - lfsr_mdir_t mroot_ = (mdir->mid == -1 ? mdir_ : lfs->mroot); - lfsr_mdir_t msibling_ = {.m.rbyd.weight=0}; + lfsr_mdir_t mroot_ = (mdir->mid.bid == -1 ? mdir_ : lfs->mroot); + lfsr_mdir_t msibling_ = {.m.rbyd.trunk=0}; lfsr_btree_t mtree_ = lfs->mtree; bool dirtymroot = false; bool dirtymtree = false; @@ -5630,7 +5625,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, if (err == LFS_ERR_RANGE) { // if we're the mroot, create a new mtree, assume the upper layers // will take care of grafting our mtree into the mroot as needed - if (mdir->mid == -1) { + if (mdir->mid.bid == -1) { // Create a null entry in our btree first. Don't worry! Thanks // to inlining this doesn't allocate anything yet. // @@ -5662,8 +5657,8 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, } // compact into new mdir tags < split_id - lfs_ssize_t mid = lfs_smax32(mdir->mid, 0); - int err = lfsr_mdir_compact_(lfs, &mdir_, mid, 0, split_id, + lfsr_smbid_t mbid = lfs_smax32(mdir->mid.bid, 0); + int err = lfsr_mdir_compact_(lfs, &mdir_, mbid, 0, split_id, mdir, attrs, attr_count, NULL, 0); if (err) { LFS_ASSERT(err != LFS_ERR_RANGE); @@ -5671,17 +5666,17 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, } // compact into new mdir tags >= split_id - err = lfsr_mdir_compact_(lfs, &msibling_, mid, split_id, -1, + err = lfsr_mdir_compact_(lfs, &msibling_, mbid, split_id, -1, mdir, attrs, attr_count, NULL, 0); if (err) { LFS_ASSERT(err != LFS_ERR_RANGE); return err; } - LFS_DEBUG("Splitting mdir %"PRId32" 0x{%"PRIx32",%"PRIx32"} " + LFS_DEBUG("Splitting mdir %"PRId16" 0x{%"PRIx32",%"PRIx32"} " "-> 0x{%"PRIx32",%"PRIx32"}" ", 0x{%"PRIx32",%"PRIx32"}", - mdir->mid, + mdir->mid.bid, mdir->m.rbyd.block, mdir->m.redund_block, mdir_.m.rbyd.block, mdir_.m.redund_block, msibling_.m.rbyd.block, msibling_.m.redund_block); @@ -5691,26 +5686,26 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, // both siblings reduced to zero if (mdir_.m.rbyd.weight == 0 && msibling_.m.rbyd.weight == 0) { - LFS_DEBUG("Dropping mdir %"PRId32" 0x{%"PRIx32",%"PRIx32"}", - mdir_.mid, + LFS_DEBUG("Dropping mdir %"PRId16" 0x{%"PRIx32",%"PRIx32"}", + mdir_.mid.bid, mdir_.m.rbyd.block, mdir_.m.redund_block); - LFS_DEBUG("Dropping mdir %"PRId32" 0x{%"PRIx32",%"PRIx32"}", - msibling_.mid, + LFS_DEBUG("Dropping mdir %"PRId16" 0x{%"PRIx32",%"PRIx32"}", + msibling_.mid.bid, msibling_.m.rbyd.block, msibling_.m.redund_block); // mark as dropped mdir_.m.rbyd.trunk = 0; msibling_.m.rbyd.trunk = 0; // update our mtree - int err = lfsr_btree_pop(lfs, &mtree_, mid); + int err = lfsr_btree_pop(lfs, &mtree_, mbid); if (err) { return err; } // one sibling reduced to zero } else if (mdir_.m.rbyd.weight == 0) { - LFS_DEBUG("Dropping mdir %"PRId32" 0x{%"PRIx32",%"PRIx32"}", - mdir_.mid, + LFS_DEBUG("Dropping mdir %"PRId16" 0x{%"PRIx32",%"PRIx32"}", + mdir_.mid.bid, mdir_.m.rbyd.block, mdir_.m.redund_block); // mark as dropped @@ -5723,7 +5718,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, return d; } - int err = lfsr_btree_set(lfs, &mtree_, mid, LFSR_TAG_MDIR, 1, + int err = lfsr_btree_set(lfs, &mtree_, mbid, LFSR_TAG_MDIR, 1, LFSR_DATA_BUF(buf, d)); if (err) { return err; @@ -5731,8 +5726,8 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, // other sibling reduced to zero } else if (msibling_.m.rbyd.weight == 0) { - LFS_DEBUG("Dropping mdir %"PRId32" 0x{%"PRIx32",%"PRIx32"}", - msibling_.mid, + LFS_DEBUG("Dropping mdir %"PRId16" 0x{%"PRIx32",%"PRIx32"}", + msibling_.mid.bid, msibling_.m.rbyd.block, msibling_.m.redund_block); // mark as dropped @@ -5745,7 +5740,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, return d; } - int err = lfsr_btree_set(lfs, &mtree_, mid, LFSR_TAG_MDIR, 1, + int err = lfsr_btree_set(lfs, &mtree_, mbid, LFSR_TAG_MDIR, 1, LFSR_DATA_BUF(buf, d)); if (err) { return err; @@ -5755,7 +5750,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, } else { // adjust our sibling's mid, do this here in case other sibling // was dropped - msibling_.mid += 1; + msibling_.mid.bid += 1; // update out mtree @@ -5783,7 +5778,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, return d2; } - err = lfsr_btree_split(lfs, &mtree_, mid, + err = lfsr_btree_split(lfs, &mtree_, mbid, (lfsr_tag_suptype(stag) == LFSR_TAG_NAME ? sdata : LFSR_DATA_NULL), @@ -5797,16 +5792,16 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, dirtymtree = true; // mdir reduced to zero? need to drop? - } else if (mdir->mid != -1 && mdir_.m.rbyd.weight == 0) { - LFS_DEBUG("Dropping mdir %"PRId32" 0x{%"PRIx32",%"PRIx32"}", - mdir->mid, + } else if (mdir->mid.bid != -1 && mdir_.m.rbyd.weight == 0) { + LFS_DEBUG("Dropping mdir %"PRId16" 0x{%"PRIx32",%"PRIx32"}", + mdir->mid.bid, mdir->m.rbyd.block, mdir->m.redund_block); // mark as dropped mdir_.m.rbyd.trunk = 0; // update our mtree - int err = lfsr_btree_pop(lfs, &mtree_, mdir->mid); + int err = lfsr_btree_pop(lfs, &mtree_, mdir->mid.bid); if (err) { return err; } @@ -5816,16 +5811,16 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, // need to relocate? } else if (lfsr_mdir_cmp(mdir, &mdir_) != 0) { // relocate mroot - if (mdir->mid == -1) { + if (mdir->mid.bid == -1) { // if we're relocating our root, just mark the root as dirty // and let our dirtymroot code handle this dirtymroot = true; // relocate a normal mdir } else { - LFS_DEBUG("Relocating mdir %"PRId32" 0x{%"PRIx32",%"PRIx32"} " + LFS_DEBUG("Relocating mdir %"PRId16" 0x{%"PRIx32",%"PRIx32"} " "-> 0x{%"PRIx32",%"PRIx32"}", - mdir->mid, + mdir->mid.bid, mdir->m.rbyd.block, mdir->m.redund_block, mdir_.m.rbyd.block, mdir_.m.redund_block); @@ -5836,7 +5831,8 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, return d; } - int err = lfsr_btree_set(lfs, &mtree_, mdir->mid, LFSR_TAG_MDIR, 1, + int err = lfsr_btree_set(lfs, &mtree_, + mdir->mid.bid, LFSR_TAG_MDIR, 1, LFSR_DATA_BUF(buf, d)); if (err) { return err; @@ -5874,32 +5870,32 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, // fix our grm for (uint8_t j = 0; j < 2; j++) { - if (grm->rms[j].mid == mdir->mid) { - LFS_ASSERT(grm->rms[j].rid + if (grm->mids[j].bid == mdir->mid.bid) { + LFS_ASSERT(grm->mids[j].rid <= (lfs_ssize_t)mdir->m.rbyd.weight); // TODO do we need this if we allow mid=0 => mroot when // inlined? // update mid if we are uninlining - grm->rms[j].mid = lfs_smax32(grm->rms[j].mid, 0); + grm->mids[j].bid = lfs_smax32(grm->mids[j].bid, 0); - if (grm->rms[j].rid >= (lfs_ssize_t)mdir_.m.rbyd.weight) { - grm->rms[j].mid += 1; - grm->rms[j].rid -= mdir_.m.rbyd.weight; + if (grm->mids[j].rid >= (lfs_ssize_t)mdir_.m.rbyd.weight) { + grm->mids[j].bid += 1; + grm->mids[j].rid -= mdir_.m.rbyd.weight; } // update mid if we had a split or drop - } else if (grm->rms[j].mid > mdir->mid + } else if (grm->mids[j].bid > mdir->mid.bid && lfsr_btree_weight(&mtree_) != lfsr_mtree_weight(lfs)) { - grm->rms[j].mid += lfsr_btree_weight(&mtree_) + grm->mids[j].bid += lfsr_btree_weight(&mtree_) - lfsr_mtree_weight(lfs); } // TODO this is a big cludge, support for mid=0 when inlined? // adjust mid if mtree is inlined if (lfsr_btree_weight(&mtree_) == 0) { - LFS_ASSERT(grm->rms[j].mid <= 0); - if (grm->rms[j].mid == 0) { - grm->rms[j].mid = -1; + LFS_ASSERT(grm->mids[j].bid <= 0); + if (grm->mids[j].bid == 0) { + grm->mids[j].bid = -1; } } } @@ -5920,7 +5916,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, // need to update mtree? if (dirtymtree) { - LFS_ASSERT(mdir_.mid != -1); + LFS_ASSERT(mdir_.mid.bid != -1); // commit mtree lfsr_tag_t tag; @@ -6064,10 +6060,11 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, for (lfs_size_t i = 0; i < attr_count; i++) { // TODO clean this up a bit? // adjust opened mdirs? - if (opened_mdir->mid == mdir->mid - && opened_mdir->rid >= attrs[i].id) { + if (opened_mdir->mid.bid == mdir->mid.bid + && opened_mdir->mid.rid >= attrs[i].id) { // removed? - if (opened_mdir->rid + attrs[i].delta < attrs[i].id) { + if (opened_mdir->mid.rid + < attrs[i].id - attrs[i].delta) { // normal mdirs mark as dropped if (j == 0) { opened_mdir->m.rbyd.trunk = 0; @@ -6075,9 +6072,9 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, } // for dir's second mdir (the position mdir), move // on to the next rid - opened_mdir->rid = attrs[i].id; + opened_mdir->mid.rid = attrs[i].id; } else { - opened_mdir->rid += attrs[i].delta; + opened_mdir->mid.rid += attrs[i].delta; // adjust dir position? if (type == LFS_TYPE_DIR && j == 0) { ((lfsr_dir_t*)opened)->pos -= attrs[i].delta; @@ -6085,7 +6082,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, ((lfsr_dir_t*)opened)->pos += attrs[i].delta; } } - } else if (opened_mdir->mid > mdir->mid) { + } else if (opened_mdir->mid.bid > mdir->mid.bid) { // adjust dir position? if (type == LFS_TYPE_DIR && j == 0) { ((lfsr_dir_t*)opened)->pos -= attrs[i].delta; @@ -6096,21 +6093,21 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, } // update any opened mdirs if we had a split or drop - if (opened_mdir->mid == mdir->mid) { + if (opened_mdir->mid.bid == mdir->mid.bid) { if (!lfsr_mdir_isdropped(&msibling_) - && opened_mdir->rid + && opened_mdir->mid.rid >= (lfs_ssize_t)mdir_.m.rbyd.weight) { LFS_ASSERT(lfsr_btree_weight(&mtree_) != lfsr_mtree_weight(lfs)); - opened_mdir->mid = msibling_.mid; - opened_mdir->rid -= mdir_.m.rbyd.weight; + opened_mdir->mid.bid = msibling_.mid.bid; + opened_mdir->mid.rid -= mdir_.m.rbyd.weight; opened_mdir->m = msibling_.m; } else { - opened_mdir->mid = mdir_.mid; + opened_mdir->mid.bid = mdir_.mid.bid; opened_mdir->m = mdir_.m; } - } else if (opened_mdir->mid > mdir->mid) { - opened_mdir->mid += lfsr_btree_weight(&mtree_) + } else if (opened_mdir->mid.bid > mdir->mid.bid) { + opened_mdir->mid.bid += lfsr_btree_weight(&mtree_) - lfsr_mtree_weight(lfs); } } @@ -6119,14 +6116,14 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, } // update mdir to follow requested rid - LFS_ASSERT(mdir->rid <= (lfs_ssize_t)mdir->m.rbyd.weight); - if (mdir->mid < 0 && mdir->rid < 0) { + LFS_ASSERT(mdir->mid.rid <= (lfs_ssize_t)mdir->m.rbyd.weight); + if (mdir->mid.bid == -1 && mdir->mid.rid == -1) { mdir->m = mroot_.m; } else if (!lfsr_mdir_isdropped(&msibling_) - && mdir->rid >= (lfs_ssize_t)mdir_.m.rbyd.weight) { + && mdir->mid.rid >= (lfs_ssize_t)mdir_.m.rbyd.weight) { LFS_ASSERT(lfsr_btree_weight(&mtree_) != lfsr_mtree_weight(lfs)); - mdir->mid = msibling_.mid; - mdir->rid -= mdir_.m.rbyd.weight; + mdir->mid.bid = msibling_.mid.bid; + mdir->mid.rid -= mdir_.m.rbyd.weight; mdir->m = msibling_.m; } else { mdir->m = mdir_.m; @@ -6170,12 +6167,12 @@ static int lfsr_mtree_dnamelookup(lfs_t *lfs, // lookup dname in actual mtree } else { - lfs_size_t mid; + lfs_size_t bid; lfsr_tag_t tag; lfsr_data_t data; int err = lfsr_btree_dnamelookup(lfs, &lfs->mtree, did, name, name_size, - &mid, &tag, NULL, &data); + &bid, &tag, NULL, &data); if (err) { return err; } @@ -6189,20 +6186,25 @@ static int lfsr_mtree_dnamelookup(lfs_t *lfs, } // fetch mdir - err = lfsr_mdir_fetch(lfs, &mdir, mptr, mid, -1); + err = lfsr_mdir_fetch(lfs, &mdir, mptr, LFSR_MID(bid, -1)); if (err) { return err; } } + // and finally lookup dname in our mdir + lfs_ssize_t rid; + int err = lfsr_mdir_dnamelookup(lfs, &mdir, + did, name, name_size, + &rid, tag_, data_); + + // update mdir weith best place to insert even if we fail + mdir.mid.rid = rid; if (mdir_) { *mdir_ = mdir; } - // and finally lookup dname in our mdir - return lfsr_mdir_dnamelookup(lfs, &mdir, - did, name, name_size, - (mdir_ ? &mdir_->rid : NULL), tag_, data_); + return err; } @@ -6221,7 +6223,7 @@ static int lfsr_mtree_pathlookup(lfs_t *lfs, const char *path, lfsr_mdir_t *mdir_, lfsr_tag_t *tag_, lfs_size_t *did_, const char **name_, lfs_size_t *name_size_) { // setup root - lfsr_mdir_t mdir = {.rid=-1}; + lfsr_mdir_t mdir = {.mid.rid=-1}; lfsr_tag_t tag = LFSR_TAG_DIR; lfs_size_t did = LFSR_DID_ROOT; @@ -6275,7 +6277,7 @@ static int lfsr_mtree_pathlookup(lfs_t *lfs, const char *path, if (name[0] == '\0') { // generally we don't allow operations that change our root, // report root as inval, but let upper layers intercept this - if (mdir.rid == -1) { + if (mdir.mid.rid == -1) { return LFS_ERR_INVAL; } return 0; @@ -6287,9 +6289,9 @@ static int lfsr_mtree_pathlookup(lfs_t *lfs, const char *path, } // read the next did from the mdir if this is not the root - if (mdir.rid != -1) { + if (mdir.mid.rid != -1) { lfsr_data_t data; - int err = lfsr_mdir_lookup(lfs, &mdir, mdir.rid, LFSR_TAG_DID, + int err = lfsr_mdir_lookup(lfs, &mdir, mdir.mid.rid, LFSR_TAG_DID, NULL, &data); if (err) { return err; @@ -6368,7 +6370,7 @@ enum { static int lfsr_mtree_traversal_next(lfs_t *lfs, lfsr_mtree_traversal_t *traversal, - lfs_size_t *mid_, lfsr_tag_t *tag_, lfsr_data_t *data_) { + lfsr_mid_t *mid_, lfsr_tag_t *tag_, lfsr_data_t *data_) { // new traversal? start with 0x{0,1} // // note we make sure to include fake mroots! @@ -6376,13 +6378,13 @@ static int lfsr_mtree_traversal_next(lfs_t *lfs, if (traversal->mdir.m.rbyd.trunk == 0) { // fetch the first mroot 0x{0,1} int err = lfsr_mdir_fetch(lfs, &traversal->mdir, - LFSR_MPTR_MROOTANCHOR, -1, -1); + LFSR_MPTR_MROOTANCHOR, LFSR_MID(-1, -1)); if (err) { return err; } if (mid_) { - *mid_ = -1; + *mid_ = LFSR_MID(-1, -1); } if (tag_) { *tag_ = LFSR_TAG_MDIR; @@ -6393,7 +6395,7 @@ static int lfsr_mtree_traversal_next(lfs_t *lfs, goto cycle_detect; // check for mroot/mtree/mdir - } else if (traversal->mdir.mid == -1) { + } else if (traversal->mdir.mid.bid == -1) { // lookup mroot, if we find one this is a fake mroot lfsr_tag_t tag; lfsr_data_t data; @@ -6412,13 +6414,14 @@ static int lfsr_mtree_traversal_next(lfs_t *lfs, return d; } - int err = lfsr_mdir_fetch(lfs, &traversal->mdir, mptr, -1, -1); + int err = lfsr_mdir_fetch(lfs, &traversal->mdir, + mptr, LFSR_MID(-1, -1)); if (err) { return err; } if (mid_) { - *mid_ = -1; + *mid_ = LFSR_MID(-1, -1); } if (tag_) { *tag_ = LFSR_TAG_MDIR; @@ -6457,12 +6460,12 @@ static int lfsr_mtree_traversal_next(lfs_t *lfs, } // traverse through the mtree - lfs_size_t mid; + lfs_size_t bid; lfsr_tag_t tag; lfsr_data_t data; int err = lfsr_btree_traversal_next( lfs, &lfs->mtree, &traversal->mtraversal, - &mid, &tag, NULL, &data); + &bid, &tag, NULL, &data); if (err) { return err; } @@ -6509,10 +6512,10 @@ static int lfsr_mtree_traversal_next(lfs_t *lfs, // still update our mdir mid so we don't get stuck in a loop // traversing mroots - traversal->mdir.mid = mid; + traversal->mdir.mid.bid = bid; if (mid_) { - *mid_ = mid; + *mid_ = LFSR_MID(bid, -1); } if (tag_) { *tag_ = tag; @@ -6530,13 +6533,14 @@ static int lfsr_mtree_traversal_next(lfs_t *lfs, return d; } - int err = lfsr_mdir_fetch(lfs, &traversal->mdir, mptr, mid, -1); + int err = lfsr_mdir_fetch(lfs, &traversal->mdir, + mptr, LFSR_MID(bid, -1)); if (err) { return err; } if (mid_) { - *mid_ = mid; + *mid_ = LFSR_MID(bid, -1); } if (tag_) { *tag_ = tag; @@ -6590,12 +6594,13 @@ cycle_detect:; // - 32-bit block_size => 5 byte leb128 (worst case) // - 32-bit block_count => 5 byte leb128 (worst case) // - 7-bit utag_limit => 1 byte leb128 (worst case) +// - 16-bit mtree_limit => 3 byte leb128 (worst case) // - 32-bit attr_limit => 5 byte leb128 (worst case) // - 32-bit name_limit => 5 byte leb128 (worst case) // - 32-bit file_limit => 5 byte leb128 (worst case) -// => 30 bytes total +// => 33 bytes total // -#define LFSR_SUPERCONFIG_DSIZE (1+1+1+1+5+5+1+5+5+5) +#define LFSR_SUPERCONFIG_DSIZE (1+1+1+1+5+5+1+3+5+5+5) static lfs_ssize_t lfsr_superconfig_todisk(lfs_t *lfs, uint8_t buffer[static LFSR_SUPERCONFIG_DSIZE]) { @@ -6632,6 +6637,13 @@ static lfs_ssize_t lfsr_superconfig_todisk(lfs_t *lfs, buffer[d] = 0x7f; d += 1; + // on-disk mtree limit + d_ = lfs_toleb128(0x7fff, &buffer[d], 3); + if (d_ < 0) { + return d_; + } + d += d_; + // on-disk attr limit d_ = lfs_toleb128(0x7fffffff, &buffer[d], 5); if (d_ < 0) { @@ -6695,7 +6707,7 @@ static int lfsr_mountinited(lfs_t *lfs) { lfsr_mdir_t *mdir = (lfsr_mdir_t*)data.buf.buffer; // found an mroot? - if (mdir->mid == -1) { + if (mdir->mid.bid == -1) { // has magic string? lfsr_data_t data; err = lfsr_mdir_lookup(lfs, mdir, -1, LFSR_TAG_SUPERMAGIC, @@ -6871,6 +6883,28 @@ static int lfsr_mountinited(lfs_t *lfs) { return LFS_ERR_INVAL; } + // check the on-disk mtree limit + // TODO actually use this + uint32_t mtree_limit; + d_ = lfsr_data_readleb128(lfs, data, d, &mtree_limit); + // treat any leb128 overflows as out-of-range values + if (d_ < 0 && d_ != LFS_ERR_CORRUPT) { + return d_; + } + if (d_ != LFS_ERR_CORRUPT) { + d += d_; + } + + if (d_ == LFS_ERR_CORRUPT || mtree_limit != 0x7fff) { + LFS_ERROR("Incompatible mdir limit 0x%"PRIx32 + " (> 0x%"PRIx32")", + (d_ == LFS_ERR_CORRUPT + ? (uint32_t)-1 + : mtree_limit), + 0x7fff); + return LFS_ERR_INVAL; + } + // check the on-disk attr limit // TODO actually use this uint32_t attr_limit; @@ -6959,11 +6993,11 @@ static int lfsr_mountinited(lfs_t *lfs) { } if (lfsr_grm_hasrm(&lfs->grm)) { - LFS_DEBUG("Found pending grm %"PRId32".%"PRId32" %"PRId32".%"PRId32, - lfs->grm.rms[0].mid, - lfs->grm.rms[0].rid, - lfs->grm.rms[1].mid, - lfs->grm.rms[1].rid); + LFS_DEBUG("Found pending grm %"PRId16".%"PRId16" %"PRId16".%"PRId16, + lfs->grm.mids[0].bid, + lfs->grm.mids[0].rid, + lfs->grm.mids[1].bid, + lfs->grm.mids[1].rid); } return 0; @@ -7189,7 +7223,7 @@ int lfsr_mkdir(lfs_t *lfs, const char *path) { err = lfsr_mtree_pathlookup(lfs, path, &parent.mdir, NULL, &parent_did, &name, &name_size); - if (err && (err != LFS_ERR_NOENT || parent.mdir.rid == -1)) { + if (err && (err != LFS_ERR_NOENT || parent.mdir.mid.rid == -1)) { return err; } @@ -7258,7 +7292,7 @@ int lfsr_mkdir(lfs_t *lfs, const char *path) { // parent's mdir/rid. We can catch this by tracking our parent // as "opened" temporarily // TODO is this the best workaround for rid update issues? - parent.mdir.rid -= 1; + parent.mdir.mid.rid -= 1; lfsr_mdir_addopened(lfs, LFS_TYPE_REG, &parent); // Conveniently, we just found where our dstart should go. The dstart @@ -7268,26 +7302,26 @@ int lfsr_mkdir(lfs_t *lfs, const char *path) { // lose power before writing the entry in our parent // err = lfsr_mdir_commit(lfs, &mdir, LFSR_ATTRS( - LFSR_ATTR_DNAME(mdir.rid, DSTART, +1, did, NULL, 0), - LFSR_ATTR_GRM(-1, GRM, 0, &((lfsr_grm_t){.rms={ - {.mid=mdir.mid, .rid=mdir.rid}, - {.mid=-1, .rid=-1}}})))); + LFSR_ATTR_DNAME(mdir.mid.rid, DSTART, +1, did, NULL, 0), + LFSR_ATTR_GRM(-1, GRM, 0, &((lfsr_grm_t){{ + mdir.mid, + LFSR_MID(-1, -1)}})))); if (err) { goto failed_with_parent; } lfsr_mdir_removeopened(lfs, LFS_TYPE_REG, &parent); - parent.mdir.rid += 1; + parent.mdir.mid.rid += 1; // commit our new directory into our parent, zeroing out our grm // in the process err = lfsr_mdir_commit(lfs, &parent.mdir, LFSR_ATTRS( - LFSR_ATTR_DNAME(parent.mdir.rid, DIR, +1, + LFSR_ATTR_DNAME(parent.mdir.mid.rid, DIR, +1, parent_did, name, name_size), - LFSR_ATTR_LEB128(parent.mdir.rid, DID, 0, did), - LFSR_ATTR_GRM(-1, GRM, 0, &((lfsr_grm_t){.rms={ - {.mid=-1, .rid=-1}, - {.mid=-1, .rid=-1}}})))); + LFSR_ATTR_LEB128(parent.mdir.mid.rid, DID, 0, did), + LFSR_ATTR_GRM(-1, GRM, 0, &((lfsr_grm_t){{ + LFSR_MID(-1, -1), + LFSR_MID(-1, -1)}})))); if (err) { return err; } @@ -7322,7 +7356,7 @@ int lfsr_remove(lfs_t *lfs, const char *path) { if (tag == LFSR_TAG_DIR) { // first lets figure out the did lfsr_data_t data; - int err = lfsr_mdir_lookup(lfs, &mdir, mdir.rid, LFSR_TAG_DID, + int err = lfsr_mdir_lookup(lfs, &mdir, mdir.mid.rid, LFSR_TAG_DID, NULL, &data); if (err) { return err; @@ -7344,7 +7378,7 @@ int lfsr_remove(lfs_t *lfs, const char *path) { } // create a grm to remove the dstart entry - lfsr_grm_pushrm(&grm, mdir_.mid, mdir_.rid); + lfsr_grm_pushrm(&grm, mdir_.mid); // check that the directory is empty err = lfsr_mtree_seek(lfs, &mdir_, 1); @@ -7354,7 +7388,8 @@ int lfsr_remove(lfs_t *lfs, const char *path) { if (err != LFS_ERR_NOENT) { lfsr_tag_t tag_; - err = lfsr_mdir_lookup(lfs, &mdir_, mdir_.rid, LFSR_TAG_WIDENAME, + err = lfsr_mdir_lookup(lfs, &mdir_, + mdir_.mid.rid, LFSR_TAG_WIDENAME, &tag_, NULL); if (err) { return err; @@ -7366,14 +7401,15 @@ int lfsr_remove(lfs_t *lfs, const char *path) { } // adjust rid if grm is on the same mdir as our dir - if (grm.rms[0].mid == mdir.mid && grm.rms[0].rid > mdir.rid) { - grm.rms[0].rid -= 1; + if (grm.mids[0].bid == mdir.mid.bid + && grm.mids[0].rid > mdir.mid.rid) { + grm.mids[0].rid -= 1; } } // remove the metadata entry err = lfsr_mdir_commit(lfs, &mdir, LFSR_ATTRS( - LFSR_ATTR(mdir.rid, UNR, -1, NULL, 0), + LFSR_ATTR(mdir.mid.rid, UNR, -1, NULL, 0), LFSR_ATTR_GRM(-1, GRM, 0, &grm))); if (err) { return err; @@ -7403,7 +7439,7 @@ int lfsr_rename(lfs_t *lfs, const char *old_path, const char *new_path) { // mark old entry for removal with a grm lfsr_grm_t grm = lfs->grm; - lfsr_grm_pushrm(&grm, old_mdir.mid, old_mdir.rid); + lfsr_grm_pushrm(&grm, old_mdir.mid); // lookup new entry lfsr_mdir_t new_mdir; @@ -7414,7 +7450,7 @@ int lfsr_rename(lfs_t *lfs, const char *old_path, const char *new_path) { err = lfsr_mtree_pathlookup(lfs, new_path, &new_mdir, &new_tag, &new_did, &new_name, &new_name_size); - if (err && (err != LFS_ERR_NOENT || new_mdir.rid == -1)) { + if (err && (err != LFS_ERR_NOENT || new_mdir.mid.rid == -1)) { return err; } bool exists = (err != LFS_ERR_NOENT); @@ -7427,8 +7463,9 @@ int lfsr_rename(lfs_t *lfs, const char *old_path, const char *new_path) { } // adjust old rid if grm is on the same mdir as new rid - if (grm.rms[0].mid == new_mdir.mid && grm.rms[0].rid >= new_mdir.rid) { - grm.rms[0].rid += 1; + if (grm.mids[0].bid == new_mdir.mid.bid + && grm.mids[0].rid >= new_mdir.mid.rid) { + grm.mids[0].rid += 1; } } else { @@ -7439,7 +7476,8 @@ int lfsr_rename(lfs_t *lfs, const char *old_path, const char *new_path) { // TODO is it? is this check necessary? // renaming to ourself is a noop - if (old_mdir.mid == new_mdir.mid && old_mdir.rid == new_mdir.rid) { + if (old_mdir.mid.bid == new_mdir.mid.bid + && old_mdir.mid.rid == new_mdir.mid.rid) { return 0; } @@ -7450,7 +7488,7 @@ int lfsr_rename(lfs_t *lfs, const char *old_path, const char *new_path) { // first lets figure out the did lfsr_data_t data; int err = lfsr_mdir_lookup(lfs, &new_mdir, - new_mdir.rid, LFSR_TAG_DID, + new_mdir.mid.rid, LFSR_TAG_DID, NULL, &data); if (err) { return err; @@ -7472,7 +7510,7 @@ int lfsr_rename(lfs_t *lfs, const char *old_path, const char *new_path) { } // create a grm to remove the dstart entry - lfsr_grm_pushrm(&grm, mdir_.mid, mdir_.rid); + lfsr_grm_pushrm(&grm, mdir_.mid); // check that the directory is empty err = lfsr_mtree_seek(lfs, &mdir_, 1); @@ -7483,7 +7521,7 @@ int lfsr_rename(lfs_t *lfs, const char *old_path, const char *new_path) { if (err != LFS_ERR_NOENT) { lfsr_tag_t tag_; err = lfsr_mdir_lookup(lfs, &mdir_, - mdir_.rid, LFSR_TAG_WIDENAME, + mdir_.mid.rid, LFSR_TAG_WIDENAME, &tag_, NULL); if (err) { return err; @@ -7500,12 +7538,11 @@ int lfsr_rename(lfs_t *lfs, const char *old_path, const char *new_path) { // new rid, while also marking the old rid for removal err = lfsr_mdir_commit(lfs, &new_mdir, LFSR_ATTRS( (exists - ? LFSR_ATTR(new_mdir.rid, UNR, -1, NULL, 0) + ? LFSR_ATTR(new_mdir.mid.rid, UNR, -1, NULL, 0) : LFSR_ATTR_NOOP), - LFSR_ATTR_DNAME_(new_mdir.rid, old_tag, +1, + LFSR_ATTR_DNAME_(new_mdir.mid.rid, old_tag, +1, new_did, new_name, new_name_size), - LFSR_ATTR_MOVE(new_mdir.rid, MOVE, 0, - &old_mdir.m.rbyd, old_mdir.rid), + LFSR_ATTR_MOVE(new_mdir.mid.rid, MOVE, 0, &old_mdir), LFSR_ATTR_GRM(-1, GRM, 0, &grm))); // we need to clean up any pending grms, fortunately we can leave @@ -7568,7 +7605,7 @@ int lfsr_dir_open(lfs_t *lfs, lfsr_dir_t *dir, const char *path) { dir->did = 0; } else { lfsr_data_t data; - int err = lfsr_mdir_lookup(lfs, &mdir, mdir.rid, LFSR_TAG_DID, + int err = lfsr_mdir_lookup(lfs, &mdir, mdir.mid.rid, LFSR_TAG_DID, NULL, &data); if (err) { return err; @@ -7631,7 +7668,7 @@ int lfsr_dir_read(lfs_t *lfs, lfsr_dir_t *dir, struct lfs_info *info) { lfsr_tag_t tag; lfsr_data_t data; err = lfsr_mdir_lookup(lfs, &dir->pos_mdir, - dir->pos_mdir.rid, LFSR_TAG_WIDENAME, + dir->pos_mdir.mid.rid, LFSR_TAG_WIDENAME, &tag, &data); if (err) { return err; @@ -7727,10 +7764,8 @@ static int lfsr_fs_fixgrm(lfs_t *lfs) { while (lfsr_grm_hasrm(&lfs->grm)) { // find our mdir lfsr_mdir_t mdir; - LFS_ASSERT(lfs->grm.rms[0].mid < (lfs_ssize_t)lfsr_mtree_weight(lfs)); - int err = lfsr_mtree_lookup(lfs, - lfs->grm.rms[0].mid, lfs->grm.rms[0].rid, - &mdir); + LFS_ASSERT(lfs->grm.mids[0].bid < (lfs_ssize_t)lfsr_mtree_weight(lfs)); + int err = lfsr_mtree_lookup(lfs, lfs->grm.mids[0], &mdir); if (err) { return err; } @@ -7740,15 +7775,16 @@ static int lfsr_fs_fixgrm(lfs_t *lfs) { lfsr_grm_poprm(&grm); // make sure to adjust any remaining grms - if (grm.rms[0].mid == mdir.mid && grm.rms[0].rid >= mdir.rid) { - LFS_ASSERT(grm.rms[0].rid != mdir.rid); - grm.rms[0].rid -= 1; + if (grm.mids[0].bid == mdir.mid.bid + && grm.mids[0].rid >= mdir.mid.rid) { + LFS_ASSERT(grm.mids[0].rid != mdir.mid.rid); + grm.mids[0].rid -= 1; } // remove the rid while also updating our grm - LFS_ASSERT(lfs->grm.rms[0].rid < (lfs_ssize_t)mdir.m.rbyd.weight); + LFS_ASSERT(lfs->grm.mids[0].rid < (lfs_ssize_t)mdir.m.rbyd.weight); err = lfsr_mdir_commit(lfs, &mdir, LFSR_ATTRS( - LFSR_ATTR(mdir.rid, UNR, -1, NULL, 0), + LFSR_ATTR(mdir.mid.rid, UNR, -1, NULL, 0), LFSR_ATTR_GRM(-1, GRM, 0, &grm))); } @@ -7761,11 +7797,11 @@ static int lfsr_fs_preparemutation(lfs_t *lfs) { // fix pending grms if (lfsr_grm_hasrm(&lfs->grm)) { - LFS_DEBUG("Fixing grm %"PRId32".%"PRId32" %"PRId32".%"PRId32, - lfs->grm.rms[0].mid, - lfs->grm.rms[0].rid, - lfs->grm.rms[1].mid, - lfs->grm.rms[1].rid); + LFS_DEBUG("Fixing grm %"PRId16".%"PRId16" %"PRId16".%"PRId16, + lfs->grm.mids[0].bid, + lfs->grm.mids[0].rid, + lfs->grm.mids[1].bid, + lfs->grm.mids[1].rid); int err = lfsr_fs_fixgrm(lfs); if (err) { diff --git a/lfs.h b/lfs.h index 27404093..37357606 100644 --- a/lfs.h +++ b/lfs.h @@ -47,6 +47,11 @@ typedef uint32_t lfs_block_t; typedef uint16_t lfsr_tag_t; typedef int16_t lfsr_stag_t; +typedef uint16_t lfsr_mbid_t; +typedef int16_t lfsr_smbid_t; +typedef uint16_t lfsr_mrid_t; +typedef int16_t lfsr_smrid_t; + // Maximum name size in bytes, may be redefined to reduce the size of the // info struct. Limited to <= 1022. Stored in superblock and must be // respected by other littlefs drivers. @@ -368,12 +373,13 @@ typedef union lfsr_btree { } inlined; } lfsr_btree_t; +typedef struct lfsr_mid { + lfsr_smbid_t bid; + lfsr_smrid_t rid; +} lfsr_mid_t; + typedef struct lfsr_mdir { - // -2 => deleted - // -1 => mroot - // >=0 => bid in the mtree - lfs_ssize_t mid; - lfs_ssize_t rid; + lfsr_mid_t mid; struct { lfsr_rbyd_t rbyd; lfs_block_t redund_block; @@ -387,17 +393,14 @@ typedef struct lfsr_openedmdir { // space for: // - type - 1 leb128 - 1 byte (worst case) -// - mid0 - 1 leb128 - 5 bytes (worst case) -// - rid0 - 1 leb128 - 5 bytes (worst case) -// - mid1 - 1 leb128 - 5 bytes (worst case) -// - rid1 - 1 leb128 - 5 bytes (worst case) -#define LFSR_GRM_DSIZE (1+5+5+5+5) +// - mid0 - 1 leb128 - 3 bytes (worst case) +// - rid0 - 1 leb128 - 3 bytes (worst case) +// - mid1 - 1 leb128 - 3 bytes (worst case) +// - rid1 - 1 leb128 - 3 bytes (worst case) +#define LFSR_GRM_DSIZE (1+3+3+3+3) typedef struct lfsr_grm { - struct { - lfs_ssize_t mid; - lfs_ssize_t rid; - } rms[2]; + lfsr_mid_t mids[2]; } lfsr_grm_t; diff --git a/tests/t3_mtree.toml b/tests/t3_mtree.toml index 45c0f93a..1ae990fc 100644 --- a/tests/t3_mtree.toml +++ b/tests/t3_mtree.toml @@ -176,7 +176,7 @@ code = ''' // assert that our entry is still in the mtree lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, @@ -200,7 +200,7 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that our entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, @@ -245,13 +245,13 @@ code = ''' // assert that our entries are still in the mtree lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); - lfsr_mtree_lookup(&lfs, 1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -269,13 +269,13 @@ code = ''' assert(lfs.mroot.m.rbyd.weight == 0); // assert that our entries are still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); - lfsr_mtree_lookup(&lfs, 1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -319,7 +319,7 @@ code = ''' // now add another large entry to the mdir, forcing a split lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); memset(buffer, alphas[2 % 26], SIZE); @@ -341,13 +341,13 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that our entries are still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; assert(memcmp(buffer, &alphas[1 % 26], 1) == 0); - lfsr_mtree_lookup(&lfs, 1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -369,13 +369,13 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that our entries are still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; assert(memcmp(buffer, &alphas[1 % 26], 1) == 0); - lfsr_mtree_lookup(&lfs, 1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -402,9 +402,9 @@ code = ''' // create entries lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, lfsr_mtree_weight(&lfs)-1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(lfsr_mtree_weight(&lfs)-1, -1), &mdir) => 0; - mdir.rid = 0; + mdir.mid.rid = 0; for (lfs_size_t i = 0; i < N; i++) { // force a compaction? if (FORCE_COMPACTION) { @@ -413,14 +413,14 @@ code = ''' } lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( - LFSR_ATTR(mdir.rid, INLINED, +1, &alphas[i % 26], 1))) => 0; + LFSR_ATTR(mdir.mid.rid, INLINED, +1, &alphas[i % 26], 1))) => 0; uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); - mdir.rid += 1; + mdir.mid.rid += 1; } // try looking up each entry @@ -429,12 +429,12 @@ code = ''' mid < (lfs_ssize_t)lfsr_mtree_weight(&lfs); mid++) { lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; - for (mdir.rid = 0; - mdir.rid < (lfs_ssize_t)mdir.m.rbyd.weight; - mdir.rid++) { + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; + for (mdir.mid.rid = 0; + mdir.mid.rid < (lfs_ssize_t)mdir.m.rbyd.weight; + mdir.mid.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); i += 1; @@ -454,12 +454,12 @@ code = ''' mid < (lfs_ssize_t)lfsr_mtree_weight(&lfs); mid++) { lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; - for (mdir.rid = 0; - mdir.rid < (lfs_ssize_t)mdir.m.rbyd.weight; - mdir.rid++) { + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; + for (mdir.mid.rid = 0; + mdir.mid.rid < (lfs_ssize_t)mdir.m.rbyd.weight; + mdir.mid.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); i += 1; @@ -498,9 +498,9 @@ code = ''' : (lfs_ssize_t)(TEST_PRNG(&prng) % lfsr_mtree_weight(&lfs)); // fetch mdir lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; // choose a pseudo-random rid - mdir.rid = TEST_PRNG(&prng) % (mdir.m.rbyd.weight+1); + mdir.mid.rid = TEST_PRNG(&prng) % (mdir.m.rbyd.weight+1); // force a compaction? if (FORCE_COMPACTION) { @@ -510,11 +510,11 @@ code = ''' // add to rbyd, potentially splitting the mdir lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( - LFSR_ATTR(mdir.rid, INLINED, +1, &alphas[i % 26], 1))) => 0; + LFSR_ATTR(mdir.mid.rid, INLINED, +1, &alphas[i % 26], 1))) => 0; // make sure we can look up the new entry uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); @@ -528,12 +528,12 @@ code = ''' mid < (lfs_ssize_t)lfsr_mtree_weight(&lfs); mid++) { lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; - for (mdir.rid = 0; - mdir.rid < (lfs_ssize_t)mdir.m.rbyd.weight; - mdir.rid++) { + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; + for (mdir.mid.rid = 0; + mdir.mid.rid < (lfs_ssize_t)mdir.m.rbyd.weight; + mdir.mid.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; count_ += 1; @@ -557,12 +557,12 @@ code = ''' mid < (lfs_ssize_t)lfsr_mtree_weight(&lfs); mid++) { lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; - for (mdir.rid = 0; - mdir.rid < (lfs_ssize_t)mdir.m.rbyd.weight; - mdir.rid++) { + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; + for (mdir.mid.rid = 0; + mdir.mid.rid < (lfs_ssize_t)mdir.m.rbyd.weight; + mdir.mid.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; count_ += 1; @@ -615,7 +615,7 @@ code = ''' // remove the entry, forcing the mdir to be dropped lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( @@ -685,7 +685,7 @@ code = ''' // remove the entry, forcing the mdir to be dropped lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); // force mdir to compact while we're removing @@ -822,7 +822,7 @@ code = ''' // assert that one entry is still in the mtree lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, @@ -841,7 +841,7 @@ code = ''' assert(lfs.mroot.m.rbyd.weight == 0); // assert that one entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, @@ -890,7 +890,7 @@ code = ''' // assert that one entry is still in the mtree lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, @@ -909,7 +909,7 @@ code = ''' assert(lfs.mroot.m.rbyd.weight == 0); // assert that one entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, @@ -1005,7 +1005,7 @@ code = ''' // now add another large entry to the mdir, forcing a split lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); memset(buffer, alphas[2 % 26], SIZE); @@ -1031,7 +1031,7 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that one entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, @@ -1055,7 +1055,7 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that one entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, @@ -1100,7 +1100,7 @@ code = ''' // now add another large entry to the mdir, forcing a split lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); memset(buffer, alphas[2 % 26], SIZE); @@ -1126,7 +1126,7 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that one entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, @@ -1150,7 +1150,7 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that one entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, @@ -1195,7 +1195,7 @@ code = ''' // now add another large entry to the mdir, forcing a split lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); memset(buffer, alphas[2 % 26], SIZE); @@ -1258,29 +1258,29 @@ code = ''' // create entries lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, lfsr_mtree_weight(&lfs)-1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(lfsr_mtree_weight(&lfs)-1, -1), &mdir) => 0; - mdir.rid = 0; + mdir.mid.rid = 0; for (lfs_size_t i = 0; i < N; i++) { lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( - LFSR_ATTR(mdir.rid, INLINED, +1, &alphas[i % 26], 1))) => 0; + LFSR_ATTR(mdir.mid.rid, INLINED, +1, &alphas[i % 26], 1))) => 0; uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); - mdir.rid += 1; + mdir.mid.rid += 1; } // remove entries for (lfs_size_t i = 0; i < N - REMAINING; i++) { lfs_ssize_t mid = (lfsr_mtree_isinlined(&lfs) ? -1 : 0); lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; // drop should make sure we never have empty mdirs - assert(mdir.mid == -1 || mdir.m.rbyd.weight > 0); + assert(mdir.mid.bid == -1 || mdir.m.rbyd.weight > 0); // force a compaction? if (FORCE_COMPACTION) { @@ -1298,12 +1298,12 @@ code = ''' mid < (lfs_ssize_t)lfsr_mtree_weight(&lfs); mid++) { lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; - for (mdir.rid = 0; - mdir.rid < (lfs_ssize_t)mdir.m.rbyd.weight; - mdir.rid++) { + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; + for (mdir.mid.rid = 0; + mdir.mid.rid < (lfs_ssize_t)mdir.m.rbyd.weight; + mdir.mid.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); i += 1; @@ -1323,12 +1323,12 @@ code = ''' mid < (lfs_ssize_t)lfsr_mtree_weight(&lfs); mid++) { lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; - for (mdir.rid = 0; - mdir.rid < (lfs_ssize_t)mdir.m.rbyd.weight; - mdir.rid++) { + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; + for (mdir.mid.rid = 0; + mdir.mid.rid < (lfs_ssize_t)mdir.m.rbyd.weight; + mdir.mid.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); i += 1; @@ -1358,19 +1358,19 @@ code = ''' for (lfs_size_t cycle = 0; cycle < CYCLES; cycle++) { // create entries lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, lfsr_mtree_weight(&lfs)-1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(lfsr_mtree_weight(&lfs)-1, -1), &mdir) => 0; - mdir.rid = 0; + mdir.mid.rid = 0; for (lfs_size_t i = 0; i < N; i++) { lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( - LFSR_ATTR(mdir.rid, INLINED, +1, &alphas[i % 26], 1))) => 0; + LFSR_ATTR(mdir.mid.rid, INLINED, +1, &alphas[i % 26], 1))) => 0; uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); - mdir.rid += 1; + mdir.mid.rid += 1; } // try looking up each entry @@ -1379,12 +1379,12 @@ code = ''' mid < (lfs_ssize_t)lfsr_mtree_weight(&lfs); mid++) { lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; - for (mdir.rid = 0; - mdir.rid < (lfs_ssize_t)mdir.m.rbyd.weight; - mdir.rid++) { + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; + for (mdir.mid.rid = 0; + mdir.mid.rid < (lfs_ssize_t)mdir.m.rbyd.weight; + mdir.mid.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); i += 1; @@ -1396,10 +1396,10 @@ code = ''' for (lfs_size_t i = 0; i < N; i++) { lfs_ssize_t mid = (lfsr_mtree_isinlined(&lfs) ? -1 : 0); lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; // drop should make sure we never have empty mdirs - assert(mdir.mid == -1 || mdir.m.rbyd.weight > 0); + assert(mdir.mid.bid == -1 || mdir.m.rbyd.weight > 0); // force a compaction? if (FORCE_COMPACTION) { @@ -1454,11 +1454,11 @@ code = ''' : (lfs_ssize_t)(TEST_PRNG(&prng) % lfsr_mtree_weight(&lfs)); // fetch mdir lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; // choose a pseudo-random rid - mdir.rid = TEST_PRNG(&prng) % (mdir.m.rbyd.weight+1); + mdir.mid.rid = TEST_PRNG(&prng) % (mdir.m.rbyd.weight+1); // choose to create or delete - uint8_t op = (lfs_size_t)mdir.rid == mdir.m.rbyd.weight + uint8_t op = (lfs_size_t)mdir.mid.rid == mdir.m.rbyd.weight ? 0 : TEST_PRNG(&prng) % 2; @@ -1472,12 +1472,12 @@ code = ''' if (op == 0) { // add to rbyd, potentially splitting the mdir lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( - LFSR_ATTR(mdir.rid, INLINED, +1, + LFSR_ATTR(mdir.mid.rid, INLINED, +1, &alphas[i % 26], 1))) => 0; // make sure we can look up the new entry uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); @@ -1486,7 +1486,7 @@ code = ''' // delete } else { lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( - LFSR_ATTR(mdir.rid, UNR, -1, NULL, 0))) => 0; + LFSR_ATTR(mdir.mid.rid, UNR, -1, NULL, 0))) => 0; count -= 1; } @@ -1499,16 +1499,16 @@ code = ''' mid < (lfs_ssize_t)lfsr_mtree_weight(&lfs); mid++) { lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; // drop should make sure we never have empty mdirs - assert(mdir.mid == -1 || mdir.m.rbyd.weight > 0); + assert(mdir.mid.bid == -1 || mdir.m.rbyd.weight > 0); - for (mdir.rid = 0; - mdir.rid < (lfs_ssize_t)mdir.m.rbyd.weight; - mdir.rid++) { + for (mdir.mid.rid = 0; + mdir.mid.rid < (lfs_ssize_t)mdir.m.rbyd.weight; + mdir.mid.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; count_ += 1; @@ -1532,16 +1532,16 @@ code = ''' mid < (lfs_ssize_t)lfsr_mtree_weight(&lfs); mid++) { lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; // drop should make sure we never have empty mdirs - assert(mdir.mid == -1 || mdir.m.rbyd.weight > 0); + assert(mdir.mid.bid == -1 || mdir.m.rbyd.weight > 0); - for (mdir.rid = 0; - mdir.rid < (lfs_ssize_t)mdir.m.rbyd.weight; - mdir.rid++) { + for (mdir.mid.rid = 0; + mdir.mid.rid < (lfs_ssize_t)mdir.m.rbyd.weight; + mdir.mid.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; count_ += 1; @@ -1597,7 +1597,7 @@ code = ''' // force mdir to compact twice, this should relocate lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_t old_mdir = mdir; @@ -1618,7 +1618,7 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that our entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, @@ -1645,7 +1645,7 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that our entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, @@ -1692,7 +1692,7 @@ code = ''' // force mdir to compact twice, this should relocate lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_t old_mdir = mdir; @@ -1708,13 +1708,13 @@ code = ''' assert(lfsr_mdir_cmp(&old_mdir, &mdir) != 0); // assert that our entries are still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; assert(memcmp(buffer, &alphas[2 % 26], 1) == 0); - lfsr_mtree_lookup(&lfs, 1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -1735,13 +1735,13 @@ code = ''' assert(lfsr_mdir_cmp(&old_mdir, &mdir) != 0); // assert that our entries are still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; assert(memcmp(buffer, &alphas[2 % 26], 1) == 0); - lfsr_mtree_lookup(&lfs, 1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -1787,7 +1787,7 @@ code = ''' // force mdir to compact twice, this should relocate lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_t old_mdir = mdir; @@ -1803,13 +1803,13 @@ code = ''' assert(lfsr_mdir_cmp(&old_mdir, &mdir) != 0); // assert that our entries are still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); - lfsr_mtree_lookup(&lfs, 1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -1830,13 +1830,13 @@ code = ''' assert(lfsr_mdir_cmp(&old_mdir, &mdir) != 0); // assert that our entries are still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); - lfsr_mtree_lookup(&lfs, 1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -2075,7 +2075,7 @@ code = ''' // force mdir to compact twice, this should relocate lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_t old_mdir = mdir; @@ -2099,7 +2099,7 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that our entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, @@ -2129,7 +2129,7 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that our entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, @@ -2181,7 +2181,7 @@ code = ''' // now add another large entry to the mdir, forcing a split lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); memset(buffer, alphas[2 % 26], SIZE); @@ -2206,13 +2206,13 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that our entries are still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; assert(memcmp(buffer, &alphas[1 % 26], 1) == 0); - lfsr_mtree_lookup(&lfs, 1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -2238,13 +2238,13 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that our entries are still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; assert(memcmp(buffer, &alphas[1 % 26], 1) == 0); - lfsr_mtree_lookup(&lfs, 1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -2295,7 +2295,7 @@ code = ''' // remove the entry, forcing the mdir to be dropped lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( @@ -2388,7 +2388,7 @@ code = ''' // assert that our entry is still in the mtree lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, @@ -2415,7 +2415,7 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that our entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, @@ -2471,13 +2471,13 @@ code = ''' // assert that our entries are still in the mtree lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); - lfsr_mtree_lookup(&lfs, 1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -2498,13 +2498,13 @@ code = ''' assert(lfsr_mdir_cmp(&old_mroot, &lfs.mroot) != 0); // assert that our entries are still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); - lfsr_mtree_lookup(&lfs, 1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -2542,11 +2542,11 @@ code = ''' : (lfs_ssize_t)(TEST_PRNG(&prng) % lfsr_mtree_weight(&lfs)); // fetch mdir lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; // choose a pseudo-random rid - mdir.rid = TEST_PRNG(&prng) % (mdir.m.rbyd.weight+1); + mdir.mid.rid = TEST_PRNG(&prng) % (mdir.m.rbyd.weight+1); // choose to create or delete - uint8_t op = (lfs_size_t)mdir.rid == mdir.m.rbyd.weight + uint8_t op = (lfs_size_t)mdir.mid.rid == mdir.m.rbyd.weight ? 0 : TEST_PRNG(&prng) % 3; @@ -2560,12 +2560,12 @@ code = ''' if (op == 0) { // add to rbyd lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( - LFSR_ATTR(mdir.rid, INLINED, +1, + LFSR_ATTR(mdir.mid.rid, INLINED, +1, &alphas[i % 26], 1))) => 0; // make sure we can look up the new entry uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); @@ -2575,19 +2575,19 @@ code = ''' } else if (op == 1) { // update rbyd lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( - LFSR_ATTR(mdir.rid, INLINED, 0, + LFSR_ATTR(mdir.mid.rid, INLINED, 0, &alphas[i % 26], 1))) => 0; // make sure we can look up the new entry uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); // delete } else { lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( - LFSR_ATTR(mdir.rid, UNR, -1, NULL, 0))) => 0; + LFSR_ATTR(mdir.mid.rid, UNR, -1, NULL, 0))) => 0; count -= 1; } @@ -2600,16 +2600,16 @@ code = ''' mid < (lfs_ssize_t)lfsr_mtree_weight(&lfs); mid++) { lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; // drop should make sure we never have empty mdirs - assert(mdir.mid == -1 || mdir.m.rbyd.weight > 0); + assert(mdir.mid.bid == -1 || mdir.m.rbyd.weight > 0); - for (mdir.rid = 0; - mdir.rid < (lfs_ssize_t)mdir.m.rbyd.weight; - mdir.rid++) { + for (mdir.mid.rid = 0; + mdir.mid.rid < (lfs_ssize_t)mdir.m.rbyd.weight; + mdir.mid.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; count_ += 1; @@ -2633,16 +2633,16 @@ code = ''' mid < (lfs_ssize_t)lfsr_mtree_weight(&lfs); mid++) { lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; // drop should make sure we never have empty mdirs - assert(mdir.mid == -1 || mdir.m.rbyd.weight > 0); + assert(mdir.mid.bid == -1 || mdir.m.rbyd.weight > 0); - for (mdir.rid = 0; - mdir.rid < (lfs_ssize_t)mdir.m.rbyd.weight; - mdir.rid++) { + for (mdir.mid.rid = 0; + mdir.mid.rid < (lfs_ssize_t)mdir.m.rbyd.weight; + mdir.mid.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; count_ += 1; @@ -2679,9 +2679,9 @@ code = ''' assert(lfsr_mtree_isinlined(&lfs)); lfsr_openedmdir_t left_neighbor = { - .mdir={.mid=-1, .rid=0, .m=lfs.mroot.m}}; + .mdir={.mid=LFSR_MID(-1, 0), .m=lfs.mroot.m}}; lfsr_openedmdir_t right_neighbor = { - .mdir={.mid=-1, .rid=1, .m=lfs.mroot.m}}; + .mdir={.mid=LFSR_MID(-1, 1), .m=lfs.mroot.m}}; lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor); @@ -2699,13 +2699,13 @@ code = ''' // assert that our neighbors were updated correctly assert(!lfsr_mdir_isdropped(&left_neighbor.mdir)); - assert(left_neighbor.mdir.mid == -1); - assert(left_neighbor.mdir.rid == 0); + assert(left_neighbor.mdir.mid.bid == -1); + assert(left_neighbor.mdir.mid.rid == 0); assert(memcmp(&left_neighbor.mdir.m, &lfs.mroot.m, sizeof(lfs.mroot.m)) == 0); assert(!lfsr_mdir_isdropped(&right_neighbor.mdir)); - assert(right_neighbor.mdir.mid == -1); - assert(right_neighbor.mdir.rid == 2); + assert(right_neighbor.mdir.mid.bid == -1); + assert(right_neighbor.mdir.mid.rid == 2); assert(memcmp(&right_neighbor.mdir.m, &lfs.mroot.m, sizeof(lfs.mroot.m)) == 0); @@ -2734,9 +2734,9 @@ code = ''' assert(lfsr_mtree_isinlined(&lfs)); lfsr_openedmdir_t left_neighbor = { - .mdir={.mid=-1, .rid=0, .m=lfs.mroot.m}}; + .mdir={.mid=LFSR_MID(-1, 0), .m=lfs.mroot.m}}; lfsr_openedmdir_t right_neighbor = { - .mdir={.mid=-1, .rid=1, .m=lfs.mroot.m}}; + .mdir={.mid=LFSR_MID(-1, 1), .m=lfs.mroot.m}}; lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor); @@ -2750,8 +2750,8 @@ code = ''' // assert that our neighbors were updated correctly assert(lfsr_mdir_isdropped(&left_neighbor.mdir)); assert(!lfsr_mdir_isdropped(&right_neighbor.mdir)); - assert(right_neighbor.mdir.mid == -1); - assert(right_neighbor.mdir.rid == 0); + assert(right_neighbor.mdir.mid.bid == -1); + assert(right_neighbor.mdir.mid.rid == 0); assert(memcmp(&right_neighbor.mdir.m, &lfs.mroot.m, sizeof(lfs.mroot.m)) == 0); @@ -2780,9 +2780,9 @@ code = ''' assert(lfsr_mtree_isinlined(&lfs)); lfsr_openedmdir_t left_neighbor = { - .mdir={.mid=-1, .rid=0, .m=lfs.mroot.m}}; + .mdir={.mid=LFSR_MID(-1, 0), .m=lfs.mroot.m}}; lfsr_openedmdir_t right_neighbor = { - .mdir={.mid=-1, .rid=1, .m=lfs.mroot.m}}; + .mdir={.mid=LFSR_MID(-1, 1), .m=lfs.mroot.m}}; lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor); @@ -2795,8 +2795,8 @@ code = ''' // assert that our neighbors were updated correctly assert(!lfsr_mdir_isdropped(&left_neighbor.mdir)); - assert(left_neighbor.mdir.mid == -1); - assert(left_neighbor.mdir.rid == 0); + assert(left_neighbor.mdir.mid.bid == -1); + assert(left_neighbor.mdir.mid.rid == 0); assert(memcmp(&left_neighbor.mdir.m, &lfs.mroot.m, sizeof(lfs.mroot.m)) == 0); assert(lfsr_mdir_isdropped(&right_neighbor.mdir)); @@ -2828,9 +2828,9 @@ code = ''' assert(lfsr_mtree_isinlined(&lfs)); lfsr_openedmdir_t left_neighbor = { - .mdir={.mid=-1, .rid=0, .m=lfs.mroot.m}}; + .mdir={.mid=LFSR_MID(-1, 0), .m=lfs.mroot.m}}; lfsr_openedmdir_t right_neighbor = { - .mdir={.mid=-1, .rid=1, .m=lfs.mroot.m}}; + .mdir={.mid=LFSR_MID(-1, 1), .m=lfs.mroot.m}}; lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor); @@ -2861,7 +2861,7 @@ code = ''' // assert that our entry is still in the mtree lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 2); lfsr_mdir_get(&lfs, &mdir, 1, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -2870,18 +2870,18 @@ code = ''' // note that our current implementation splits here, which is suboptimal // but saves on code size lfsr_mdir_t msibling; - lfsr_mtree_lookup(&lfs, 1, -1, &msibling) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &msibling) => 0; assert(msibling.m.rbyd.weight == 1); // assert that our neighbors were updated correctly assert(!lfsr_mdir_isdropped(&left_neighbor.mdir)); - assert(left_neighbor.mdir.mid == 0); - assert(left_neighbor.mdir.rid == 0); + assert(left_neighbor.mdir.mid.bid == 0); + assert(left_neighbor.mdir.mid.rid == 0); assert(memcmp(&left_neighbor.mdir.m, &mdir.m, sizeof(mdir.m)) == 0); assert(!lfsr_mdir_isdropped(&right_neighbor.mdir)); - assert(right_neighbor.mdir.mid == 1); - assert(right_neighbor.mdir.rid == 0); + assert(right_neighbor.mdir.mid.bid == 1); + assert(right_neighbor.mdir.mid.rid == 0); assert(memcmp(&right_neighbor.mdir.m, &msibling.m, sizeof(msibling.m)) == 0); @@ -2912,9 +2912,9 @@ code = ''' assert(lfsr_mtree_isinlined(&lfs)); lfsr_openedmdir_t left_neighbor = { - .mdir={.mid=-1, .rid=0, .m=lfs.mroot.m}}; + .mdir={.mid=LFSR_MID(-1, 0), .m=lfs.mroot.m}}; lfsr_openedmdir_t right_neighbor = { - .mdir={.mid=-1, .rid=1, .m=lfs.mroot.m}}; + .mdir={.mid=LFSR_MID(-1, 1), .m=lfs.mroot.m}}; lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor); @@ -2939,14 +2939,14 @@ code = ''' // assert that our entries are still in the mtree lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 2); lfsr_mdir_get(&lfs, &mdir, 1, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; assert(memcmp(buffer, &alphas[2 % 26], 1) == 0); lfsr_mdir_t msibling; - lfsr_mtree_lookup(&lfs, 1, -1, &msibling) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &msibling) => 0; assert(msibling.m.rbyd.weight == 2); lfsr_mdir_get(&lfs, &msibling, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -2954,13 +2954,13 @@ code = ''' // assert that our neighbors were updated correctly assert(!lfsr_mdir_isdropped(&left_neighbor.mdir)); - assert(left_neighbor.mdir.mid == 0); - assert(left_neighbor.mdir.rid == 0); + assert(left_neighbor.mdir.mid.bid == 0); + assert(left_neighbor.mdir.mid.rid == 0); assert(memcmp(&left_neighbor.mdir.m, &mdir.m, sizeof(mdir.m)) == 0); assert(!lfsr_mdir_isdropped(&right_neighbor.mdir)); - assert(right_neighbor.mdir.mid == 1); - assert(right_neighbor.mdir.rid == 1); + assert(right_neighbor.mdir.mid.bid == 1); + assert(right_neighbor.mdir.mid.rid == 1); assert(memcmp(&right_neighbor.mdir.m, &msibling.m, sizeof(msibling.m)) == 0); @@ -3007,7 +3007,7 @@ code = ''' // note we do this after uninlining! this is because uninlining may // aggresively split the mtree if there are already neighbors in the mdir lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( @@ -3018,9 +3018,9 @@ code = ''' assert(mdir.m.rbyd.weight == 3); lfsr_openedmdir_t left_neighbor = { - .mdir={.mid=mdir.mid, .rid=0, .m=mdir.m}}; + .mdir={.mid=LFSR_MID(mdir.mid.bid, 0), .m=mdir.m}}; lfsr_openedmdir_t right_neighbor = { - .mdir={.mid=mdir.mid, .rid=2, .m=mdir.m}}; + .mdir={.mid=LFSR_MID(mdir.mid.bid, 2), .m=mdir.m}}; lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor); @@ -3044,14 +3044,14 @@ code = ''' assert(memcmp(buffer, &alphas[2 % 26], 1) == 0); // assert that our entries are still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 2); lfsr_mdir_get(&lfs, &mdir, 1, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; assert(memcmp(buffer, &alphas[3 % 26], 1) == 0); lfsr_mdir_t msibling; - lfsr_mtree_lookup(&lfs, 1, -1, &msibling) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &msibling) => 0; assert(msibling.m.rbyd.weight == 2); lfsr_mdir_get(&lfs, &msibling, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -3059,13 +3059,13 @@ code = ''' // assert that our neighbors were updated correctly assert(!lfsr_mdir_isdropped(&left_neighbor.mdir)); - assert(left_neighbor.mdir.mid == 0); - assert(left_neighbor.mdir.rid == 0); + assert(left_neighbor.mdir.mid.bid == 0); + assert(left_neighbor.mdir.mid.rid == 0); assert(memcmp(&left_neighbor.mdir.m, &mdir.m, sizeof(mdir.m)) == 0); assert(!lfsr_mdir_isdropped(&right_neighbor.mdir)); - assert(right_neighbor.mdir.mid == 1); - assert(right_neighbor.mdir.rid == 1); + assert(right_neighbor.mdir.mid.bid == 1); + assert(right_neighbor.mdir.mid.rid == 1); assert(memcmp(&right_neighbor.mdir.m, &msibling.m, sizeof(msibling.m)) == 0); @@ -3098,9 +3098,9 @@ code = ''' assert(lfsr_mtree_isinlined(&lfs)); lfsr_openedmdir_t left_neighbor = { - .mdir={.mid=-1, .rid=0, .m=lfs.mroot.m}}; + .mdir={.mid=LFSR_MID(-1, 0), .m=lfs.mroot.m}}; lfsr_openedmdir_t right_neighbor = { - .mdir={.mid=-1, .rid=1, .m=lfs.mroot.m}}; + .mdir={.mid=LFSR_MID(-1, 1), .m=lfs.mroot.m}}; lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor); @@ -3130,13 +3130,13 @@ code = ''' // assert that our neighbors were updated correctly assert(!lfsr_mdir_isdropped(&left_neighbor.mdir)); - assert(left_neighbor.mdir.mid == -1); - assert(left_neighbor.mdir.rid == 0); + assert(left_neighbor.mdir.mid.bid == -1); + assert(left_neighbor.mdir.mid.rid == 0); assert(memcmp(&left_neighbor.mdir.m, &lfs.mroot.m, sizeof(lfs.mroot.m)) == 0); assert(!lfsr_mdir_isdropped(&right_neighbor.mdir)); - assert(right_neighbor.mdir.mid == -1); - assert(right_neighbor.mdir.rid == 1); + assert(right_neighbor.mdir.mid.bid == -1); + assert(right_neighbor.mdir.mid.rid == 1); assert(memcmp(&right_neighbor.mdir.m, &lfs.mroot.m, sizeof(lfs.mroot.m)) == 0); @@ -3185,7 +3185,7 @@ code = ''' // note we do this after uninlining! this is because uninlining may // aggresively split the mtree if there are already neighbors in the mdir lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( @@ -3196,9 +3196,9 @@ code = ''' assert(mdir.m.rbyd.weight == 3); lfsr_openedmdir_t left_neighbor = { - .mdir={.mid=mdir.mid, .rid=0, .m=mdir.m}}; + .mdir={.mid=LFSR_MID(mdir.mid.bid, 0), .m=mdir.m}}; lfsr_openedmdir_t right_neighbor = { - .mdir={.mid=mdir.mid, .rid=2, .m=mdir.m}}; + .mdir={.mid=LFSR_MID(mdir.mid.bid, 2), .m=mdir.m}}; lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor); @@ -3221,7 +3221,7 @@ code = ''' assert(memcmp(buffer, &alphas[2 % 26], 1) == 0); // assert that our entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 3); lfsr_mdir_get(&lfs, &mdir, 1, LFSR_TAG_INLINED, @@ -3230,12 +3230,12 @@ code = ''' // assert that our neighbors were updated correctly assert(!lfsr_mdir_isdropped(&left_neighbor.mdir)); - assert(left_neighbor.mdir.mid == 0); - assert(left_neighbor.mdir.rid == 0); + assert(left_neighbor.mdir.mid.bid == 0); + assert(left_neighbor.mdir.mid.rid == 0); assert(memcmp(&left_neighbor.mdir.m, &mdir.m, sizeof(mdir.m)) == 0); assert(!lfsr_mdir_isdropped(&right_neighbor.mdir)); - assert(right_neighbor.mdir.mid == 0); - assert(right_neighbor.mdir.rid == 2); + assert(right_neighbor.mdir.mid.bid == 0); + assert(right_neighbor.mdir.mid.rid == 2); assert(memcmp(&right_neighbor.mdir.m, &mdir.m, sizeof(mdir.m)) == 0); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &left_neighbor); @@ -3279,7 +3279,7 @@ code = ''' // now force one of our siblings to split lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); memset(buffer, alphas[2 % 26], SIZE); lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( @@ -3297,20 +3297,20 @@ code = ''' // setup our neighbors lfsr_openedmdir_t left_neighbor; - lfsr_mtree_lookup(&lfs, 0, -1, &left_neighbor.mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &left_neighbor.mdir) => 0; assert(left_neighbor.mdir.m.rbyd.weight == 1); - left_neighbor.mdir.rid = 0; + left_neighbor.mdir.mid.rid = 0; lfsr_openedmdir_t right_neighbor; - lfsr_mtree_lookup(&lfs, 2, -1, &right_neighbor.mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(2, -1), &right_neighbor.mdir) => 0; assert(right_neighbor.mdir.m.rbyd.weight == 1); - right_neighbor.mdir.rid = 0; + right_neighbor.mdir.mid.rid = 0; lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor); // cause middle mdir to split - lfsr_mtree_lookup(&lfs, 1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); memset(buffer, alphas[3 % 26], SIZE); lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( @@ -3325,14 +3325,14 @@ code = ''' // assert that our neighbors were updated correctly assert(!lfsr_mdir_isdropped(&left_neighbor.mdir)); - assert(left_neighbor.mdir.mid == 0); - assert(left_neighbor.mdir.rid == 0); - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + assert(left_neighbor.mdir.mid.bid == 0); + assert(left_neighbor.mdir.mid.rid == 0); + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(memcmp(&left_neighbor.mdir.m, &mdir.m, sizeof(mdir.m)) == 0); - assert(right_neighbor.mdir.mid == 3); - assert(right_neighbor.mdir.rid == 0); - lfsr_mtree_lookup(&lfs, 3, -1, &mdir) => 0; + assert(right_neighbor.mdir.mid.bid == 3); + assert(right_neighbor.mdir.mid.rid == 0); + lfsr_mtree_lookup(&lfs, LFSR_MID(3, -1), &mdir) => 0; assert(memcmp(&right_neighbor.mdir.m, &mdir.m, sizeof(mdir.m)) == 0); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &left_neighbor); @@ -3376,7 +3376,7 @@ code = ''' // now force one of our siblings to split lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); memset(buffer, alphas[2 % 26], SIZE); lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( @@ -3394,20 +3394,20 @@ code = ''' // setup our neighbors lfsr_openedmdir_t left_neighbor; - lfsr_mtree_lookup(&lfs, 0, -1, &left_neighbor.mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &left_neighbor.mdir) => 0; assert(left_neighbor.mdir.m.rbyd.weight == 1); - left_neighbor.mdir.rid = 0; + left_neighbor.mdir.mid.rid = 0; lfsr_openedmdir_t right_neighbor; - lfsr_mtree_lookup(&lfs, 2, -1, &right_neighbor.mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(2, -1), &right_neighbor.mdir) => 0; assert(right_neighbor.mdir.m.rbyd.weight == 1); - right_neighbor.mdir.rid = 0; + right_neighbor.mdir.mid.rid = 0; lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor); // cause middle mdir to drop - lfsr_mtree_lookup(&lfs, 1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; @@ -3417,15 +3417,15 @@ code = ''' // assert that our neighbors were updated correctly assert(!lfsr_mdir_isdropped(&left_neighbor.mdir)); - assert(left_neighbor.mdir.mid == 0); - assert(left_neighbor.mdir.rid == 0); - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + assert(left_neighbor.mdir.mid.bid == 0); + assert(left_neighbor.mdir.mid.rid == 0); + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(memcmp(&left_neighbor.mdir.m, &mdir.m, sizeof(mdir.m)) == 0); assert(!lfsr_mdir_isdropped(&right_neighbor.mdir)); - assert(right_neighbor.mdir.mid == 1); - assert(right_neighbor.mdir.rid == 0); - lfsr_mtree_lookup(&lfs, 1, -1, &mdir) => 0; + assert(right_neighbor.mdir.mid.bid == 1); + assert(right_neighbor.mdir.mid.rid == 0); + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &mdir) => 0; assert(memcmp(&right_neighbor.mdir.m, &mdir.m, sizeof(mdir.m)) == 0); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &left_neighbor); @@ -3473,7 +3473,7 @@ code = ''' // a bit hacky, but this catches infinite loops assert(i < 2*1); - lfs_size_t mid_; + lfsr_mid_t mid_; lfsr_tag_t tag_; lfsr_data_t data_; int err = lfsr_mtree_traversal_next(&lfs, &traversal, @@ -3485,8 +3485,9 @@ code = ''' if (tag_ == LFSR_TAG_BTREE) { lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.buf.buffer; - printf("traversal: %d 0x%x btree 0x%x.%x\n", - mid_, + printf("traversal: %d.%d 0x%x btree 0x%x.%x\n", + mid_.bid, + mid_.rid, tag_, branch->block, branch->trunk); @@ -3494,8 +3495,9 @@ code = ''' seen[branch->block / 8] |= 1 << (branch->block % 8); } else if (tag_ == LFSR_TAG_MDIR) { lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.buf.buffer; - printf("traversal: %d 0x%x mdir 0x{%x,%x}\n", - mid_, + printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n", + mid_.bid, + mid_.rid, tag_, mdir->m.rbyd.block, mdir->m.redund_block); @@ -3504,8 +3506,9 @@ code = ''' seen[mdir->m.redund_block / 8] |= 1 << (mdir->m.redund_block % 8); } else { // this shouldn't happen - printf("traversal: %d 0x%x %d\n", - mid_, + printf("traversal: %d.%d 0x%x %d\n", + mid_.bid, + mid_.rid, tag_, lfsr_data_size(data_)); assert(false); @@ -3577,7 +3580,7 @@ code = ''' // assert that our entry is still in the mtree lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, @@ -3595,7 +3598,7 @@ code = ''' // a bit hacky, but this catches infinite loops assert(i < 2*2); - lfs_size_t mid_; + lfsr_mid_t mid_; lfsr_tag_t tag_; lfsr_data_t data_; int err = lfsr_mtree_traversal_next(&lfs, &traversal, @@ -3607,8 +3610,9 @@ code = ''' if (tag_ == LFSR_TAG_BTREE) { lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.buf.buffer; - printf("traversal: %d 0x%x btree 0x%x.%x\n", - mid_, + printf("traversal: %d.%d 0x%x btree 0x%x.%x\n", + mid_.bid, + mid_.rid, tag_, branch->block, branch->trunk); @@ -3616,8 +3620,9 @@ code = ''' seen[branch->block / 8] |= 1 << (branch->block % 8); } else if (tag_ == LFSR_TAG_MDIR) { lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.buf.buffer; - printf("traversal: %d 0x%x mdir 0x{%x,%x}\n", - mid_, + printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n", + mid_.bid, + mid_.rid, tag_, mdir->m.rbyd.block, mdir->m.redund_block); @@ -3626,8 +3631,9 @@ code = ''' seen[mdir->m.redund_block / 8] |= 1 << (mdir->m.redund_block % 8); } else { // this shouldn't happen - printf("traversal: %d 0x%x %d\n", - mid_, + printf("traversal: %d.%d 0x%x %d\n", + mid_.bid, + mid_.rid, tag_, lfsr_data_size(data_)); assert(false); @@ -3658,7 +3664,7 @@ code = ''' assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); // assert that our entry is still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, @@ -3704,14 +3710,14 @@ code = ''' // assert that our entries are still in the mtree lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); lfsr_mdir_t msibling; - lfsr_mtree_lookup(&lfs, 1, -1, &msibling) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &msibling) => 0; assert(msibling.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &msibling, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -3728,7 +3734,7 @@ code = ''' // a bit hacky, but this catches infinite loops assert(i < 2*3); - lfs_size_t mid_; + lfsr_mid_t mid_; lfsr_tag_t tag_; lfsr_data_t data_; int err = lfsr_mtree_traversal_next(&lfs, &traversal, @@ -3740,8 +3746,9 @@ code = ''' if (tag_ == LFSR_TAG_BTREE) { lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.buf.buffer; - printf("traversal: %d 0x%x btree 0x%x.%x\n", - mid_, + printf("traversal: %d.%d 0x%x btree 0x%x.%x\n", + mid_.bid, + mid_.rid, tag_, branch->block, branch->trunk); @@ -3749,8 +3756,9 @@ code = ''' seen[branch->block / 8] |= 1 << (branch->block % 8); } else if (tag_ == LFSR_TAG_MDIR) { lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.buf.buffer; - printf("traversal: %d 0x%x mdir 0x{%x,%x}\n", - mid_, + printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n", + mid_.bid, + mid_.rid, tag_, mdir->m.rbyd.block, mdir->m.redund_block); @@ -3759,8 +3767,9 @@ code = ''' seen[mdir->m.redund_block / 8] |= 1 << (mdir->m.redund_block % 8); } else { // this shouldn't happen - printf("traversal: %d 0x%x %d\n", - mid_, + printf("traversal: %d.%d 0x%x %d\n", + mid_.bid, + mid_.rid, tag_, lfsr_data_size(data_)); assert(false); @@ -3786,13 +3795,13 @@ code = ''' assert(lfs.mroot.m.rbyd.weight == 0); // assert that our entries are still in the mtree - lfsr_mtree_lookup(&lfs, 0, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(0, -1), &mdir) => 0; assert(mdir.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &mdir, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; assert(memcmp(buffer, &alphas[0 % 26], 1) == 0); - lfsr_mtree_lookup(&lfs, 1, -1, &msibling) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(1, -1), &msibling) => 0; assert(msibling.m.rbyd.weight == 1); lfsr_mdir_get(&lfs, &msibling, 0, LFSR_TAG_INLINED, buffer, SIZE) => SIZE; @@ -3853,7 +3862,7 @@ code = ''' // a bit hacky, but this catches infinite loops assert(i < 2*3); - lfs_size_t mid_; + lfsr_mid_t mid_; lfsr_tag_t tag_; lfsr_data_t data_; int err = lfsr_mtree_traversal_next(&lfs, &traversal, @@ -3865,8 +3874,9 @@ code = ''' if (tag_ == LFSR_TAG_BTREE) { lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.buf.buffer; - printf("traversal: %d 0x%x btree 0x%x.%x\n", - mid_, + printf("traversal: %d.%d 0x%x btree 0x%x.%x\n", + mid_.bid, + mid_.rid, tag_, branch->block, branch->trunk); @@ -3874,8 +3884,9 @@ code = ''' seen[branch->block / 8] |= 1 << (branch->block % 8); } else if (tag_ == LFSR_TAG_MDIR) { lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.buf.buffer; - printf("traversal: %d 0x%x mdir 0x{%x,%x}\n", - mid_, + printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n", + mid_.bid, + mid_.rid, tag_, mdir->m.rbyd.block, mdir->m.redund_block); @@ -3884,8 +3895,9 @@ code = ''' seen[mdir->m.redund_block / 8] |= 1 << (mdir->m.redund_block % 8); } else { // this shouldn't happen - printf("traversal: %d 0x%x %d\n", - mid_, + printf("traversal: %d.%d 0x%x %d\n", + mid_.bid, + mid_.rid, tag_, lfsr_data_size(data_)); assert(false); @@ -3934,9 +3946,9 @@ code = ''' // create entries lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, lfsr_mtree_weight(&lfs)-1, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(lfsr_mtree_weight(&lfs)-1, -1), &mdir) => 0; - mdir.rid = 0; + mdir.mid.rid = 0; for (lfs_size_t i = 0; i < N; i++) { // force a compaction? if (FORCE_COMPACTION) { @@ -3945,14 +3957,14 @@ code = ''' } lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( - LFSR_ATTR(mdir.rid, INLINED, +1, &alphas[i % 26], 1))) => 0; + LFSR_ATTR(mdir.mid.rid, INLINED, +1, &alphas[i % 26], 1))) => 0; uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); - mdir.rid += 1; + mdir.mid.rid += 1; } // try looking up each entry @@ -3961,12 +3973,12 @@ code = ''' mid < (lfs_ssize_t)lfsr_mtree_weight(&lfs); mid++) { lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; - for (mdir.rid = 0; - mdir.rid < (lfs_ssize_t)mdir.m.rbyd.weight; - mdir.rid++) { + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; + for (mdir.mid.rid = 0; + mdir.mid.rid < (lfs_ssize_t)mdir.m.rbyd.weight; + mdir.mid.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); i += 1; @@ -3985,7 +3997,7 @@ code = ''' // a bit hacky, but this catches infinite loops assert(i < 2*(1+N)); - lfs_size_t mid_; + lfsr_mid_t mid_; lfsr_tag_t tag_; lfsr_data_t data_; int err = lfsr_mtree_traversal_next(&lfs, &traversal, @@ -3997,8 +4009,9 @@ code = ''' if (tag_ == LFSR_TAG_BTREE) { lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.buf.buffer; - printf("traversal: %d 0x%x btree 0x%x.%x\n", - mid_, + printf("traversal: %d.%d 0x%x btree 0x%x.%x\n", + mid_.bid, + mid_.rid, tag_, branch->block, branch->trunk); @@ -4006,8 +4019,9 @@ code = ''' seen[branch->block / 8] |= 1 << (branch->block % 8); } else if (tag_ == LFSR_TAG_MDIR) { lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.buf.buffer; - printf("traversal: %d 0x%x mdir 0x{%x,%x}\n", - mid_, + printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n", + mid_.bid, + mid_.rid, tag_, mdir->m.rbyd.block, mdir->m.redund_block); @@ -4016,8 +4030,9 @@ code = ''' seen[mdir->m.redund_block / 8] |= 1 << (mdir->m.redund_block % 8); } else { // this shouldn't happen - printf("traversal: %d 0x%x %d\n", - mid_, + printf("traversal: %d.%d 0x%x %d\n", + mid_.bid, + mid_.rid, tag_, lfsr_data_size(data_)); assert(false); @@ -4043,12 +4058,12 @@ code = ''' mid < (lfs_ssize_t)lfsr_mtree_weight(&lfs); mid++) { lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; - for (mdir.rid = 0; - mdir.rid < (lfs_ssize_t)mdir.m.rbyd.weight; - mdir.rid++) { + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; + for (mdir.mid.rid = 0; + mdir.mid.rid < (lfs_ssize_t)mdir.m.rbyd.weight; + mdir.mid.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); i += 1; @@ -4087,9 +4102,9 @@ code = ''' : (lfs_ssize_t)(TEST_PRNG(&prng) % lfsr_mtree_weight(&lfs)); // fetch mdir lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; // choose a pseudo-random rid - mdir.rid = TEST_PRNG(&prng) % (mdir.m.rbyd.weight+1); + mdir.mid.rid = TEST_PRNG(&prng) % (mdir.m.rbyd.weight+1); // force a compaction? if (FORCE_COMPACTION) { @@ -4099,11 +4114,11 @@ code = ''' // add to rbyd, potentially splitting the mdir lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( - LFSR_ATTR(mdir.rid, INLINED, +1, &alphas[i % 26], 1))) => 0; + LFSR_ATTR(mdir.mid.rid, INLINED, +1, &alphas[i % 26], 1))) => 0; // make sure we can look up the new entry uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); @@ -4117,12 +4132,12 @@ code = ''' mid < (lfs_ssize_t)lfsr_mtree_weight(&lfs); mid++) { lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; - for (mdir.rid = 0; - mdir.rid < (lfs_ssize_t)mdir.m.rbyd.weight; - mdir.rid++) { + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; + for (mdir.mid.rid = 0; + mdir.mid.rid < (lfs_ssize_t)mdir.m.rbyd.weight; + mdir.mid.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; count_ += 1; @@ -4145,7 +4160,7 @@ code = ''' // a bit hacky, but this catches infinite loops assert(i < 2*(1+N)); - lfs_size_t mid_; + lfsr_mid_t mid_; lfsr_tag_t tag_; lfsr_data_t data_; int err = lfsr_mtree_traversal_next(&lfs, &traversal, @@ -4157,8 +4172,9 @@ code = ''' if (tag_ == LFSR_TAG_BTREE) { lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.buf.buffer; - printf("traversal: %d 0x%x btree 0x%x.%x\n", - mid_, + printf("traversal: %d.%d 0x%x btree 0x%x.%x\n", + mid_.bid, + mid_.rid, tag_, branch->block, branch->trunk); @@ -4166,8 +4182,9 @@ code = ''' seen[branch->block / 8] |= 1 << (branch->block % 8); } else if (tag_ == LFSR_TAG_MDIR) { lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.buf.buffer; - printf("traversal: %d 0x%x mdir 0x{%x,%x}\n", - mid_, + printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n", + mid_.bid, + mid_.rid, tag_, mdir->m.rbyd.block, mdir->m.redund_block); @@ -4176,8 +4193,9 @@ code = ''' seen[mdir->m.redund_block / 8] |= 1 << (mdir->m.redund_block % 8); } else { // this shouldn't happen - printf("traversal: %d 0x%x %d\n", - mid_, + printf("traversal: %d.%d 0x%x %d\n", + mid_.bid, + mid_.rid, tag_, lfsr_data_size(data_)); assert(false); @@ -4204,12 +4222,12 @@ code = ''' mid < (lfs_ssize_t)lfsr_mtree_weight(&lfs); mid++) { lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; - for (mdir.rid = 0; - mdir.rid < (lfs_ssize_t)mdir.m.rbyd.weight; - mdir.rid++) { + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; + for (mdir.mid.rid = 0; + mdir.mid.rid < (lfs_ssize_t)mdir.m.rbyd.weight; + mdir.mid.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; count_ += 1; @@ -4249,7 +4267,7 @@ code = ''' // assert that we detect the cycle in a reasonable number of iterations assert(i < 1024); - lfs_size_t mid_; + lfsr_mid_t mid_; lfsr_tag_t tag_; lfsr_data_t data_; int err = lfsr_mtree_traversal_next(&lfs, &traversal, @@ -4261,20 +4279,23 @@ code = ''' if (tag_ == LFSR_TAG_BTREE) { lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.buf.buffer; - printf("traversal: %d 0x%x btree 0x%x.%x\n", - mid_, + printf("traversal: %d.%d 0x%x btree 0x%x.%x\n", + mid_.bid, + mid_.rid, tag_, branch->block, branch->trunk); } else if (tag_ == LFSR_TAG_MDIR) { lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.buf.buffer; - printf("traversal: %d 0x%x mdir 0x{%x,%x}\n", - mid_, + printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n", + mid_.bid, + mid_.rid, tag_, mdir->m.rbyd.block, mdir->m.redund_block); } else { // this shouldn't happen - printf("traversal: %d 0x%x %d\n", - mid_, + printf("traversal: %d.%d 0x%x %d\n", + mid_.bid, + mid_.rid, tag_, lfsr_data_size(data_)); assert(false); diff --git a/tests/t4_alloc.toml b/tests/t4_alloc.toml index 611a9cd4..80fc7a03 100644 --- a/tests/t4_alloc.toml +++ b/tests/t4_alloc.toml @@ -108,8 +108,9 @@ code = ''' LFSR_ATTR(0, UNR, -1, NULL, 0))) => 0; lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, lfsr_mtree_weight(&lfs)-1, -1, &mdir) => 0; - mdir.rid = 0; + lfsr_mtree_lookup(&lfs, LFSR_MID(lfsr_mtree_weight(&lfs)-1, -1), + &mdir) => 0; + mdir.mid.rid = 0; lfs_size_t count = 0; while (true) { @@ -121,19 +122,19 @@ code = ''' // keep creating new metadata entries until we run out of space int err = lfsr_mdir_commit(&lfs, &mdir, LFSR_ATTRS( - LFSR_ATTR(mdir.rid, INLINED, +1, &alphas[count % 26], 1))); + LFSR_ATTR(mdir.mid.rid, INLINED, +1, &alphas[count % 26], 1))); assert(!err || err == LFS_ERR_NOSPC); if (err == LFS_ERR_NOSPC) { break; } uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[count % 26], 1) == 0); count += 1; - mdir.rid += 1; + mdir.mid.rid += 1; } printf("alloced %d metadata entries in %d blocks\n", @@ -145,12 +146,12 @@ code = ''' mid < (lfs_ssize_t)lfsr_mtree_weight(&lfs); mid++) { lfsr_mdir_t mdir; - lfsr_mtree_lookup(&lfs, mid, -1, &mdir) => 0; - for (mdir.rid = 0; - mdir.rid < (lfs_ssize_t)mdir.m.rbyd.weight; - mdir.rid++) { + lfsr_mtree_lookup(&lfs, LFSR_MID(mid, -1), &mdir) => 0; + for (mdir.mid.rid = 0; + mdir.mid.rid < (lfs_ssize_t)mdir.m.rbyd.weight; + mdir.mid.rid++) { uint8_t buffer[4]; - lfsr_mdir_get(&lfs, &mdir, mdir.rid, LFSR_TAG_INLINED, + lfsr_mdir_get(&lfs, &mdir, mdir.mid.rid, LFSR_TAG_INLINED, buffer, 4) => 1; assert(memcmp(buffer, &alphas[i % 26], 1) == 0); i += 1;