struct PoolInner {Show 17 fields
budget_bytes: AtomicU64,
rss_target_bytes: AtomicU64,
regions: Vec<Region>,
extent_arena: Arc<ExtentArena>,
store: ExtentStore,
full_hint: AtomicBool,
parked_extents: Mutex<ParkedExtents>,
parked_classes: AtomicU64,
file_release: Mutex<FileRelease>,
queues: [Mutex<VecDeque<Weak<ChunkMeta>>>; 4],
extent_queue: Mutex<VecDeque<ExtentEntry>>,
live_chunks: AtomicU64,
extent_residents: AtomicU64,
enforcing: Mutex<()>,
enforce_pending: AtomicBool,
counters: Counters,
spill: Spill,
}pool only.Expand description
The shared state behind every Pool handle. One per process in
practice; Pool clones and chunk handles share it through an Arc,
so it lives until the last handle and spill thread release it.
Lock order: a chunk’s state mutex may be held while taking any of the
leaf locks (the eviction queue, the extent_queue, the spill queue,
the region slot allocators, and the file store’s per-class slot
allocators, which alloc, free, and hole punching take) but never the
reverse. The enforcement and backing scans additionally drop the queue
guard before trying a chunk’s state lock, so no path holds a queue lock
while waiting on chunk state. Scans only ever try_lock a chunk they
pop, with one exception: a demotion re-locks its victim with a blocking
lock to commit after the unlocked write. That wait holds no other
chunk or queue lock. From budget enforcement it holds the enforcing
single-flight mutex, which is only ever try_locked, so no thread waits
on it. Hence enforce_compressed_cap must never run while its caller holds
any chunk’s state lock: two such callers demoting each other’s chunks
would deadlock on the re-lock. The admitting read’s victim steal is the
one place a chunk’s state lock is held while probing another chunk’s,
and the victim is only ever try_locked, so two admitters stealing
toward each other skip instead of deadlocking.
Reads copy out under the chunk’s state lock, the same lock eviction
takes, so there is no reader-side count and no reader the evictor must
account for. The exception is a plain read of an extent demoted to file,
which copies out after the unlock, sound per Home::File in extent.rs.
Fields§
§budget_bytes: AtomicU64Resident-bytes target, enforced against evictable bytes (resident
minus heap-backed, which no eviction can reclaim). Atomic so a
running pool can be retuned in place (operator-driven budget
changes) without orphaning live handles, which share this value
through their Arc<PoolInner>.
rss_target_bytes: AtomicU64Ceiling on the pool’s total RSS: slots (the budget) plus warm free
slots plus compressed-resident extents. The compressed tier’s
capacity derives as max(0, rss_target - budget - warm cap); zero
(the default) collapses the tier, paging every extent out as soon as
it is written.
regions: Vec<Region>One region per entry of SIZE_CLASSES, same order.
extent_arena: Arc<ExtentArena>The arena backing extents. Shared with every live Extent,
whose drop returns its slot.
store: ExtentStoreWhere RSS-target enforcement sends arena extents: the swap device, or a file store that demoted extents keep alive.
full_hint: AtomicBoolFile mode: set when a demotion pass found the store unable to take
any extent it probed, cleared by a committed demotion or a freed file
slot, or by enqueueing an extent whose class the store can place. While
set, inline callers run no demotion pass, and each spill thread runs
one at most every SPILL_PARK_TIMEOUT.
NOTE: setting and clearing race. A pass can set the hint after a concurrent free cleared it, and demotion then stays deferred until the next free, commit, or enqueue of a placeable extent, or the next spill thread retry.
parked_extents: Mutex<ParkedExtents>File mode: entries whose extent class the store refused, set aside so
that passes stop revisiting them. A pass returns a class’s entries to
the front of extent_queue once the store can place that class.
parked_classes: AtomicU64class_bit of every class with parked entries, so a pass skips the
parked lock when nothing is parked.
file_release: Mutex<FileRelease>File mode: the schedule on which spill threads release warm file
store slots. See Pool::set_file_release.
queues: [Mutex<VecDeque<Weak<ChunkMeta>>>; 4]Second-chance FIFOs of eviction candidates, one per depth band; a
chunk joins the band of its ChunkHints depth at insert and again
on re-admission. Entries for freed chunks go stale in place and are
dropped by PoolInner::prune_queues.
Two scanners walk them with different obligations, both visiting the
deepest band first. Budget enforcement is the one that ages chunks:
it spends the touched bit (second chance) and drops entries it
evicts. Eager backing (PoolInner::back_one) rotates visited
entries to the back but never spends a touched bit, so a backing
pass shuffles FIFO order without aging any chunk toward eviction.
extent_queue: Mutex<VecDeque<ExtentEntry>>FIFO of chunks whose extents are resident, oldest first — the
RSS-target enforcement’s victim queue. Entries go stale when an
extent pages out, is dropped, or its chunk dies; visits drop them,
and PoolInner::prune_extent_queue compacts dead-chunk entries
that under-cap operation never visits.
live_chunks: AtomicU64Number of live size-classed chunks (whatever their residency), which
is the number of non-stale queue entries across all bands;
PoolInner::prune_queues compacts the queues against it.
extent_residents: AtomicU64Number of live chunks whose extent is currently resident, including
unreclaimable extents that deliberately hold no extent_queue entry
(heap-backed and retry-capped ones). It therefore upper-bounds the
queue’s non-stale entries, and PoolInner::prune_extent_queue’s
compaction threshold is conservative by the unreclaimable count.
enforcing: Mutex<()>Single-flight claim for budget enforcement.
enforce_pending: AtomicBoolSet by an insert turned away from enforcing. The holder re-runs its
pass while it is set, so a caller turned away after the holder’s final
counter read still has its bytes enforced rather than dropped.
counters: Counters§spill: SpillImplementations§
Source§impl PoolInner
impl PoolInner
Sourcefn queue(&self, band: usize) -> MutexGuard<'_, VecDeque<Weak<ChunkMeta>>>
fn queue(&self, band: usize) -> MutexGuard<'_, VecDeque<Weak<ChunkMeta>>>
Locks the eviction queue of one depth band.
Sourcefn extent_queue(&self) -> MutexGuard<'_, VecDeque<ExtentEntry>>
fn extent_queue(&self) -> MutexGuard<'_, VecDeque<ExtentEntry>>
Locks the resident-extent queue.
Sourcefn parked_extents(&self) -> MutexGuard<'_, ParkedExtents>
fn parked_extents(&self) -> MutexGuard<'_, ParkedExtents>
Locks the parked resident-extent entries.
Sourcefn spill_queue(&self) -> MutexGuard<'_, VecDeque<Arc<ChunkMeta>>>
fn spill_queue(&self) -> MutexGuard<'_, VecDeque<Arc<ChunkMeta>>>
Locks the spill hand-off queue.
Sourcefn region_of(&self, meta: &ChunkMeta) -> &Region
fn region_of(&self, meta: &ChunkMeta) -> &Region
The region behind a slotted chunk’s size class.
Sourceunsafe fn slot_data(&self, meta: &ChunkMeta, slot: u32) -> &[u64]
unsafe fn slot_data(&self, meta: &ChunkMeta, slot: u32) -> &[u64]
Borrows the payload of a slotted chunk.
§Safety
slot must be meta’s slot, its contents must be initialized (they
are from insert onward), and nothing may write the slot while the
borrow lives.
Sourcefn commit_extent(
&self,
meta: &Arc<ChunkMeta>,
state: &mut ChunkState,
extent: Extent,
)
fn commit_extent( &self, meta: &Arc<ChunkMeta>, state: &mut ChunkState, extent: Extent, )
Records a freshly written extent under the chunk’s state lock: the compressed-bytes counter, the compressed-tier accounting, and the state’s extent field.
Sourcefn prune_queues(&self)
fn prune_queues(&self)
Drops queue entries whose chunk has been freed, detected by their
Weak no longer holding a live chunk. Each band compacts only when
its stale entries outnumber all live chunks (plus a small floor), so
the cost amortizes to a constant per insert and the total queue
length stays proportional to the number of live slotted chunks even
when the pool never comes under budget pressure.
Sourcefn reserve_insert(&self, len_bytes: usize) -> bool
fn reserve_insert(&self, len_bytes: usize) -> bool
Reserve insertion bytes before populating a slot. Enforcement can
lag by insert_slack of the budget, or one payload for small
budgets. Read admissions use the budget itself and cannot consume
this slack.
fn enforce_budget(&self)
Sourcefn evictable_bytes(&self) -> u64
fn evictable_bytes(&self) -> u64
Bytes budget enforcement can actually reclaim: resident bytes minus heap-backed (oversize and class-exhaustion) chunks, which hold no slot and can never be evicted. Enforcing against raw resident bytes would, once unevictable bytes alone exceed the budget, compress every slotted chunk on arrival forever.
fn enforce_budget_inner(&self)
fn enforce_budget_band(&self, band: usize, quota: &mut u64)
fn evict_locked(&self, meta: &Arc<ChunkMeta>, state: &mut ChunkState)
Sourcefn spill_eligible(&self) -> bool
fn spill_eligible(&self) -> bool
Whether the next eviction should be handed to spill threads: enabled, and the queue is below the backpressure bound (beyond it, callers evict inline rather than growing an unbounded queue of still-resident chunks).
Sourcefn spill_schedule(&self, meta: Arc<ChunkMeta>)
fn spill_schedule(&self, meta: Arc<ChunkMeta>)
Hands a WriteInFlight chunk to the spill threads.
Sourcefn spill_worker(self: Arc<Self>)
fn spill_worker(self: Arc<Self>)
Spill-thread main loop. The thread owns an Arc<PoolInner>, so the
pool (a process-wide singleton in production) lives as long as its
threads. Queued (budget-driven) evictions take priority; with eager
backing enabled, idle threads compress unbacked chunks to
BackedResident instead of parking, and park with a timeout once
everything reachable is backed.
Sourcefn spill_trim(&self, hinted_retry: &mut Instant)
fn spill_trim(&self, hinted_retry: &mut Instant)
The spill loop’s compressed-tier trim. Tier-2 pageouts ride the spill
threads: every pass through the loop (job completion, condvar wakeup,
park timeout) trims the compressed tier if needed, at a single atomic
load when under cap. While the file store’s full hint is set, a pass
runs only once hinted_retry has passed, which then moves one
SPILL_PARK_TIMEOUT ahead.
Sourcefn spill_file_upkeep(&self)
fn spill_file_upkeep(&self)
Re-derives the file store’s capacity and releases warm file store slots, each when due. The first spill thread to see one due claims its interval.
fn file_release(&self) -> MutexGuard<'_, FileRelease>
Sourcefn back_one(&self) -> bool
fn back_one(&self) -> bool
Eagerly compresses one unbacked chunk from the eviction queues into
BackedResident, returning whether a chunk was backed — false
means nothing was actionable (queues empty, or the bounded scans
found only already-backed, in-flight, contended, or stale entries)
and the caller should park rather than rescan. Bands are visited
deepest first, mirroring eviction order so the chunks evicted first
are the ones whose backing is already pre-paid.
Sourcefn back_one_from(&self, band: usize) -> bool
fn back_one_from(&self, band: usize) -> bool
One bounded backing scan over a single band’s queue. Non-actionable
entries are requeued or dropped per the same rules budget
enforcement uses, except that the second-chance touched bit is
left alone — backing is not an eviction and must not consume a
chunk’s reprieve.
Sourcefn spill_process(&self, meta: &Arc<ChunkMeta>, kind: SpillKind)
fn spill_process(&self, meta: &Arc<ChunkMeta>, kind: SpillKind)
Performs (or cancels) one scheduled compression. Runs on spill
threads only. Lock discipline: the chunk lock is held only to validate
and to commit, never across the compression or the pageout
reclaim, which are the multi-millisecond costs this path exists to
keep off budget-enforcing threads.
Sourcefn release_resident(&self, meta: &ChunkMeta, state: &mut ChunkState)
fn release_resident(&self, meta: &ChunkMeta, state: &mut ChunkState)
Releases whichever resident form the chunk holds, its slot or its
typed body, under PoolInner::release_slot’s precondition.
Sourcefn release_slot(&self, meta: &ChunkMeta, state: &mut ChunkState)
fn release_slot(&self, meta: &ChunkMeta, state: &mut ChunkState)
Releases state’s slot — slot returned to the region free list,
physical pages discarded unless the slot joins the bounded warm pool —
and decrements resident bytes. Releasing pages beyond the warm pool is
what keeps RSS aligned with the resident_bytes gauge the budget
enforcer trusts; the warm pool relaxes that alignment by an explicit,
bounded amount (warm_bytes, capped at a fraction of the budget) so
slot reuse faults no pages and skips the kernel’s page zeroing.
Precondition: the caller holds the chunk’s state lock, and no
reference into the slot exists — copy-out reads borrow the slot only
under that same lock, and a WriteInFlight chunk’s unlocked
compression read belongs to the spill thread, which is the only
caller that releases the slot in that state. This is what makes the
dontneed below sound, and what makes keeping a warm slot’s stale
contents safe: the slot’s next occupant fully overwrites every byte
it reads, satisfying the contents-undefined contract either way.
Sourcefn warm_cap(&self) -> u64
fn warm_cap(&self) -> u64
The warm pool’s byte ceiling: an eighth of the budget, clamped at an absolute maximum. The fraction sizes fault amortization at small budgets; the clamp keeps large budgets from parking gigabytes of idle warm slots no fault rate could justify.
Sourcefn trim_warm_pool(&self)
fn trim_warm_pool(&self)
Cools warm free slots until warm_bytes falls to the warm cap. A
budget shrink lowers the cap, and warm capacity is checked only when
a slot is freed, so without this pass slots parked under the old cap
would hold their pages until same-class reuse happened to drain them,
exactly when the shrink wanted the memory back.
Sourcefn try_keep_warm(&self, class_size: usize) -> bool
fn try_keep_warm(&self, class_size: usize) -> bool
Claims warm-pool capacity for a slot of class_size bytes, returning
whether the slot may keep its pages. The RSS overshoot the warm pool
introduces is bounded by PoolInner::warm_cap and visible as the
warm_bytes stat.
Sourcefn try_alloc_slot(&self, class: usize, len_bytes: usize) -> Option<u32>
fn try_alloc_slot(&self, class: usize, len_bytes: usize) -> Option<u32>
Allocates a slot in class for a payload of len_bytes with
warm-pool accounting (a warm allocation is counted as a reuse and
trimmed to the payload), or None when the class has no free slot.
Sourcefn trim_slot_tail(&self, class: usize, slot: u32, len_bytes: usize)
fn trim_slot_tail(&self, class: usize, slot: u32, len_bytes: usize)
Releases a slot’s pages beyond the first len_bytes (rounded up to
a page), so a slot reused for a smaller payload does not keep its
prior occupant’s tail pages resident with no bytes in the ledger to
answer for them.
Precondition: the caller exclusively owns the slot (freshly allocated, or taken from a victim under the victim’s state lock) with no reference into it.
Sourcefn alloc_slot(&self, class: usize, len_bytes: usize) -> Option<u32>
fn alloc_slot(&self, class: usize, len_bytes: usize) -> Option<u32>
Allocates a slot in class for an insert: as
PoolInner::try_alloc_slot, with an exhausted class counted as a
heap fallback for a len_bytes payload (warned about once). None
means the caller must degrade to the heap.
Sourcefn admit_slot(&self, meta: &ChunkMeta) -> Option<u32>
fn admit_slot(&self, meta: &ChunkMeta) -> Option<u32>
Acquires a slot for re-admitting an evicted chunk, from free budget
headroom or by stealing a clean backed victim’s slot, never by
evicting or compressing anything. None counts a denied admission.
On success the admitted chunk’s resident-bytes accounting and the
admission counter are settled, and the caller (who holds the chunk’s
state lock) owns the slot: its contents are unspecified (fresh,
warm, or the victim’s stale bytes) and must be fully overwritten.
Sourcefn steal_clean_victim(
&self,
class: usize,
admitted_len_bytes: usize,
) -> Option<u32>
fn steal_clean_victim( &self, class: usize, admitted_len_bytes: usize, ) -> Option<u32>
Takes the slot of a clean victim in class for an admitted payload
of admitted_len_bytes: a BackedResident chunk with a clear
touched bit, whose extent already duplicates its slot, so the victim
transitions to Evicted with zero I/O, its extent intact, and its
queue entry dropped. The returned slot keeps its physical pages (no
dontneed, no free-list round trip); they hold the victim’s stale
bytes. None when the bounded scan finds no such victim, or none
whose growth the budget can absorb.
The caller holds its own chunk’s state lock. The scan follows the
enforcement discipline (deepest band first, queue guard dropped
before any chunk lock, victims only ever try_locked), which is
what keeps the chunk-lock-while-probing-chunk-lock window
deadlock-free: two admitters stealing toward each other both fail
the try_lock and skip. Unlike enforcement, the scan rotates
unsuitable entries (touched, wrong class, unbacked) to the back
without spending touched bits, shuffling FIFO order the way the
backing scan does.
Sourcefn compressed_cap(&self) -> u64
fn compressed_cap(&self) -> u64
Capacity of the compressed-resident tier: the RSS target’s headroom above the slot budget, the insertion slack currently in use, and the warm cap. With no target set the tier has zero capacity, so extents page out as soon as they are written.
Sourcefn compressed_tier_above(&self, over: u64) -> bool
fn compressed_tier_above(&self, over: u64) -> bool
Whether the compressed tier holds more than over bytes, counted as
enforcement counts it for the store.
Sourcefn insert_slack_in_use(&self, budget: u64) -> u64
fn insert_slack_in_use(&self, budget: u64) -> u64
Slot bytes reserved above budget by insertions that outran
enforcement, at most insert_slack. Oversize payloads live on the
heap and are excluded, as in PoolInner::reserve_insert.
Sourcefn note_extent_resident(
&self,
meta: &Arc<ChunkMeta>,
extent_alloc: usize,
reclaimable: bool,
)
fn note_extent_resident( &self, meta: &Arc<ChunkMeta>, extent_alloc: usize, reclaimable: bool, )
Counts a newly resident extent (written, or revived by a read)
against the compressed tier. A reclaimable extent additionally
enqueues its chunk for RSS-target enforcement; an unreclaimable one
(a heap-fallback extent, which is never advised out) counts against
the unreclaimable gauge instead and stays out of the queue, so
enforcement never walks entries it cannot act on. Callers hold the
chunk’s state lock with the extent present and resident, and follow
up with PoolInner::enforce_compressed_cap once the lock is
released.
Invariant: extent_resident_bytes equals the sum of alloc_size
over live chunks’ extents whose is_resident() is true, and
extent_residents counts those extents; extent_unreclaimable_bytes
is the subset whose pageout_capped() is true. A freed chunk’s
Demoting extent stays counted until its demoter’s commit releases
it. This method, PoolInner::note_extent_reclaimable,
PoolInner::note_extent_released, the pageout arms in
PoolInner::enforce_compressed_cap, and the demotion commit in
PoolInner::demote are the only adjusters. Every flag flip pairs
with one of them under the chunk’s state lock.
Likewise extent_file_bytes equals the sum of file_bytes() over
live chunks’ extents. The demotion commit adds to it and
PoolInner::release_extent subtracts, each under the chunk’s state
lock.
Sourcefn note_extent_reclaimable(&self, meta: &Arc<ChunkMeta>, extent_alloc: usize)
fn note_extent_reclaimable(&self, meta: &Arc<ChunkMeta>, extent_alloc: usize)
Returns a retry-capped resident extent to the reclaimable set after a
read restored its pageout budget: uncounts it from the unreclaimable
gauge and re-enqueues its chunk for RSS-target enforcement. The
caller holds the chunk’s state lock with the extent present, resident,
and no longer pageout_capped().
Sourcefn enqueue_extent(&self, meta: &Arc<ChunkMeta>, extent_alloc: usize)
fn enqueue_extent(&self, meta: &Arc<ChunkMeta>, extent_alloc: usize)
Enqueues a reclaimable resident extent for RSS-target enforcement.
Sourcefn note_extent_released(&self, extent: &Extent)
fn note_extent_released(&self, extent: &Extent)
Uncounts a resident extent that is being dropped (chunk freed or
degraded). Its queue entry goes stale and is dropped on visit or by
PoolInner::prune_extent_queue.
Sourcefn release_extent(&self, state: &mut ChunkState)
fn release_extent(&self, state: &mut ChunkState)
Drops a freed chunk’s extent with its accounting, under the chunk’s
state lock. A Demoting extent stays in place, per Home::Demoting.
Sourcefn prune_extent_queue(&self)
fn prune_extent_queue(&self)
Drops extent-queue entries whose chunk has been freed, mirroring
PoolInner::prune_queues: compact only when the queue outgrows
all live resident extents (plus a small floor), so the cost
amortizes to a constant per push. Enforcement drops stale entries
too, but only while the tier is over capacity. A pool that stays
under its compressed cap would otherwise accumulate an entry (and a
pin on the dead chunk’s allocation) per freed extent forever.
Sourcefn park_extent(&self, class: usize, entry: ExtentEntry)
fn park_extent(&self, class: usize, entry: ExtentEntry)
Sets aside entry, whose extent class class the store refused,
until a pass finds the class placeable. A class beyond the bit mask
is requeued at the back instead.
Sourcefn unpark_placeable(&self, store: &FileStore)
fn unpark_placeable(&self, store: &FileStore)
Returns the parked entries of every class store can place now to
the front of the extent queue, where they keep their age order ahead
of the younger entries queued since.
Sourcefn enforce_or_defer_compressed_cap(&self)
fn enforce_or_defer_compressed_cap(&self)
Routes compressed-cap enforcement off latency-sensitive threads: with
spill threads spawned, wakes one to perform the pageouts
(MADV_PAGEOUT is synchronous reclaim, bounded per extent but not
free at chunk rates). Without them, enforces inline unless the file
store’s full hint is set. The test is for
thread existence, not spill.enabled: spawned threads trim the tier
in their loop even with eviction hand-off disabled.
Deferral makes the target eventually-enforced with bounded lag, and the backstop below bounds the lag: a caller finding the reclaimable tier at double its capacity enforces inline, so sustained creation cannot outrun trimming by more than one capacity’s worth. In file mode the bound does not hold while the store’s full hint is set or its writes are disabled. The backstop then defers to the spill threads, and the tier grows past the bound by whatever the store cannot take.
Sourcefn reclaimable_resident(&self) -> u64
fn reclaimable_resident(&self) -> u64
Bytes of resident extents RSS-target enforcement can push out.
Sourcefn enforce_compressed_cap(&self, pass: Pass)
fn enforce_compressed_cap(&self, pass: Pass)
Pages out the oldest resident extents until the compressed tier falls
to its capacity. The compression is already paid and the device write
is the kernel’s async writeback, so each pageout is one bounded
madvise plus a page-table observation; spill threads run this between
jobs, and other threads only when no spill threads exist (see
PoolInner::enforce_or_defer_compressed_cap). Not single-flighted:
concurrent passes pop disjoint victims. Visits are bounded by the
queue’s length at entry; stale entries (extent paged out, dropped, or
chunk dead) are dropped. Incomplete extents are requeued with their
accounting intact until their retry budget runs out, at which point
they leave the queue with their bytes on the unreclaimable gauge, so
the tier may settle above its capacity by the bytes the kernel
declined to reclaim without enforcement re-walking them.
In file mode each victim is demoted to the file store instead, per
PoolInner::demote. A victim whose class the store cannot place
moves to the back of the queue, and a store that can place no class
or has writes disabled ends the pass. An inline file-mode pass with
spill threads present stops at the backstop_threshold, and a
background file-mode pass stops per DEMOTION_PASS_BYTES. An inline
file-mode pass with spill threads present also stops after
DEMOTION_PASS_BYTES.
Sourcefn demote(
&self,
store: &Arc<FileStore>,
meta: &Arc<ChunkMeta>,
state: MutexGuard<'_, ChunkState>,
entry: ExtentEntry,
pass: Pass,
) -> Demotion
fn demote( &self, store: &Arc<FileStore>, meta: &Arc<ChunkMeta>, state: MutexGuard<'_, ChunkState>, entry: ExtentEntry, pass: Pass, ) -> Demotion
Demotes the extent of the chunk behind state to store, the file
mode counterpart of the pageout arms of
PoolInner::enforce_compressed_cap. entry is the chunk’s popped
queue entry, which this function requeues unless the entry is stale
or the extent left the arena.
The write runs without the chunk lock, with the extent Demoting
(see Home::Demoting in extent.rs).
Sourcefn refuse(
&self,
store: &FileStore,
class: usize,
entry: ExtentEntry,
) -> Demotion
fn refuse( &self, store: &FileStore, class: usize, entry: ExtentEntry, ) -> Demotion
Parks or requeues the entry of an extent whose class the store
could not take.
Sourcefn spill_handoff(&self, meta: &Arc<ChunkMeta>, state: &mut ChunkState) -> bool
fn spill_handoff(&self, meta: &Arc<ChunkMeta>, state: &mut ChunkState) -> bool
If the chunk is a live UnbackedResident holding a slot and the
spill threads have capacity, transitions it to WriteInFlight and
hands it to them, returning true. The hand-off happens under the
held state lock; the spill thread blocks on that lock only after this
call returns and the caller releases it.
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for PoolInner
impl RefUnwindSafe for PoolInner
impl Send for PoolInner
impl Sync for PoolInner
impl Unpin for PoolInner
impl UnsafeUnpin for PoolInner
impl UnwindSafe for PoolInner
Blanket Implementations§
impl<T> Allocation for T
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> FutureExt for T
impl<T> FutureExt for T
Source§fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
Source§fn with_current_context(self) -> WithContext<Self> ⓘ
fn with_current_context(self) -> WithContext<Self> ⓘ
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::RequestSource§impl<T> Paint for Twhere
T: ?Sized,
impl<T> Paint for Twhere
T: ?Sized,
Source§fn fg(&self, value: Color) -> Painted<&T>
fn fg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the foreground set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like red() and
green(), which have the same functionality but are
pithier.
§Example
Set foreground color to white using fg():
use yansi::{Paint, Color};
painted.fg(Color::White);Set foreground color to white using white().
use yansi::Paint;
painted.white();Source§fn bright_black(&self) -> Painted<&T>
fn bright_black(&self) -> Painted<&T>
Source§fn bright_red(&self) -> Painted<&T>
fn bright_red(&self) -> Painted<&T>
Source§fn bright_green(&self) -> Painted<&T>
fn bright_green(&self) -> Painted<&T>
Source§fn bright_yellow(&self) -> Painted<&T>
fn bright_yellow(&self) -> Painted<&T>
Source§fn bright_blue(&self) -> Painted<&T>
fn bright_blue(&self) -> Painted<&T>
Source§fn bright_magenta(&self) -> Painted<&T>
fn bright_magenta(&self) -> Painted<&T>
Source§fn bright_cyan(&self) -> Painted<&T>
fn bright_cyan(&self) -> Painted<&T>
Source§fn bright_white(&self) -> Painted<&T>
fn bright_white(&self) -> Painted<&T>
Source§fn bg(&self, value: Color) -> Painted<&T>
fn bg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the background set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like on_red() and
on_green(), which have the same functionality but
are pithier.
§Example
Set background color to red using fg():
use yansi::{Paint, Color};
painted.bg(Color::Red);Set background color to red using on_red().
use yansi::Paint;
painted.on_red();Source§fn on_primary(&self) -> Painted<&T>
fn on_primary(&self) -> Painted<&T>
Source§fn on_magenta(&self) -> Painted<&T>
fn on_magenta(&self) -> Painted<&T>
Source§fn on_bright_black(&self) -> Painted<&T>
fn on_bright_black(&self) -> Painted<&T>
Source§fn on_bright_red(&self) -> Painted<&T>
fn on_bright_red(&self) -> Painted<&T>
Source§fn on_bright_green(&self) -> Painted<&T>
fn on_bright_green(&self) -> Painted<&T>
Source§fn on_bright_yellow(&self) -> Painted<&T>
fn on_bright_yellow(&self) -> Painted<&T>
Source§fn on_bright_blue(&self) -> Painted<&T>
fn on_bright_blue(&self) -> Painted<&T>
Source§fn on_bright_magenta(&self) -> Painted<&T>
fn on_bright_magenta(&self) -> Painted<&T>
Source§fn on_bright_cyan(&self) -> Painted<&T>
fn on_bright_cyan(&self) -> Painted<&T>
Source§fn on_bright_white(&self) -> Painted<&T>
fn on_bright_white(&self) -> Painted<&T>
Source§fn attr(&self, value: Attribute) -> Painted<&T>
fn attr(&self, value: Attribute) -> Painted<&T>
Enables the styling Attribute value.
This method should be used rarely. Instead, prefer to use
attribute-specific builder methods like bold() and
underline(), which have the same functionality
but are pithier.
§Example
Make text bold using attr():
use yansi::{Paint, Attribute};
painted.attr(Attribute::Bold);Make text bold using using bold().
use yansi::Paint;
painted.bold();Source§fn rapid_blink(&self) -> Painted<&T>
fn rapid_blink(&self) -> Painted<&T>
Source§fn quirk(&self, value: Quirk) -> Painted<&T>
fn quirk(&self, value: Quirk) -> Painted<&T>
Enables the yansi Quirk value.
This method should be used rarely. Instead, prefer to use quirk-specific
builder methods like mask() and
wrap(), which have the same functionality but are
pithier.
§Example
Enable wrapping using .quirk():
use yansi::{Paint, Quirk};
painted.quirk(Quirk::Wrap);Enable wrapping using wrap().
use yansi::Paint;
painted.wrap();Source§fn clear(&self) -> Painted<&T>
👎Deprecated since 1.0.1: renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
fn clear(&self) -> Painted<&T>
renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
Source§fn whenever(&self, value: Condition) -> Painted<&T>
fn whenever(&self, value: Condition) -> Painted<&T>
Conditionally enable styling based on whether the Condition value
applies. Replaces any previous condition.
See the crate level docs for more details.
§Example
Enable styling painted only when both stdout and stderr are TTYs:
use yansi::{Paint, Condition};
painted.red().on_yellow().whenever(Condition::STDOUTERR_ARE_TTY);Source§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<'a, S, T> Semigroup<&'a S> for Twhere
T: Semigroup<S>,
impl<'a, S, T> Semigroup<&'a S> for Twhere
T: Semigroup<S>,
Source§fn plus_equals(&mut self, rhs: &&'a S)
fn plus_equals(&mut self, rhs: &&'a S)
std::ops::AddAssign, for types that do not implement AddAssign.