Skip to main content

threatflux_cache/
config.rs

1//! Configuration types for the cache
2
3use serde::{Deserialize, Serialize};
4use std::path::PathBuf;
5use std::time::Duration;
6
7/// Cache configuration
8#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct CacheConfig {
10    /// Maximum number of entries per key
11    pub max_entries_per_key: usize,
12    /// Maximum total number of entries
13    pub max_total_entries: usize,
14    /// Eviction policy to use
15    pub eviction_policy: EvictionPolicy,
16    /// Persistence configuration
17    pub persistence: PersistenceConfig,
18    /// Enable compression for stored values
19    #[cfg(feature = "compression")]
20    pub compression: Option<CompressionConfig>,
21    /// Default TTL for entries (if not specified per-entry)
22    pub default_ttl: Option<Duration>,
23    /// Enable metrics collection
24    #[cfg(feature = "metrics")]
25    pub enable_metrics: bool,
26}
27
28impl Default for CacheConfig {
29    fn default() -> Self {
30        Self {
31            max_entries_per_key: 100,
32            max_total_entries: 10_000,
33            eviction_policy: EvictionPolicy::Lru,
34            persistence: PersistenceConfig::default(),
35            #[cfg(feature = "compression")]
36            compression: None,
37            default_ttl: None,
38            #[cfg(feature = "metrics")]
39            enable_metrics: false,
40        }
41    }
42}
43
44impl CacheConfig {
45    /// Create a new cache configuration with default values
46    pub fn new() -> Self {
47        Self::default()
48    }
49
50    /// Set maximum entries per key
51    pub fn with_max_entries_per_key(mut self, max: usize) -> Self {
52        self.max_entries_per_key = max;
53        self
54    }
55
56    /// Set maximum total entries
57    pub fn with_max_total_entries(mut self, max: usize) -> Self {
58        self.max_total_entries = max;
59        self
60    }
61
62    /// Set eviction policy
63    pub fn with_eviction_policy(mut self, policy: EvictionPolicy) -> Self {
64        self.eviction_policy = policy;
65        self
66    }
67
68    /// Set persistence configuration
69    pub fn with_persistence(mut self, persistence: PersistenceConfig) -> Self {
70        self.persistence = persistence;
71        self
72    }
73
74    /// Set default TTL for entries
75    pub fn with_default_ttl(mut self, ttl: Duration) -> Self {
76        self.default_ttl = Some(ttl);
77        self
78    }
79
80    /// Enable compression with given configuration
81    #[cfg(feature = "compression")]
82    pub fn with_compression(mut self, compression: CompressionConfig) -> Self {
83        self.compression = Some(compression);
84        self
85    }
86
87    /// Enable metrics collection
88    #[cfg(feature = "metrics")]
89    pub fn with_metrics(mut self, enable: bool) -> Self {
90        self.enable_metrics = enable;
91        self
92    }
93}
94
95/// Eviction policy for cache entries
96#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
97pub enum EvictionPolicy {
98    /// Least Recently Used
99    Lru,
100    /// Least Frequently Used
101    Lfu,
102    /// First In First Out
103    Fifo,
104    /// Time To Live based
105    Ttl,
106    /// No eviction (manual only)
107    None,
108}
109
110/// Persistence configuration
111#[derive(Debug, Clone, Serialize, Deserialize)]
112pub struct PersistenceConfig {
113    /// Enable persistence
114    pub enabled: bool,
115    /// Path to store cache data
116    pub path: Option<PathBuf>,
117    /// Sync to disk after every N operations
118    pub sync_interval: usize,
119    /// Automatically save on drop
120    pub save_on_drop: bool,
121    /// Load existing cache on startup
122    pub load_on_startup: bool,
123}
124
125impl Default for PersistenceConfig {
126    fn default() -> Self {
127        Self {
128            enabled: false,
129            path: None,
130            sync_interval: 100,
131            save_on_drop: true,
132            load_on_startup: true,
133        }
134    }
135}
136
137impl PersistenceConfig {
138    /// Create persistence config with path
139    pub fn with_path<P: Into<PathBuf>>(path: P) -> Self {
140        Self {
141            enabled: true,
142            path: Some(path.into()),
143            ..Default::default()
144        }
145    }
146
147    /// Disable persistence
148    pub fn disabled() -> Self {
149        Self {
150            enabled: false,
151            ..Default::default()
152        }
153    }
154}
155
156/// Compression configuration
157#[cfg(feature = "compression")]
158#[derive(Debug, Clone, Serialize, Deserialize)]
159pub struct CompressionConfig {
160    /// Compression algorithm to use
161    pub algorithm: CompressionAlgorithm,
162    /// Compression level (1-9, higher = better compression, slower)
163    pub level: u32,
164    /// Minimum size in bytes before compression is applied
165    pub min_size: usize,
166}
167
168#[cfg(feature = "compression")]
169impl Default for CompressionConfig {
170    fn default() -> Self {
171        Self {
172            algorithm: CompressionAlgorithm::Gzip,
173            level: 6,
174            min_size: 1024, // 1KB
175        }
176    }
177}
178
179/// Supported compression algorithms
180#[cfg(feature = "compression")]
181#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
182pub enum CompressionAlgorithm {
183    /// Gzip compression
184    Gzip,
185    /// Zlib compression
186    Zlib,
187    /// Raw DEFLATE compression
188    Deflate,
189}
190
191#[cfg(test)]
192mod tests {
193    use super::*;
194
195    #[test]
196    fn test_default_config() {
197        let config = CacheConfig::default();
198        assert_eq!(config.max_entries_per_key, 100);
199        assert_eq!(config.max_total_entries, 10_000);
200        assert_eq!(config.eviction_policy, EvictionPolicy::Lru);
201        assert!(!config.persistence.enabled);
202    }
203
204    #[test]
205    fn test_config_builder() {
206        let config = CacheConfig::new()
207            .with_max_entries_per_key(50)
208            .with_max_total_entries(5000)
209            .with_eviction_policy(EvictionPolicy::Lfu)
210            .with_default_ttl(Duration::from_secs(300));
211
212        assert_eq!(config.max_entries_per_key, 50);
213        assert_eq!(config.max_total_entries, 5000);
214        assert_eq!(config.eviction_policy, EvictionPolicy::Lfu);
215        assert_eq!(config.default_ttl, Some(Duration::from_secs(300)));
216    }
217
218    #[test]
219    fn test_persistence_config() {
220        let persistence = PersistenceConfig::with_path("/tmp/cache");
221        assert!(persistence.enabled);
222        assert_eq!(persistence.path, Some(PathBuf::from("/tmp/cache")));
223        assert_eq!(persistence.sync_interval, 100);
224        assert!(persistence.save_on_drop);
225        assert!(persistence.load_on_startup);
226    }
227
228    #[cfg(feature = "compression")]
229    #[test]
230    fn test_compression_config() {
231        let compression = CompressionConfig::default();
232        assert_eq!(compression.algorithm, CompressionAlgorithm::Gzip);
233        assert_eq!(compression.level, 6);
234        assert_eq!(compression.min_size, 1024);
235    }
236}