Reworked crystallization to better use erased-state on rewrites

This adopts lazy crystallization in _addition_ to lazy grafting, managed
by separate LFS_o_UNCRYST and LFS_o_UNGRAFT flags:

  LFS_o_UNCRYST  0x00400000  File's leaf not fully crystallized
  LFS_o_UNGRAFT  0x00800000  File's leaf does not match bshrub/btree

This lets us graft not-fully-crystallized blocks into the tree without
needing to fully crystallize, avoiding repeated recrystallizations when
linearly rewriting a file.

Long story short, this gives file rewrites roughly the same performance
as linear file writes.

---

In theory you could also have fully crystallized but ungrafted blocks
(UNGRAFT + ~UNCRYST), but this doesn't happen with the current logic.
lfsr_file_crystallize eagerly grafts blocks once they're crystallized.

Internally, lfsr_file_crystallize replaces lfsr_file_graft for the
"don't care, gimme file->leaf" operation. This is analogous to
lfsr_file_flush for file->cache.

Note we do _not_ use LFS_o_UNCRYST to track erased-state! If we did,
erased-state wouldn't survive lfsr_file_flush!

---

Of course, this adds even more code. Fortunately not _that_ much
considering how many lines of code changed:

           code          stack          ctx
  before: 37012           2304          636
  after   37084 (+0.2%)   2304 (+0.0%)  636 (+0.0%)

There is another downside however, and that's that our benchmarked disk
usage is slightly worse during random writes.

I haven't fully investigated this, but I think it's due to more
temporary fragments/blocks in the B-tree before flushing. This can cause
B-tree inner nodes to split earlier than when eagerly recrystallizing.

This also leads to higher disk usage pre-flush since we keep both the
old and new blocks around while uncrystallized, but since most rewrites
are probably going to be CoW on top of committed files, I don't think
this will be a big deal.

Note the disk usage ends up the same after lfsr_file_flush.
This commit is contained in:
Christopher Haster
2025-05-23 01:10:23 -05:00
parent f4c1753075
commit 9c3a866508
3 changed files with 104 additions and 83 deletions

View File

@@ -44,7 +44,8 @@ FLAGS = [
('^', 'ORPHAN', 0x50000000, "Type = orphan" ),
('^', 'TRAVERSAL', 0x60000000, "Type = traversal" ),
('^', 'UNKNOWN', 0x70000000, "Type = unknown" ),
('o', 'UNGRAFT', 0x00800000, "File's leaf does not match btree" ),
('o', 'UNCRYST', 0x00400000, "File's leaf not fully crystallized" ),
('o', 'UNGRAFT', 0x00800000, "File's leaf does not match bshrub/btree" ),
('o', 'UNFLUSH', 0x01000000, "File's data does not match disk" ),
('o', 'UNSYNC', 0x02000000, "File's metadata does not match disk" ),
('o', 'UNCREAT', 0x04000000, "File does not exist yet" ),