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
This commit is contained in:
@@ -407,10 +407,13 @@ enum lfs_rtag_type1 {
|
|||||||
LFS_TYPE1_GSTATE = 0x10,
|
LFS_TYPE1_GSTATE = 0x10,
|
||||||
|
|
||||||
LFS_TYPE1_CRC0 = 0x02,
|
LFS_TYPE1_CRC0 = 0x02,
|
||||||
LFS_TYPE1_CRC1 = 0x0a,
|
LFS_TYPE1_CRC1 = 0x03,
|
||||||
LFS_TYPE1_FCRC = 0x12,
|
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 {
|
enum lfs_rtag_color {
|
||||||
@@ -432,8 +435,8 @@ enum lfs_rtag_dir {
|
|||||||
LFS_MKRTAG_(LFS_TYPE1_##type1, type2, id)
|
LFS_MKRTAG_(LFS_TYPE1_##type1, type2, id)
|
||||||
|
|
||||||
#define LFS_MKRALT_(color, dir, weight) \
|
#define LFS_MKRALT_(color, dir, weight) \
|
||||||
(0x1 \
|
(LFS_TYPE1_ALTBLT \
|
||||||
| ((0x1 & (lfs_rtag_t)(color)) << 2) \
|
| ((0x1 & (lfs_rtag_t)(color)) << 0) \
|
||||||
| ((0x1 & (lfs_rtag_t)(dir)) << 1) \
|
| ((0x1 & (lfs_rtag_t)(dir)) << 1) \
|
||||||
| ((0xfffffff & (lfs_rtag_t)(weight)) << 3))
|
| ((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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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;
|
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,
|
lfs_rbyd_t *rbyd, lfs_block_t block,
|
||||||
struct lfs_fetchpattern *patterns) {
|
struct lfs_fetchpattern *patterns) {
|
||||||
// read the revision count and get the crc started
|
// 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?
|
// found trunk of tree?
|
||||||
if (!wastrunk && (lfs_rtag_isalt(tag) || lfs_rtag_intree(tag))) {
|
if (!wastrunk && lfs_rtag_intree(tag)) {
|
||||||
trunk = off;
|
trunk = off;
|
||||||
wastrunk = true;
|
wastrunk = true;
|
||||||
}
|
}
|
||||||
@@ -962,7 +965,7 @@ static int lfs_rbyd_fetchmatch(lfs_t *lfs,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// not an end-of-commit crc
|
// 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
|
// fcrc is only valid if the last tag was a crc
|
||||||
hasfcrc = false;
|
hasfcrc = false;
|
||||||
|
|
||||||
@@ -1056,10 +1059,6 @@ static int lfs_rbyd_fetchmatch(lfs_t *lfs,
|
|||||||
return 0;
|
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,
|
//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) {
|
// lfs_rtag_t tag, lfs_off_t *off, lfs_rtag_t *ntag) {
|
||||||
// // TODO
|
// // 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
|
// so we can really change any bit to make this happen, we've reserved a bit
|
||||||
// in crc tags just for this purpose
|
// in crc tags just for this purpose
|
||||||
if ((lfs_popc(crc) & 1) == (perturb & 1)) {
|
if ((lfs_popc(crc) & 1) == (perturb & 1)) {
|
||||||
buffer[0] ^= 0x10;
|
buffer[0] ^= 0x2;
|
||||||
crc ^= 0xc00c303e; // note crc(a ^ b) == crc(a) ^ crc(b)
|
crc ^= 0xdb8ca0c3; // note crc(a ^ b) == crc(a) ^ crc(b)
|
||||||
}
|
}
|
||||||
lfs_tole32_(crc, &buffer[1+5]);
|
lfs_tole32_(crc, &buffer[1+5]);
|
||||||
|
|
||||||
|
|||||||
+20
-21
@@ -45,15 +45,7 @@ def tagrepr(tag, size, off=None):
|
|||||||
type2 = (tag >> 7) & 0xff
|
type2 = (tag >> 7) & 0xff
|
||||||
id = (tag >> 15) & 0xffff
|
id = (tag >> 15) & 0xffff
|
||||||
|
|
||||||
if type1 & 1:
|
if type1 == 0x40:
|
||||||
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:
|
|
||||||
return 'create x%02x id%d %d' % (type2, id, size)
|
return 'create x%02x id%d %d' % (type2, id, size)
|
||||||
elif type1 == 0x48:
|
elif type1 == 0x48:
|
||||||
return 'delete x%02x id%d %d' % (type2, id, size)
|
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)
|
return 'tail x%02x %d' % (type2, size)
|
||||||
elif type1 == 0x10:
|
elif type1 == 0x10:
|
||||||
return 'gstate x%02x %d' % (type2, size)
|
return 'gstate x%02x %d' % (type2, size)
|
||||||
elif type1 == 0x02 or type1 == 0x0a:
|
elif (type1 & 0x7e) == 0x02:
|
||||||
if type2 == 0:
|
if type2 == 0:
|
||||||
return 'crc%x %d' % (type1 >> 3, size)
|
return 'crc%x %d' % (type1 >> 3, size)
|
||||||
else:
|
else:
|
||||||
return 'crc%x x%02x %d' % (type1 >> 3, type2, size)
|
return 'crc%x x%02x %d' % (type1 >> 3, type2, size)
|
||||||
elif type1 == 0x12:
|
elif type1 == 0x0a:
|
||||||
if type2 == 0:
|
if type2 == 0:
|
||||||
return 'fcrc %d' % (size)
|
return 'fcrc %d' % (size)
|
||||||
else:
|
else:
|
||||||
return 'fcrc x%02x %d' % (type2, size)
|
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:
|
else:
|
||||||
return 'x%02x x%02x id%d %d' % (type1, type2, id, size)
|
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)
|
crc = crc32c(data[j:j+delta], crc)
|
||||||
j += delta
|
j += delta
|
||||||
|
|
||||||
if not tag & 0x1:
|
if not tag & 0x4:
|
||||||
if (tag & 0x37) != 0x2:
|
if (tag & 0x7e) != 0x2:
|
||||||
crc = crc32c(data[j:j+size], crc)
|
crc = crc32c(data[j:j+size], crc)
|
||||||
# found a crc?
|
# found a crc?
|
||||||
else:
|
else:
|
||||||
@@ -131,11 +131,10 @@ def main(disk, block_size, block1, block2=None, **args):
|
|||||||
|
|
||||||
# print contents of the winning metadata block
|
# print contents of the winning metadata block
|
||||||
block, data, rev, off = blocks[i], datas[i], revs[i], offs[i]
|
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,
|
block, rev, off,
|
||||||
blocks[len(blocks)-1-i],
|
' (was 0x%x, %d, %d)' % (blocks[~i], revs[~i], offs[~i])
|
||||||
revs[len(revs)-1-i],
|
if len(blocks) > 1 else ''))
|
||||||
offs[len(offs)-1-i]))
|
|
||||||
print('%-8s %-22s %s' % (
|
print('%-8s %-22s %s' % (
|
||||||
'off', 'tag',
|
'off', 'tag',
|
||||||
'data (truncated)'
|
'data (truncated)'
|
||||||
@@ -158,8 +157,8 @@ def main(disk, block_size, block1, block2=None, **args):
|
|||||||
crc = crc32c(data[j:j+delta], crc)
|
crc = crc32c(data[j:j+delta], crc)
|
||||||
j += delta
|
j += delta
|
||||||
|
|
||||||
if not tag & 0x1:
|
if not tag & 0x4:
|
||||||
if (tag & 0x37) != 0x2:
|
if (tag & 0x7e) != 0x2:
|
||||||
crc = crc32c(data[j:j+size], crc)
|
crc = crc32c(data[j:j+size], crc)
|
||||||
# found a crc?
|
# found a crc?
|
||||||
else:
|
else:
|
||||||
@@ -173,7 +172,7 @@ def main(disk, block_size, block1, block2=None, **args):
|
|||||||
'%-22s%s' % (
|
'%-22s%s' % (
|
||||||
tagrepr(tag, size, j_),
|
tagrepr(tag, size, j_),
|
||||||
' %s' % next(xxd(data[j_+delta:j_+delta+min(size, 8)], 8), '')
|
' %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)
|
' (%s)' % ', '.join(notes)
|
||||||
if notes else ''))
|
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])):
|
for o, line in enumerate(xxd(data[j_:j_+delta])):
|
||||||
print('%8s: %s' % ('%04x' % (j_ + o*16), line))
|
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'):
|
if args.get('raw') or args.get('no_truncate'):
|
||||||
for o, line in enumerate(xxd(data[j_+delta:j_+delta+size])):
|
for o, line in enumerate(xxd(data[j_+delta:j_+delta+size])):
|
||||||
print('%8s: %s' % ('%04x' % (j_+delta + o*16), line))
|
print('%8s: %s' % ('%04x' % (j_+delta + o*16), line))
|
||||||
|
|||||||
@@ -22,14 +22,14 @@ code = '''
|
|||||||
lfs_rbyd_t rbyd_ = rbyd;
|
lfs_rbyd_t rbyd_ = rbyd;
|
||||||
lfs_bd_erase(&lfs, rbyd_.block) => 0;
|
lfs_bd_erase(&lfs, rbyd_.block) => 0;
|
||||||
lfs_rbyd_commit(&lfs, &rbyd_, NULL) => 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
|
// commit with one attribute
|
||||||
rbyd_ = rbyd;
|
rbyd_ = rbyd;
|
||||||
lfs_bd_erase(&lfs, rbyd_.block) => 0;
|
lfs_bd_erase(&lfs, rbyd_.block) => 0;
|
||||||
lfs_rbyd_commit(&lfs, &rbyd_,
|
lfs_rbyd_commit(&lfs, &rbyd_,
|
||||||
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, NULL)) => 0;
|
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
|
// commit with two attributes
|
||||||
rbyd_ = rbyd;
|
rbyd_ = rbyd;
|
||||||
@@ -38,7 +38,7 @@ code = '''
|
|||||||
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
|
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
|
||||||
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
|
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
|
||||||
NULL))) => 0;
|
NULL))) => 0;
|
||||||
lfs_rbyd_fetch(&lfs, &rbyd_, rbyd.block) => 0;
|
lfs_rbyd_fetch(&lfs, &rbyd_, rbyd.block, NULL) => 0;
|
||||||
|
|
||||||
// // commit with three attributes
|
// // commit with three attributes
|
||||||
// rbyd_ = rbyd;
|
// rbyd_ = rbyd;
|
||||||
@@ -74,7 +74,7 @@ code = '''
|
|||||||
lfs_rbyd_t rbyd_ = rbyd;
|
lfs_rbyd_t rbyd_ = rbyd;
|
||||||
lfs_bd_erase(&lfs, rbyd_.block) => 0;
|
lfs_bd_erase(&lfs, rbyd_.block) => 0;
|
||||||
lfs_rbyd_commit(&lfs, &rbyd_, NULL) => 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
|
// commit with one attribute
|
||||||
rbyd_ = rbyd;
|
rbyd_ = rbyd;
|
||||||
@@ -82,7 +82,7 @@ code = '''
|
|||||||
lfs_rbyd_commit(&lfs, &rbyd_, NULL) => 0;
|
lfs_rbyd_commit(&lfs, &rbyd_, NULL) => 0;
|
||||||
lfs_rbyd_commit(&lfs, &rbyd_,
|
lfs_rbyd_commit(&lfs, &rbyd_,
|
||||||
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, NULL)) => 0;
|
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
|
// commit with two attributes
|
||||||
rbyd_ = rbyd;
|
rbyd_ = rbyd;
|
||||||
@@ -91,7 +91,7 @@ code = '''
|
|||||||
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, NULL)) => 0;
|
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, NULL)) => 0;
|
||||||
lfs_rbyd_commit(&lfs, &rbyd_,
|
lfs_rbyd_commit(&lfs, &rbyd_,
|
||||||
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, NULL)) => 0;
|
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
|
// // commit with three attributes
|
||||||
// rbyd_ = rbyd;
|
// rbyd_ = rbyd;
|
||||||
|
|||||||
Reference in New Issue
Block a user