From 024aaeba569cb211d75ae9346893a663a3452f69 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Wed, 21 Dec 2022 12:05:17 -0600 Subject: [PATCH] Some small tweaks - Moved alt encoding 0x1 => 0x4, which can lead to slightly better lookup tables, the perturb bit takes the same place as the color bit, which means both can be ignored in readonly operations. - Dropped lfs_rbyd_fetchmatch, asking each lfs_rbyd_fetch to include NULL isn't that bad. New encoding: tags: iiii iiiiiii iiiiiTT TTTTTTt ttt0tpv ^--------^------^^^- 16-bit id '------|||- 8-bit type2 '||- 5-bit type1 '|- perturb bit '- valid bit llll lllllll lllllll lllllll lllllll ^- n-bit length alts: wwww wwwwwww wwwwwww wwwwwww www1dcv ^^^-^- 28-bit weight '|-|- color bit '-|- direction bit '- valid bit jjjj jjjjjjj jjjjjjj jjjjjjj jjjjjjj ^- n-bit jump --- lfs.c | 39 +++++++++++++++++++-------------------- scripts/dbgrbyd.py | 41 ++++++++++++++++++++--------------------- tests/test_rbyd.toml | 12 ++++++------ 3 files changed, 45 insertions(+), 47 deletions(-) diff --git a/lfs.c b/lfs.c index 87e2cbf9..31e08793 100644 --- a/lfs.c +++ b/lfs.c @@ -407,10 +407,13 @@ enum lfs_rtag_type1 { LFS_TYPE1_GSTATE = 0x10, LFS_TYPE1_CRC0 = 0x02, - LFS_TYPE1_CRC1 = 0x0a, - LFS_TYPE1_FCRC = 0x12, + LFS_TYPE1_CRC1 = 0x03, + LFS_TYPE1_FCRC = 0x0a, - LFS_TYPE1_ALT = 0x01, + LFS_TYPE1_ALTBLT = 0x04, + LFS_TYPE1_ALTRLT = 0x05, + LFS_TYPE1_ALTBGT = 0x06, + LFS_TYPE1_ALTRGT = 0x07, }; enum lfs_rtag_color { @@ -432,8 +435,8 @@ enum lfs_rtag_dir { LFS_MKRTAG_(LFS_TYPE1_##type1, type2, id) #define LFS_MKRALT_(color, dir, weight) \ - (0x1 \ - | ((0x1 & (lfs_rtag_t)(color)) << 2) \ + (LFS_TYPE1_ALTBLT \ + | ((0x1 & (lfs_rtag_t)(color)) << 0) \ | ((0x1 & (lfs_rtag_t)(dir)) << 1) \ | ((0xfffffff & (lfs_rtag_t)(weight)) << 3)) @@ -445,11 +448,11 @@ static inline bool lfs_rtag_isvalid(lfs_rtag_t tag) { } static inline bool lfs_rtag_isalt(lfs_rtag_t tag) { - return tag & 0x1; + return tag & 0x4; } static inline bool lfs_rtag_intree(lfs_rtag_t tag) { - return tag & 0x2; + return !(tag & 0x6); } static inline uint8_t lfs_rtag_type1(lfs_rtag_t tag) { @@ -473,11 +476,11 @@ static inline bool lfs_rtag_isgt(lfs_rtag_t tag) { } static inline bool lfs_rtag_isblack(lfs_rtag_t tag) { - return !(tag & 0x4); + return !(tag & 0x1); } static inline bool lfs_rtag_isred(lfs_rtag_t tag) { - return tag & 0x4; + return tag & 0x1; } static inline lfs_rtag_t lfs_rtag_weight(lfs_rtag_t tag) { @@ -485,11 +488,11 @@ static inline lfs_rtag_t lfs_rtag_weight(lfs_rtag_t tag) { } static inline lfs_rtag_t lfs_rtag_red(lfs_rtag_t tag) { - return tag | 0x4; + return tag | 0x1; } static inline lfs_rtag_t lfs_rtag_black(lfs_rtag_t tag) { - return tag & ~0x4; + return tag & ~0x1; } static inline lfs_rtag_t lfs_rtag_parallel(lfs_rtag_t a, lfs_rtag_t b) { @@ -895,7 +898,7 @@ static lfs_ssize_t lfs_rbyd_readtag(lfs_t *lfs, return i; } -static int lfs_rbyd_fetchmatch(lfs_t *lfs, +static int lfs_rbyd_fetch(lfs_t *lfs, lfs_rbyd_t *rbyd, lfs_block_t block, struct lfs_fetchpattern *patterns) { // read the revision count and get the crc started @@ -941,7 +944,7 @@ static int lfs_rbyd_fetchmatch(lfs_t *lfs, } // found trunk of tree? - if (!wastrunk && (lfs_rtag_isalt(tag) || lfs_rtag_intree(tag))) { + if (!wastrunk && lfs_rtag_intree(tag)) { trunk = off; wastrunk = true; } @@ -962,7 +965,7 @@ static int lfs_rbyd_fetchmatch(lfs_t *lfs, } // not an end-of-commit crc - if ((lfs_rtag_type1(tag) & ~0x8) != LFS_TYPE1_CRC0) { + if ((lfs_rtag_type1(tag) & ~0x1) != LFS_TYPE1_CRC0) { // fcrc is only valid if the last tag was a crc hasfcrc = false; @@ -1056,10 +1059,6 @@ static int lfs_rbyd_fetchmatch(lfs_t *lfs, return 0; } -static int lfs_rbyd_fetch(lfs_t *lfs, lfs_rbyd_t *rbyd, lfs_block_t block) { - return lfs_rbyd_fetchmatch(lfs, rbyd, block, NULL); -} - //static lfs_ssize_t lfs_rbyd_lookup(lfs_t *lfs, lfs_rbyd_t *rbyd, // lfs_rtag_t tag, lfs_off_t *off, lfs_rtag_t *ntag) { // // TODO @@ -1474,8 +1473,8 @@ static int lfs_rbyd_commit(lfs_t *lfs, lfs_rbyd_t *rbyd, // so we can really change any bit to make this happen, we've reserved a bit // in crc tags just for this purpose if ((lfs_popc(crc) & 1) == (perturb & 1)) { - buffer[0] ^= 0x10; - crc ^= 0xc00c303e; // note crc(a ^ b) == crc(a) ^ crc(b) + buffer[0] ^= 0x2; + crc ^= 0xdb8ca0c3; // note crc(a ^ b) == crc(a) ^ crc(b) } lfs_tole32_(crc, &buffer[1+5]); diff --git a/scripts/dbgrbyd.py b/scripts/dbgrbyd.py index dcc8ca9d..e1bbb1e8 100755 --- a/scripts/dbgrbyd.py +++ b/scripts/dbgrbyd.py @@ -45,15 +45,7 @@ def tagrepr(tag, size, off=None): type2 = (tag >> 7) & 0xff id = (tag >> 15) & 0xffff - if type1 & 1: - return 'alt %s %s x%x %s' % ( - 'r' if type1 & 4 else 'b', - 'gt' if type1 & 2 else 'lt', - tag >> 3, - 'x%x' % (0xffffffff & (off-size)) - if off is not None - else '-%d' % off) - elif type1 == 0x40: + if type1 == 0x40: return 'create x%02x id%d %d' % (type2, id, size) elif type1 == 0x48: return 'delete x%02x id%d %d' % (type2, id, size) @@ -68,16 +60,24 @@ def tagrepr(tag, size, off=None): return 'tail x%02x %d' % (type2, size) elif type1 == 0x10: return 'gstate x%02x %d' % (type2, size) - elif type1 == 0x02 or type1 == 0x0a: + elif (type1 & 0x7e) == 0x02: if type2 == 0: return 'crc%x %d' % (type1 >> 3, size) else: return 'crc%x x%02x %d' % (type1 >> 3, type2, size) - elif type1 == 0x12: + elif type1 == 0x0a: if type2 == 0: return 'fcrc %d' % (size) else: return 'fcrc x%02x %d' % (type2, size) + elif type1 & 0x4: + return 'alt%s%s x%x %s' % ( + 'r' if type1 & 4 else 'b', + 'gt' if type1 & 2 else 'lt', + tag >> 3, + 'x%x' % (0xffffffff & (off-size)) + if off is not None + else '-%d' % off) else: return 'x%02x x%02x id%d %d' % (type1, type2, id, size) @@ -104,8 +104,8 @@ def main(disk, block_size, block1, block2=None, **args): crc = crc32c(data[j:j+delta], crc) j += delta - if not tag & 0x1: - if (tag & 0x37) != 0x2: + if not tag & 0x4: + if (tag & 0x7e) != 0x2: crc = crc32c(data[j:j+size], crc) # found a crc? else: @@ -131,11 +131,10 @@ def main(disk, block_size, block1, block2=None, **args): # print contents of the winning metadata block block, data, rev, off = blocks[i], datas[i], revs[i], offs[i] - print('mdir 0x%x, rev %d, size %d (was 0x%x, %d, %d)' % ( + print('mdir 0x%x, rev %d, size %d%s' % ( block, rev, off, - blocks[len(blocks)-1-i], - revs[len(revs)-1-i], - offs[len(offs)-1-i])) + ' (was 0x%x, %d, %d)' % (blocks[~i], revs[~i], offs[~i]) + if len(blocks) > 1 else '')) print('%-8s %-22s %s' % ( 'off', 'tag', 'data (truncated)' @@ -158,8 +157,8 @@ def main(disk, block_size, block1, block2=None, **args): crc = crc32c(data[j:j+delta], crc) j += delta - if not tag & 0x1: - if (tag & 0x37) != 0x2: + if not tag & 0x4: + if (tag & 0x7e) != 0x2: crc = crc32c(data[j:j+size], crc) # found a crc? else: @@ -173,7 +172,7 @@ def main(disk, block_size, block1, block2=None, **args): '%-22s%s' % ( tagrepr(tag, size, j_), ' %s' % next(xxd(data[j_+delta:j_+delta+min(size, 8)], 8), '') - if not tag & 1 and not args.get('no_truncate') else ''), + if not tag & 0x4 and not args.get('no_truncate') else ''), ' (%s)' % ', '.join(notes) if notes else '')) @@ -181,7 +180,7 @@ def main(disk, block_size, block1, block2=None, **args): for o, line in enumerate(xxd(data[j_:j_+delta])): print('%8s: %s' % ('%04x' % (j_ + o*16), line)) - if not tag & 0x1: + if not tag & 0x4: if args.get('raw') or args.get('no_truncate'): for o, line in enumerate(xxd(data[j_+delta:j_+delta+size])): print('%8s: %s' % ('%04x' % (j_+delta + o*16), line)) diff --git a/tests/test_rbyd.toml b/tests/test_rbyd.toml index e07d4766..be6ab6ed 100644 --- a/tests/test_rbyd.toml +++ b/tests/test_rbyd.toml @@ -22,14 +22,14 @@ code = ''' lfs_rbyd_t rbyd_ = rbyd; lfs_bd_erase(&lfs, rbyd_.block) => 0; lfs_rbyd_commit(&lfs, &rbyd_, NULL) => 0; - lfs_rbyd_fetch(&lfs, &rbyd_, rbyd.block) => 0; + lfs_rbyd_fetch(&lfs, &rbyd_, rbyd.block, NULL) => 0; // commit with one attribute rbyd_ = rbyd; lfs_bd_erase(&lfs, rbyd_.block) => 0; lfs_rbyd_commit(&lfs, &rbyd_, LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, NULL)) => 0; - lfs_rbyd_fetch(&lfs, &rbyd_, rbyd.block) => 0; + lfs_rbyd_fetch(&lfs, &rbyd_, rbyd.block, NULL) => 0; // commit with two attributes rbyd_ = rbyd; @@ -38,7 +38,7 @@ code = ''' LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, NULL))) => 0; - lfs_rbyd_fetch(&lfs, &rbyd_, rbyd.block) => 0; + lfs_rbyd_fetch(&lfs, &rbyd_, rbyd.block, NULL) => 0; // // commit with three attributes // rbyd_ = rbyd; @@ -74,7 +74,7 @@ code = ''' lfs_rbyd_t rbyd_ = rbyd; lfs_bd_erase(&lfs, rbyd_.block) => 0; lfs_rbyd_commit(&lfs, &rbyd_, NULL) => 0; - lfs_rbyd_fetch(&lfs, &rbyd_, rbyd.block) => 0; + lfs_rbyd_fetch(&lfs, &rbyd_, rbyd.block, NULL) => 0; // commit with one attribute rbyd_ = rbyd; @@ -82,7 +82,7 @@ code = ''' lfs_rbyd_commit(&lfs, &rbyd_, NULL) => 0; lfs_rbyd_commit(&lfs, &rbyd_, LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, NULL)) => 0; - lfs_rbyd_fetch(&lfs, &rbyd_, rbyd.block) => 0; + lfs_rbyd_fetch(&lfs, &rbyd_, rbyd.block, NULL) => 0; // commit with two attributes rbyd_ = rbyd; @@ -91,7 +91,7 @@ code = ''' LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, NULL)) => 0; lfs_rbyd_commit(&lfs, &rbyd_, LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, NULL)) => 0; - lfs_rbyd_fetch(&lfs, &rbyd_, rbyd.block) => 0; + lfs_rbyd_fetch(&lfs, &rbyd_, rbyd.block, NULL) => 0; // // commit with three attributes // rbyd_ = rbyd;