Skip to main content

CacheStore

Struct CacheStore 

Source
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

Source

pub fn open(path: &Path, config: CacheConfig) -> Result<CacheHandle, AppError>

Open a redb database at path and return a shared CacheHandle.

Source

pub fn in_memory(config: CacheConfig) -> CacheHandle

In-memory only store — used in tests that do not exercise the disk layer.

Source

pub fn new_with_clock( config: CacheConfig, clock: Arc<dyn Clock>, db: Option<Arc<Database>>, ) -> CacheHandle

Constructor with an injected clock for tests.

Source

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.

Source

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.

Source

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.

Source

pub fn invalidate(&self, key: &CacheKey)

Remove a single entry from both memory and disk.

Source

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.

Source

pub fn clear_all(&self)

Wipe every cached entry from both layers.

Source

fn classify_entry_bytes<T: DeserializeOwned>( raw: &[u8], now: i64, expires_at: i64, swr_deadline: i64, ) -> Result<Option<CacheRead<T>>, AppError>

Deserialise raw bytes and classify freshness based on the current time.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
§

impl<Unshared, Shared> IntoShared<Shared> for Unshared
where Shared: FromUnshared<Unshared>,

§

fn into_shared(self) -> Shared

Creates a shared type from an unshared type.
§

impl<T> PolicyExt for T
where T: ?Sized,

§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] only if self and other return Action::Follow. Read more
§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more