pub struct CompositionBackend<L1, L2, O, R = SequentialReadPolicy, W = OptimisticParallelWritePolicy>where
L1: Backend,
L2: Backend,
O: Offload<'static>,
R: CompositionReadPolicy,
W: CompositionWritePolicy,{ /* private fields */ }Expand description
A backend that composes two cache backends into a layered caching system.
The first backend (L1) is checked first on reads, and if not found, the second backend (L2) is checked. On writes, both backends are updated.
Each layer can use its own serialization format and compression since
CacheBackend operates on typed data, not raw bytes.
Behavior can be customized via CompositionReadPolicy, CompositionWritePolicy, and RefillPolicy to control
how reads, writes, and L1 refills are executed across the layers.
Implementations§
Source§impl<L1, L2, O> CompositionBackend<L1, L2, O, SequentialReadPolicy, OptimisticParallelWritePolicy>
impl<L1, L2, O> CompositionBackend<L1, L2, O, SequentialReadPolicy, OptimisticParallelWritePolicy>
Sourcepub fn new(l1: L1, l2: L2, offload: O) -> Self
pub fn new(l1: L1, l2: L2, offload: O) -> Self
Creates a new composition backend with two layers using default policies.
Default policies:
- Read:
SequentialReadPolicy(try L1 first, then L2) - Write:
OptimisticParallelWritePolicy(write to both, succeed if ≥1 succeeds) - Refill:
RefillPolicy::Never(do not populate L1 after L2 hit)
§Arguments
l1- First-layer backend (checked first on reads)l2- Second-layer backend (checked if L1 misses)offload- Offload manager for background tasks (e.g., race policy losers)
Source§impl<L1, L2, O, R, W> CompositionBackend<L1, L2, O, R, W>where
L1: Backend,
L2: Backend,
O: Offload<'static>,
R: CompositionReadPolicy,
W: CompositionWritePolicy,
impl<L1, L2, O, R, W> CompositionBackend<L1, L2, O, R, W>where
L1: Backend,
L2: Backend,
O: Offload<'static>,
R: CompositionReadPolicy,
W: CompositionWritePolicy,
Sourcepub fn read_policy(&self) -> &R
pub fn read_policy(&self) -> &R
Returns a reference to the read policy.
Sourcepub fn write_policy(&self) -> &W
pub fn write_policy(&self) -> &W
Returns a reference to the write policy.
Sourcepub fn refill_policy(&self) -> &RefillPolicy
pub fn refill_policy(&self) -> &RefillPolicy
Returns a reference to the refill policy.
Sourcepub fn label(self, label: impl Into<BackendLabel>) -> Self
pub fn label(self, label: impl Into<BackendLabel>) -> Self
Set a custom label for this backend.
The label is used for source path composition in multi-layer caches. For example, with label “cache”, the source path might be “cache.L1”.
Sourcepub fn with_policy<NewR, NewW>(
self,
policy: CompositionPolicy<NewR, NewW>,
) -> CompositionBackend<L1, L2, O, NewR, NewW>where
NewR: CompositionReadPolicy,
NewW: CompositionWritePolicy,
pub fn with_policy<NewR, NewW>(
self,
policy: CompositionPolicy<NewR, NewW>,
) -> CompositionBackend<L1, L2, O, NewR, NewW>where
NewR: CompositionReadPolicy,
NewW: CompositionWritePolicy,
Set all policies at once using CompositionPolicy builder.
This is the preferred way to configure multiple policies.
§Example
use hitbox_backend::{CompositionBackend, composition::CompositionPolicy};
use hitbox_backend::composition::policy::{RaceReadPolicy, SequentialWritePolicy, RefillPolicy};
let policy = CompositionPolicy::new()
.read(RaceReadPolicy::new())
.write(SequentialWritePolicy::new())
.refill(RefillPolicy::Always);
let backend = CompositionBackend::new(l1, l2, offload)
.with_policy(policy);Sourcepub fn read<NewR: CompositionReadPolicy>(
self,
read_policy: NewR,
) -> CompositionBackend<L1, L2, O, NewR, W>
pub fn read<NewR: CompositionReadPolicy>( self, read_policy: NewR, ) -> CompositionBackend<L1, L2, O, NewR, W>
Set the read policy (builder pattern).
This consumes the backend and returns a new one with the updated read policy.
§Example
use hitbox_backend::CompositionBackend;
use hitbox_backend::composition::policy::RaceReadPolicy;
let backend = CompositionBackend::new(l1, l2, offload)
.read(RaceReadPolicy::new());Sourcepub fn write<NewW: CompositionWritePolicy>(
self,
write_policy: NewW,
) -> CompositionBackend<L1, L2, O, R, NewW>
pub fn write<NewW: CompositionWritePolicy>( self, write_policy: NewW, ) -> CompositionBackend<L1, L2, O, R, NewW>
Set the write policy (builder pattern).
This consumes the backend and returns a new one with the updated write policy.
§Example
use hitbox_backend::CompositionBackend;
use hitbox_backend::composition::policy::SequentialWritePolicy;
let backend = CompositionBackend::new(l1, l2, offload)
.write(SequentialWritePolicy::new());Sourcepub fn refill(self, refill_policy: RefillPolicy) -> Self
pub fn refill(self, refill_policy: RefillPolicy) -> Self
Set the refill policy (builder pattern).
This consumes the backend and returns a new one with the updated refill policy.
§Example
use hitbox_backend::CompositionBackend;
use hitbox_backend::composition::policy::RefillPolicy;
let backend = CompositionBackend::new(l1, l2, offload)
.refill(RefillPolicy::Always);Trait Implementations§
Source§impl<L1, L2, O, R, W> Backend for CompositionBackend<L1, L2, O, R, W>
impl<L1, L2, O, R, W> Backend for CompositionBackend<L1, L2, O, R, W>
Source§fn read<'life0, 'life1, 'async_trait>(
&'life0 self,
key: &'life1 CacheKey,
) -> Pin<Box<dyn Future<Output = BackendResult<Option<CacheValue<Raw>>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn read<'life0, 'life1, 'async_trait>(
&'life0 self,
key: &'life1 CacheKey,
) -> Pin<Box<dyn Future<Output = BackendResult<Option<CacheValue<Raw>>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn write<'life0, 'life1, 'async_trait>(
&'life0 self,
key: &'life1 CacheKey,
value: CacheValue<Raw>,
) -> Pin<Box<dyn Future<Output = BackendResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn write<'life0, 'life1, 'async_trait>(
&'life0 self,
key: &'life1 CacheKey,
value: CacheValue<Raw>,
) -> Pin<Box<dyn Future<Output = BackendResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn remove<'life0, 'life1, 'async_trait>(
&'life0 self,
key: &'life1 CacheKey,
) -> Pin<Box<dyn Future<Output = BackendResult<DeleteStatus>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn remove<'life0, 'life1, 'async_trait>(
&'life0 self,
key: &'life1 CacheKey,
) -> Pin<Box<dyn Future<Output = BackendResult<DeleteStatus>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn label(&self) -> BackendLabel
fn label(&self) -> BackendLabel
Source§fn value_format(&self) -> &dyn Format
fn value_format(&self) -> &dyn Format
BincodeFormat.Source§fn key_format(&self) -> &CacheKeyFormat
fn key_format(&self) -> &CacheKeyFormat
CacheKeyFormat::Bitcode.Source§fn compressor(&self) -> &dyn Compressor
fn compressor(&self) -> &dyn Compressor
PassthroughCompressor.Source§impl<L1, L2, O, R, W> CacheBackend for CompositionBackend<L1, L2, O, R, W>where
L1: CacheBackend + Clone + Send + Sync + 'static,
L2: CacheBackend + Clone + Send + Sync + 'static,
O: Offload<'static>,
R: CompositionReadPolicy,
W: CompositionWritePolicy,
impl<L1, L2, O, R, W> CacheBackend for CompositionBackend<L1, L2, O, R, W>where
L1: CacheBackend + Clone + Send + Sync + 'static,
L2: CacheBackend + Clone + Send + Sync + 'static,
O: Offload<'static>,
R: CompositionReadPolicy,
W: CompositionWritePolicy,
Source§async fn get<T>(
&self,
key: &CacheKey,
ctx: &mut BoxContext,
) -> BackendResult<Option<CacheValue<T::Cached>>>
async fn get<T>( &self, key: &CacheKey, ctx: &mut BoxContext, ) -> BackendResult<Option<CacheValue<T::Cached>>>
Source§async fn set<T>(
&self,
key: &CacheKey,
value: &CacheValue<T::Cached>,
ctx: &mut BoxContext,
) -> BackendResult<()>
async fn set<T>( &self, key: &CacheKey, value: &CacheValue<T::Cached>, ctx: &mut BoxContext, ) -> BackendResult<()>
Source§async fn delete(
&self,
key: &CacheKey,
ctx: &mut BoxContext,
) -> BackendResult<DeleteStatus>
async fn delete( &self, key: &CacheKey, ctx: &mut BoxContext, ) -> BackendResult<DeleteStatus>
Source§impl<L1, L2, O, R, W> Clone for CompositionBackend<L1, L2, O, R, W>where
L1: Clone + Backend,
L2: Clone + Backend,
O: Offload<'static>,
R: Clone + CompositionReadPolicy,
W: Clone + CompositionWritePolicy,
impl<L1, L2, O, R, W> Clone for CompositionBackend<L1, L2, O, R, W>where
L1: Clone + Backend,
L2: Clone + Backend,
O: Offload<'static>,
R: Clone + CompositionReadPolicy,
W: Clone + CompositionWritePolicy,
Source§impl<L1, L2, O, R, W> Debug for CompositionBackend<L1, L2, O, R, W>where
L1: Debug + Backend,
L2: Debug + Backend,
O: Debug + Offload<'static>,
R: Debug + CompositionReadPolicy,
W: Debug + CompositionWritePolicy,
impl<L1, L2, O, R, W> Debug for CompositionBackend<L1, L2, O, R, W>where
L1: Debug + Backend,
L2: Debug + Backend,
O: Debug + Offload<'static>,
R: Debug + CompositionReadPolicy,
W: Debug + CompositionWritePolicy,
Auto Trait Implementations§
impl<L1, L2, O, R, W> Freeze for CompositionBackend<L1, L2, O, R, W>
impl<L1, L2, O, R = SequentialReadPolicy, W = OptimisticParallelWritePolicy> !RefUnwindSafe for CompositionBackend<L1, L2, O, R, W>
impl<L1, L2, O, R, W> Send for CompositionBackend<L1, L2, O, R, W>
impl<L1, L2, O, R, W> Sync for CompositionBackend<L1, L2, O, R, W>
impl<L1, L2, O, R, W> Unpin for CompositionBackend<L1, L2, O, R, W>
impl<L1, L2, O, R = SequentialReadPolicy, W = OptimisticParallelWritePolicy> !UnwindSafe for CompositionBackend<L1, L2, O, R, W>
Blanket Implementations§
Source§impl<T> ArchivePointee for T
impl<T> ArchivePointee for T
Source§type ArchivedMetadata = ()
type ArchivedMetadata = ()
Source§fn pointer_metadata(
_: &<T as ArchivePointee>::ArchivedMetadata,
) -> <T as Pointee>::Metadata
fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata, ) -> <T as Pointee>::Metadata
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> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Compose for Twhere
T: Backend,
impl<T> Compose for Twhere
T: Backend,
Source§fn compose<L2, O>(self, l2: L2, offload: O) -> CompositionBackend<Self, L2, O>
fn compose<L2, O>(self, l2: L2, offload: O) -> CompositionBackend<Self, L2, O>
Source§fn compose_with<L2, O, R, W>(
self,
l2: L2,
offload: O,
policy: CompositionPolicy<R, W>,
) -> CompositionBackend<Self, L2, O, R, W>
fn compose_with<L2, O, R, W>( self, l2: L2, offload: O, policy: CompositionPolicy<R, W>, ) -> CompositionBackend<Self, L2, O, R, W>
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> LayoutRaw for T
impl<T> LayoutRaw for T
Source§fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>
fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>
Source§impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
Source§unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool
unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool
Source§fn resolve_niched(out: Place<NichedOption<T, N1>>)
fn resolve_niched(out: Place<NichedOption<T, N1>>)
out indicating that a T is niched.