Calculate grm deltas at the last minute
This finally gets rid of the annoying grm re-xoring we needed to do in
lfsr_mdir_commit.
If we're waiting until the last minute to append gdeltas, we might as
well wait to the last minute to encode/xor gdeltas. This avoids any
redundant xors because of failed mdir commits.
Note though, we still need our *_d copies to collect gdelta from any
dropped mdirs.
Also dropped lfsr_gdelta_xor and lfsr_is_zero. These were just small
wrappers over memxor and memcchr that add more noise than anything else.
This saves a nice bit of code/stack:
code stack ctx
before: 38588 2648 644
after: 38560 (-0.1%) 2624 (-0.9%) 644 (+0.0%)
This commit is contained in:
@@ -6823,11 +6823,6 @@ static void lfsr_fs_mkdirty(lfs_t *lfs) {
|
||||
|
||||
/// Global-state things ///
|
||||
|
||||
static inline bool lfsr_gdelta_iszero(
|
||||
const uint8_t *gdelta, lfs_size_t size) {
|
||||
return lfs_memcchr(gdelta, 0, size) == NULL;
|
||||
}
|
||||
|
||||
static inline lfs_size_t lfsr_gdelta_size(
|
||||
const uint8_t *gdelta, lfs_size_t size) {
|
||||
// truncate based on number of trailing zeros
|
||||
@@ -6838,11 +6833,6 @@ static inline lfs_size_t lfsr_gdelta_size(
|
||||
return size;
|
||||
}
|
||||
|
||||
static inline void lfsr_gdelta_xor(
|
||||
uint8_t *a, const uint8_t *b, lfs_size_t size) {
|
||||
lfs_memxor(a, b, size);
|
||||
}
|
||||
|
||||
|
||||
// gcksum (global checksum) things
|
||||
|
||||
@@ -6941,18 +6931,15 @@ static int lfsr_data_readgrm(lfs_t *lfs, lfsr_data_t *data,
|
||||
static void lfsr_fs_flushgdelta(lfs_t *lfs) {
|
||||
// zero any pending gdeltas
|
||||
lfs->gcksum_d = 0;
|
||||
|
||||
lfs_memset(lfs->grm_d, 0, LFSR_GRM_DSIZE);
|
||||
}
|
||||
|
||||
static void lfsr_fs_preparegdelta(lfs_t *lfs) {
|
||||
// first flush everything
|
||||
lfsr_fs_flushgdelta(lfs);
|
||||
static void lfsr_fs_commitgdelta(lfs_t *lfs) {
|
||||
// commit any pending gdeltas
|
||||
lfs->gcksum_p = lfs->gcksum;
|
||||
|
||||
// any pending grms?
|
||||
lfsr_data_fromgrm(&lfs->grm, lfs->grm_d);
|
||||
|
||||
// xor with current gstate to find our initial gdelta
|
||||
lfsr_gdelta_xor(lfs->grm_d, lfs->grm_p, LFSR_GRM_DSIZE);
|
||||
lfsr_data_fromgrm(&lfs->grm, lfs->grm_p);
|
||||
}
|
||||
|
||||
static void lfsr_fs_revertgdelta(lfs_t *lfs) {
|
||||
@@ -6967,19 +6954,18 @@ static void lfsr_fs_revertgdelta(lfs_t *lfs) {
|
||||
}
|
||||
}
|
||||
|
||||
static void lfsr_fs_commitgdelta(lfs_t *lfs) {
|
||||
// commit any pending gdeltas
|
||||
lfs->gcksum_p = lfs->gcksum;
|
||||
lfsr_data_fromgrm(&lfs->grm, lfs->grm_p);
|
||||
}
|
||||
|
||||
// append and consume any pending gstate
|
||||
static int lfsr_rbyd_appendgdelta(lfs_t *lfs, lfsr_rbyd_t *rbyd) {
|
||||
// gcksums are a special case and handled directly in
|
||||
// note gcksums are a special case and handled directly in
|
||||
// lfsr_mdir_commit__/lfsr_rbyd_appendcksum_
|
||||
|
||||
// need grm delta?
|
||||
if (!lfsr_gdelta_iszero(lfs->grm_d, LFSR_GRM_DSIZE)) {
|
||||
// pending grm state?
|
||||
uint8_t grmdelta_[LFSR_GRM_DSIZE];
|
||||
lfsr_data_fromgrm(&lfs->grm, grmdelta_);
|
||||
lfs_memxor(grmdelta_, lfs->grm_p, LFSR_GRM_DSIZE);
|
||||
lfs_memxor(grmdelta_, lfs->grm_d, LFSR_GRM_DSIZE);
|
||||
|
||||
if (lfsr_gdelta_size(grmdelta_, LFSR_GRM_DSIZE) != 0) {
|
||||
// make sure to xor any existing delta
|
||||
lfsr_data_t data;
|
||||
int err = lfsr_rbyd_lookup(lfs, rbyd, -1, LFSR_TAG_GRMDELTA,
|
||||
@@ -6988,25 +6974,26 @@ static int lfsr_rbyd_appendgdelta(lfs_t *lfs, lfsr_rbyd_t *rbyd) {
|
||||
return err;
|
||||
}
|
||||
|
||||
uint8_t grm_d[LFSR_GRM_DSIZE];
|
||||
lfs_memset(grm_d, 0, LFSR_GRM_DSIZE);
|
||||
uint8_t grmdelta[LFSR_GRM_DSIZE];
|
||||
lfs_memset(grmdelta, 0, LFSR_GRM_DSIZE);
|
||||
if (err != LFS_ERR_NOENT) {
|
||||
lfs_ssize_t d = lfsr_data_read(lfs, &data, grm_d, LFSR_GRM_DSIZE);
|
||||
lfs_ssize_t d = lfsr_data_read(lfs, &data,
|
||||
grmdelta, LFSR_GRM_DSIZE);
|
||||
if (d < 0) {
|
||||
return d;
|
||||
}
|
||||
}
|
||||
|
||||
lfsr_gdelta_xor(grm_d, lfs->grm_d, LFSR_GRM_DSIZE);
|
||||
lfs_memxor(grmdelta_, grmdelta, LFSR_GRM_DSIZE);
|
||||
|
||||
// append to our rbyd, replacing any existing delta
|
||||
lfs_size_t size = lfsr_gdelta_size(grm_d, LFSR_GRM_DSIZE);
|
||||
lfs_size_t size = lfsr_gdelta_size(grmdelta_, LFSR_GRM_DSIZE);
|
||||
err = lfsr_rbyd_appendrat(lfs, rbyd, -1, LFSR_RAT(
|
||||
// opportunistically remove this tag if delta is all zero
|
||||
(size == 0)
|
||||
? LFSR_TAG_RM | LFSR_TAG_GRMDELTA
|
||||
: LFSR_TAG_GRMDELTA, 0,
|
||||
LFSR_DATA_BUF(grm_d, size)));
|
||||
LFSR_DATA_BUF(grmdelta_, size)));
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
@@ -7028,13 +7015,13 @@ static int lfsr_fs_consumegdelta(lfs_t *lfs, const lfsr_mdir_t *mdir) {
|
||||
}
|
||||
|
||||
if (err != LFS_ERR_NOENT) {
|
||||
uint8_t grm_d[LFSR_GRM_DSIZE];
|
||||
lfs_ssize_t d = lfsr_data_read(lfs, &data, grm_d, LFSR_GRM_DSIZE);
|
||||
uint8_t grmdelta[LFSR_GRM_DSIZE];
|
||||
lfs_ssize_t d = lfsr_data_read(lfs, &data, grmdelta, LFSR_GRM_DSIZE);
|
||||
if (d < 0) {
|
||||
return d;
|
||||
}
|
||||
|
||||
lfsr_gdelta_xor(lfs->grm_d, grm_d, d);
|
||||
lfs_memxor(lfs->grm_d, grmdelta, d);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -8298,8 +8285,8 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
|
||||
mid_ = lfsr_rat_nextrid(rats[i], mid_);
|
||||
}
|
||||
|
||||
// setup any pending gdeltas
|
||||
lfsr_fs_preparegdelta(lfs);
|
||||
// flush gdeltas
|
||||
lfsr_fs_flushgdelta(lfs);
|
||||
|
||||
// xor our old cksum
|
||||
lfs->gcksum ^= mdir->rbyd.cksum;
|
||||
@@ -8581,19 +8568,6 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
|
||||
}
|
||||
|
||||
// patch any pending grms
|
||||
//
|
||||
// Assuming we already xored our gdelta with the grm, we first
|
||||
// need to xor the grm out of the gdelta. We can't just zero
|
||||
// the gdelta because we may have picked up extra gdelta from
|
||||
// split/dropped mdirs
|
||||
//
|
||||
// gd' = gd xor (grm' xor grm)
|
||||
//
|
||||
uint8_t grm_d[LFSR_GRM_DSIZE];
|
||||
lfsr_data_t data = lfsr_data_fromgrm(&lfs->grm, grm_d);
|
||||
lfsr_gdelta_xor(lfs->grm_d, grm_d, lfsr_data_size(data));
|
||||
|
||||
// patch our grm
|
||||
for (int j = 0; j < 2; j++) {
|
||||
if (lfsr_mid_bid(lfs, lfs->grm.mids[j])
|
||||
== lfsr_mid_bid(lfs, lfs_smax(mdir->mid, 0))) {
|
||||
@@ -8608,10 +8582,6 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
|
||||
}
|
||||
}
|
||||
|
||||
// xor our patch into our gdelta
|
||||
data = lfsr_data_fromgrm(&lfs->grm, grm_d);
|
||||
lfsr_gdelta_xor(lfs->grm_d, grm_d, lfsr_data_size(data));
|
||||
|
||||
// need to update mtree?
|
||||
if (lfsr_mtree_cmp(&mtree_, &lfs->mtree) != 0) {
|
||||
// mtree should never go to zero since we always have a root bookmark
|
||||
|
||||
Reference in New Issue
Block a user