pub struct EdgeCache { /* private fields */ }Expand description
LRU + version + TTL cache. Cheap to clone via Arc.
Implementations§
Source§impl EdgeCache
impl EdgeCache
pub fn new(max_entries: usize) -> Self
Sourcepub fn epoch(&self) -> u64
pub fn epoch(&self) -> u64
This process’s per-boot epoch (home role: stamped into every broadcast invalidation + the subscribe hello frame).
Sourcepub fn next_version(&self) -> u64
pub fn next_version(&self) -> u64
Mint a fresh logical version (home role: stamps read misses and write invalidations from one local clock).
Sourcepub fn current_version(&self) -> u64
pub fn current_version(&self) -> u64
Current value of the local version counter, without minting. Strictly greater than every version this process has stamped.
Sourcepub fn observe_home_version(&self, v: u64)
pub fn observe_home_version(&self, v: u64)
Record a version observed from the home (edge role: SSE
invalidations + the hello frame carry the home’s clock). Edge
reads are stamped with observed_home_version(), i.e. at the
last home version — any later home write mints a strictly
greater version, so its <= sweep always catches them.
Sourcepub fn observed_home_version(&self) -> u64
pub fn observed_home_version(&self) -> u64
Last home version observed (0 until the first event/hello). The edge-role read stamp.
Sourcepub fn on_home_epoch(&self, epoch: u64) -> usize
pub fn on_home_epoch(&self, epoch: u64) -> usize
Handle the home’s per-boot epoch carried by an event. Returns
the number of entries flushed. 0 (legacy/absent) is ignored.
First sighting just records the epoch; a CHANGE means the home
restarted with a reset version clock — every cached stamp is
from an incomparable clock, so flush everything and reset the
observed-home clock (the same event’s observe_home_version
re-syncs it).
Sourcepub fn flush_all(&self) -> usize
pub fn flush_all(&self) -> usize
Drop every entry. Bumps the invalidation counter BEFORE taking
the map lock so in-flight epoch-gated stores are rejected (same
ordering contract as invalidate). Returns the count dropped.
Sourcepub fn should_cache(&self, version: u64) -> bool
pub fn should_cache(&self, version: u64) -> bool
Whether a home-role read stamped with version is still safe
to cache. False once an invalidation with up_to_version >= version has been applied — the read may predate the write that
triggered it. (Cheap unlocked fast-path; the authoritative
re-check is insert_if_fresh.)
Sourcepub fn invalidation_epoch(&self) -> u64
pub fn invalidation_epoch(&self) -> u64
Monotonic count of invalidation events applied. Edge-role reads
snapshot it before forwarding; insert_if_epoch re-checks it
under the map lock, so a store whose flight overlapped ANY
invalidation is skipped (table-agnostic and conservative — the
next identical read simply re-stores).
Sourcepub fn get(&self, key: &CacheKey) -> Option<Arc<CacheEntry>>
pub fn get(&self, key: &CacheKey) -> Option<Arc<CacheEntry>>
Look up a cache entry. Returns None on miss or expired TTL. Bumps the LRU on hit (O(1)); increments hit/miss counters either way. Expired entries are removed lazily here.
Sourcepub fn insert(&self, key: CacheKey, entry: CacheEntry)
pub fn insert(&self, key: CacheKey, entry: CacheEntry)
Insert / overwrite an entry. The LRU victim is auto-evicted when at capacity (O(1)). Prefer the race-checked variants on production store paths.
Sourcepub fn insert_if_fresh(&self, key: CacheKey, entry: CacheEntry) -> bool
pub fn insert_if_fresh(&self, key: CacheKey, entry: CacheEntry) -> bool
Home-role store: re-checks the invalidation high-water mark
UNDER the map lock, closing the TOCTOU between an unlocked
should_cache and the push (a concurrent invalidate bumps
the hwm before taking this same lock, so either we see the bump
here and skip, or our insert lands first and its sweep drops
the entry). Returns whether the entry was stored.
Sourcepub fn insert_if_epoch(
&self,
key: CacheKey,
entry: CacheEntry,
epoch: u64,
) -> bool
pub fn insert_if_epoch( &self, key: CacheKey, entry: CacheEntry, epoch: u64, ) -> bool
Edge-role store: entry stamps live in the home’s clock, so the
hwm gate is inert (stamps == hwm right after every event).
Instead the store is valid only if NO invalidation was applied
since epoch was snapshotted (before the read was forwarded).
Checked under the map lock — same ordering proof as
insert_if_fresh (invalidate bumps the counter before locking).
Returns whether the entry was stored.
Sourcepub fn invalidate(&self, up_to_version: u64, tables: &[String]) -> usize
pub fn invalidate(&self, up_to_version: u64, tables: &[String]) -> usize
Drop every entry whose version <= up_to_version AND whose
tables overlaps with tables (empty tables invalidates
every entry meeting the version bound). Also raises the
high-water mark consulted by should_cache and bumps the
invalidation epoch — both BEFORE the map lock is taken, which
the insert_if_* race checks rely on. Returns the count
dropped.
Table-targeted sweeps walk only the keys registered under the written tables (reverse index) — O(matching entries). Only the empty-table wildcard falls back to a full scan.
pub fn stats(&self) -> EdgeCacheStats
Sourcepub fn insert_with(&self, key: CacheKey, entry: CacheEntry)
pub fn insert_with(&self, key: CacheKey, entry: CacheEntry)
Test-only: deterministic insert with explicit version + TTL.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for EdgeCache
impl RefUnwindSafe for EdgeCache
impl Send for EdgeCache
impl Sync for EdgeCache
impl Unpin for EdgeCache
impl UnsafeUnpin for EdgeCache
impl UnwindSafe for EdgeCache
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
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
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 more