Reverted lfsr_data_t lazily encoded leb128s

- It didn't save code.

- An inlined buffer is potentially more useful, even if only marginally,
  and, uh, unproven yet.

- Requiring lfs_toleb128 in a readonly implementation is a hard ask.
This commit is contained in:
Christopher Haster
2024-02-25 12:31:32 -06:00
parent 415e148f62
commit 692810e18e
4 changed files with 97 additions and 86 deletions
+61 -51
View File
@@ -1113,13 +1113,13 @@ static lfs_ssize_t lfsr_bd_progtag(lfs_t *lfs,
/// lfsr_data_t stuff ///
// the top 2 bits of data's size indicates the actual encoding
// 0b00 => in-RAM buffer
// 0b01 => a single leb128
// 0b10 => on-disk reference
// 0b11 => concatenated datas
// the top bits of data's size indicates the actual encoding
// 0x0 => buffer pointer
// 0x4 => inlined data
// 0x8 => on-disk reference
// 0xc => concatenated data pointer
#define LFSR_DATA_ONDISK 0x80000000
#define LFSR_DATA_ISWORD 0x40000000
#define LFSR_DATA_ISIMM 0x40000000
#define LFSR_DATA_ISCAT 0xc0000000
#define LFSR_DATA_NULL() \
@@ -1138,10 +1138,11 @@ static lfs_ssize_t lfsr_bd_progtag(lfs_t *lfs,
.u.buf.size=_size, \
.u.buf.buffer=(const void*)(_buffer)})
#define LFSR_DATA_WORD(_word) \
((lfsr_data_t){ \
.u.word.size=LFSR_DATA_ISWORD | lfs_sizeleb128(_word), \
.u.word.word=_word}) \
#define LFSR_DATA_IMM(_buffer, _size) \
lfsr_data_fromimm(_buffer, _size)
#define LFSR_DATA_LEB128(_word) \
lfsr_data_fromleb128(_word)
// this relies on temporary allocations which is a bit precarious...
#define LFSR_DATA_CAT(...) \
@@ -1183,8 +1184,8 @@ static inline bool lfsr_data_isbuf(lfsr_data_t data) {
return (data.u.size & LFSR_DATA_ISCAT) == 0;
}
static inline bool lfsr_data_isword(lfsr_data_t data) {
return (data.u.size & LFSR_DATA_ISCAT) == LFSR_DATA_ISWORD;
static inline bool lfsr_data_isimm(lfsr_data_t data) {
return (data.u.size & LFSR_DATA_ISCAT) == LFSR_DATA_ISIMM;
}
static inline bool lfsr_data_iscat(lfsr_data_t data) {
@@ -1195,8 +1196,27 @@ static inline lfs_size_t lfsr_data_size(lfsr_data_t data) {
return data.u.size & ~LFSR_DATA_ISCAT;
}
// cat just can't be a macro, at least not without statement expressions, we
// at least make these inline so hopefully the internal logic is elided
// some data initializers just can't be macros, we at least make these inline
// so most of the internal logic is hopefully elided
static inline lfsr_data_t lfsr_data_fromimm(
const void *buffer, lfs_size_t size) {
LFS_ASSERT(size <= 8);
lfsr_data_t data;
memcpy(data.u.imm.buf, buffer, size);
data.u.imm.size = LFSR_DATA_ISIMM | size;
return data;
}
static inline lfsr_data_t lfsr_data_fromleb128(uint32_t word) {
lfsr_data_t data;
lfs_ssize_t size = lfs_toleb128(word, data.u.imm.buf, 5);
LFS_ASSERT(size > 0);
LFS_ASSERT(size <= 5);
data.u.imm.size = LFSR_DATA_ISIMM | size;
return data;
}
static inline lfsr_data_t lfsr_data_fromcat(
const lfsr_data_t *datas, lfs_size_t count) {
// find total size
@@ -1232,10 +1252,12 @@ static lfsr_data_t lfsr_data_slice(lfsr_data_t data,
data.u.buf.buffer += off_;
data.u.buf.size = size_;
// word? shift
} else if (lfsr_data_isword(data)) {
data.u.word.word >>= 7*off_;
data.u.word.size = LFSR_DATA_ISWORD | size_;
// inlined? internal memmove
} else if (lfsr_data_isimm(data)) {
memmove(data.u.imm.buf,
data.u.imm.buf + off_,
size_);
data.u.imm.size = LFSR_DATA_ISIMM | size_;
// concatenated? not supported
} else {
@@ -1283,13 +1305,9 @@ static lfs_ssize_t lfsr_data_read(lfs_t *lfs, lfsr_data_t *data,
} else if (lfsr_data_isbuf(*data)) {
memcpy(buffer, data->u.buf.buffer, d);
// word?
} else if (lfsr_data_isword(*data)) {
uint8_t buf[5];
lfs_ssize_t d_ = lfs_toleb128(data->u.word.word, buf, sizeof(buf));
LFS_ASSERT(d_ == (lfs_ssize_t)lfsr_data_size(*data));
LFS_ASSERT(d <= (lfs_size_t)d_ && (lfs_size_t)d_ <= sizeof(buf));
memcpy(buffer, buf, d);
// inlined?
} else if (lfsr_data_isimm(*data)) {
memcpy(buffer, data->u.imm.buf, d);
// concatenated? not supported
} else {
@@ -1381,13 +1399,9 @@ static lfs_scmp_t lfsr_data_cmp(lfs_t *lfs, lfsr_data_t data,
return LFS_CMP_GT;
}
// word?
} else if (lfsr_data_isword(data)) {
uint8_t buf[5];
lfs_ssize_t d_ = lfs_toleb128(data.u.word.word, buf, sizeof(buf));
LFS_ASSERT(d_ == (lfs_ssize_t)lfsr_data_size(data));
LFS_ASSERT(d <= (lfs_size_t)d_ && (lfs_size_t)d_ <= sizeof(buf));
int cmp = memcmp(buf, buffer, d);
// inlined?
} else if (lfsr_data_isimm(data)) {
int cmp = memcmp(data.u.imm.buf, buffer, d);
if (cmp < 0) {
return LFS_CMP_LT;
} else if (cmp > 0) {
@@ -1452,12 +1466,9 @@ static int lfsr_bd_progdata_(lfs_t *lfs,
}
// inlined?
} else if (lfsr_data_isword(data)) {
uint8_t buf[5];
lfs_ssize_t d_ = lfs_toleb128(data.u.word.word, buf, sizeof(buf));
LFS_ASSERT(d_ == (lfs_ssize_t)lfsr_data_size(data));
} else if (lfsr_data_isimm(data)) {
int err = lfsr_bd_prog(lfs, block, off,
buf, lfsr_data_size(data),
data.u.imm.buf, lfsr_data_size(data),
cksum_);
if (err) {
return err;
@@ -8122,28 +8133,27 @@ static int lfsr_formatinited(lfs_t *lfs) {
LFSR_DATA_BUF("littlefs", 8)),
LFSR_ATTR(
LFSR_TAG_VERSION, 0,
LFSR_DATA_BUF(((const uint8_t[2]){
LFSR_DATA_IMM(((const uint8_t[2]){
LFS_DISK_VERSION_MAJOR,
LFS_DISK_VERSION_MINOR}), 2)),
LFSR_ATTR(
LFSR_TAG_RCOMPATFLAGS, 0,
LFSR_DATA_BUF(((uint8_t[1]){
LFSR_RCOMPAT_GRM}), 1)),
LFSR_DATA_IMM(((uint8_t[1]){LFSR_RCOMPAT_GRM}), 1)),
LFSR_ATTR(
LFSR_TAG_BLOCKSIZE, 0,
LFSR_DATA_WORD(lfs->cfg->block_size-1)),
LFSR_DATA_LEB128(lfs->cfg->block_size-1)),
LFSR_ATTR(
LFSR_TAG_BLOCKCOUNT, 0,
LFSR_DATA_WORD(lfs->cfg->block_count-1)),
LFSR_DATA_LEB128(lfs->cfg->block_count-1)),
LFSR_ATTR(
LFSR_TAG_NAMELIMIT, 0,
LFSR_DATA_WORD(lfs->name_limit)),
LFSR_DATA_LEB128(lfs->name_limit)),
LFSR_ATTR(
LFSR_TAG_SIZELIMIT, 0,
LFSR_DATA_WORD(lfs->size_limit)),
LFSR_DATA_LEB128(lfs->size_limit)),
LFSR_ATTR(
LFSR_TAG_BOOKMARK, +1,
LFSR_DATA_WORD(0))));
LFSR_DATA_LEB128(0))));
if (err) {
return err;
}
@@ -8617,7 +8627,7 @@ int lfsr_mkdir(lfs_t *lfs, const char *path) {
// commit our bookmark and a grm to self-remove in case of powerloss
err = lfsr_mdir_commit(lfs, &mdir, LFSR_ATTRS(
LFSR_ATTR(LFSR_TAG_BOOKMARK, +1, LFSR_DATA_WORD(did_)),
LFSR_ATTR(LFSR_TAG_BOOKMARK, +1, LFSR_DATA_LEB128(did_)),
LFSR_ATTR(
LFSR_TAG_GRM, 0,
LFSR_DATA_GRM(&((lfsr_grm_t){{mdir.mid, -1}})))));
@@ -8641,9 +8651,9 @@ int lfsr_mkdir(lfs_t *lfs, const char *path) {
LFSR_ATTR(
LFSR_TAG_SUP | LFSR_TAG_DIR, (!exists) ? +1 : 0,
LFSR_DATA_CAT(
LFSR_DATA_WORD(did),
LFSR_DATA_LEB128(did),
LFSR_DATA_BUF(name, name_size))),
LFSR_ATTR(LFSR_TAG_DID, 0, LFSR_DATA_WORD(did_)),
LFSR_ATTR(LFSR_TAG_DID, 0, LFSR_DATA_LEB128(did_)),
LFSR_ATTR(
LFSR_TAG_GRM, 0,
LFSR_DATA_GRM(&((lfsr_grm_t){{-1, -1}})))));
@@ -8748,7 +8758,7 @@ int lfsr_remove(lfs_t *lfs, const char *path) {
? LFSR_ATTR(
LFSR_TAG_SUP | LFSR_TAG_ORPHAN, 0,
LFSR_DATA_CAT(
LFSR_DATA_WORD(did),
LFSR_DATA_LEB128(did),
LFSR_DATA_BUF(name, name_size)))
: LFSR_ATTR(
LFSR_TAG_RM, -1, LFSR_DATA_NULL()),
@@ -8898,7 +8908,7 @@ int lfsr_rename(lfs_t *lfs, const char *old_path, const char *new_path) {
LFSR_ATTR(
LFSR_TAG_SUP | old_tag, (!exists) ? +1 : 0,
LFSR_DATA_CAT(
LFSR_DATA_WORD(new_did),
LFSR_DATA_LEB128(new_did),
LFSR_DATA_BUF(new_name, new_name_size))),
LFSR_ATTR(LFSR_TAG_MOVE, 0, LFSR_DATA_MOVE(&old_mdir)),
LFSR_ATTR(LFSR_TAG_GRM, 0, LFSR_DATA_GRM(&grm))));
@@ -9377,7 +9387,7 @@ int lfsr_file_opencfg(lfs_t *lfs, lfsr_file_t *file,
LFSR_ATTR(
LFSR_TAG_ORPHAN, +1,
LFSR_DATA_CAT(
LFSR_DATA_WORD(did),
LFSR_DATA_LEB128(did),
LFSR_DATA_BUF(name, name_size)))));
if (err) {
return err;
+13 -7
View File
@@ -399,11 +399,17 @@ typedef struct lfs_mdir {
// Either an on-disk or in-device data pointer
//
// The top 2 bits of data's size indicates the actual encoding
// 0b00 => in-RAM buffer
// 0b01 => a single leb128
// 0b10 => on-disk reference
// 0b11 => concatenated datas
// The sign-bit of the size field indicates if the data is
// in-device or on-disk.
//
// After removing the sign bit, the size always encodes the
// resulting size on-disk.
//
// The exact representation of in-device data also depends on the
// mode field:
// - pointer to a RAM-backed buffer
// - inlined data able to fit at least 1 leb128
// - an array of concatenated datas
//
// Note concatenated datas can only be 1 level deep. Concatenating
// concatenated datas would require recursion to resolve.
@@ -422,8 +428,8 @@ typedef struct lfsr_data {
} buf;
struct {
lfs_ssize_t size;
uint32_t word;
} word;
uint8_t buf[8];
} imm;
struct {
lfs_ssize_t size;
const struct lfsr_data *datas;
-5
View File
@@ -348,11 +348,6 @@ ssize_t lfs_toleb128(uint32_t word, void *buffer, size_t size);
ssize_t lfs_fromleb128(uint32_t *word, const void *buffer, size_t size);
// Calculate the on-disk size of a leb128 without actually encoding
static inline size_t lfs_sizeleb128(uint32_t word) {
return (lfs_nlog2(word+1)+7-1) / 7;
}
// Calculate CRC-32 with polynomial = 0x04c11db7
+23 -23
View File
@@ -3251,7 +3251,7 @@ code = '''
lfsr_btree_commit(&lfs, &btree, 0, LFSR_ATTRS(
LFSR_ATTR(
LFSR_TAG_NAME, +1,
LFSR_DATA_CAT(LFSR_DATA_WORD(0), LFSR_DATA_BUF("aaa", 3))),
LFSR_DATA_CAT(LFSR_DATA_LEB128(0), LFSR_DATA_BUF("aaa", 3))),
LFSR_ATTR(LFSR_TAG_DATA, 0, LFSR_DATA_BUF("0", 1)))) => 0;
printf("btree: w%d 0x%x.%x\n",
btree.weight,
@@ -3304,13 +3304,13 @@ code = '''
lfsr_btree_commit(&lfs, &btree, 0, LFSR_ATTRS(
LFSR_ATTR(
LFSR_TAG_NAME, +1,
LFSR_DATA_CAT(LFSR_DATA_WORD(0), LFSR_DATA_BUF("aaa", 3))),
LFSR_DATA_CAT(LFSR_DATA_LEB128(0), LFSR_DATA_BUF("aaa", 3))),
LFSR_ATTR(LFSR_TAG_DATA, 0, LFSR_DATA_BUF("0", 1)))) => 0;
lfsr_btree_commit(&lfs, &btree, 0, LFSR_ATTRS(
LFSR_ATTR(LFSR_TAG_DATA, 0, LFSR_DATA_BUF("0", 1)),
LFSR_ATTR(
LFSR_TAG_NAME, +1,
LFSR_DATA_CAT(LFSR_DATA_WORD(0), LFSR_DATA_BUF("aab", 3))),
LFSR_DATA_CAT(LFSR_DATA_LEB128(0), LFSR_DATA_BUF("aab", 3))),
LFSR_ATTR(LFSR_TAG_DATA, 0, LFSR_DATA_BUF("1", 1)))) => 0;
printf("btree: w%d 0x%x.%x\n",
btree.weight,
@@ -3372,7 +3372,7 @@ code = '''
LFSR_ATTR(
LFSR_TAG_NAME, +1,
LFSR_DATA_CAT(
LFSR_DATA_WORD(0),
LFSR_DATA_LEB128(0),
LFSR_DATA_BUF("aaa", 3))),
LFSR_ATTR(LFSR_TAG_DATA, 0, LFSR_DATA_BUF("0", 1)))) => 0;
lfsr_btree_commit(&lfs, &btree, 0, LFSR_ATTRS(
@@ -3380,7 +3380,7 @@ code = '''
LFSR_ATTR(
LFSR_TAG_NAME, +1,
LFSR_DATA_CAT(
LFSR_DATA_WORD(1*DID),
LFSR_DATA_LEB128(1*DID),
LFSR_DATA_BUF("aab", 3))),
LFSR_ATTR(LFSR_TAG_DATA, 0, LFSR_DATA_BUF("1", 1)))) => 0;
lfsr_btree_commit(&lfs, &btree, 1, LFSR_ATTRS(
@@ -3388,7 +3388,7 @@ code = '''
LFSR_ATTR(
LFSR_TAG_NAME, +1,
LFSR_DATA_CAT(
LFSR_DATA_WORD(2*DID),
LFSR_DATA_LEB128(2*DID),
LFSR_DATA_BUF("aac", 3))),
LFSR_ATTR(LFSR_TAG_DATA, 0, LFSR_DATA_BUF("2", 1)))) => 0;
printf("btree: w%d 0x%x.%x\n",
@@ -3459,7 +3459,7 @@ code = '''
LFSR_ATTR(
LFSR_TAG_NAME, +1,
LFSR_DATA_CAT(
LFSR_DATA_WORD(0),
LFSR_DATA_LEB128(0),
LFSR_DATA_BUF("aaa", 3))),
LFSR_ATTR(LFSR_TAG_DATA, 0, LFSR_DATA_BUF("0", 1)))) => 0;
lfsr_btree_commit(&lfs, &btree, 0, LFSR_ATTRS(
@@ -3467,7 +3467,7 @@ code = '''
LFSR_ATTR(
LFSR_TAG_NAME, +1,
LFSR_DATA_CAT(
LFSR_DATA_WORD(2*DID),
LFSR_DATA_LEB128(2*DID),
LFSR_DATA_BUF("aac", 3))),
LFSR_ATTR(LFSR_TAG_DATA, 0, LFSR_DATA_BUF("2", 1)))) => 0;
lfsr_btree_commit(&lfs, &btree, 0, LFSR_ATTRS(
@@ -3475,7 +3475,7 @@ code = '''
LFSR_ATTR(
LFSR_TAG_NAME, +1,
LFSR_DATA_CAT(
LFSR_DATA_WORD(1*DID),
LFSR_DATA_LEB128(1*DID),
LFSR_DATA_BUF("aab", 3))),
LFSR_ATTR(LFSR_TAG_DATA, 0, LFSR_DATA_BUF("1", 1)))) => 0;
printf("btree: w%d 0x%x.%x\n",
@@ -3549,7 +3549,7 @@ code = '''
lfsr_btree_commit(&lfs, &btree, 0, LFSR_ATTRS(
LFSR_ATTR(
LFSR_TAG_NAME, +1,
LFSR_DATA_CAT(LFSR_DATA_WORD(0), LFSR_DATA_BUF(name, 3))),
LFSR_DATA_CAT(LFSR_DATA_LEB128(0), LFSR_DATA_BUF(name, 3))),
LFSR_ATTR(
LFSR_TAG_DATA, 0,
LFSR_DATA_BUF(&(uint8_t){'0'+(0 % 10)}, 1)))) => 0;
@@ -3564,7 +3564,7 @@ code = '''
LFSR_DATA_BUF(&(uint8_t){'0'+((i-1) % 10)}, 1)),
LFSR_ATTR(
LFSR_TAG_NAME, +1, LFSR_DATA_CAT(
LFSR_DATA_WORD(i*DID),
LFSR_DATA_LEB128(i*DID),
LFSR_DATA_BUF(name, 3))),
LFSR_ATTR(
LFSR_TAG_DATA, 0,
@@ -3625,7 +3625,7 @@ code = '''
lfsr_btree_commit(&lfs, &btree, 0, LFSR_ATTRS(
LFSR_ATTR(
LFSR_TAG_NAME, +1,
LFSR_DATA_CAT(LFSR_DATA_WORD(0), LFSR_DATA_BUF("___", 3))),
LFSR_DATA_CAT(LFSR_DATA_LEB128(0), LFSR_DATA_BUF("___", 3))),
LFSR_ATTR(LFSR_TAG_DATA, 0, LFSR_DATA_BUF("_", 1)))) => 0;
// set up a simulation to compare against
@@ -3666,7 +3666,7 @@ code = '''
LFSR_ATTR(
LFSR_TAG_NAME, +1,
LFSR_DATA_CAT(
LFSR_DATA_WORD(0),
LFSR_DATA_LEB128(0),
LFSR_DATA_BUF(name, 3))),
LFSR_ATTR(
LFSR_TAG_DATA, 0,
@@ -3750,7 +3750,7 @@ code = '''
lfsr_btree_commit(&lfs, &btree, 0, LFSR_ATTRS(
LFSR_ATTR(
LFSR_TAG_NAME, +W,
LFSR_DATA_CAT(LFSR_DATA_WORD(0), LFSR_DATA_BUF(name, 3))),
LFSR_DATA_CAT(LFSR_DATA_LEB128(0), LFSR_DATA_BUF(name, 3))),
LFSR_ATTR(
LFSR_TAG_DATA, 0,
LFSR_DATA_BUF(&(uint8_t){'0'+(0 % 10)}, 1)))) => 0;
@@ -3766,7 +3766,7 @@ code = '''
LFSR_ATTR(
LFSR_TAG_NAME, +W,
LFSR_DATA_CAT(
LFSR_DATA_WORD(i*DID),
LFSR_DATA_LEB128(i*DID),
LFSR_DATA_BUF(name, 3))),
LFSR_ATTR(
LFSR_TAG_DATA, 0,
@@ -3828,7 +3828,7 @@ code = '''
lfsr_btree_commit(&lfs, &btree, 0, LFSR_ATTRS(
LFSR_ATTR(
LFSR_TAG_NAME, +W,
LFSR_DATA_CAT(LFSR_DATA_WORD(0), LFSR_DATA_BUF("___", 3))),
LFSR_DATA_CAT(LFSR_DATA_LEB128(0), LFSR_DATA_BUF("___", 3))),
LFSR_ATTR(LFSR_TAG_DATA, 0, LFSR_DATA_BUF("_", 1)))) => 0;
// set up a simulation to compare against
@@ -3885,7 +3885,7 @@ code = '''
LFSR_ATTR(
LFSR_TAG_NAME, +weight2,
LFSR_DATA_CAT(
LFSR_DATA_WORD(0),
LFSR_DATA_LEB128(0),
LFSR_DATA_BUF(name, 3))),
LFSR_ATTR(
LFSR_TAG_DATA, 0,
@@ -3991,7 +3991,7 @@ code = '''
lfsr_btree_commit(&lfs, &btree, 0, LFSR_ATTRS(
LFSR_ATTR(
LFSR_TAG_NAME, +1,
LFSR_DATA_CAT(LFSR_DATA_WORD(0), LFSR_DATA_BUF("___", 3))),
LFSR_DATA_CAT(LFSR_DATA_LEB128(0), LFSR_DATA_BUF("___", 3))),
LFSR_ATTR(LFSR_TAG_DATA, 0, LFSR_DATA_BUF("_", 1)))) => 0;
// set up a simulation to compare against
@@ -4043,7 +4043,7 @@ code = '''
LFSR_ATTR(
LFSR_TAG_NAME, +1,
LFSR_DATA_CAT(
LFSR_DATA_WORD(0),
LFSR_DATA_LEB128(0),
LFSR_DATA_BUF(name, 3))),
LFSR_ATTR(
LFSR_TAG_DATA, 0,
@@ -4059,7 +4059,7 @@ code = '''
LFSR_ATTR(
LFSR_TAG_NAME, +1,
LFSR_DATA_CAT(
LFSR_DATA_WORD(0),
LFSR_DATA_LEB128(0),
LFSR_DATA_BUF(name, 3))),
LFSR_ATTR(
LFSR_TAG_DATA, 0,
@@ -4169,7 +4169,7 @@ code = '''
lfsr_btree_commit(&lfs, &btree, 0, LFSR_ATTRS(
LFSR_ATTR(
LFSR_TAG_NAME, +W,
LFSR_DATA_CAT(LFSR_DATA_WORD(0), LFSR_DATA_BUF("___", 3))),
LFSR_DATA_CAT(LFSR_DATA_LEB128(0), LFSR_DATA_BUF("___", 3))),
LFSR_ATTR(LFSR_TAG_DATA, 0, LFSR_DATA_BUF("_", 1)))) => 0;
// set up a simulation to compare against
@@ -4233,7 +4233,7 @@ code = '''
LFSR_ATTR(
LFSR_TAG_NAME, +weight,
LFSR_DATA_CAT(
LFSR_DATA_WORD(0),
LFSR_DATA_LEB128(0),
LFSR_DATA_BUF(name, 3))),
LFSR_ATTR(
LFSR_TAG_DATA, 0,
@@ -4249,7 +4249,7 @@ code = '''
LFSR_ATTR(
LFSR_TAG_NAME, +weight,
LFSR_DATA_CAT(
LFSR_DATA_WORD(0),
LFSR_DATA_LEB128(0),
LFSR_DATA_BUF(name, 3))),
LFSR_ATTR(
LFSR_TAG_DATA, 0,