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}