Split crystal_thresh into crystal_thresh + fragment_thresh

So now crystal_thresh only controls when fragments are compacted into
blocks, while fragment_thresh controls when blocks are broken into
fragments. Setting fragment_thresh=-1 will follow crystal_thresh and
keeps the previous behavior.

These were already two separate pieces of logic, so it makes sense to
provide two separate knobs for tuning.

Setting fragment_thresh lower than crystal_thresh has some potential to
reduce hysteresis in cases where random writes push blocks close to
crystal_thresh. It will be interesting to explore this more when
benchmarking.

---

The additional config option adds a bit of code/ctx, but hopefully that
will go away in the future config rework:

           code          stack          ctx
  before: 35584           2480          636
  after:  35600 (+0.0%)   2480 (+0.0%)  640 (+0.6%)
This commit is contained in:
Christopher Haster
2025-04-18 15:43:38 -05:00
parent 200830aafe
commit c5efe35ab2
5 changed files with 37 additions and 10 deletions
+11 -4
View File
@@ -11614,10 +11614,12 @@ static int lfsr_file_carve(lfs_t *lfs, lfsr_file_t *file,
-1);
// left sibling needs carving but falls underneath our
// crystallization threshold? break into fragments
// fragment threshold? break into fragments
while (lfsr_bptr_isbptr(&bptr_)
&& lfsr_data_size(l.data) > lfs->cfg->fragment_size
&& lfsr_data_size(l.data) < lfs->cfg->crystal_thresh) {
&& lfsr_data_size(l.data) < lfs_min(
lfs->cfg->fragment_thresh,
lfs->cfg->crystal_thresh)) {
bptr_.data = LFSR_DATA_SLICE(bptr_.data,
lfs->cfg->fragment_size,
-1);
@@ -11643,10 +11645,12 @@ static int lfsr_file_carve(lfs_t *lfs, lfsr_file_t *file,
}
// right sibling needs carving but falls underneath our
// crystallization threshold? break into fragments
// fragment threshold? break into fragments
while (lfsr_bptr_isbptr(&bptr_)
&& lfsr_data_size(r.data) > lfs->cfg->fragment_size
&& lfsr_data_size(r.data) < lfs->cfg->crystal_thresh) {
&& lfsr_data_size(r.data) < lfs_min(
lfs->cfg->fragment_thresh,
lfs->cfg->crystal_thresh)) {
bptr_.data = LFSR_DATA_SLICE(bptr_.data,
-1,
lfsr_data_size(bptr_.data) - lfs->cfg->fragment_size);
@@ -13093,6 +13097,9 @@ static int lfs_init(lfs_t *lfs, uint32_t flags,
LFS_ASSERT(lfs->cfg->inline_size <= lfs->cfg->block_size/4);
// fragment_size must be <= block_size/4
LFS_ASSERT(lfs->cfg->fragment_size <= lfs->cfg->block_size/4);
// fragment_thresh > crystal_thresh is probably a mistake
LFS_ASSERT(lfs->cfg->fragment_thresh == (lfs_size_t)-1
|| lfs->cfg->fragment_thresh <= lfs->cfg->crystal_thresh);
// setup flags
lfs->flags = flags