Middle of a rewrite for 3-leb encoding, but rbyd appends and creates both work

If we combine rbyd ids and B-tree weights, we need 32-bit ids since this
will eventually need to cover the full range of a file. This simply
doesn't fit into a single word anymore, unless littlefs uses 64-bit tags.
Generally not a great idea for a filesystem targeting even 8-bit
microcontrollers.

So here is a tag encoding that uses 3 leb128 words. This will likely
have more code cost and slightly more disk usage (we can no longer fit
tags into 2 bytes), though with most tags being alt pointers (O(m log m)
vs O(m)), this may not be that significant.

Note that we try to keep tags limited to 14-bits to avoid an extra leb128 byte,
which would likely affect all alt pointers. To pull this off we do away
with the subtype/suptype distinction, limiting in-tree tag types to
10-bits encoded on a per-suptype basis:

  in-tree tags:
                       ttttttt ttt00rv
                                 ^--^^- 10-bit type
                                    '|- removed bit
                                     '- valid bit
  iiii iiiiiii iiiiiii iiiiiii iiiiiii
                                     ^- n-bit id
       lllllll lllllll lllllll lllllll
                                     ^- m-bit length

  out-of-tree tags:
                       ttttttt ttt010v
                                 ^---^- 10-bit type
                                     '- valid bit
                               0000000
       lllllll lllllll lllllll lllllll
                                     ^- m-bit length

  alt tags:
                       kkkkkkk kkk1dcv
                                 ^-^^^- 10-bit key
                                   '||- direction bit
                                    '|- color bit
                                     '- valid bit
  wwww wwwwwww wwwwwww wwwwwww wwwwwww
                                     ^- n-bit weight
       jjjjjjj jjjjjjj jjjjjjj jjjjjjj
                                     ^- m-bit jump

The real pain is that with separate integers for id and tag, it no
longer makes sense to combine these into one big weight field. This
requires a significant rewrite.
This commit is contained in:
Christopher Haster
2023-01-24 01:38:26 -06:00
parent cdc3a486d6
commit 08f5d9ddf4
5 changed files with 4772 additions and 3954 deletions
+9 -3
View File
@@ -44,6 +44,11 @@ typedef int32_t lfs_soff_t;
typedef uint32_t lfs_block_t;
typedef uint16_t lfsr_tag_t;
typedef int16_t lfsr_stag_t;
typedef uint32_t lfsr_id_t;
typedef int32_t lfsr_sid_t;
// Maximum name size in bytes, may be redefined to reduce the size of the
// info struct. Limited to <= 1022. Stored in superblock and must be
// respected by other littlefs drivers.
@@ -331,11 +336,12 @@ typedef struct lfs_cache {
typedef struct lfsr_rbyd {
lfs_block_t block;
lfs_off_t trunk;
lfs_off_t off;
uint32_t rev;
lfs_off_t off;
uint32_t crc;
uint16_t count;
lfs_off_t trunk;
lfs_size_t weight;
// TODO can we get rid of erased? use sign bit of off maybe?
bool erased;
} lfsr_rbyd_t;