Skip to main content

micromegas_object_cache/
backend.rs

1use async_trait::async_trait;
2use bytes::Bytes;
3
4/// Hints the backend's fill priority: prefetch fills should not evict hot
5/// demand data from a bounded cache tier.
6#[derive(Copy, Clone, Debug, PartialEq, Eq)]
7pub enum FillHint {
8    Demand,
9    Prefetch,
10}
11
12/// Point-in-time disk write-path counters (cumulative since process start).
13/// foyer-independent so the trait stays buildable without the `foyer`
14/// feature; `None` for backends with no disk tier (e.g. in-memory).
15#[derive(Clone, Copy, Debug, Default)]
16pub struct BackendDiskStats {
17    pub write_bytes: u64,
18    pub read_bytes: u64,
19    pub write_ios: u64,
20    pub read_ios: u64,
21}
22
23#[async_trait]
24pub trait RangeCacheBackend: Send + Sync {
25    /// `expected_len` is the exact length the caller will accept for `key`.
26    /// A backend MUST NOT copy a value whose length differs into any faster
27    /// tier it maintains (the promotion gate) and MUST treat such a value as
28    /// a miss. Single-tier backends accept and ignore the parameter.
29    async fn get(&self, key: &str, expected_len: u64) -> Option<Bytes>;
30
31    /// `value` is an owned buffer, not a view into a larger one (e.g. a slice
32    /// of a coalesced multi-block origin GET): `range_cache::fetch` copies
33    /// each block once before calling `put`, specifically so no cached (or
34    /// in-flight-write) value pins a larger parent allocation alive. A
35    /// backend may therefore store `value` as-is; it must not assume it needs
36    /// its own defensive copy to detach from a parent buffer.
37    async fn put(&self, key: String, value: Bytes, hint: FillHint);
38
39    /// Disk write-path counters, for the saturation monitor's per-second
40    /// gauges. Defaulted to `None` so backends without a disk tier (e.g.
41    /// `MemoryBackend`) need no override.
42    fn disk_stats(&self) -> Option<BackendDiskStats> {
43        None
44    }
45
46    /// Accounted RAM-tier byte usage, for the saturation monitor's residency
47    /// gauge. `None` for backends with no RAM tier accounting (e.g.
48    /// `MemoryBackend`). Divergence between this and process RSS is the
49    /// signature of a cached value pinning more than its accounted weight.
50    fn ram_usage_bytes(&self) -> Option<usize> {
51        None
52    }
53
54    /// Accounted RAM-tier entry count, the entry-count sibling to
55    /// `ram_usage_bytes`. `None` for backends with no RAM tier accounting
56    /// (e.g. `MemoryBackend`).
57    fn ram_entries(&self) -> Option<usize> {
58        None
59    }
60}