pub struct BlobCacheSweeper;Expand description
Stateless namespace for sweeper operations against a BlobCache.
The sweeper holds no state of its own; every method is a free-function
over &BlobCache. This keeps the surface easy to call from admin
handlers, the runtime scheduler, and tests without owning a sweeper
instance.
Implementations§
Source§impl BlobCacheSweeper
impl BlobCacheSweeper
Sourcepub fn sweep_expired(cache: &BlobCache, limit: SweepLimit) -> SweepReport
pub fn sweep_expired(cache: &BlobCache, limit: SweepLimit) -> SweepReport
Bounded sweep of expired L1 entries.
Walks the L1 entries (across shards) checking
Entry::is_expired_at(now), and evicts expired ones via
BlobCache::invalidate_key. Honors limit precisely.
§Concurrency
Concurrent reads on the cache MUST NOT block. Per-shard locks are
taken only for the brief windows that BlobCache::invalidate_key
needs them; readers on other shards run unimpeded.
§Current implementation status
Today this is bounded scaffolding: it sets up the time/entries
budget and returns a zero-work report. The actual L1 walk requires a
public iteration accessor on BlobCache (see flag #2 at the top of
this module). Once that lands, the body becomes:
cache.for_each_l1_entry(|namespace, key, view| {
if budget.exhausted() { return ControlFlow::Break(()); }
report.entries_scanned += 1;
if view.is_expired_at(now_ms) {
let bytes = view.size as u64;
if cache.invalidate_key(namespace, key) > 0 {
report.entries_evicted += 1;
report.bytes_reclaimed += bytes;
accumulate_namespace(&mut report, namespace, bytes);
}
}
budget.tick()
});Sourcepub fn reclaim_orphans(cache: &BlobCache, limit: SweepLimit) -> OrphanReport
pub fn reclaim_orphans(cache: &BlobCache, limit: SweepLimit) -> OrphanReport
Bounded reclamation of L2 orphan blob chains.
Orphan chains arise when a writer flushes the blob bytes to L2 pages
but is killed before the metadata B+ tree commit (see the WAL-ordering
note in docs/perf/blob-cache-l2-spike.md). Recovery cannot tell
these pages apart from a successful write without cross-checking the
metadata catalog, so they accumulate as wasted L2 capacity until the
sweeper reclaims them.
The algorithm (once accessor #2 lands):
- Walk the L2 free-list of allocated blob chains
(
cache.l2_blob_chains()— to-be-added). - For each chain root, look up the metadata B+ tree
(
cache.for_each_l2_record) and check whether any record points at this root. - Chains with no metadata reference are orphans — free their pages
via the L2 API and accumulate
bytes_reclaimed.
§Concurrency
Same contract as BlobCacheSweeper::sweep_expired.
Sourcepub fn flush_namespace(
cache: &BlobCache,
namespace: &str,
) -> NamespaceFlushReport
pub fn flush_namespace( cache: &BlobCache, namespace: &str, ) -> NamespaceFlushReport
Foreground-fast namespace flush.
Delegates to BlobCache::invalidate_namespace, which is O(1): it
only bumps a per-namespace generation counter. Cached entries with
the old generation become invisible immediately and are physically
removed by later cache access or by BlobCacheSweeper::sweep_expired.
§Foreground-fast contract
Returns within ~100 µs typical. The elapsed_micros field on the
returned NamespaceFlushReport makes the contract observable so
admin endpoints can alert on regressions.
§Generation reporting
generation_before and generation_after are reported on a
best-effort basis. Because BlobCache does not expose a public
generation accessor, the sweeper reports them as (0, 0) when the
flush call signals “namespace did not exist” and (0, 0) when it
signals success — placeholder values until a current_generation
public accessor is added (see flag #2). The namespace and
elapsed_micros fields are accurate today.
Auto Trait Implementations§
impl Freeze for BlobCacheSweeper
impl RefUnwindSafe for BlobCacheSweeper
impl Send for BlobCacheSweeper
impl Sync for BlobCacheSweeper
impl Unpin for BlobCacheSweeper
impl UnsafeUnpin for BlobCacheSweeper
impl UnwindSafe for BlobCacheSweeper
Blanket Implementations§
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
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::Request