Reworked grm encoding a bit

This drops the leading count/mode byte, and instead uses mid=0 to
terminate grms. This shaves off 1 bytes from grmdeltas.

Previously, we needed the count/mode byte for a couple reasons:

- We needed to know the number of grm entries somehow, and there wasn't
  always an obvious sentinel value. mid=-1, for example, is
  unrepresentable with our unsigned leb128 encoding.

  But now that development has settled, we can use mid=0.0 to figure out
  the end-of-queue. mid=0.0 should always map to the root bookmark,
  which doesn't make sense to delete, so it makes for a reasonable null
  terminator here.

- It provided a route for future grm extensions, which could use the >2
  count/mode encodings.

  But I think we can use additional grm tag encodings for this.

  There's only one gdelta tag so far, but the current plan for future
  gdelta tags is to carve out the bottom 2 bits for redund like we do
  with the struct tags:

    LFSR_TAG_GDELTA        0x01tt  v--- ---1 -ttt ttrr
    LFSR_TAG_GRMDELTA      0x0100  v--- ---1 ---- ----
    LFSR_TAG_GBMAPDELTA    0x0104  v--- ---1 ---- -1rr
    LFSR_TAG_GDDTREEDELTA  0x0108  v--- ---1 ---- 1-rr
    LFSR_TAG_GPTREEDELTA   0x010c  v--- ---1 ---- 11rr
    ...

  Decoding is a bit more complicated for gstate, since we will need to
  xor those bits if mutable, but this avoids needing a full byte just
  for redund in every auxiliary tree.

  Long story short, we can leverage the lower 2 bits of the grm tag for
  future extensions using the same mechanism.

This may seem like a lot of effort for only a handful of bytes, but keep
in mind each gdelta lives in more-or-less every mdir in the filesystem.

Also saves a bit of code/ctx:

           code          stack          ctx
  before: 35772           2368          640
  after:  35768 (-0.0%)   2368 (+0.0%)  636 (-0.6%)
This commit is contained in:
Christopher Haster
2025-04-29 12:32:01 -05:00
parent 98b4aaccc5
commit f2e6b60f36
7 changed files with 145 additions and 153 deletions
+8 -8
View File
@@ -7976,8 +7976,8 @@ code = '''
lfsr_fs_mkconsistent(&lfs) => 0;
// we should have cleaned up all grms/orphans
assert(lfs.grm.mids[0] == -1);
assert(lfs.grm.mids[1] == -1);
assert(lfs.grm.queue[0] == 0);
assert(lfs.grm.queue[1] == 0);
assert(!(lfs.flags & LFS_I_MKCONSISTENT));
struct lfs_fsinfo fsinfo;
@@ -8112,8 +8112,8 @@ code = '''
lfsr_fs_mkconsistent(&lfs) => 0;
// we should have cleaned up all grms/orphans
assert(lfs.grm.mids[0] == -1);
assert(lfs.grm.mids[1] == -1);
assert(lfs.grm.queue[0] == 0);
assert(lfs.grm.queue[1] == 0);
assert(!(lfs.flags & LFS_I_MKCONSISTENT));
struct lfs_fsinfo fsinfo;
@@ -8262,8 +8262,8 @@ code = '''
lfsr_fs_mkconsistent(&lfs) => 0;
// we should have cleaned up all grms/orphans
assert(lfs.grm.mids[0] == -1);
assert(lfs.grm.mids[1] == -1);
assert(lfs.grm.queue[0] == 0);
assert(lfs.grm.queue[1] == 0);
assert(!(lfs.flags & LFS_I_MKCONSISTENT));
struct lfs_fsinfo fsinfo;
@@ -8418,8 +8418,8 @@ code = '''
lfsr_fs_mkconsistent(&lfs) => 0;
// we should have cleaned up all grms/orphans
assert(lfs.grm.mids[0] == -1);
assert(lfs.grm.mids[1] == -1);
assert(lfs.grm.queue[0] == 0);
assert(lfs.grm.queue[1] == 0);
assert(!(lfs.flags & LFS_I_MKCONSISTENT));
struct lfs_fsinfo fsinfo;