pool only.Expand description
Prototype buffer pool for dataflow state. See
doc/developer/design/20260610_buffer_managed_state.md.
The pool is the cache: size-class anonymous virtual-memory regions whose
slots hold resident chunks. Slots are scoped to residency — eviction
returns a chunk’s slot to the free list along with its physical pages —
so slot demand tracks the resident set (bounded by the budget), not the
potentially unbounded live backlog. Reads are copy-out
(ChunkHandle::read_into): a resident slot is copied and an evicted
extent decompressed straight into the caller’s buffer, all under the
chunk’s state lock, so no reference into pool memory escapes the pool and
a read leaves residency untouched. The backing is the swap-backed extent
store of the design’s Layer 1: a slot in a pool-owned anonymous-memory
extent arena holding the chunk’s lz4-compressed bytes.
Memory descends a ladder of tiers, each with its own ceiling and each cheaper to vacate than the one above:
- Slots (uncompressed, free reads) — bounded by the budget; crossing it compresses the oldest chunks into extents and releases their slots.
- Warm free slots (pages kept for fault-free reuse) — bounded by the warm cap.
- Compressed-resident extents (reads decompress, no device) — bounded
by the headroom the RSS target leaves above the first two; crossing it
pushes the oldest extents to the swap device with
MADV_PAGEOUT. - The swap device — overflow; reads fault and decompress.
Residency is a state, not a type. It descends through eviction and
ascends through exactly one transition: an admitting read
(ChunkHandle::read_into_admit) lifts an evicted chunk back to
BackedResident when a slot is free within the budget or stealable from
a clean backed victim of the same class, never by evicting or
compressing anything. Plain reads (ChunkHandle::read_into) leave
residency untouched. Eviction I/O runs on spill threads when enabled —
WriteInFlight marks a chunk whose compression a spill thread owns — and
inline on the evicting caller otherwise. Chunks are immutable after
Pool::insert_with, which is what makes a BackedResident slot always
identical to its extent and its eviction free of I/O.
Freeing an UnbackedResident chunk is a pure memory operation — the
design’s “never write dead data” win, surfaced as writes_elided in
PoolStats. Budget pressure evicts cold chunks via second-chance
FIFOs banded by the caller-supplied generational depth (ChunkHints).
Structs§
- Chunk
Handle - Handle to one immutable chunk in a
Pool. Dropping the handle frees the chunk: the slot (if resident) returns to the region free list with its physical pages released, and the extent (if any) is deallocated, discarding any swapped copy for free. - Chunk
Hints - Advisory placement hints for a chunk, supplied at insert and immutable thereafter (merges mint new chunks, so a chunk’s generation never changes). Hints steer policy — eviction order and write-behind candidacy — never correctness: a mislabeled chunk performs worse, while the budget and residency invariants hold regardless.
- Identity
Codec - The identity
ExtentCodec: the stored form is the body. Encode and decode are copies, and range reads copy the range directly, so a chunk stored under this codec pays no compression work in either direction while remaining fully budgeted and swap-backed like any other extent. - Pool
- A buffer pool over swap-backed extents. Cheap to clone; all clones share one budget and one backing store.
- Pool
Stats - Snapshot of pool counters.
Statics§
- IDENTITY_
CODEC - The
IdentityCodecinstance to pass toPool::insert_with.
Traits§
- Extent
Codec - A chunk-provided transform between a chunk’s body bytes and the stored
bytes its extent holds. The pool owns scheduling: spill threads, the
residency state machine, cancellation, and the ledger. It invokes the
codec on opaque bytes at the extent boundary,
encodewhen backing a chunk (on a spill thread, or inline under overload) anddecodewhen reading an evicted one, under the chunk’s state lock. The pool itself has no opinion on the stored form: framing, compression, and validation all belong to the codec.
Functions§
- max_
stored_ len - The largest stored form
ExtentCodec::encodemay produce for abody_len-byte body: an incompressible-input expansion matching lz4’s worst case plus a four-byte length prefix. The extent store’s size-class ladder is provisioned to this bound, so a codec that exceeds it can strand payloads with no class to hold them (they degrade to unpageable heap fallbacks).