Fixed inlined mid -1/0 equivalence issue, made mid.bid left-leaning

We weren't comparing mid=-1/mid=0 correctly in lfsr_mdir_commit, which
can happend now thanks to inlining mids in our mroot. This went
unnoticed because we were just copying mroot.mid in our tests so we
never actually tested with mid=0. This is fixed now and the tests test
with a literal mid=0.

This also changes the mbids to be left-leaning, carving out an
mrid-sized number of bits from the mbid, making the route to compressed
mids easier.
This commit is contained in:
Christopher Haster
2023-08-29 14:49:43 -05:00
parent 19f2b24161
commit 2ea569c746
2 changed files with 105 additions and 109 deletions
+39 -43
View File
@@ -4795,13 +4795,15 @@ static int lfsr_mtree_lookup(lfs_t *lfs, lfsr_mid_t mid, lfsr_mdir_t *mdir_) {
} else { } else {
LFS_ASSERT(mid.bid >= 0); LFS_ASSERT(mid.bid >= 0);
LFS_ASSERT(mid.bid < (lfs_ssize_t)lfsr_mtree_weight(lfs)); LFS_ASSERT(mid.bid < (lfs_ssize_t)lfsr_mtree_weight(lfs));
lfs_size_t bid;
lfsr_tag_t tag; lfsr_tag_t tag;
lfsr_data_t data; lfsr_data_t data;
int err = lfsr_btree_lookupnext(lfs, &lfs->mtree, mid.bid, int err = lfsr_btree_lookupnext(lfs, &lfs->mtree, mid.bid,
(lfs_size_t*)&mid.bid, &tag, NULL, &data); &bid, &tag, NULL, &data);
if (err) { if (err) {
return err; return err;
} }
LFS_ASSERT(bid == (mid.bid | lfsr_mridmask(lfs)));
LFS_ASSERT(tag == LFSR_TAG_MDIR); LFS_ASSERT(tag == LFSR_TAG_MDIR);
// decode mdir // decode mdir
@@ -4862,7 +4864,7 @@ static int lfsr_mtree_seek(lfs_t *lfs, lfsr_mdir_t *mdir, lfs_off_t off) {
// lookup mdirs until we find our rid, we need to do this because // 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 // we don't know how many rids are in each mdir until we fetch
while (rid_ >= (lfs_ssize_t)mdir->u.m.weight) { while (rid_ >= (lfs_ssize_t)mdir->u.m.weight) {
lfsr_smbid_t bid_ = mdir->mid.bid + 1; lfsr_smbid_t bid_ = mdir->mid.bid + lfsr_mbidweight(lfs);
// end of mtree? // end of mtree?
if (bid_ >= (lfs_ssize_t)lfsr_mtree_weight(lfs)) { if (bid_ >= (lfs_ssize_t)lfsr_mtree_weight(lfs)) {
// TODO is this needed? // TODO is this needed?
@@ -5239,9 +5241,8 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
} }
// compact into new mdir tags < split_rid // compact into new mdir tags < split_rid
lfsr_smbid_t mbid = lfs_smax32(mdir->mid.bid, 0) | lfsr_mridmask(lfs);
int err = lfsr_mdir_compact_(lfs, &mdir_, int err = lfsr_mdir_compact_(lfs, &mdir_,
mbid, 0, split_rid, lfs_smax32(mdir->mid.bid, 0), 0, split_rid,
mdir, attrs, attr_count, NULL, 0); mdir, attrs, attr_count, NULL, 0);
if (err) { if (err) {
LFS_ASSERT(err != LFS_ERR_RANGE); LFS_ASSERT(err != LFS_ERR_RANGE);
@@ -5250,7 +5251,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
// compact into new mdir tags >= split_rid // compact into new mdir tags >= split_rid
err = lfsr_mdir_compact_(lfs, &msibling_, err = lfsr_mdir_compact_(lfs, &msibling_,
mbid+lfsr_mbidweight(lfs), split_rid, -1, lfs_smax32(mdir->mid.bid, 0), split_rid, -1,
mdir, attrs, attr_count, NULL, 0); mdir, attrs, attr_count, NULL, 0);
if (err) { if (err) {
LFS_ASSERT(err != LFS_ERR_RANGE); LFS_ASSERT(err != LFS_ERR_RANGE);
@@ -5282,8 +5283,8 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
// update our mtree // update our mtree
int err = lfsr_btree_commit(lfs, &mtree_, LFSR_ATTRS( int err = lfsr_btree_commit(lfs, &mtree_, LFSR_ATTRS(
LFSR_ATTR(mdir_.mid.bid, RM, -lfsr_mbidweight(lfs), LFSR_ATTR(mdir_.mid.bid | lfsr_mridmask(lfs),
NULL))); RM, -lfsr_mbidweight(lfs), NULL)));
if (err) { if (err) {
return err; return err;
} }
@@ -5306,8 +5307,8 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
} }
int err = lfsr_btree_commit(lfs, &mtree_, LFSR_ATTRS( int err = lfsr_btree_commit(lfs, &mtree_, LFSR_ATTRS(
LFSR_ATTR(mdir_.mid.bid, MDIR, 0, LFSR_ATTR(mdir_.mid.bid | lfsr_mridmask(lfs),
BUF(mdir_buf, mdir_dsize)))); MDIR, 0, BUF(mdir_buf, mdir_dsize))));
if (err) { if (err) {
return err; return err;
} }
@@ -5320,7 +5321,6 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
// mark as dropped // mark as dropped
mdir_.u.r.rbyd.trunk = 0; mdir_.u.r.rbyd.trunk = 0;
msibling_.mid.bid -= lfsr_mbidweight(lfs);
// update our mtree // update our mtree
uint8_t msibling_buf[LFSR_MDIR_DSIZE]; uint8_t msibling_buf[LFSR_MDIR_DSIZE];
@@ -5331,14 +5331,18 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
} }
int err = lfsr_btree_commit(lfs, &mtree_, LFSR_ATTRS( int err = lfsr_btree_commit(lfs, &mtree_, LFSR_ATTRS(
LFSR_ATTR(msibling_.mid.bid, MDIR, 0, LFSR_ATTR(msibling_.mid.bid | lfsr_mridmask(lfs),
BUF(msibling_buf, msibling_dsize)))); MDIR, 0, BUF(msibling_buf, msibling_dsize))));
if (err) { if (err) {
return err; return err;
} }
// no siblings reduced to zero // no siblings reduced to zero
} else { } else {
// adjust our sibling's mid, do this here in case other sibling
// was dropped
msibling_.mid.bid += lfsr_mbidweight(lfs);
// update out mtree // update out mtree
// lookup first name in sibling to use as the split name // lookup first name in sibling to use as the split name
@@ -5367,12 +5371,12 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
} }
err = lfsr_btree_commit(lfs, &mtree_, LFSR_ATTRS( err = lfsr_btree_commit(lfs, &mtree_, LFSR_ATTRS(
LFSR_ATTR(mdir_.mid.bid, MDIR, 0, LFSR_ATTR(mdir_.mid.bid | lfsr_mridmask(lfs),
BUF(mdir_buf, mdir_dsize)), MDIR, 0, BUF(mdir_buf, mdir_dsize)),
LFSR_ATTR(mdir_.mid.bid+1, BRANCH, +lfsr_mbidweight(lfs), LFSR_ATTR((mdir_.mid.bid | lfsr_mridmask(lfs))+1,
DATA(split_data)), BRANCH, +lfsr_mbidweight(lfs), DATA(split_data)),
LFSR_ATTR(msibling_.mid.bid, MDIR, 0, LFSR_ATTR(msibling_.mid.bid | lfsr_mridmask(lfs),
BUF(msibling_buf, msibling_dsize)))); MDIR, 0, BUF(msibling_buf, msibling_dsize))));
if (err) { if (err) {
return err; return err;
} }
@@ -5393,7 +5397,8 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
// update our mtree // update our mtree
int err = lfsr_btree_commit(lfs, &mtree_, LFSR_ATTRS( int err = lfsr_btree_commit(lfs, &mtree_, LFSR_ATTRS(
LFSR_ATTR(mdir->mid.bid, RM, -lfsr_mbidweight(lfs), NULL))); LFSR_ATTR(mdir->mid.bid | lfsr_mridmask(lfs),
RM, -lfsr_mbidweight(lfs), NULL)));
if (err) { if (err) {
return err; return err;
} }
@@ -5425,8 +5430,8 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
} }
int err = lfsr_btree_commit(lfs, &mtree_, LFSR_ATTRS( int err = lfsr_btree_commit(lfs, &mtree_, LFSR_ATTRS(
LFSR_ATTR(mdir->mid.bid, MDIR, 0, LFSR_ATTR(mdir->mid.bid | lfsr_mridmask(lfs),
BUF(mdir_buf, mdir_dsize)))); MDIR, 0, BUF(mdir_buf, mdir_dsize))));
if (err) { if (err) {
return err; return err;
} }
@@ -5463,11 +5468,11 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
// fix our grm // fix our grm
for (uint8_t j = 0; j < 2; j++) { for (uint8_t j = 0; j < 2; j++) {
if (grm->rms[j].bid == mdir->mid.bid) { if (grm->rms[j].bid == lfs_smax32(mdir->mid.bid, 0)) {
LFS_ASSERT(grm->rms[j].rid LFS_ASSERT(grm->rms[j].rid
<= (lfs_ssize_t)mdir->u.m.weight); <= (lfs_ssize_t)mdir->u.m.weight);
if (grm->rms[j].rid >= (lfs_ssize_t)mdir_.u.m.weight) { if (grm->rms[j].rid >= (lfs_ssize_t)mdir_.u.m.weight) {
grm->rms[j].bid = msibling_.mid.bid; grm->rms[j].bid += lfsr_mbidweight(lfs);
grm->rms[j].rid -= mdir_.u.m.weight; grm->rms[j].rid -= mdir_.u.m.weight;
} }
// update mid if we had a split or drop // update mid if we had a split or drop
@@ -5477,16 +5482,6 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
grm->rms[j].bid += lfsr_btree_weight(&mtree_) grm->rms[j].bid += lfsr_btree_weight(&mtree_)
- lfsr_mtree_weight(lfs); - lfsr_mtree_weight(lfs);
} }
//// TODO?
// // 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].bid <= 0);
// if (grm->rms[j].bid == 0) {
// grm->rms[j].bid = -1;
// }
// }
} }
// xor our fix into our gdelta // xor our fix into our gdelta
@@ -5665,12 +5660,13 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
// mdirs and normal dirs which are pairs of mdirs // mdirs and normal dirs which are pairs of mdirs
for (uint8_t j = 0; j <= type; j++) { for (uint8_t j = 0; j <= type; j++) {
lfsr_mdir_t *opened_mdir = &(&opened->mdir)[j]; lfsr_mdir_t *opened_mdir = &(&opened->mdir)[j];
LFS_ASSERT(opened_mdir->mid.bid >= 0);
// first play out any attrs that change our rid // first play out any attrs that change our rid
for (lfs_size_t i = 0; i < attr_count; i++) { for (lfs_size_t i = 0; i < attr_count; i++) {
// TODO clean this up a bit? // TODO clean this up a bit?
// adjust opened mdirs? // adjust opened mdirs?
if (opened_mdir->mid.bid == mdir->mid.bid if (opened_mdir->mid.bid == lfs_smax32(mdir->mid.bid, 0)
&& opened_mdir->mid.rid >= attrs[i].rid) { && opened_mdir->mid.rid >= attrs[i].rid) {
// removed? // removed?
if (opened_mdir->mid.rid if (opened_mdir->mid.rid
@@ -5703,17 +5699,16 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
} }
// update any opened mdirs if we had a split or drop // update any opened mdirs if we had a split or drop
if (opened_mdir->mid.bid == mdir->mid.bid) { if (opened_mdir->mid.bid == lfs_smax32(mdir->mid.bid, 0)) {
if (!lfsr_mdir_isdropped(&msibling_) if (!lfsr_mdir_isdropped(&msibling_)
&& opened_mdir->mid.rid && opened_mdir->mid.rid
>= (lfs_ssize_t)mdir_.u.m.weight) { >= (lfs_ssize_t)mdir_.u.m.weight) {
LFS_ASSERT(lfsr_btree_weight(&mtree_) LFS_ASSERT(lfsr_btree_weight(&mtree_)
!= lfsr_mtree_weight(lfs)); != lfsr_mtree_weight(lfs));
opened_mdir->mid.bid = msibling_.mid.bid; opened_mdir->mid.bid += lfsr_mbidweight(lfs);
opened_mdir->mid.rid -= mdir_.u.m.weight; opened_mdir->mid.rid -= mdir_.u.m.weight;
opened_mdir->u.m = msibling_.u.m; opened_mdir->u.m = msibling_.u.m;
} else { } else {
opened_mdir->mid.bid = mdir_.mid.bid;
opened_mdir->u.m = mdir_.u.m; opened_mdir->u.m = mdir_.u.m;
} }
} else if (opened_mdir->mid.bid > mdir->mid.bid) { } else if (opened_mdir->mid.bid > mdir->mid.bid) {
@@ -5727,12 +5722,11 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
// update mdir to follow requested rid // update mdir to follow requested rid
LFS_ASSERT(mdir->mid.rid <= (lfs_ssize_t)mdir->u.m.weight); LFS_ASSERT(mdir->mid.rid <= (lfs_ssize_t)mdir->u.m.weight);
if (mdir == &lfs->mroot) { if (mdir->mid.bid != -1
// do nothing, we update mroot later && !lfsr_mdir_isdropped(&msibling_)
} else if (!lfsr_mdir_isdropped(&msibling_)
&& mdir->mid.rid >= (lfs_ssize_t)mdir_.u.m.weight) { && mdir->mid.rid >= (lfs_ssize_t)mdir_.u.m.weight) {
LFS_ASSERT(lfsr_btree_weight(&mtree_) != lfsr_mtree_weight(lfs)); LFS_ASSERT(lfsr_btree_weight(&mtree_) != lfsr_mtree_weight(lfs));
mdir->mid.bid = msibling_.mid.bid; mdir->mid.bid += lfsr_mbidweight(lfs);
mdir->mid.rid -= mdir_.u.m.weight; mdir->mid.rid -= mdir_.u.m.weight;
mdir->u.m = msibling_.u.m; mdir->u.m = msibling_.u.m;
} else { } else {
@@ -5781,10 +5775,11 @@ static int lfsr_mtree_namelookup(lfs_t *lfs,
} else { } else {
lfs_size_t bid; lfs_size_t bid;
lfsr_tag_t tag; lfsr_tag_t tag;
lfs_size_t weight;
lfsr_data_t data; lfsr_data_t data;
int err = lfsr_btree_namelookup(lfs, &lfs->mtree, int err = lfsr_btree_namelookup(lfs, &lfs->mtree,
did, name, name_size, did, name, name_size,
&bid, &tag, NULL, &data); &bid, &tag, &weight, &data);
if (err) { if (err) {
return err; return err;
} }
@@ -5797,7 +5792,8 @@ static int lfsr_mtree_namelookup(lfs_t *lfs,
} }
// fetch mdir // fetch mdir
err = lfsr_mdir_fetch(lfs, &mdir, mdir.u.m.blocks, LFSR_MID(bid, -1)); err = lfsr_mdir_fetch(lfs, &mdir, mdir.u.m.blocks,
LFSR_MID(bid-(weight-1), -1));
if (err) { if (err) {
return err; return err;
} }
+66 -66
View File
@@ -2675,9 +2675,9 @@ code = '''
assert(lfsr_mtree_isinlined(&lfs)); assert(lfsr_mtree_isinlined(&lfs));
lfsr_openedmdir_t left_neighbor = { lfsr_openedmdir_t left_neighbor = {
.mdir={.mid=LFSR_MID(lfs.mroot.mid.bid, 0), .u=lfs.mroot.u}}; .mdir={.mid=LFSR_MID(0, 0), .u.m=lfs.mroot.u.m}};
lfsr_openedmdir_t right_neighbor = { lfsr_openedmdir_t right_neighbor = {
.mdir={.mid=LFSR_MID(lfs.mroot.mid.bid, 1), .u=lfs.mroot.u}}; .mdir={.mid=LFSR_MID(0, 1), .u.m=lfs.mroot.u.m}};
lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor);
lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor);
@@ -2695,15 +2695,15 @@ code = '''
// assert that our neighbors were updated correctly // assert that our neighbors were updated correctly
assert(!lfsr_mdir_isdropped(&left_neighbor.mdir)); assert(!lfsr_mdir_isdropped(&left_neighbor.mdir));
assert(left_neighbor.mdir.mid.bid == lfs.mroot.mid.bid); assert(left_neighbor.mdir.mid.bid == 0);
assert(left_neighbor.mdir.mid.rid == 0); assert(left_neighbor.mdir.mid.rid == 0);
assert(memcmp(&left_neighbor.mdir.u, &lfs.mroot.u, assert(memcmp(&left_neighbor.mdir.u.m, &lfs.mroot.u.m,
sizeof(lfs.mroot.u)) == 0); sizeof(lfs.mroot.u.m)) == 0);
assert(!lfsr_mdir_isdropped(&right_neighbor.mdir)); assert(!lfsr_mdir_isdropped(&right_neighbor.mdir));
assert(right_neighbor.mdir.mid.bid == lfs.mroot.mid.bid); assert(right_neighbor.mdir.mid.bid == 0);
assert(right_neighbor.mdir.mid.rid == 2); assert(right_neighbor.mdir.mid.rid == 2);
assert(memcmp(&right_neighbor.mdir.u, &lfs.mroot.u, assert(memcmp(&right_neighbor.mdir.u.m, &lfs.mroot.u.m,
sizeof(lfs.mroot.u)) == 0); sizeof(lfs.mroot.u.m)) == 0);
lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &left_neighbor);
lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &right_neighbor); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &right_neighbor);
@@ -2729,9 +2729,9 @@ code = '''
assert(lfsr_mtree_isinlined(&lfs)); assert(lfsr_mtree_isinlined(&lfs));
lfsr_openedmdir_t left_neighbor = { lfsr_openedmdir_t left_neighbor = {
.mdir={.mid=LFSR_MID(lfs.mroot.mid.bid, 0), .u=lfs.mroot.u}}; .mdir={.mid=LFSR_MID(0, 0), .u.m=lfs.mroot.u.m}};
lfsr_openedmdir_t right_neighbor = { lfsr_openedmdir_t right_neighbor = {
.mdir={.mid=LFSR_MID(lfs.mroot.mid.bid, 1), .u=lfs.mroot.u}}; .mdir={.mid=LFSR_MID(0, 1), .u.m=lfs.mroot.u.m}};
lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor);
lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor);
@@ -2745,10 +2745,10 @@ code = '''
// assert that our neighbors were updated correctly // assert that our neighbors were updated correctly
assert(lfsr_mdir_isdropped(&left_neighbor.mdir)); assert(lfsr_mdir_isdropped(&left_neighbor.mdir));
assert(!lfsr_mdir_isdropped(&right_neighbor.mdir)); assert(!lfsr_mdir_isdropped(&right_neighbor.mdir));
assert(right_neighbor.mdir.mid.bid == lfs.mroot.mid.bid); assert(right_neighbor.mdir.mid.bid == 0);
assert(right_neighbor.mdir.mid.rid == 0); assert(right_neighbor.mdir.mid.rid == 0);
assert(memcmp(&right_neighbor.mdir.u, &lfs.mroot.u, assert(memcmp(&right_neighbor.mdir.u.m, &lfs.mroot.u.m,
sizeof(lfs.mroot.u)) == 0); sizeof(lfs.mroot.u.m)) == 0);
lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &left_neighbor);
lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &right_neighbor); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &right_neighbor);
@@ -2774,9 +2774,9 @@ code = '''
assert(lfsr_mtree_isinlined(&lfs)); assert(lfsr_mtree_isinlined(&lfs));
lfsr_openedmdir_t left_neighbor = { lfsr_openedmdir_t left_neighbor = {
.mdir={.mid=LFSR_MID(lfs.mroot.mid.bid, 0), .u=lfs.mroot.u}}; .mdir={.mid=LFSR_MID(0, 0), .u.m=lfs.mroot.u.m}};
lfsr_openedmdir_t right_neighbor = { lfsr_openedmdir_t right_neighbor = {
.mdir={.mid=LFSR_MID(lfs.mroot.mid.bid, 1), .u=lfs.mroot.u}}; .mdir={.mid=LFSR_MID(0, 1), .u.m=lfs.mroot.u.m}};
lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor);
lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor);
@@ -2789,10 +2789,10 @@ code = '''
// assert that our neighbors were updated correctly // assert that our neighbors were updated correctly
assert(!lfsr_mdir_isdropped(&left_neighbor.mdir)); assert(!lfsr_mdir_isdropped(&left_neighbor.mdir));
assert(left_neighbor.mdir.mid.bid == lfs.mroot.mid.bid); assert(left_neighbor.mdir.mid.bid == 0);
assert(left_neighbor.mdir.mid.rid == 0); assert(left_neighbor.mdir.mid.rid == 0);
assert(memcmp(&left_neighbor.mdir.u, &lfs.mroot.u, assert(memcmp(&left_neighbor.mdir.u.m, &lfs.mroot.u.m,
sizeof(lfs.mroot.u)) == 0); sizeof(lfs.mroot.u.m)) == 0);
assert(lfsr_mdir_isdropped(&right_neighbor.mdir)); assert(lfsr_mdir_isdropped(&right_neighbor.mdir));
lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &left_neighbor);
@@ -2821,9 +2821,9 @@ code = '''
assert(lfsr_mtree_isinlined(&lfs)); assert(lfsr_mtree_isinlined(&lfs));
lfsr_openedmdir_t left_neighbor = { lfsr_openedmdir_t left_neighbor = {
.mdir={.mid=LFSR_MID(lfs.mroot.mid.bid, 0), .u=lfs.mroot.u}}; .mdir={.mid=LFSR_MID(0, 0), .u.m=lfs.mroot.u.m}};
lfsr_openedmdir_t right_neighbor = { lfsr_openedmdir_t right_neighbor = {
.mdir={.mid=LFSR_MID(lfs.mroot.mid.bid, 1), .u=lfs.mroot.u}}; .mdir={.mid=LFSR_MID(0, 1), .u.m=lfs.mroot.u.m}};
lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor);
lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor);
@@ -2868,15 +2868,15 @@ code = '''
// assert that our neighbors were updated correctly // assert that our neighbors were updated correctly
assert(!lfsr_mdir_isdropped(&left_neighbor.mdir)); assert(!lfsr_mdir_isdropped(&left_neighbor.mdir));
assert(left_neighbor.mdir.mid.bid == 0*lfsr_mbidweight(&lfs) | lfsr_mridmask(&lfs)); assert(left_neighbor.mdir.mid.bid == 0*lfsr_mbidweight(&lfs));
assert(left_neighbor.mdir.mid.rid == 0); assert(left_neighbor.mdir.mid.rid == 0);
assert(memcmp(&left_neighbor.mdir.u, &mdir.u, assert(memcmp(&left_neighbor.mdir.u.m, &mdir.u.m,
sizeof(mdir.u)) == 0); sizeof(mdir.u.m)) == 0);
assert(!lfsr_mdir_isdropped(&right_neighbor.mdir)); assert(!lfsr_mdir_isdropped(&right_neighbor.mdir));
assert(right_neighbor.mdir.mid.bid == 1*lfsr_mbidweight(&lfs) | lfsr_mridmask(&lfs)); assert(right_neighbor.mdir.mid.bid == 1*lfsr_mbidweight(&lfs));
assert(right_neighbor.mdir.mid.rid == 0); assert(right_neighbor.mdir.mid.rid == 0);
assert(memcmp(&right_neighbor.mdir.u, &msibling.u, assert(memcmp(&right_neighbor.mdir.u.m, &msibling.u.m,
sizeof(msibling.u)) == 0); sizeof(msibling.u.m)) == 0);
lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &left_neighbor);
lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &right_neighbor); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &right_neighbor);
@@ -2904,9 +2904,9 @@ code = '''
assert(lfsr_mtree_isinlined(&lfs)); assert(lfsr_mtree_isinlined(&lfs));
lfsr_openedmdir_t left_neighbor = { lfsr_openedmdir_t left_neighbor = {
.mdir={.mid=LFSR_MID(lfs.mroot.mid.bid, 0), .u=lfs.mroot.u}}; .mdir={.mid=LFSR_MID(0, 0), .u.m=lfs.mroot.u.m}};
lfsr_openedmdir_t right_neighbor = { lfsr_openedmdir_t right_neighbor = {
.mdir={.mid=LFSR_MID(lfs.mroot.mid.bid, 1), .u=lfs.mroot.u}}; .mdir={.mid=LFSR_MID(0, 1), .u.m=lfs.mroot.u.m}};
lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor);
lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor);
@@ -2946,15 +2946,15 @@ code = '''
// assert that our neighbors were updated correctly // assert that our neighbors were updated correctly
assert(!lfsr_mdir_isdropped(&left_neighbor.mdir)); assert(!lfsr_mdir_isdropped(&left_neighbor.mdir));
assert(left_neighbor.mdir.mid.bid == 0*lfsr_mbidweight(&lfs) | lfsr_mridmask(&lfs)); assert(left_neighbor.mdir.mid.bid == 0*lfsr_mbidweight(&lfs));
assert(left_neighbor.mdir.mid.rid == 0); assert(left_neighbor.mdir.mid.rid == 0);
assert(memcmp(&left_neighbor.mdir.u, &mdir.u, assert(memcmp(&left_neighbor.mdir.u.m, &mdir.u.m,
sizeof(mdir.u)) == 0); sizeof(mdir.u.m)) == 0);
assert(!lfsr_mdir_isdropped(&right_neighbor.mdir)); assert(!lfsr_mdir_isdropped(&right_neighbor.mdir));
assert(right_neighbor.mdir.mid.bid == 1*lfsr_mbidweight(&lfs) | lfsr_mridmask(&lfs)); assert(right_neighbor.mdir.mid.bid == 1*lfsr_mbidweight(&lfs));
assert(right_neighbor.mdir.mid.rid == 1); assert(right_neighbor.mdir.mid.rid == 1);
assert(memcmp(&right_neighbor.mdir.u, &msibling.u, assert(memcmp(&right_neighbor.mdir.u.m, &msibling.u.m,
sizeof(msibling.u)) == 0); sizeof(msibling.u.m)) == 0);
lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &left_neighbor);
lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &right_neighbor); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &right_neighbor);
@@ -3009,9 +3009,9 @@ code = '''
assert(mdir.u.m.weight == 3); assert(mdir.u.m.weight == 3);
lfsr_openedmdir_t left_neighbor = { lfsr_openedmdir_t left_neighbor = {
.mdir={.mid=LFSR_MID(mdir.mid.bid, 0), .u=mdir.u}}; .mdir={.mid=LFSR_MID(0, 0), .u.m=mdir.u.m}};
lfsr_openedmdir_t right_neighbor = { lfsr_openedmdir_t right_neighbor = {
.mdir={.mid=LFSR_MID(mdir.mid.bid, 2), .u=mdir.u}}; .mdir={.mid=LFSR_MID(0, 2), .u.m=mdir.u.m}};
lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor);
lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor);
@@ -3050,15 +3050,15 @@ code = '''
// assert that our neighbors were updated correctly // assert that our neighbors were updated correctly
assert(!lfsr_mdir_isdropped(&left_neighbor.mdir)); assert(!lfsr_mdir_isdropped(&left_neighbor.mdir));
assert(left_neighbor.mdir.mid.bid == 0*lfsr_mbidweight(&lfs) | lfsr_mridmask(&lfs)); assert(left_neighbor.mdir.mid.bid == 0*lfsr_mbidweight(&lfs));
assert(left_neighbor.mdir.mid.rid == 0); assert(left_neighbor.mdir.mid.rid == 0);
assert(memcmp(&left_neighbor.mdir.u, &mdir.u, assert(memcmp(&left_neighbor.mdir.u.m, &mdir.u.m,
sizeof(mdir.u)) == 0); sizeof(mdir.u.m)) == 0);
assert(!lfsr_mdir_isdropped(&right_neighbor.mdir)); assert(!lfsr_mdir_isdropped(&right_neighbor.mdir));
assert(right_neighbor.mdir.mid.bid == 1*lfsr_mbidweight(&lfs) | lfsr_mridmask(&lfs)); assert(right_neighbor.mdir.mid.bid == 1*lfsr_mbidweight(&lfs));
assert(right_neighbor.mdir.mid.rid == 1); assert(right_neighbor.mdir.mid.rid == 1);
assert(memcmp(&right_neighbor.mdir.u, &msibling.u, assert(memcmp(&right_neighbor.mdir.u.m, &msibling.u.m,
sizeof(msibling.u)) == 0); sizeof(msibling.u.m)) == 0);
lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &left_neighbor);
lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &right_neighbor); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &right_neighbor);
@@ -3088,9 +3088,9 @@ code = '''
assert(lfsr_mtree_isinlined(&lfs)); assert(lfsr_mtree_isinlined(&lfs));
lfsr_openedmdir_t left_neighbor = { lfsr_openedmdir_t left_neighbor = {
.mdir={.mid=LFSR_MID(lfs.mroot.mid.bid, 0), .u=lfs.mroot.u}}; .mdir={.mid=LFSR_MID(0, 0), .u.m=lfs.mroot.u.m}};
lfsr_openedmdir_t right_neighbor = { lfsr_openedmdir_t right_neighbor = {
.mdir={.mid=LFSR_MID(lfs.mroot.mid.bid, 1), .u=lfs.mroot.u}}; .mdir={.mid=LFSR_MID(0, 1), .u.m=lfs.mroot.u.m}};
lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor);
lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor);
@@ -3120,15 +3120,15 @@ code = '''
// assert that our neighbors were updated correctly // assert that our neighbors were updated correctly
assert(!lfsr_mdir_isdropped(&left_neighbor.mdir)); assert(!lfsr_mdir_isdropped(&left_neighbor.mdir));
assert(left_neighbor.mdir.mid.bid == lfs.mroot.mid.bid); assert(left_neighbor.mdir.mid.bid == 0);
assert(left_neighbor.mdir.mid.rid == 0); assert(left_neighbor.mdir.mid.rid == 0);
assert(memcmp(&left_neighbor.mdir.u, &lfs.mroot.u, assert(memcmp(&left_neighbor.mdir.u.m, &lfs.mroot.u.m,
sizeof(lfs.mroot.u)) == 0); sizeof(lfs.mroot.u.m)) == 0);
assert(!lfsr_mdir_isdropped(&right_neighbor.mdir)); assert(!lfsr_mdir_isdropped(&right_neighbor.mdir));
assert(right_neighbor.mdir.mid.bid == lfs.mroot.mid.bid); assert(right_neighbor.mdir.mid.bid == 0);
assert(right_neighbor.mdir.mid.rid == 1); assert(right_neighbor.mdir.mid.rid == 1);
assert(memcmp(&right_neighbor.mdir.u, &lfs.mroot.u, assert(memcmp(&right_neighbor.mdir.u.m, &lfs.mroot.u.m,
sizeof(lfs.mroot.u)) == 0); sizeof(lfs.mroot.u.m)) == 0);
lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &left_neighbor);
lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &right_neighbor); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &right_neighbor);
@@ -3185,9 +3185,9 @@ code = '''
assert(mdir.u.m.weight == 3); assert(mdir.u.m.weight == 3);
lfsr_openedmdir_t left_neighbor = { lfsr_openedmdir_t left_neighbor = {
.mdir={.mid=LFSR_MID(mdir.mid.bid, 0), .u=mdir.u}}; .mdir={.mid=LFSR_MID(0, 0), .u.m=mdir.u.m}};
lfsr_openedmdir_t right_neighbor = { lfsr_openedmdir_t right_neighbor = {
.mdir={.mid=LFSR_MID(mdir.mid.bid, 2), .u=mdir.u}}; .mdir={.mid=LFSR_MID(0, 2), .u.m=mdir.u.m}};
lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &left_neighbor);
lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor); lfsr_mdir_addopened(&lfs, LFS_TYPE_REG, &right_neighbor);
@@ -3219,20 +3219,20 @@ code = '''
// assert that our neighbors were updated correctly // assert that our neighbors were updated correctly
assert(!lfsr_mdir_isdropped(&left_neighbor.mdir)); assert(!lfsr_mdir_isdropped(&left_neighbor.mdir));
assert(left_neighbor.mdir.mid.bid == 0*lfsr_mbidweight(&lfs) | lfsr_mridmask(&lfs)); assert(left_neighbor.mdir.mid.bid == 0*lfsr_mbidweight(&lfs));
assert(left_neighbor.mdir.mid.rid == 0); assert(left_neighbor.mdir.mid.rid == 0);
assert(memcmp(&left_neighbor.mdir.u, &mdir.u, sizeof(mdir.u)) == 0); assert(memcmp(&left_neighbor.mdir.u.m, &mdir.u.m, sizeof(mdir.u.m)) == 0);
assert(!lfsr_mdir_isdropped(&right_neighbor.mdir)); assert(!lfsr_mdir_isdropped(&right_neighbor.mdir));
assert(right_neighbor.mdir.mid.bid == 0*lfsr_mbidweight(&lfs) | lfsr_mridmask(&lfs)); assert(right_neighbor.mdir.mid.bid == 0*lfsr_mbidweight(&lfs));
assert(right_neighbor.mdir.mid.rid == 2); assert(right_neighbor.mdir.mid.rid == 2);
assert(memcmp(&right_neighbor.mdir.u, &mdir.u, sizeof(mdir.u)) == 0); assert(memcmp(&right_neighbor.mdir.u.m, &mdir.u.m, sizeof(mdir.u.m)) == 0);
lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &left_neighbor);
lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &right_neighbor); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &right_neighbor);
lfsr_unmount(&lfs) => 0; lfsr_unmount(&lfs) => 0;
''' '''
[cases.test_mtree_neighbor_mid_split] [cases.test_mtree_neighbor_middle_split]
# this should be set so only one entry can fit in a metadata block # this should be set so only one entry can fit in a metadata block
defines.SIZE = 'BLOCK_SIZE / 4' defines.SIZE = 'BLOCK_SIZE / 4'
# make it so blocks relocate every two compacts # make it so blocks relocate every two compacts
@@ -3313,22 +3313,22 @@ code = '''
// assert that our neighbors were updated correctly // assert that our neighbors were updated correctly
assert(!lfsr_mdir_isdropped(&left_neighbor.mdir)); assert(!lfsr_mdir_isdropped(&left_neighbor.mdir));
assert(left_neighbor.mdir.mid.bid == 0*lfsr_mbidweight(&lfs) | lfsr_mridmask(&lfs)); assert(left_neighbor.mdir.mid.bid == 0*lfsr_mbidweight(&lfs));
assert(left_neighbor.mdir.mid.rid == 0); assert(left_neighbor.mdir.mid.rid == 0);
lfsr_mtree_lookup(&lfs, LFSR_MID(0*lfsr_mbidweight(&lfs), -1), &mdir) => 0; lfsr_mtree_lookup(&lfs, LFSR_MID(0*lfsr_mbidweight(&lfs), -1), &mdir) => 0;
assert(memcmp(&left_neighbor.mdir.u, &mdir.u, sizeof(mdir.u)) == 0); assert(memcmp(&left_neighbor.mdir.u.m, &mdir.u.m, sizeof(mdir.u.m)) == 0);
assert(right_neighbor.mdir.mid.bid == 3*lfsr_mbidweight(&lfs) | lfsr_mridmask(&lfs)); assert(right_neighbor.mdir.mid.bid == 3*lfsr_mbidweight(&lfs));
assert(right_neighbor.mdir.mid.rid == 0); assert(right_neighbor.mdir.mid.rid == 0);
lfsr_mtree_lookup(&lfs, LFSR_MID(3*lfsr_mbidweight(&lfs), -1), &mdir) => 0; lfsr_mtree_lookup(&lfs, LFSR_MID(3*lfsr_mbidweight(&lfs), -1), &mdir) => 0;
assert(memcmp(&right_neighbor.mdir.u, &mdir.u, sizeof(mdir.u)) == 0); assert(memcmp(&right_neighbor.mdir.u.m, &mdir.u.m, sizeof(mdir.u.m)) == 0);
lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &left_neighbor);
lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &right_neighbor); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &right_neighbor);
lfsr_unmount(&lfs) => 0; lfsr_unmount(&lfs) => 0;
''' '''
[cases.test_mtree_neighbor_mid_drop] [cases.test_mtree_neighbor_middle_drop]
# this should be set so only one entry can fit in a metadata block # this should be set so only one entry can fit in a metadata block
defines.SIZE = 'BLOCK_SIZE / 4' defines.SIZE = 'BLOCK_SIZE / 4'
# make it so blocks relocate every two compacts # make it so blocks relocate every two compacts
@@ -3404,16 +3404,16 @@ code = '''
// assert that our neighbors were updated correctly // assert that our neighbors were updated correctly
assert(!lfsr_mdir_isdropped(&left_neighbor.mdir)); assert(!lfsr_mdir_isdropped(&left_neighbor.mdir));
assert(left_neighbor.mdir.mid.bid == 0*lfsr_mbidweight(&lfs) | lfsr_mridmask(&lfs)); assert(left_neighbor.mdir.mid.bid == 0*lfsr_mbidweight(&lfs));
assert(left_neighbor.mdir.mid.rid == 0); assert(left_neighbor.mdir.mid.rid == 0);
lfsr_mtree_lookup(&lfs, LFSR_MID(0*lfsr_mbidweight(&lfs), -1), &mdir) => 0; lfsr_mtree_lookup(&lfs, LFSR_MID(0*lfsr_mbidweight(&lfs), -1), &mdir) => 0;
assert(memcmp(&left_neighbor.mdir.u, &mdir.u, sizeof(mdir.u)) == 0); assert(memcmp(&left_neighbor.mdir.u.m, &mdir.u.m, sizeof(mdir.u.m)) == 0);
assert(!lfsr_mdir_isdropped(&right_neighbor.mdir)); assert(!lfsr_mdir_isdropped(&right_neighbor.mdir));
assert(right_neighbor.mdir.mid.bid == 1*lfsr_mbidweight(&lfs) | lfsr_mridmask(&lfs)); assert(right_neighbor.mdir.mid.bid == 1*lfsr_mbidweight(&lfs));
assert(right_neighbor.mdir.mid.rid == 0); assert(right_neighbor.mdir.mid.rid == 0);
lfsr_mtree_lookup(&lfs, LFSR_MID(1*lfsr_mbidweight(&lfs), -1), &mdir) => 0; lfsr_mtree_lookup(&lfs, LFSR_MID(1*lfsr_mbidweight(&lfs), -1), &mdir) => 0;
assert(memcmp(&right_neighbor.mdir.u, &mdir.u, sizeof(mdir.u)) == 0); assert(memcmp(&right_neighbor.mdir.u.m, &mdir.u.m, sizeof(mdir.u.m)) == 0);
lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &left_neighbor); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &left_neighbor);
lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &right_neighbor); lfsr_mdir_removeopened(&lfs, LFS_TYPE_REG, &right_neighbor);