Skip to main content

iqdb_cache/
config.rs

1//! Cache configuration.
2
3use core::time::Duration;
4
5/// Default cache capacity: the number of distinct recent searches whose results
6/// are kept resident when no explicit capacity is given.
7pub(crate) const DEFAULT_CAPACITY: usize = 1024;
8
9/// Tuning for a [`CachedIndex`](crate::CachedIndex) — the Tier-2 configured path.
10///
11/// Build one with [`CacheConfig::new`] and the chaining setters, then hand it to
12/// [`CachedIndex::with_config`](crate::CachedIndex::with_config). Every setting
13/// has a sensible default, so `CacheConfig::new()` alone is a valid config.
14///
15/// | Setting | Default | Meaning |
16/// |---|---|---|
17/// | [`capacity`](CacheConfig::capacity) | `1024` | Max distinct searches cached; `0` disables caching. |
18/// | [`ttl`](CacheConfig::ttl) | none | Optional per-entry time-to-live; expired results are recomputed. |
19///
20/// # Examples
21///
22/// ```
23/// use std::time::Duration;
24///
25/// use iqdb_cache::{CacheConfig, CachedIndex};
26///
27/// let config = CacheConfig::new()
28///     .capacity(4096)
29///     .ttl(Duration::from_secs(30));
30///
31/// let cached = CachedIndex::with_config(iqdb_cache::doc_stub::stub_index(), config);
32/// assert_eq!(cached.capacity(), 4096);
33/// assert_eq!(cached.ttl(), Some(Duration::from_secs(30)));
34/// ```
35#[derive(Clone, Debug, PartialEq, Eq)]
36pub struct CacheConfig {
37    /// Maximum number of distinct cached searches.
38    pub(crate) capacity: usize,
39    /// Optional per-entry time-to-live.
40    pub(crate) ttl: Option<Duration>,
41}
42
43impl CacheConfig {
44    /// A configuration with the default capacity (1024) and no TTL.
45    ///
46    /// # Examples
47    ///
48    /// ```
49    /// use iqdb_cache::CacheConfig;
50    ///
51    /// let config = CacheConfig::new();
52    /// // Equivalent to `CachedIndex::new(..)`'s defaults.
53    /// # let _ = config;
54    /// ```
55    #[must_use]
56    pub fn new() -> Self {
57        Self {
58            capacity: DEFAULT_CAPACITY,
59            ttl: None,
60        }
61    }
62
63    /// Sets the maximum number of distinct cached searches.
64    ///
65    /// A `capacity` of `0` disables caching: searches pass straight through.
66    ///
67    /// # Examples
68    ///
69    /// ```
70    /// use iqdb_cache::CacheConfig;
71    ///
72    /// let config = CacheConfig::new().capacity(256);
73    /// # let _ = config;
74    /// ```
75    #[must_use]
76    pub fn capacity(mut self, capacity: usize) -> Self {
77        self.capacity = capacity;
78        self
79    }
80
81    /// Sets a per-entry time-to-live: a cached result older than `ttl` is
82    /// treated as a miss and recomputed.
83    ///
84    /// TTL bounds staleness from changes the wrapper cannot observe (for
85    /// example, the wrapped index mutated through another handle). Mutations
86    /// *through* the wrapper already invalidate exactly, independent of TTL.
87    ///
88    /// # Examples
89    ///
90    /// ```
91    /// use std::time::Duration;
92    ///
93    /// use iqdb_cache::CacheConfig;
94    ///
95    /// let config = CacheConfig::new().ttl(Duration::from_secs(60));
96    /// # let _ = config;
97    /// ```
98    #[must_use]
99    pub fn ttl(mut self, ttl: Duration) -> Self {
100        self.ttl = Some(ttl);
101        self
102    }
103
104    /// Clears any previously set TTL, so cached results never expire on time
105    /// (only on mutation).
106    ///
107    /// # Examples
108    ///
109    /// ```
110    /// use std::time::Duration;
111    ///
112    /// use iqdb_cache::CacheConfig;
113    ///
114    /// let config = CacheConfig::new().ttl(Duration::from_secs(60)).no_ttl();
115    /// # let _ = config;
116    /// ```
117    #[must_use]
118    pub fn no_ttl(mut self) -> Self {
119        self.ttl = None;
120        self
121    }
122}
123
124impl Default for CacheConfig {
125    fn default() -> Self {
126        Self::new()
127    }
128}