lru: slab-elements instead of grow - #23557
Closed
AskAlexSharov wants to merge 1 commit into
Closed
Conversation
AskAlexSharov
force-pushed
the
alex/lru_slab_elements_37
branch
10 times, most recently
from
August 25, 2026 09:38
f44f71a to
9ebefb0
Compare
freelru sizes the element array from capacity at construction, so a cache either pre-commits its whole ceiling or has to be copied into a bigger table as it fills -- 195ms fenced at 1M entries, and the ladder ends with a 4.19M-entry step. Element positions are dense and self-relative, so the array does not have to be contiguous: hold it as 8192-entry slabs appended on demand. Residency then follows what is stored, and capacity never needs a rehash. Only the bucket index, 4B per slot, is sized up front.
AskAlexSharov
force-pushed
the
alex/lru_slab_elements_37
branch
from
August 25, 2026 10:56
9ebefb0 to
e9a4214
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
freelru sizes its element array from capacity at construction, so a cache either pre-commits its whole ceiling or gets copied into a bigger table as it fills. That copy is what costs
fenced=194.8msat 1M entries on n5, with a 4,194,304-entry step still ahead of it.It does not have to be that way. Element positions are dense and self-relative —
pos := lru.len, and every stored index (buckets[b],nextBucket,prevBucket,next,prev,head) is an offset into the same array. So the array need not be contiguous: hold it as fixed 8192-entry slabs (~917 KB) appended on demand.maybeGrow, the all-stripe fence,curCapand the generation swap are gone.execution/cache/slablruis freelru's singleLRUvendored (LGPL/Apache headers kept) withelements []elementreplaced byslabs [][]elementplus anelem(pos)accessor andreserve(pos). Upstream's own test suite is vendored with it and passes unchanged — that is the correctness argument.TestSlabsGrowOnDemandpins the new property: zero slabs empty, one at 8192 entries, two at 8193, and every key still addressable across the boundary.Two tests are deleted rather than adapted, because the code they guard no longer exists:
TestGenericCache_PutIfAbsentDefersAcrossGrowandTestGenericCache_GrowMigrationLosslessboth pin hazards of the jump-grow generation swap. There is no migration and no swap on growth any more — the only remaining swap isClear, which is a different, fenced path.Known gap for review: envelope accounting still charges at construction as before and does not yet follow slab allocation. It should charge buckets up front and a slab as each is appended.
Alternative to #23546 and #23553, which keep the copy and make it cheaper. Independent of #23552.