Reworked grm encoding a bit
This drops the leading count/mode byte, and instead uses mid=0 to
terminate grms. This shaves off 1 bytes from grmdeltas.
Previously, we needed the count/mode byte for a couple reasons:
- We needed to know the number of grm entries somehow, and there wasn't
always an obvious sentinel value. mid=-1, for example, is
unrepresentable with our unsigned leb128 encoding.
But now that development has settled, we can use mid=0.0 to figure out
the end-of-queue. mid=0.0 should always map to the root bookmark,
which doesn't make sense to delete, so it makes for a reasonable null
terminator here.
- It provided a route for future grm extensions, which could use the >2
count/mode encodings.
But I think we can use additional grm tag encodings for this.
There's only one gdelta tag so far, but the current plan for future
gdelta tags is to carve out the bottom 2 bits for redund like we do
with the struct tags:
LFSR_TAG_GDELTA 0x01tt v--- ---1 -ttt ttrr
LFSR_TAG_GRMDELTA 0x0100 v--- ---1 ---- ----
LFSR_TAG_GBMAPDELTA 0x0104 v--- ---1 ---- -1rr
LFSR_TAG_GDDTREEDELTA 0x0108 v--- ---1 ---- 1-rr
LFSR_TAG_GPTREEDELTA 0x010c v--- ---1 ---- 11rr
...
Decoding is a bit more complicated for gstate, since we will need to
xor those bits if mutable, but this avoids needing a full byte just
for redund in every auxiliary tree.
Long story short, we can leverage the lower 2 bits of the grm tag for
future extensions using the same mechanism.
This may seem like a lot of effort for only a handful of bytes, but keep
in mind each gdelta lives in more-or-less every mdir in the filesystem.
Also saves a bit of code/ctx:
code stack ctx
before: 35772 2368 640
after: 35768 (-0.0%) 2368 (+0.0%) 636 (-0.6%)
This commit is contained in:
@@ -7185,29 +7185,34 @@ static void lfsr_fs_mkdirty(lfs_t *lfs) {
|
|||||||
/// Global-state things ///
|
/// Global-state things ///
|
||||||
|
|
||||||
// grm (global remove) things
|
// grm (global remove) things
|
||||||
static inline uint8_t lfsr_grm_count_(const lfsr_grm_t *grm) {
|
static inline lfs_size_t lfsr_grm_count_(const lfsr_grm_t *grm) {
|
||||||
return (grm->mids[0] >= 0) + (grm->mids[1] >= 0);
|
return (grm->queue[0] != 0) + (grm->queue[1] != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint8_t lfsr_grm_count(const lfs_t *lfs) {
|
static inline lfs_size_t lfsr_grm_count(const lfs_t *lfs) {
|
||||||
return lfsr_grm_count_(&lfs->grm);
|
return lfsr_grm_count_(&lfs->grm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void lfsr_grm_push(lfs_t *lfs, lfsr_smid_t mid) {
|
static inline void lfsr_grm_push(lfs_t *lfs, lfsr_smid_t mid) {
|
||||||
LFS_ASSERT(lfs->grm.mids[1] == -1);
|
// note mid=0.0 always maps to the root bookmark and should never
|
||||||
lfs->grm.mids[1] = lfs->grm.mids[0];
|
// be grmed
|
||||||
lfs->grm.mids[0] = mid;
|
LFS_ASSERT(mid != 0);
|
||||||
|
LFS_ASSERT(lfs->grm.queue[1] == 0);
|
||||||
|
lfs->grm.queue[1] = lfs->grm.queue[0];
|
||||||
|
lfs->grm.queue[0] = mid;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline lfsr_smid_t lfsr_grm_pop(lfs_t *lfs) {
|
static inline lfsr_smid_t lfsr_grm_pop(lfs_t *lfs) {
|
||||||
lfsr_smid_t mid = lfs->grm.mids[0];
|
lfsr_smid_t mid = lfs->grm.queue[0];
|
||||||
lfs->grm.mids[0] = lfs->grm.mids[1];
|
lfs->grm.queue[0] = lfs->grm.queue[1];
|
||||||
lfs->grm.mids[1] = -1;
|
lfs->grm.queue[1] = 0;
|
||||||
return mid;
|
return mid;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool lfsr_grm_ismidrm(const lfs_t *lfs, lfsr_smid_t mid) {
|
static inline bool lfsr_grm_ismidrm(const lfs_t *lfs, lfsr_smid_t mid) {
|
||||||
return lfs->grm.mids[0] == mid || lfs->grm.mids[1] == mid;
|
return mid != 0
|
||||||
|
&& (lfs->grm.queue[0] == mid
|
||||||
|
|| lfs->grm.queue[1] == mid);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LFSR_DATA_GRM(_grm, _buffer) \
|
#define LFSR_DATA_GRM(_grm, _buffer) \
|
||||||
@@ -7218,15 +7223,11 @@ static lfsr_data_t lfsr_data_fromgrm(const lfsr_grm_t *grm,
|
|||||||
// make sure to zero so we don't leak any info
|
// make sure to zero so we don't leak any info
|
||||||
lfs_memset(buffer, 0, LFSR_GRM_DSIZE);
|
lfs_memset(buffer, 0, LFSR_GRM_DSIZE);
|
||||||
|
|
||||||
// first encode the number of grms, this can be 0, 1, or 2 and may
|
// encode grms
|
||||||
// be extended to a general purpose leb128 type field in the future
|
lfs_size_t count = lfsr_grm_count_(grm);
|
||||||
uint8_t mode = lfsr_grm_count_(grm);
|
|
||||||
lfs_ssize_t d = 0;
|
lfs_ssize_t d = 0;
|
||||||
buffer[d] = mode;
|
for (lfs_size_t i = 0; i < count; i++) {
|
||||||
d += 1;
|
lfs_ssize_t d_ = lfs_toleb128(grm->queue[i], &buffer[d], 5);
|
||||||
|
|
||||||
for (uint8_t i = 0; i < mode; i++) {
|
|
||||||
lfs_ssize_t d_ = lfs_toleb128(grm->mids[i], &buffer[d], 5);
|
|
||||||
if (d_ < 0) {
|
if (d_ < 0) {
|
||||||
LFS_UNREACHABLE();
|
LFS_UNREACHABLE();
|
||||||
}
|
}
|
||||||
@@ -7242,28 +7243,26 @@ static inline lfsr_mid_t lfsr_mtree_weight(lfs_t *lfs);
|
|||||||
static int lfsr_data_readgrm(lfs_t *lfs, lfsr_data_t *data,
|
static int lfsr_data_readgrm(lfs_t *lfs, lfsr_data_t *data,
|
||||||
lfsr_grm_t *grm) {
|
lfsr_grm_t *grm) {
|
||||||
// clear first
|
// clear first
|
||||||
grm->mids[0] = -1;
|
grm->queue[0] = 0;
|
||||||
grm->mids[1] = -1;
|
grm->queue[1] = 0;
|
||||||
|
|
||||||
// first read the mode field
|
// decode grms, these are terminated by either a null (mid=0) or the
|
||||||
uint8_t mode;
|
// size of the grm buffer
|
||||||
lfs_ssize_t d = lfsr_data_read(lfs, data, &mode, 1);
|
for (lfs_size_t i = 0; i < 2; i++) {
|
||||||
if (d < 0) {
|
lfsr_mid_t mid;
|
||||||
return d;
|
int err = lfsr_data_readleb128(lfs, data, &mid);
|
||||||
}
|
|
||||||
LFS_ASSERT(d == 1);
|
|
||||||
|
|
||||||
// unknown mode? return an error, we may be able to mount read-only
|
|
||||||
if (mode > 2) {
|
|
||||||
return LFS_ERR_CORRUPT;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint8_t i = 0; i < mode; i++) {
|
|
||||||
int err = lfsr_data_readleb128(lfs, data, (lfsr_mid_t*)&grm->mids[i]);
|
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
LFS_ASSERT((lfsr_mid_t)grm->mids[i] < lfsr_mtree_weight(lfs));
|
|
||||||
|
// null grm?
|
||||||
|
if (!mid) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// grm inside mtree?
|
||||||
|
LFS_ASSERT(mid < lfsr_mtree_weight(lfs));
|
||||||
|
grm->queue[i] = mid;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -7271,24 +7270,31 @@ static int lfsr_data_readgrm(lfs_t *lfs, lfsr_data_t *data,
|
|||||||
|
|
||||||
|
|
||||||
// some mdir-related gstate things we need
|
// some mdir-related gstate things we need
|
||||||
|
|
||||||
|
// zero any pending gdeltas
|
||||||
static void lfsr_fs_flushgdelta(lfs_t *lfs) {
|
static void lfsr_fs_flushgdelta(lfs_t *lfs) {
|
||||||
// zero any pending gdeltas
|
// zero the gcksumdelta
|
||||||
lfs->gcksum_d = 0;
|
lfs->gcksum_d = 0;
|
||||||
|
|
||||||
|
// zero the grmdelta
|
||||||
lfs_memset(lfs->grm_d, 0, LFSR_GRM_DSIZE);
|
lfs_memset(lfs->grm_d, 0, LFSR_GRM_DSIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// commit any pending gdeltas
|
||||||
static void lfsr_fs_commitgdelta(lfs_t *lfs) {
|
static void lfsr_fs_commitgdelta(lfs_t *lfs) {
|
||||||
// commit any pending gdeltas
|
// keep track of the on-disk gcksum
|
||||||
lfs->gcksum_p = lfs->gcksum;
|
lfs->gcksum_p = lfs->gcksum;
|
||||||
|
|
||||||
|
// keep track of the on-disk grm
|
||||||
lfsr_data_fromgrm(&lfs->grm, lfs->grm_p);
|
lfsr_data_fromgrm(&lfs->grm, lfs->grm_p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// revert gstate to on-disk state
|
||||||
static void lfsr_fs_revertgdelta(lfs_t *lfs) {
|
static void lfsr_fs_revertgdelta(lfs_t *lfs) {
|
||||||
// revert gstate to on-disk state
|
// revert to the on-disk gcksum
|
||||||
lfs->gcksum = lfs->gcksum_p;
|
lfs->gcksum = lfs->gcksum_p;
|
||||||
|
|
||||||
|
// revert to the on-disk grm
|
||||||
int err = lfsr_data_readgrm(lfs,
|
int err = lfsr_data_readgrm(lfs,
|
||||||
&LFSR_DATA_BUF(lfs->grm_p, LFSR_GRM_DSIZE),
|
&LFSR_DATA_BUF(lfs->grm_p, LFSR_GRM_DSIZE),
|
||||||
&lfs->grm);
|
&lfs->grm);
|
||||||
@@ -8526,13 +8532,13 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
|
|||||||
// adjust pending grms?
|
// adjust pending grms?
|
||||||
} else {
|
} else {
|
||||||
for (int j = 0; j < 2; j++) {
|
for (int j = 0; j < 2; j++) {
|
||||||
if (lfsr_mbid(lfs, lfs->grm.mids[j]) == lfsr_mbid(lfs, mid_)
|
if (lfsr_mbid(lfs, lfs->grm.queue[j]) == lfsr_mbid(lfs, mid_)
|
||||||
&& lfs->grm.mids[j] >= mid_) {
|
&& lfs->grm.queue[j] >= mid_) {
|
||||||
// deleting a pending grm doesn't really make sense
|
// deleting a pending grm doesn't really make sense
|
||||||
LFS_ASSERT(lfs->grm.mids[j] >= mid_ - rattrs[i].weight);
|
LFS_ASSERT(lfs->grm.queue[j] >= mid_ - rattrs[i].weight);
|
||||||
|
|
||||||
// adjust the grm
|
// adjust the grm
|
||||||
lfs->grm.mids[j] += rattrs[i].weight;
|
lfs->grm.queue[j] += rattrs[i].weight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8825,16 +8831,16 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
|
|||||||
|
|
||||||
// patch any pending grms
|
// patch any pending grms
|
||||||
for (int j = 0; j < 2; j++) {
|
for (int j = 0; j < 2; j++) {
|
||||||
if (lfsr_mbid(lfs, lfs->grm.mids[j])
|
if (lfsr_mbid(lfs, lfs->grm.queue[j])
|
||||||
== lfsr_mbid(lfs, lfs_smax(mdir->mid, 0))) {
|
== lfsr_mbid(lfs, lfs_smax(mdir->mid, 0))) {
|
||||||
if (mdelta > 0
|
if (mdelta > 0
|
||||||
&& lfsr_mrid(lfs, lfs->grm.mids[j])
|
&& lfsr_mrid(lfs, lfs->grm.queue[j])
|
||||||
>= (lfsr_srid_t)mdir_[0].rbyd.weight) {
|
>= (lfsr_srid_t)mdir_[0].rbyd.weight) {
|
||||||
lfs->grm.mids[j]
|
lfs->grm.queue[j]
|
||||||
+= (1 << lfs->mbits) - mdir_[0].rbyd.weight;
|
+= (1 << lfs->mbits) - mdir_[0].rbyd.weight;
|
||||||
}
|
}
|
||||||
} else if (lfs->grm.mids[j] > mdir->mid) {
|
} else if (lfs->grm.queue[j] > mdir->mid) {
|
||||||
lfs->grm.mids[j] += mdelta;
|
lfs->grm.queue[j] += mdelta;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -10286,7 +10292,7 @@ int lfsr_mkdir(lfs_t *lfs, const char *path) {
|
|||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
LFS_ASSERT(lfs->grm.mids[0] == mdir.mid);
|
LFS_ASSERT(lfs->grm.queue[0] == mdir.mid);
|
||||||
|
|
||||||
// committing our bookmark may have changed the mid of our metadata entry,
|
// committing our bookmark may have changed the mid of our metadata entry,
|
||||||
// we need to look it up again, we can at least avoid the full path walk
|
// we need to look it up again, we can at least avoid the full path walk
|
||||||
@@ -10644,7 +10650,7 @@ int lfsr_rename(lfs_t *lfs, const char *old_path, const char *new_path) {
|
|||||||
|
|
||||||
// update moved files with the new mdir
|
// update moved files with the new mdir
|
||||||
} else if (lfsr_o_type(o->flags) == LFS_TYPE_REG
|
} else if (lfsr_o_type(o->flags) == LFS_TYPE_REG
|
||||||
&& o->mdir.mid == lfs->grm.mids[0]) {
|
&& o->mdir.mid == lfs->grm.queue[0]) {
|
||||||
o->mdir = new_mdir;
|
o->mdir = new_mdir;
|
||||||
|
|
||||||
// mark any removed dirs as zombied
|
// mark any removed dirs as zombied
|
||||||
@@ -10662,8 +10668,8 @@ int lfsr_rename(lfs_t *lfs, const char *old_path, const char *new_path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (((lfsr_dir_t*)o)->did == old_did
|
if (((lfsr_dir_t*)o)->did == old_did
|
||||||
&& o->mdir.mid >= lfs->grm.mids[0]) {
|
&& o->mdir.mid >= lfs->grm.queue[0]) {
|
||||||
if (o->mdir.mid == lfs->grm.mids[0]) {
|
if (o->mdir.mid == lfs->grm.queue[0]) {
|
||||||
o->mdir.mid += 1;
|
o->mdir.mid += 1;
|
||||||
} else {
|
} else {
|
||||||
((lfsr_dir_t*)o)->pos -= 1;
|
((lfsr_dir_t*)o)->pos -= 1;
|
||||||
@@ -10673,7 +10679,7 @@ int lfsr_rename(lfs_t *lfs, const char *old_path, const char *new_path) {
|
|||||||
// clobber entangled traversals
|
// clobber entangled traversals
|
||||||
} else if (lfsr_o_type(o->flags) == LFS_type_TRAVERSAL
|
} else if (lfsr_o_type(o->flags) == LFS_type_TRAVERSAL
|
||||||
&& ((exists && o->mdir.mid == new_mdir.mid)
|
&& ((exists && o->mdir.mid == new_mdir.mid)
|
||||||
|| o->mdir.mid == lfs->grm.mids[0])) {
|
|| o->mdir.mid == lfs->grm.queue[0])) {
|
||||||
lfsr_traversal_clobber(lfs, (lfsr_traversal_t*)o);
|
lfsr_traversal_clobber(lfs, (lfsr_traversal_t*)o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -13486,8 +13492,8 @@ static int lfs_init(lfs_t *lfs, uint32_t flags,
|
|||||||
lfs->gcksum_p = 0;
|
lfs->gcksum_p = 0;
|
||||||
lfs->gcksum_d = 0;
|
lfs->gcksum_d = 0;
|
||||||
|
|
||||||
lfs->grm.mids[0] = -1;
|
lfs->grm.queue[0] = -1;
|
||||||
lfs->grm.mids[1] = -1;
|
lfs->grm.queue[1] = -1;
|
||||||
lfs_memset(lfs->grm_p, 0, LFSR_GRM_DSIZE);
|
lfs_memset(lfs->grm_p, 0, LFSR_GRM_DSIZE);
|
||||||
lfs_memset(lfs->grm_d, 0, LFSR_GRM_DSIZE);
|
lfs_memset(lfs->grm_d, 0, LFSR_GRM_DSIZE);
|
||||||
|
|
||||||
@@ -14019,14 +14025,14 @@ static int lfsr_mountinited(lfs_t *lfs) {
|
|||||||
// found pending grms? this should only happen if we lost power
|
// found pending grms? this should only happen if we lost power
|
||||||
if (lfsr_grm_count(lfs) == 2) {
|
if (lfsr_grm_count(lfs) == 2) {
|
||||||
LFS_INFO("Found pending grm %"PRId32".%"PRId32" %"PRId32".%"PRId32,
|
LFS_INFO("Found pending grm %"PRId32".%"PRId32" %"PRId32".%"PRId32,
|
||||||
lfsr_dbgmbid(lfs, lfs->grm.mids[0]),
|
lfsr_dbgmbid(lfs, lfs->grm.queue[0]),
|
||||||
lfsr_dbgmrid(lfs, lfs->grm.mids[0]),
|
lfsr_dbgmrid(lfs, lfs->grm.queue[0]),
|
||||||
lfsr_dbgmbid(lfs, lfs->grm.mids[1]),
|
lfsr_dbgmbid(lfs, lfs->grm.queue[1]),
|
||||||
lfsr_dbgmrid(lfs, lfs->grm.mids[1]));
|
lfsr_dbgmrid(lfs, lfs->grm.queue[1]));
|
||||||
} else if (lfsr_grm_count(lfs) == 1) {
|
} else if (lfsr_grm_count(lfs) == 1) {
|
||||||
LFS_INFO("Found pending grm %"PRId32".%"PRId32,
|
LFS_INFO("Found pending grm %"PRId32".%"PRId32,
|
||||||
lfsr_dbgmbid(lfs, lfs->grm.mids[0]),
|
lfsr_dbgmbid(lfs, lfs->grm.queue[0]),
|
||||||
lfsr_dbgmrid(lfs, lfs->grm.mids[0]));
|
lfsr_dbgmrid(lfs, lfs->grm.queue[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -14434,22 +14440,22 @@ lfs_ssize_t lfsr_fs_size(lfs_t *lfs) {
|
|||||||
static int lfsr_fs_fixgrm(lfs_t *lfs) {
|
static int lfsr_fs_fixgrm(lfs_t *lfs) {
|
||||||
if (lfsr_grm_count(lfs) == 2) {
|
if (lfsr_grm_count(lfs) == 2) {
|
||||||
LFS_INFO("Fixing grm %"PRId32".%"PRId32" %"PRId32".%"PRId32,
|
LFS_INFO("Fixing grm %"PRId32".%"PRId32" %"PRId32".%"PRId32,
|
||||||
lfsr_dbgmbid(lfs, lfs->grm.mids[0]),
|
lfsr_dbgmbid(lfs, lfs->grm.queue[0]),
|
||||||
lfsr_dbgmrid(lfs, lfs->grm.mids[0]),
|
lfsr_dbgmrid(lfs, lfs->grm.queue[0]),
|
||||||
lfsr_dbgmbid(lfs, lfs->grm.mids[1]),
|
lfsr_dbgmbid(lfs, lfs->grm.queue[1]),
|
||||||
lfsr_dbgmrid(lfs, lfs->grm.mids[1]));
|
lfsr_dbgmrid(lfs, lfs->grm.queue[1]));
|
||||||
} else if (lfsr_grm_count(lfs) == 1) {
|
} else if (lfsr_grm_count(lfs) == 1) {
|
||||||
LFS_INFO("Fixing grm %"PRId32".%"PRId32,
|
LFS_INFO("Fixing grm %"PRId32".%"PRId32,
|
||||||
lfsr_dbgmbid(lfs, lfs->grm.mids[0]),
|
lfsr_dbgmbid(lfs, lfs->grm.queue[0]),
|
||||||
lfsr_dbgmrid(lfs, lfs->grm.mids[0]));
|
lfsr_dbgmrid(lfs, lfs->grm.queue[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
while (lfsr_grm_count(lfs) > 0) {
|
while (lfsr_grm_count(lfs) > 0) {
|
||||||
LFS_ASSERT(lfs->grm.mids[0] != -1);
|
LFS_ASSERT(lfs->grm.queue[0] != -1);
|
||||||
|
|
||||||
// find our mdir
|
// find our mdir
|
||||||
lfsr_mdir_t mdir;
|
lfsr_mdir_t mdir;
|
||||||
int err = lfsr_mtree_lookup(lfs, lfs->grm.mids[0],
|
int err = lfsr_mtree_lookup(lfs, lfs->grm.queue[0],
|
||||||
&mdir);
|
&mdir);
|
||||||
if (err) {
|
if (err) {
|
||||||
LFS_ASSERT(err != LFS_ERR_NOENT);
|
LFS_ASSERT(err != LFS_ERR_NOENT);
|
||||||
|
|||||||
@@ -812,18 +812,16 @@ typedef struct lfsr_traversal {
|
|||||||
//} lfs_gstate_t;
|
//} lfs_gstate_t;
|
||||||
|
|
||||||
// grm encoding:
|
// grm encoding:
|
||||||
// .---. mode: 1 leb128 1 byte
|
// .- -+- -+- -+- -+- -. mids: 2 leb128s <=2x5 bytes
|
||||||
// |mod| mids: 2 leb128s <=2x5 bytes
|
// ' mids ' total: <=10 bytes
|
||||||
// +- -+- -+- -+- -+- -. total: <=11 bytes
|
|
||||||
// ' mid x mod '
|
|
||||||
// + +
|
// + +
|
||||||
// ' '
|
// ' '
|
||||||
// '- -+- -+- -+- -+- -'
|
// '- -+- -+- -+- -+- -'
|
||||||
//
|
//
|
||||||
#define LFSR_GRM_DSIZE (1+5+5)
|
#define LFSR_GRM_DSIZE (5+5)
|
||||||
|
|
||||||
typedef struct lfsr_grm {
|
typedef struct lfsr_grm {
|
||||||
lfsr_smid_t mids[2];
|
lfsr_smid_t queue[2];
|
||||||
} lfsr_grm_t;
|
} lfsr_grm_t;
|
||||||
|
|
||||||
#ifdef LFS_CKPARITY
|
#ifdef LFS_CKPARITY
|
||||||
|
|||||||
+14
-18
@@ -2726,26 +2726,22 @@ class Gstate:
|
|||||||
|
|
||||||
def __init__(self, mtree, tag, gdeltas):
|
def __init__(self, mtree, tag, gdeltas):
|
||||||
super().__init__(mtree, tag, gdeltas)
|
super().__init__(mtree, tag, gdeltas)
|
||||||
|
queue = []
|
||||||
d = 0
|
d = 0
|
||||||
count, d_ = fromleb128(self.data, d); d += d_
|
for _ in range(2):
|
||||||
rms = []
|
mid, d_ = fromleb128(self.data, d); d += d_
|
||||||
if count <= 2:
|
# a null mid (mid=0.0) terminates the grm queue
|
||||||
for _ in range(count):
|
if not mid:
|
||||||
mid, d_ = fromleb128(self.data, d); d += d_
|
break
|
||||||
mid = mtree.mid(mid)
|
mid = mtree.mid(mid)
|
||||||
# map mbids -> -1 if mroot-inlined
|
# map mbids -> -1 if mroot-inlined
|
||||||
if mtree.mtree is None:
|
if mtree.mtree is None:
|
||||||
mid = mtree.mid(-1, mid.mrid)
|
mid = mtree.mid(-1, mid.mrid)
|
||||||
rms.append(mid)
|
queue.append(mid)
|
||||||
self.count = count
|
self.queue = queue
|
||||||
self.rms = rms
|
|
||||||
|
|
||||||
def repr(self):
|
def repr(self):
|
||||||
return 'grm %s' % (
|
return 'grm [%s]' % ', '.join(mid.repr() for mid in self.queue)
|
||||||
'none' if self.count == 0
|
|
||||||
else ' '.join(mid.repr() for mid in self.rms)
|
|
||||||
if self.count <= 2
|
|
||||||
else '0x%x %d' % (self.count, len(self.data)))
|
|
||||||
|
|
||||||
# keep track of known gstate
|
# keep track of known gstate
|
||||||
_known = [g for g in Gstate.__subclasses__() if g.tag is not None]
|
_known = [g for g in Gstate.__subclasses__() if g.tag is not None]
|
||||||
@@ -2961,7 +2957,7 @@ class Lfs:
|
|||||||
if not isinstance(mid, Mid):
|
if not isinstance(mid, Mid):
|
||||||
mid = self.mid(mid)
|
mid = self.mid(mid)
|
||||||
|
|
||||||
return mid in self.gstate.grm.rms
|
return mid in self.gstate.grm.queue
|
||||||
|
|
||||||
# lookup operations
|
# lookup operations
|
||||||
def lookup(self, mid, mdir=None, *,
|
def lookup(self, mid, mdir=None, *,
|
||||||
|
|||||||
+14
-18
@@ -2756,26 +2756,22 @@ class Gstate:
|
|||||||
|
|
||||||
def __init__(self, mtree, tag, gdeltas):
|
def __init__(self, mtree, tag, gdeltas):
|
||||||
super().__init__(mtree, tag, gdeltas)
|
super().__init__(mtree, tag, gdeltas)
|
||||||
|
queue = []
|
||||||
d = 0
|
d = 0
|
||||||
count, d_ = fromleb128(self.data, d); d += d_
|
for _ in range(2):
|
||||||
rms = []
|
mid, d_ = fromleb128(self.data, d); d += d_
|
||||||
if count <= 2:
|
# a null mid (mid=0.0) terminates the grm queue
|
||||||
for _ in range(count):
|
if not mid:
|
||||||
mid, d_ = fromleb128(self.data, d); d += d_
|
break
|
||||||
mid = mtree.mid(mid)
|
mid = mtree.mid(mid)
|
||||||
# map mbids -> -1 if mroot-inlined
|
# map mbids -> -1 if mroot-inlined
|
||||||
if mtree.mtree is None:
|
if mtree.mtree is None:
|
||||||
mid = mtree.mid(-1, mid.mrid)
|
mid = mtree.mid(-1, mid.mrid)
|
||||||
rms.append(mid)
|
queue.append(mid)
|
||||||
self.count = count
|
self.queue = queue
|
||||||
self.rms = rms
|
|
||||||
|
|
||||||
def repr(self):
|
def repr(self):
|
||||||
return 'grm %s' % (
|
return 'grm [%s]' % ', '.join(mid.repr() for mid in self.queue)
|
||||||
'none' if self.count == 0
|
|
||||||
else ' '.join(mid.repr() for mid in self.rms)
|
|
||||||
if self.count <= 2
|
|
||||||
else '0x%x %d' % (self.count, len(self.data)))
|
|
||||||
|
|
||||||
# keep track of known gstate
|
# keep track of known gstate
|
||||||
_known = [g for g in Gstate.__subclasses__() if g.tag is not None]
|
_known = [g for g in Gstate.__subclasses__() if g.tag is not None]
|
||||||
@@ -2991,7 +2987,7 @@ class Lfs:
|
|||||||
if not isinstance(mid, Mid):
|
if not isinstance(mid, Mid):
|
||||||
mid = self.mid(mid)
|
mid = self.mid(mid)
|
||||||
|
|
||||||
return mid in self.gstate.grm.rms
|
return mid in self.gstate.grm.queue
|
||||||
|
|
||||||
# lookup operations
|
# lookup operations
|
||||||
def lookup(self, mid, mdir=None, *,
|
def lookup(self, mid, mdir=None, *,
|
||||||
|
|||||||
+14
-18
@@ -2683,26 +2683,22 @@ class Gstate:
|
|||||||
|
|
||||||
def __init__(self, mtree, tag, gdeltas):
|
def __init__(self, mtree, tag, gdeltas):
|
||||||
super().__init__(mtree, tag, gdeltas)
|
super().__init__(mtree, tag, gdeltas)
|
||||||
|
queue = []
|
||||||
d = 0
|
d = 0
|
||||||
count, d_ = fromleb128(self.data, d); d += d_
|
for _ in range(2):
|
||||||
rms = []
|
mid, d_ = fromleb128(self.data, d); d += d_
|
||||||
if count <= 2:
|
# a null mid (mid=0.0) terminates the grm queue
|
||||||
for _ in range(count):
|
if not mid:
|
||||||
mid, d_ = fromleb128(self.data, d); d += d_
|
break
|
||||||
mid = mtree.mid(mid)
|
mid = mtree.mid(mid)
|
||||||
# map mbids -> -1 if mroot-inlined
|
# map mbids -> -1 if mroot-inlined
|
||||||
if mtree.mtree is None:
|
if mtree.mtree is None:
|
||||||
mid = mtree.mid(-1, mid.mrid)
|
mid = mtree.mid(-1, mid.mrid)
|
||||||
rms.append(mid)
|
queue.append(mid)
|
||||||
self.count = count
|
self.queue = queue
|
||||||
self.rms = rms
|
|
||||||
|
|
||||||
def repr(self):
|
def repr(self):
|
||||||
return 'grm %s' % (
|
return 'grm [%s]' % ', '.join(mid.repr() for mid in self.queue)
|
||||||
'none' if self.count == 0
|
|
||||||
else ' '.join(mid.repr() for mid in self.rms)
|
|
||||||
if self.count <= 2
|
|
||||||
else '0x%x %d' % (self.count, len(self.data)))
|
|
||||||
|
|
||||||
# keep track of known gstate
|
# keep track of known gstate
|
||||||
_known = [g for g in Gstate.__subclasses__() if g.tag is not None]
|
_known = [g for g in Gstate.__subclasses__() if g.tag is not None]
|
||||||
@@ -2918,7 +2914,7 @@ class Lfs:
|
|||||||
if not isinstance(mid, Mid):
|
if not isinstance(mid, Mid):
|
||||||
mid = self.mid(mid)
|
mid = self.mid(mid)
|
||||||
|
|
||||||
return mid in self.gstate.grm.rms
|
return mid in self.gstate.grm.queue
|
||||||
|
|
||||||
# lookup operations
|
# lookup operations
|
||||||
def lookup(self, mid, mdir=None, *,
|
def lookup(self, mid, mdir=None, *,
|
||||||
|
|||||||
@@ -7976,8 +7976,8 @@ code = '''
|
|||||||
lfsr_fs_mkconsistent(&lfs) => 0;
|
lfsr_fs_mkconsistent(&lfs) => 0;
|
||||||
|
|
||||||
// we should have cleaned up all grms/orphans
|
// we should have cleaned up all grms/orphans
|
||||||
assert(lfs.grm.mids[0] == -1);
|
assert(lfs.grm.queue[0] == 0);
|
||||||
assert(lfs.grm.mids[1] == -1);
|
assert(lfs.grm.queue[1] == 0);
|
||||||
assert(!(lfs.flags & LFS_I_MKCONSISTENT));
|
assert(!(lfs.flags & LFS_I_MKCONSISTENT));
|
||||||
|
|
||||||
struct lfs_fsinfo fsinfo;
|
struct lfs_fsinfo fsinfo;
|
||||||
@@ -8112,8 +8112,8 @@ code = '''
|
|||||||
lfsr_fs_mkconsistent(&lfs) => 0;
|
lfsr_fs_mkconsistent(&lfs) => 0;
|
||||||
|
|
||||||
// we should have cleaned up all grms/orphans
|
// we should have cleaned up all grms/orphans
|
||||||
assert(lfs.grm.mids[0] == -1);
|
assert(lfs.grm.queue[0] == 0);
|
||||||
assert(lfs.grm.mids[1] == -1);
|
assert(lfs.grm.queue[1] == 0);
|
||||||
assert(!(lfs.flags & LFS_I_MKCONSISTENT));
|
assert(!(lfs.flags & LFS_I_MKCONSISTENT));
|
||||||
|
|
||||||
struct lfs_fsinfo fsinfo;
|
struct lfs_fsinfo fsinfo;
|
||||||
@@ -8262,8 +8262,8 @@ code = '''
|
|||||||
lfsr_fs_mkconsistent(&lfs) => 0;
|
lfsr_fs_mkconsistent(&lfs) => 0;
|
||||||
|
|
||||||
// we should have cleaned up all grms/orphans
|
// we should have cleaned up all grms/orphans
|
||||||
assert(lfs.grm.mids[0] == -1);
|
assert(lfs.grm.queue[0] == 0);
|
||||||
assert(lfs.grm.mids[1] == -1);
|
assert(lfs.grm.queue[1] == 0);
|
||||||
assert(!(lfs.flags & LFS_I_MKCONSISTENT));
|
assert(!(lfs.flags & LFS_I_MKCONSISTENT));
|
||||||
|
|
||||||
struct lfs_fsinfo fsinfo;
|
struct lfs_fsinfo fsinfo;
|
||||||
@@ -8418,8 +8418,8 @@ code = '''
|
|||||||
lfsr_fs_mkconsistent(&lfs) => 0;
|
lfsr_fs_mkconsistent(&lfs) => 0;
|
||||||
|
|
||||||
// we should have cleaned up all grms/orphans
|
// we should have cleaned up all grms/orphans
|
||||||
assert(lfs.grm.mids[0] == -1);
|
assert(lfs.grm.queue[0] == 0);
|
||||||
assert(lfs.grm.mids[1] == -1);
|
assert(lfs.grm.queue[1] == 0);
|
||||||
assert(!(lfs.flags & LFS_I_MKCONSISTENT));
|
assert(!(lfs.flags & LFS_I_MKCONSISTENT));
|
||||||
|
|
||||||
struct lfs_fsinfo fsinfo;
|
struct lfs_fsinfo fsinfo;
|
||||||
|
|||||||
+16
-16
@@ -6461,8 +6461,8 @@ code = '''
|
|||||||
lfsr_traversal_close(&lfs, &t) => 0;
|
lfsr_traversal_close(&lfs, &t) => 0;
|
||||||
|
|
||||||
// we should have cleaned up all grms/orphans
|
// we should have cleaned up all grms/orphans
|
||||||
assert(lfs.grm.mids[0] == -1);
|
assert(lfs.grm.queue[0] == 0);
|
||||||
assert(lfs.grm.mids[1] == -1);
|
assert(lfs.grm.queue[1] == 0);
|
||||||
assert(!(lfs.flags & LFS_I_MKCONSISTENT));
|
assert(!(lfs.flags & LFS_I_MKCONSISTENT));
|
||||||
|
|
||||||
// which means there shouldn't be that many files left
|
// which means there shouldn't be that many files left
|
||||||
@@ -6603,8 +6603,8 @@ code = '''
|
|||||||
lfsr_traversal_close(&lfs, &t) => 0;
|
lfsr_traversal_close(&lfs, &t) => 0;
|
||||||
|
|
||||||
// we should be able to clean up grms
|
// we should be able to clean up grms
|
||||||
assert(lfs.grm.mids[0] == -1);
|
assert(lfs.grm.queue[0] == 0);
|
||||||
assert(lfs.grm.mids[1] == -1);
|
assert(lfs.grm.queue[1] == 0);
|
||||||
// if we introduce actual orphans, me _must not_ clear the orphan flag
|
// if we introduce actual orphans, me _must not_ clear the orphan flag
|
||||||
if (ORPHANS >= 3) {
|
if (ORPHANS >= 3) {
|
||||||
assert(lfs.flags & LFS_I_MKCONSISTENT);
|
assert(lfs.flags & LFS_I_MKCONSISTENT);
|
||||||
@@ -6762,8 +6762,8 @@ code = '''
|
|||||||
lfsr_traversal_close(&lfs, &t) => 0;
|
lfsr_traversal_close(&lfs, &t) => 0;
|
||||||
|
|
||||||
// we should have cleaned up all grms/orphans
|
// we should have cleaned up all grms/orphans
|
||||||
assert(lfs.grm.mids[0] == -1);
|
assert(lfs.grm.queue[0] == 0);
|
||||||
assert(lfs.grm.mids[1] == -1);
|
assert(lfs.grm.queue[1] == 0);
|
||||||
assert(!(lfs.flags & LFS_I_MKCONSISTENT));
|
assert(!(lfs.flags & LFS_I_MKCONSISTENT));
|
||||||
|
|
||||||
// which means there shouldn't be that many files left
|
// which means there shouldn't be that many files left
|
||||||
@@ -6920,8 +6920,8 @@ code = '''
|
|||||||
lfsr_traversal_close(&lfs, &t) => 0;
|
lfsr_traversal_close(&lfs, &t) => 0;
|
||||||
|
|
||||||
// we should have cleaned up all grms/orphans
|
// we should have cleaned up all grms/orphans
|
||||||
assert(lfs.grm.mids[0] == -1);
|
assert(lfs.grm.queue[0] == 0);
|
||||||
assert(lfs.grm.mids[1] == -1);
|
assert(lfs.grm.queue[1] == 0);
|
||||||
assert(!(lfs.flags & LFS_I_MKCONSISTENT));
|
assert(!(lfs.flags & LFS_I_MKCONSISTENT));
|
||||||
|
|
||||||
// which means there shouldn't be that many files left
|
// which means there shouldn't be that many files left
|
||||||
@@ -7089,8 +7089,8 @@ code = '''
|
|||||||
lfsr_traversal_close(&lfs, &t) => 0;
|
lfsr_traversal_close(&lfs, &t) => 0;
|
||||||
|
|
||||||
// we should have cleaned up all grms/orphans
|
// we should have cleaned up all grms/orphans
|
||||||
assert(lfs.grm.mids[0] == -1);
|
assert(lfs.grm.queue[0] == 0);
|
||||||
assert(lfs.grm.mids[1] == -1);
|
assert(lfs.grm.queue[1] == 0);
|
||||||
assert(!(lfs.flags & LFS_I_MKCONSISTENT));
|
assert(!(lfs.flags & LFS_I_MKCONSISTENT));
|
||||||
|
|
||||||
// which means there shouldn't be that many files left
|
// which means there shouldn't be that many files left
|
||||||
@@ -7256,8 +7256,8 @@ code = '''
|
|||||||
lfsr_traversal_close(&lfs, &t) => 0;
|
lfsr_traversal_close(&lfs, &t) => 0;
|
||||||
|
|
||||||
// we should have cleaned up all grms/orphans
|
// we should have cleaned up all grms/orphans
|
||||||
assert(lfs.grm.mids[0] == -1);
|
assert(lfs.grm.queue[0] == 0);
|
||||||
assert(lfs.grm.mids[1] == -1);
|
assert(lfs.grm.queue[1] == 0);
|
||||||
assert(!(lfs.flags & LFS_I_MKCONSISTENT));
|
assert(!(lfs.flags & LFS_I_MKCONSISTENT));
|
||||||
|
|
||||||
// which means there shouldn't be that many files left
|
// which means there shouldn't be that many files left
|
||||||
@@ -7421,8 +7421,8 @@ code = '''
|
|||||||
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT;
|
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT;
|
||||||
|
|
||||||
// we should have cleaned up all grms/orphans
|
// we should have cleaned up all grms/orphans
|
||||||
assert(lfs.grm.mids[0] == -1);
|
assert(lfs.grm.queue[0] == 0);
|
||||||
assert(lfs.grm.mids[1] == -1);
|
assert(lfs.grm.queue[1] == 0);
|
||||||
assert(!(lfs.flags & LFS_I_MKCONSISTENT));
|
assert(!(lfs.flags & LFS_I_MKCONSISTENT));
|
||||||
|
|
||||||
// which means there shouldn't be that many files left
|
// which means there shouldn't be that many files left
|
||||||
@@ -7614,8 +7614,8 @@ code = '''
|
|||||||
lfsr_traversal_close(&lfs, &t) => 0;
|
lfsr_traversal_close(&lfs, &t) => 0;
|
||||||
|
|
||||||
// we should be able to clean up grms
|
// we should be able to clean up grms
|
||||||
assert(lfs.grm.mids[0] == -1);
|
assert(lfs.grm.queue[0] == 0);
|
||||||
assert(lfs.grm.mids[1] == -1);
|
assert(lfs.grm.queue[1] == 0);
|
||||||
// if we introduce actual orphans, me _must not_ clear the orphan flag
|
// if we introduce actual orphans, me _must not_ clear the orphan flag
|
||||||
if (ORPHANS >= 3) {
|
if (ORPHANS >= 3) {
|
||||||
assert(lfs.flags & LFS_I_MKCONSISTENT);
|
assert(lfs.flags & LFS_I_MKCONSISTENT);
|
||||||
|
|||||||
Reference in New Issue
Block a user