From ab9b975ac16b384d7cff88ea5e27163fc79e98cb Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Sat, 15 Jun 2024 12:06:24 -0500 Subject: [PATCH] t: Tweaked lfsr_btree_traverse so btinfo/mtinfo alias The traversal logic is a bit simpler if everything can pass around/ populate the same struct, so this reverts some changes made when implementing lfsr_traversal_t, bringing back bid as a side-channel and making btinfo/mtinfo typedef aliases. btinfo/mtinfo are also required arguments for lfsr_btree_traverse/ lfsr_fs_traverse now, so it's even easier to forward these to lower layers if they alias. What return-pointers should/shouldn't be optional is still an open question, but at least for btinfo/mtinfo matching lfs_stat makes sense. This saves a bit of code/stack: code stack before: 34474 2552 after: 34454 (-0.0%) 2544 (-0.3%) --- lfs.c | 87 ++++++++++++++++++++++--------------------- tests/test_btree.toml | 22 ++++++----- 2 files changed, 56 insertions(+), 53 deletions(-) diff --git a/lfs.c b/lfs.c index 8b8c24e0..0b8104b7 100644 --- a/lfs.c +++ b/lfs.c @@ -4961,17 +4961,19 @@ static lfs_scmp_t lfsr_btree_namelookup(lfs_t *lfs, const lfsr_btree_t *btree, // note this is different from iteration, iteration should use // lfsr_btree_lookupnext, traversal includes inner btree nodes -#define LFSR_BTRAVERSAL() \ +#define LFSR_BTRAVERSAL(_bid) \ ((lfsr_btraversal_t){ \ - .bid=0, \ + .bid=_bid, \ .rid=0, \ .branch.trunk=0, \ .branch.weight=0}) typedef struct lfsr_btinfo { - lfsr_bid_t bid; lfsr_tag_t tag; union { + // ignore the mdir here, things get a bit simpler if we can + // alias mtinfo=btinfo + lfsr_mdir_t mdir; lfsr_rbyd_t rbyd; lfsr_data_t data; lfsr_bptr_t bptr; @@ -4979,7 +4981,8 @@ typedef struct lfsr_btinfo { } lfsr_btinfo_t; static int lfsr_btree_traverse_(lfs_t *lfs, const lfsr_btree_t *btree, - lfsr_btraversal_t *bt, lfsr_btinfo_t *btinfo) { + lfsr_btraversal_t *bt, + lfsr_bid_t *bid_, lfsr_btinfo_t *btinfo) { // explicitly traverse the root even if weight=0 if (bt->branch.trunk == 0 // unless we don't even have a root yet @@ -4991,7 +4994,9 @@ static int lfsr_btree_traverse_(lfs_t *lfs, const lfsr_btree_t *btree, // traverse the root if (bt->rid == 0) { - btinfo->bid = btree->weight-1; + if (bid_) { + *bid_ = btree->weight-1; + } btinfo->tag = LFSR_TAG_BRANCH; btinfo->u.rbyd = bt->branch; return 0; @@ -5041,7 +5046,9 @@ static int lfsr_btree_traverse_(lfs_t *lfs, const lfsr_btree_t *btree, // return inner btree nodes if this is the first time we've // seen them if (bt->rid == 0) { - btinfo->bid = bt->bid + (rid__ - bt->rid); + if (bid_) { + *bid_ = bt->bid + (rid__ - bt->rid); + } btinfo->tag = LFSR_TAG_BRANCH; btinfo->u.rbyd = bt->branch; return 0; @@ -5057,7 +5064,9 @@ static int lfsr_btree_traverse_(lfs_t *lfs, const lfsr_btree_t *btree, bt->bid = bid__ + 1; bt->rid = rid__ + 1; - btinfo->bid = bid__; + if (bid_) { + *bid_ = bid__; + } btinfo->tag = tag__; btinfo->u.data = data__; return 0; @@ -5066,8 +5075,9 @@ static int lfsr_btree_traverse_(lfs_t *lfs, const lfsr_btree_t *btree, } static int lfsr_btree_traverse(lfs_t *lfs, const lfsr_btree_t *btree, - lfsr_btraversal_t *bt, lfsr_btinfo_t *btinfo) { - return lfsr_btree_traverse_(lfs, btree, bt, btinfo); + lfsr_btraversal_t *bt, + lfsr_bid_t *bid_, lfsr_btinfo_t *btinfo) { + return lfsr_btree_traverse_(lfs, btree, bt, bid_, btinfo); } @@ -7789,19 +7799,13 @@ static inline bool lfsr_f_isdirty(uint32_t flags) { } -typedef struct lfsr_mtinfo { - lfsr_tag_t tag; - union { - lfsr_mdir_t mdir; - lfsr_rbyd_t rbyd; - lfsr_data_t data; - lfsr_bptr_t bptr; - } u; -} lfsr_mtinfo_t; +// alias mtinfo=btinfo +typedef lfsr_btinfo_t lfsr_mtinfo_t; // needed in lfsr_fs_traverse_ static int lfsr_bshrub_traverse(lfs_t *lfs, const lfsr_file_t *file, - lfsr_btraversal_t *bt, lfsr_btinfo_t *btinfo); + lfsr_btraversal_t *bt, + lfsr_bid_t *bid_, lfsr_btinfo_t *btinfo); // low-level traversal _only_ finds blocks static int lfsr_fs_traverse_(lfs_t *lfs, lfsr_mtraversal_t *mt, @@ -7917,7 +7921,7 @@ static int lfsr_fs_traverse_(lfs_t *lfs, lfsr_mtraversal_t *mt, // transition to traversing the mtree mt->o.state = LFSR_TSTATE_MTREE; - mt->u.mt = LFSR_BTRAVERSAL(); + mt->u.mt = LFSR_BTRAVERSAL(0); mtinfo->tag = LFSR_TAG_BRANCH; mtinfo->u.rbyd = mtree; @@ -7938,9 +7942,9 @@ static int lfsr_fs_traverse_(lfs_t *lfs, lfsr_mtraversal_t *mt, } // traverse through the mtree - lfsr_btinfo_t btinfo; + lfsr_bid_t bid; err = lfsr_btree_traverse(lfs, &lfs->mtree.u.btree, &mt->u.mt, - &btinfo); + &bid, mtinfo); if (err) { // end of mtree? transition to traversing any opened mdirs if (err == LFS_ERR_NOENT) { @@ -7955,28 +7959,26 @@ static int lfsr_fs_traverse_(lfs_t *lfs, lfsr_mtraversal_t *mt, // seen it above (this gets a bit weird because 1. mtree may be // uninitialized in mountinited and 2. stack really matters since // we're at the bottom of lfs_alloc) - if (btinfo.tag == LFSR_TAG_BRANCH - && btinfo.u.rbyd.blocks[0] + if (mtinfo->tag == LFSR_TAG_BRANCH + && mtinfo->u.rbyd.blocks[0] == lfs->mtree.u.btree.blocks[0]) { continue; } // inner btree nodes already decoded - if (btinfo.tag == LFSR_TAG_BRANCH) { - mtinfo->tag = LFSR_TAG_BRANCH; - mtinfo->u.rbyd = btinfo.u.rbyd; + if (mtinfo->tag == LFSR_TAG_BRANCH) { return 0; // fetch mdir if we're on a leaf - } else if (btinfo.tag == LFSR_TAG_MDIR) { + } else if (mtinfo->tag == LFSR_TAG_MDIR) { lfsr_mptr_t mptr; - err = lfsr_data_readmptr(lfs, &btinfo.u.data, &mptr); + err = lfsr_data_readmptr(lfs, &mtinfo->u.data, &mptr); if (err) { return err; } err = lfsr_mdir_fetch(lfs, &mt->o.mdir, - LFSR_MID(lfs, btinfo.bid, 0), + LFSR_MID(lfs, bid, 0), &mptr); if (err) { return err; @@ -8042,7 +8044,7 @@ static int lfsr_fs_traverse_(lfs_t *lfs, lfsr_mtraversal_t *mt, } // start traversing - mt->bt = LFSR_BTRAVERSAL(); + mt->bt = LFSR_BTRAVERSAL(0); mt->o.state = LFSR_TSTATE_MDIRBTREE; continue; @@ -8064,7 +8066,7 @@ static int lfsr_fs_traverse_(lfs_t *lfs, lfsr_mtraversal_t *mt, const lfsr_file_t *file = (const lfsr_file_t*)mt->u.o; mt->o.mdir = file->o.mdir; mt->bshrub = file->bshrub; - mt->bt = LFSR_BTRAVERSAL(); + mt->bt = LFSR_BTRAVERSAL(0); mt->o.state = LFSR_TSTATE_OMDIRBTREE; continue; @@ -8074,7 +8076,7 @@ static int lfsr_fs_traverse_(lfs_t *lfs, lfsr_mtraversal_t *mt, case LFSR_TSTATE_OMDIRBTREE:; // traverse through our file err = lfsr_bshrub_traverse(lfs, (const lfsr_file_t*)mt, &mt->bt, - &btinfo); + NULL, mtinfo); if (err) { if (err == LFS_ERR_NOENT) { // end of btree? go to next file @@ -8094,19 +8096,15 @@ static int lfsr_fs_traverse_(lfs_t *lfs, lfsr_mtraversal_t *mt, } // found an inner btree node? - if (btinfo.tag == LFSR_TAG_BRANCH) { - mtinfo->tag = LFSR_TAG_BRANCH; - mtinfo->u.rbyd = btinfo.u.rbyd; + if (mtinfo->tag == LFSR_TAG_BRANCH) { return 0; // found inlined data? ignore this - } else if (btinfo.tag == LFSR_TAG_DATA) { + } else if (mtinfo->tag == LFSR_TAG_DATA) { continue; // found an indirect block? - } else if (btinfo.tag == LFSR_TAG_BLOCK) { - mtinfo->tag = LFSR_TAG_BLOCK; - mtinfo->u.bptr = btinfo.u.bptr; + } else if (mtinfo->tag == LFSR_TAG_BLOCK) { return 0; } else { @@ -10769,7 +10767,8 @@ static int lfsr_bshrub_lookupnext(lfs_t *lfs, const lfsr_file_t *file, } static int lfsr_bshrub_traverse(lfs_t *lfs, const lfsr_file_t *file, - lfsr_btraversal_t *bt, lfsr_btinfo_t *btinfo) { + lfsr_btraversal_t *bt, + lfsr_bid_t *bid_, lfsr_btinfo_t *btinfo) { // bnull/bsprout do nothing if (lfsr_bshrub_isbnull(&file->bshrub) || lfsr_bshrub_isbsprout(&file->o.mdir, &file->bshrub)) { @@ -10782,7 +10781,9 @@ static int lfsr_bshrub_traverse(lfs_t *lfs, const lfsr_file_t *file, return LFS_ERR_NOENT; } - btinfo->bid = lfsr_data_size(file->bshrub.u.bptr.data)-1; + if (bid_) { + *bid_ = lfsr_data_size(file->bshrub.u.bptr.data)-1; + } btinfo->tag = LFSR_TAG_BLOCK; btinfo->u.bptr = file->bshrub.u.bptr; return 0; @@ -10790,7 +10791,7 @@ static int lfsr_bshrub_traverse(lfs_t *lfs, const lfsr_file_t *file, // bshrub/btree? } else if (lfsr_bshrub_isbshruborbtree(&file->bshrub)) { int err = lfsr_btree_traverse_(lfs, &file->bshrub.u.btree, bt, - btinfo); + bid_, btinfo); if (err) { return err; } diff --git a/tests/test_btree.toml b/tests/test_btree.toml index 485c4900..6e4f5f7b 100644 --- a/tests/test_btree.toml +++ b/tests/test_btree.toml @@ -4092,13 +4092,14 @@ code = ''' uint8_t *seen = malloc((BLOCK_COUNT+7)/8); memset(seen, 0, (BLOCK_COUNT+7)/8); - lfsr_btraversal_t bt = LFSR_BTRAVERSAL(); + lfsr_btraversal_t bt = LFSR_BTRAVERSAL(0); for (lfs_block_t i = 0;; i++) { // a bit hacky, but this catches infinite loops assert(i <= 2*N); + lfsr_bid_t bid; lfsr_btinfo_t btinfo; - int err = lfsr_btree_traverse(&lfs, &btree, &bt, &btinfo); + int err = lfsr_btree_traverse(&lfs, &btree, &bt, &bid, &btinfo); assert(!err || err == LFS_ERR_NOENT); if (err == LFS_ERR_NOENT) { break; @@ -4106,7 +4107,7 @@ code = ''' if (btinfo.tag == LFSR_TAG_BRANCH) { printf("traversal: %d 0x%x btree 0x%x.%x\n", - btinfo.bid, + bid, btinfo.tag, btinfo.u.rbyd.blocks[0], btinfo.u.rbyd.trunk); @@ -4116,14 +4117,14 @@ code = ''' } else if (btinfo.tag == LFSR_TAG_DATA) { printf("traversal: %d 0x%x data %d\n", - btinfo.bid, + bid, btinfo.tag, lfsr_data_size(btinfo.u.data)); } else { // well this shouldn't happen printf("traversal: %d 0x%x\n", - btinfo.bid, + bid, btinfo.tag); assert(false); } @@ -4240,13 +4241,14 @@ code = ''' uint8_t *seen = malloc((BLOCK_COUNT+7)/8); memset(seen, 0, (BLOCK_COUNT+7)/8); - lfsr_btraversal_t bt = LFSR_BTRAVERSAL(); + lfsr_btraversal_t bt = LFSR_BTRAVERSAL(0); for (lfs_block_t i = 0;; i++) { // a bit hacky, but this catches infinite loops assert(i <= 2*N); + lfsr_bid_t bid; lfsr_btinfo_t btinfo; - int err = lfsr_btree_traverse(&lfs, &btree, &bt, &btinfo); + int err = lfsr_btree_traverse(&lfs, &btree, &bt, &bid, &btinfo); assert(!err || err == LFS_ERR_NOENT); if (err == LFS_ERR_NOENT) { break; @@ -4254,7 +4256,7 @@ code = ''' if (btinfo.tag == LFSR_TAG_BRANCH) { printf("traversal: %d 0x%x btree 0x%x.%x\n", - btinfo.bid, + bid, btinfo.tag, btinfo.u.rbyd.blocks[0], btinfo.u.rbyd.trunk); @@ -4264,14 +4266,14 @@ code = ''' } else if (btinfo.tag == LFSR_TAG_DATA) { printf("traversal: %d 0x%x data %d\n", - btinfo.bid, + bid, btinfo.tag, lfsr_data_size(btinfo.u.data)); } else { // well this shouldn't happen printf("traversal: %d 0x%x\n", - btinfo.bid, + bid, btinfo.tag); assert(false); }