pub struct LockFreeReadHistoryCache { /* private fields */ }Expand description
HistoryCache variant with a lock-free read path via RCU/copy-on-write.
Note: readers (e.g. the SEDP tick, heartbeat build,
resend iteration) see an Arc-stable snapshot of the
BTreeMap storage; they access it without a further lock touch.
Writers serialize over an internal [RcuCell] mutex and
publish copy-on-write.
§Trade-offs
- Read path: 1× mutex acquire for the refcount inc + 0 further locks. Concurrent readers see the same Arc; read iteration is essentially lock-free.
- Write path: O(n) per insert/remove, because the
BTreeMapcontent must be cloned. Acceptable for small caches (<= 1000 samples). For write-heavy paths keep usingHistoryCache. - Memory: active snapshots consume memory until they are released (reader lifetime). Cache mutations do not invalidate existing reader snapshots.
§When to use
- Discovery caches that are read frequently by the SEDP tick + match loops,
but mutated only on
announce_publication/subscription. - Monitoring/tooling paths that want to iterate over the cache without a lock touch.
§When NOT to use
- Reliable-writer cache with a high insert rate (every insert clones
the whole BTreeMap). There
HistoryCachestays better.
Persistent data structures (im::OrdMap) would push the
write-cost effort to O(log n) — that is the
natural follow-up optimization once this variant lands in production.
Implementations§
Source§impl LockFreeReadHistoryCache
impl LockFreeReadHistoryCache
Sourcepub fn new_with_kind(kind: HistoryKind, max_samples: usize) -> Self
pub fn new_with_kind(kind: HistoryKind, max_samples: usize) -> Self
Creates a new lock-free read cache.
Sourcepub fn stats(&self) -> Arc<HistoryCacheStats>
pub fn stats(&self) -> Arc<HistoryCacheStats>
Lock-free read snapshot of stats.
Sourcepub fn snapshot(&self) -> Arc<LockFreeInner>
pub fn snapshot(&self) -> Arc<LockFreeInner>
Returns an Arc snapshot of the current cache state for
lock-free iteration.
Sourcepub fn kind(&self) -> HistoryKind
pub fn kind(&self) -> HistoryKind
History kind.
Sourcepub fn evicted_count(&self) -> u64
pub fn evicted_count(&self) -> u64
Number of samples discarded by KeepLast eviction.
Sourcepub fn min_sn(&self) -> Option<SequenceNumber>
pub fn min_sn(&self) -> Option<SequenceNumber>
Smallest SN from the atom — lock-free.
Sourcepub fn max_sn(&self) -> Option<SequenceNumber>
pub fn max_sn(&self) -> Option<SequenceNumber>
Largest SN from the atom — lock-free.
Sourcepub fn get(&self, sn: SequenceNumber) -> Option<CacheChange>
pub fn get(&self, sn: SequenceNumber) -> Option<CacheChange>
Fetches a change by SN — cloned (CacheChange is Arc-payload- wrapped, so a refcount inc).
Sourcepub fn iter_range_snapshot(
&self,
lo: SequenceNumber,
hi: SequenceNumber,
) -> Vec<CacheChange>
pub fn iter_range_snapshot( &self, lo: SequenceNumber, hi: SequenceNumber, ) -> Vec<CacheChange>
Sample snapshot in the SN range [lo, hi]. Returns a Vec
— we cannot return an Iter <'a> over an Arc snapshot
when the snapshot is not referenced.
Sourcepub fn insert(&self, change: CacheChange) -> Result<(), CacheError>
pub fn insert(&self, change: CacheChange) -> Result<(), CacheError>
Sourcepub fn remove_up_to(&self, sn: SequenceNumber) -> usize
pub fn remove_up_to(&self, sn: SequenceNumber) -> usize
Removes all changes with SN ≤ sn. Returns the number removed.