From b06d48364dc4949e4c7aa5b06929e6d3db54b595 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Tue, 5 Sep 2023 13:24:24 -0500 Subject: [PATCH] Switched to mid=-1 to detect removed mids, drops lfsr_mdir_isdropped This is a simpler way to track dropped mids. Setting trunk=0 was more a workaround that worked but added more purpose to the trunk field than originally needed. The mdir's trunk usually still exists after all. Using mid=-1 previously didn't work due to conflict with mid=-1 to indicate an mdir is an mroot, but since removed mids only appear in the opened-mdir list, and the opened-mdir list stores inlined mdirs as mid=0, this is no longer a problem. One downside of this change is we no longer get implicit NOENT behavior from lfsr_rbyd_lookup when attempting to lookup a removed mid, but it wasn't clear this behavior was going to be very useful... --- lfs.c | 30 +++++++----------------------- tests/test_mtree.toml | 21 ++------------------- 2 files changed, 9 insertions(+), 42 deletions(-) diff --git a/lfs.c b/lfs.c index 271c8e3f..606b4b94 100644 --- a/lfs.c +++ b/lfs.c @@ -4644,10 +4644,6 @@ static int lfsr_data_readmdir(lfs_t *lfs, lfsr_data_t *data, return 0; } -static inline bool lfsr_mdir_isdropped(const lfsr_mdir_t *mdir) { - return mdir->u.r.rbyd.trunk == 0; -} - // track opened mdirs that may need to by updated static void lfsr_mdir_addopened(lfs_t *lfs, uint8_t type, lfsr_openedmdir_t *opened) { @@ -5195,7 +5191,6 @@ 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 || lfsr_mtree_isinlined(lfs) || mdir->u.m.weight > 0); @@ -5244,7 +5239,8 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, lfsr_mdir_t mroot_ = (mdir->mid == -1 || lfsr_mtree_isinlined(lfs) ? mdir_ : lfs->mroot); - lfsr_mdir_t msibling_ = {.u.r.rbyd.trunk=0}; + // TODO + lfsr_mdir_t msibling_ = {.u.m.weight=0}; lfsr_btree_t mtree_ = lfs->mtree; bool dirtymroot = false; bool dirtymtree = false; @@ -5322,10 +5318,6 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, msibling_.mid & lfsr_mbidmask(lfs), msibling_.mid & lfsr_mridmask(lfs), msibling_.u.m.blocks[0], msibling_.u.m.blocks[1]); - // mark as dropped - mdir_.u.r.rbyd.trunk = 0; - msibling_.u.r.rbyd.trunk = 0; - // update our mtree int err = lfsr_btree_commit(lfs, &mtree_, LFSR_ATTRS( LFSR_ATTR(mdir_.mid | lfsr_mridmask(lfs), @@ -5342,9 +5334,6 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, msibling_.mid & lfsr_mridmask(lfs), msibling_.u.m.blocks[0], msibling_.u.m.blocks[1]); - // mark as dropped - msibling_.u.r.rbyd.trunk = 0; - // update our mtree uint8_t mdir_buf[LFSR_MDIR_DSIZE]; lfs_ssize_t mdir_dsize = lfsr_mdir_todisk(lfs, @@ -5368,9 +5357,6 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, mdir_.mid & lfsr_mridmask(lfs), mdir_.u.m.blocks[0], mdir_.u.m.blocks[1]); - // mark as dropped - mdir_.u.r.rbyd.trunk = 0; - // update our mtree uint8_t msibling_buf[LFSR_MDIR_DSIZE]; lfs_ssize_t msibling_dsize = lfsr_mdir_todisk(lfs, @@ -5444,9 +5430,6 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, mdir->mid & lfsr_mridmask(lfs), mdir->u.m.blocks[0], mdir->u.m.blocks[1]); - // mark as dropped - mdir_.u.r.rbyd.trunk = 0; - // update our mtree int err = lfsr_btree_commit(lfs, &mtree_, LFSR_ATTRS( LFSR_ATTR(mdir->mid | lfsr_mridmask(lfs), @@ -5705,7 +5688,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, opened; opened = opened->next) { // avoid double updating current mdir, avoid updating dropped mdirs - if (&opened->mdir == mdir || lfsr_mdir_isdropped(&opened->mdir)) { + if (&opened->mdir == mdir || opened->mdir.mid == -1) { continue; } @@ -5727,6 +5710,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, if (opened_mdir->mid < attrs[i].rid - attrs[i].delta) { // normal mdirs mark as dropped if (j == 0) { + opened_mdir->mid = -1; opened_mdir->u.r.rbyd.trunk = 0; goto next; } @@ -5755,7 +5739,7 @@ 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 & lfsr_mbidmask(lfs)) == (lfs_smax32(mdir->mid, 0) & lfsr_mbidmask(lfs))) { - if (!lfsr_mdir_isdropped(&msibling_) + if (msibling_.u.m.weight > 0 && (opened_mdir->mid & lfsr_mridmask(lfs)) >= (lfs_ssize_t)mdir_.u.m.weight) { LFS_ASSERT(lfsr_btree_weight(&mtree_) @@ -5777,7 +5761,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, // update mdir to follow requested rid if (mdir->mid != -1 - && !lfsr_mdir_isdropped(&msibling_) + && msibling_.u.m.weight > 0 && (mdir->mid & lfsr_mridmask(lfs)) >= (lfs_ssize_t)mdir_.u.m.weight) { // TODO this can happen if we split+drop while removing this mid, @@ -7395,7 +7379,7 @@ lfs_soff_t lfsr_dir_tell(lfs_t *lfs, lfsr_dir_t *dir) { int lfsr_dir_rewind(lfs_t *lfs, lfsr_dir_t *dir) { // do nothing if removed - if (lfsr_mdir_isdropped(&dir->bookmark_mdir)) { + if (dir->bookmark_mdir.mid == -1) { return 0; } diff --git a/tests/test_mtree.toml b/tests/test_mtree.toml index d764a792..66029b09 100644 --- a/tests/test_mtree.toml +++ b/tests/test_mtree.toml @@ -2725,11 +2725,9 @@ code = ''' assert(memcmp(buffer, "c", 1) == 0); // assert that our neighbors were updated correctly - assert(!lfsr_mdir_isdropped(&left_neighbor.mdir)); assert(left_neighbor.mdir.mid == 0); assert(memcmp(&left_neighbor.mdir.u.m, &lfs.mroot.u.m, sizeof(lfs.mroot.u.m)) == 0); - assert(!lfsr_mdir_isdropped(&right_neighbor.mdir)); assert(right_neighbor.mdir.mid == 2); assert(memcmp(&right_neighbor.mdir.u.m, &lfs.mroot.u.m, sizeof(lfs.mroot.u.m)) == 0); @@ -2772,8 +2770,7 @@ code = ''' assert(lfs.mroot.u.m.weight == 1); // assert that our neighbors were updated correctly - assert(lfsr_mdir_isdropped(&left_neighbor.mdir)); - assert(!lfsr_mdir_isdropped(&right_neighbor.mdir)); + assert(left_neighbor.mdir.mid == -1); assert(right_neighbor.mdir.mid == 0); assert(memcmp(&right_neighbor.mdir.u.m, &lfs.mroot.u.m, sizeof(lfs.mroot.u.m)) == 0); @@ -2816,11 +2813,10 @@ code = ''' assert(lfs.mroot.u.m.weight == 1); // assert that our neighbors were updated correctly - assert(!lfsr_mdir_isdropped(&left_neighbor.mdir)); assert(left_neighbor.mdir.mid == 0); assert(memcmp(&left_neighbor.mdir.u.m, &lfs.mroot.u.m, sizeof(lfs.mroot.u.m)) == 0); - assert(lfsr_mdir_isdropped(&right_neighbor.mdir)); + assert(right_neighbor.mdir.mid == -1); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &right_neighbor); @@ -2894,11 +2890,9 @@ code = ''' assert(msibling.u.m.weight == 1); // assert that our neighbors were updated correctly - assert(!lfsr_mdir_isdropped(&left_neighbor.mdir)); assert(left_neighbor.mdir.mid == 0*lfsr_mweight(&lfs)+0); assert(memcmp(&left_neighbor.mdir.u.m, &mdir.u.m, sizeof(mdir.u.m)) == 0); - assert(!lfsr_mdir_isdropped(&right_neighbor.mdir)); assert(right_neighbor.mdir.mid == 1*lfsr_mweight(&lfs)+0); assert(memcmp(&right_neighbor.mdir.u.m, &msibling.u.m, sizeof(msibling.u.m)) == 0); @@ -2970,11 +2964,9 @@ code = ''' assert(memcmp(buffer, "d", 1) == 0); // assert that our neighbors were updated correctly - assert(!lfsr_mdir_isdropped(&left_neighbor.mdir)); assert(left_neighbor.mdir.mid == 0*lfsr_mweight(&lfs)+0); assert(memcmp(&left_neighbor.mdir.u.m, &mdir.u.m, sizeof(mdir.u.m)) == 0); - assert(!lfsr_mdir_isdropped(&right_neighbor.mdir)); assert(right_neighbor.mdir.mid == 1*lfsr_mweight(&lfs)+1); assert(memcmp(&right_neighbor.mdir.u.m, &msibling.u.m, sizeof(msibling.u.m)) == 0); @@ -3073,11 +3065,9 @@ code = ''' assert(memcmp(buffer, "e", 1) == 0); // assert that our neighbors were updated correctly - assert(!lfsr_mdir_isdropped(&left_neighbor.mdir)); assert(left_neighbor.mdir.mid == 0*lfsr_mweight(&lfs)+0); assert(memcmp(&left_neighbor.mdir.u.m, &mdir.u.m, sizeof(mdir.u.m)) == 0); - assert(!lfsr_mdir_isdropped(&right_neighbor.mdir)); assert(right_neighbor.mdir.mid == 1*lfsr_mweight(&lfs)+1); assert(memcmp(&right_neighbor.mdir.u.m, &msibling.u.m, sizeof(msibling.u.m)) == 0); @@ -3141,11 +3131,9 @@ code = ''' assert(memcmp(buffer, "b", 1) == 0); // assert that our neighbors were updated correctly - assert(!lfsr_mdir_isdropped(&left_neighbor.mdir)); assert(left_neighbor.mdir.mid == 0); assert(memcmp(&left_neighbor.mdir.u.m, &lfs.mroot.u.m, sizeof(lfs.mroot.u.m)) == 0); - assert(!lfsr_mdir_isdropped(&right_neighbor.mdir)); assert(right_neighbor.mdir.mid == 1); assert(memcmp(&right_neighbor.mdir.u.m, &lfs.mroot.u.m, sizeof(lfs.mroot.u.m)) == 0); @@ -3238,10 +3226,8 @@ code = ''' assert(memcmp(buffer, "e", 1) == 0); // assert that our neighbors were updated correctly - assert(!lfsr_mdir_isdropped(&left_neighbor.mdir)); assert(left_neighbor.mdir.mid == 0*lfsr_mweight(&lfs)+0); assert(memcmp(&left_neighbor.mdir.u.m, &mdir.u.m, sizeof(mdir.u.m)) == 0); - assert(!lfsr_mdir_isdropped(&right_neighbor.mdir)); assert(right_neighbor.mdir.mid == 0*lfsr_mweight(&lfs)+2); assert(memcmp(&right_neighbor.mdir.u.m, &mdir.u.m, sizeof(mdir.u.m)) == 0); @@ -3330,7 +3316,6 @@ code = ''' assert(lfsr_mtree_weight(&lfs) == 4*lfsr_mweight(&lfs)); // assert that our neighbors were updated correctly - assert(!lfsr_mdir_isdropped(&left_neighbor.mdir)); assert(left_neighbor.mdir.mid == 0*lfsr_mweight(&lfs)+0); lfsr_mtree_lookup(&lfs, 0*lfsr_mweight(&lfs)+0, &mdir) => 0; assert(memcmp(&left_neighbor.mdir.u.m, &mdir.u.m, sizeof(mdir.u.m)) == 0); @@ -3419,12 +3404,10 @@ code = ''' assert(lfsr_mtree_weight(&lfs) == 2*lfsr_mweight(&lfs)); // assert that our neighbors were updated correctly - assert(!lfsr_mdir_isdropped(&left_neighbor.mdir)); assert(left_neighbor.mdir.mid == 0*lfsr_mweight(&lfs)+0); lfsr_mtree_lookup(&lfs, 0*lfsr_mweight(&lfs)+0, &mdir) => 0; assert(memcmp(&left_neighbor.mdir.u.m, &mdir.u.m, sizeof(mdir.u.m)) == 0); - assert(!lfsr_mdir_isdropped(&right_neighbor.mdir)); assert(right_neighbor.mdir.mid == 1*lfsr_mweight(&lfs)+0); lfsr_mtree_lookup(&lfs, 1*lfsr_mweight(&lfs)+0, &mdir) => 0; assert(memcmp(&right_neighbor.mdir.u.m, &mdir.u.m, sizeof(mdir.u.m)) == 0);