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...
This commit is contained in:
Christopher Haster
2023-09-05 13:24:24 -05:00
parent 441181d3d7
commit b06d48364d
2 changed files with 9 additions and 42 deletions
+7 -23
View File
@@ -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;
}
+2 -19
View File
@@ -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);