pub struct CacheStore {
config: CacheConfig,
clock: Arc<dyn Clock>,
mem: Mutex<HashMap<Vec<u8>, InMemoryEntry>>,
db: Option<Arc<Database>>,
}Expand description
In-memory + disk-backed authoritative cache.
All methods are synchronous (redb is synchronous). Callers that need
async can wrap calls in tokio::task::spawn_blocking.
Fields§
§config: CacheConfig§clock: Arc<dyn Clock>§mem: Mutex<HashMap<Vec<u8>, InMemoryEntry>>In-memory LRU map. HashMap with a simple insertion-order eviction
is sufficient for the v1 max_in_memory_entries budget; a proper LRU
is a future optimisation.
db: Option<Arc<Database>>redb database handle. None in unit tests that skip the disk layer.
Implementations§
Source§impl CacheStore
impl CacheStore
Sourcepub fn open(path: &Path, config: CacheConfig) -> Result<CacheHandle, AppError>
pub fn open(path: &Path, config: CacheConfig) -> Result<CacheHandle, AppError>
Open a redb database at path and return a shared CacheHandle.
Sourcepub fn in_memory(config: CacheConfig) -> CacheHandle
pub fn in_memory(config: CacheConfig) -> CacheHandle
In-memory only store — used in tests that do not exercise the disk layer.
Sourcepub fn new_with_clock(
config: CacheConfig,
clock: Arc<dyn Clock>,
db: Option<Arc<Database>>,
) -> CacheHandle
pub fn new_with_clock( config: CacheConfig, clock: Arc<dyn Clock>, db: Option<Arc<Database>>, ) -> CacheHandle
Constructor with an injected clock for tests.
Sourcepub fn db(&self) -> Option<Arc<Database>>
pub fn db(&self) -> Option<Arc<Database>>
Return the underlying redb::Database handle, if one was opened.
Used by MultipartTable (task 32) to share the same file handle
rather than opening cache.redb a second time.
Sourcepub fn get<T: DeserializeOwned>(
&self,
key: &CacheKey,
profile_validation_ts: Option<i64>,
) -> Result<Option<CacheRead<T>>, AppError>
pub fn get<T: DeserializeOwned>( &self, key: &CacheKey, profile_validation_ts: Option<i64>, ) -> Result<Option<CacheRead<T>>, AppError>
Read a cached value.
§Validation gate (AC-8)
If profile_validation_ts is None, the profile has not been
validated in the current session and cached data MUST NOT be surfaced.
The gate returns Ok(None) without reading from disk.
Sourcepub fn put<T: Serialize>(
&self,
key: &CacheKey,
value: T,
ttl: Option<Duration>,
) -> Result<(), AppError>
pub fn put<T: Serialize>( &self, key: &CacheKey, value: T, ttl: Option<Duration>, ) -> Result<(), AppError>
Write a value into both the in-memory and disk layers.
Sourcepub fn invalidate(&self, key: &CacheKey)
pub fn invalidate(&self, key: &CacheKey)
Remove a single entry from both memory and disk.
Sourcepub fn invalidate_profile(&self, profile: &ProfileId)
pub fn invalidate_profile(&self, profile: &ProfileId)
Remove all entries scoped to profile from both layers.
In-memory: O(n) linear scan — acceptable for max_in_memory_entries.
Disk: full table scan, removing matching keys in one transaction.
Auto Trait Implementations§
impl !Freeze for CacheStore
impl !RefUnwindSafe for CacheStore
impl Send for CacheStore
impl Sync for CacheStore
impl Unpin for CacheStore
impl UnsafeUnpin for CacheStore
impl !UnwindSafe for CacheStore
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<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§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