cache_rs/config.rs
1//! Cache Configuration Module
2//!
3//! This module provides configuration structures for all cache algorithm implementations.
4//! Each cache type has its own dedicated configuration struct with public fields.
5//!
6//! # Design Philosophy
7//!
8//! Configuration structs have all public fields for simple instantiation:
9//!
10//! - **Simple**: Just create the struct with all fields set
11//! - **Type safety**: All parameters must be provided at construction
12//! - **No boilerplate**: No constructors or builder methods needed
13//!
14//! # Sizing Guidelines
15//!
16//! ## Understanding `max_size` and `capacity`
17//!
18//! All cache configurations include two key sizing parameters:
19//!
20//! - **`max_size`**: Maximum total size in bytes for cached *values*. Set this to your
21//! memory/disk budget for the actual cache data.
22//! - **`capacity`**: Maximum number of entries. Each entry incurs memory overhead
23//! (~64-128 bytes) beyond the value size for keys, pointers, and metadata.
24//!
25//! ## For In-Memory Caches
26//!
27//! Set `max_size` based on how much memory you want to allocate for cached values:
28//!
29//! ```text
30//! Total Memory ≈ max_size + (capacity × overhead_per_entry)
31//! overhead_per_entry ≈ 64-128 bytes (keys, pointers, metadata)
32//! ```
33//!
34//! **Example**: 100MB cache with ~10KB average values:
35//! - `max_size = 100 * 1024 * 1024` (100MB for values)
36//! - `capacity = 10_000` entries
37//! - Overhead ≈ 10,000 × 100 bytes = ~1MB additional
38//!
39//! ## For Disk-Based or External Caches
40//!
41//! When caching references to external storage, size based on your target cache size:
42//!
43//! ```text
44//! capacity = target_cache_size / average_object_size
45//! ```
46//!
47//! **Example**: 1GB disk cache with 50KB average objects:
48//! - `max_size = 1024 * 1024 * 1024` (1GB)
49//! - `capacity = 1GB / 50KB ≈ 20_000` entries
50//!
51//! # Single-Threaded Cache Configs
52//!
53//! | Config | Cache | Description |
54//! |--------|-------|-------------|
55//! | `LruCacheConfig` | [`LruCache`](crate::LruCache) | Least Recently Used |
56//! | `LfuCacheConfig` | [`LfuCache`](crate::LfuCache) | Least Frequently Used |
57//! | `LfudaCacheConfig` | [`LfudaCache`](crate::LfudaCache) | LFU with Dynamic Aging |
58//! | `SlruCacheConfig` | [`SlruCache`](crate::SlruCache) | Segmented LRU |
59//! | `GdsfCacheConfig` | [`GdsfCache`](crate::GdsfCache) | Greedy Dual-Size Frequency |
60//!
61//! # Concurrent Cache Configs (requires `concurrent` feature)
62//!
63//! Use `ConcurrentCacheConfig<C>` wrapper around any base config:
64//!
65//! | Type Alias | Base Config | Description |
66//! |------------|-------------|-------------|
67//! | `ConcurrentLruCacheConfig` | `LruCacheConfig` | Thread-safe LRU |
68//! | `ConcurrentLfuCacheConfig` | `LfuCacheConfig` | Thread-safe LFU |
69//! | `ConcurrentLfudaCacheConfig` | `LfudaCacheConfig` | Thread-safe LFUDA |
70//! | `ConcurrentSlruCacheConfig` | `SlruCacheConfig` | Thread-safe SLRU |
71//! | `ConcurrentGdsfCacheConfig` | `GdsfCacheConfig` | Thread-safe GDSF |
72//!
73//! # Examples
74//!
75//! ```
76//! use cache_rs::config::LruCacheConfig;
77//! use cache_rs::LruCache;
78//! use core::num::NonZeroUsize;
79//!
80//! // 10MB in-memory cache for ~1KB average values
81//! let config = LruCacheConfig {
82//! capacity: NonZeroUsize::new(10_000).unwrap(),
83//! max_size: 10 * 1024 * 1024, // 10MB
84//! };
85//!
86//! // Create cache from config
87//! let cache: LruCache<String, Vec<u8>> = LruCache::init(config, None);
88//! ```
89
90// Single-threaded cache configs
91pub mod gdsf;
92pub mod lfu;
93pub mod lfuda;
94pub mod lru;
95pub mod slru;
96
97// Re-exports for convenience - single-threaded
98pub use gdsf::GdsfCacheConfig;
99pub use lfu::LfuCacheConfig;
100pub use lfuda::LfudaCacheConfig;
101pub use lru::LruCacheConfig;
102pub use slru::SlruCacheConfig;
103
104/// Generic configuration wrapper for concurrent caches.
105///
106/// Wraps any base cache configuration and adds the `segments` field
107/// for controlling the number of independent segments used for sharding.
108///
109/// # Type Parameter
110///
111/// - `C`: The base cache configuration type (e.g., `LruCacheConfig`, `LfuCacheConfig`)
112///
113/// # Fields
114///
115/// - `base`: The underlying single-threaded cache configuration. See the base
116/// config docs for sizing guidance on `capacity` and `max_size`.
117/// - `segments`: Number of independent segments for sharding (more = less contention)
118///
119/// # Sizing Note
120///
121/// The `capacity` and `max_size` in the base config apply to the **entire cache**
122/// (distributed across all segments), not per-segment.
123///
124/// # Example
125///
126/// ```ignore
127/// use cache_rs::config::{ConcurrentCacheConfig, LruCacheConfig, ConcurrentLruCacheConfig};
128/// use core::num::NonZeroUsize;
129///
130/// // 100MB concurrent cache with 16 segments
131/// let config: ConcurrentLruCacheConfig = ConcurrentCacheConfig {
132/// base: LruCacheConfig {
133/// capacity: NonZeroUsize::new(10_000).unwrap(),
134/// max_size: 100 * 1024 * 1024, // 100MB total
135/// },
136/// segments: 16,
137/// };
138/// ```
139#[cfg(feature = "concurrent")]
140#[derive(Clone, Copy)]
141pub struct ConcurrentCacheConfig<C> {
142 /// Base configuration for the underlying cache algorithm.
143 /// See individual config docs for sizing guidance.
144 pub base: C,
145 /// Number of segments for sharding (more segments = less contention)
146 pub segments: usize,
147}
148
149#[cfg(feature = "concurrent")]
150impl<C: core::fmt::Debug> core::fmt::Debug for ConcurrentCacheConfig<C> {
151 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
152 f.debug_struct("ConcurrentCacheConfig")
153 .field("base", &self.base)
154 .field("segments", &self.segments)
155 .finish()
156 }
157}
158
159// Type aliases for concurrent cache configs
160#[cfg(feature = "concurrent")]
161/// Configuration for a concurrent LRU cache.
162/// Type alias for `ConcurrentCacheConfig<LruCacheConfig>`.
163pub type ConcurrentLruCacheConfig = ConcurrentCacheConfig<LruCacheConfig>;
164
165#[cfg(feature = "concurrent")]
166/// Configuration for a concurrent LFU cache.
167/// Type alias for `ConcurrentCacheConfig<LfuCacheConfig>`.
168pub type ConcurrentLfuCacheConfig = ConcurrentCacheConfig<LfuCacheConfig>;
169
170#[cfg(feature = "concurrent")]
171/// Configuration for a concurrent LFUDA cache.
172/// Type alias for `ConcurrentCacheConfig<LfudaCacheConfig>`.
173pub type ConcurrentLfudaCacheConfig = ConcurrentCacheConfig<LfudaCacheConfig>;
174
175#[cfg(feature = "concurrent")]
176/// Configuration for a concurrent SLRU cache.
177/// Type alias for `ConcurrentCacheConfig<SlruCacheConfig>`.
178pub type ConcurrentSlruCacheConfig = ConcurrentCacheConfig<SlruCacheConfig>;
179
180#[cfg(feature = "concurrent")]
181/// Configuration for a concurrent GDSF cache.
182/// Type alias for `ConcurrentCacheConfig<GdsfCacheConfig>`.
183pub type ConcurrentGdsfCacheConfig = ConcurrentCacheConfig<GdsfCacheConfig>;