1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
//! Eviction wrapper infrastructure for fuzzy dictionaries.
//!
//! This module provides composable eviction strategy wrappers that implement
//! the `MappedDictionary` trait, allowing them to be stacked and composed.
//!
//! # Overview
//!
//! The eviction wrappers use a decorator pattern to add caching behavior to any
//! dictionary implementation. Each wrapper maintains separate metadata (access times,
//! hit counts, sizes, etc.) in thread-safe storage (`Arc<RwLock<HashMap>>`).
//!
//! # Architecture
//!
//! ```text
//! ┌─────────────────────────────────────────────────────────────┐
//! │ Eviction Wrapper (e.g., Lru<D>) │
//! │ ┌────────────────────────────────────────────────────────┐ │
//! │ │ inner: D │ │
//! │ │ metadata: Arc<RwLock<HashMap<String, Metadata>>> │ │
//! │ └────────────────────────────────────────────────────────┘ │
//! └─────────────────────────────────────────────────────────────┘
//! │
//! ▼
//! ┌─────────────────────────────────────────────────────────────┐
//! │ Inner Dictionary (PathMapDictionary, etc.) │
//! └─────────────────────────────────────────────────────────────┘
//! ```
//!
//! # Available Wrappers
//!
//! ## Core Wrappers
//!
//! - **`Noop`**: Zero-cost passthrough wrapper (identity function)
//! - **`LazyInit`**: Deferred dictionary initialization (Default, Fn, or Full closure)
//!
//! ## Time-Based Eviction
//!
//! - **`TTL`**: Time-to-live filtering - expires entries after a duration
//! - **`Age`**: FIFO (First In, First Out) - evicts oldest entries
//! - **`LRU`**: Least Recently Used - evicts entries not accessed recently
//!
//! ## Frequency-Based Eviction
//!
//! - **`LFU`**: Least Frequently Used - evicts entries with lowest access count
//!
//! ## Cost-Based Eviction
//!
//! - **`CostAware`**: Balances age, size, and hit count - formula: `(age * size) / (hits + 1)`
//! - **`MemoryPressure`**: Memory-aware eviction - formula: `size / (hit_rate + 0.1)`
//!
//! # Examples
//!
//! ## Basic Usage
//!
//! ```rust,ignore
//! use liblevenshtein::prelude::*;
//! use liblevenshtein::dictionary::MappedDictionary;
//! use liblevenshtein::cache::eviction::Lru;
//!
//! let dict = PathMapDictionary::from_terms_with_values([
//! ("hello", 1),
//! ("world", 2),
//! ]);
//!
//! let lru = Lru::new(dict);
//! assert_eq!(lru.get_value("hello"), Some(1));
//!
//! // Find least recently used entry
//! let lru_term = lru.find_lru(&["hello", "world"]);
//! ```
//!
//! ## Composing Wrappers
//!
//! Wrappers can be composed to combine multiple eviction strategies:
//!
//! ```rust,ignore
//! use liblevenshtein::prelude::*;
//! use liblevenshtein::dictionary::MappedDictionary;
//! use liblevenshtein::cache::eviction::{Lru, Ttl};
//! use std::time::Duration;
//!
//! let dict = PathMapDictionary::from_terms_with_values([
//! ("foo", 42),
//! ("bar", 99),
//! ]);
//!
//! // Compose TTL + LRU: entries expire after 5 minutes AND track recency
//! let ttl = Ttl::new(dict, Duration::from_secs(300));
//! let lru = Lru::new(ttl);
//!
//! assert_eq!(lru.get_value("foo"), Some(42));
//! ```
//!
//! ## Memory-Aware Caching
//!
//! ```rust,ignore
//! use liblevenshtein::prelude::*;
//! use liblevenshtein::dictionary::MappedDictionary;
//! use liblevenshtein::cache::eviction::MemoryPressure;
//!
//! let dict = PathMapDictionary::from_terms_with_values([
//! ("large_data", vec![1, 2, 3, 4, 5]),
//! ("small_data", vec![1]),
//! ]);
//!
//! let memory = MemoryPressure::new(dict);
//!
//! // Access both entries
//! memory.get_value("large_data");
//! memory.get_value("small_data");
//!
//! // Find entry with highest memory pressure
//! let high_pressure = memory.find_highest_pressure(&["large_data", "small_data"]);
//! ```
//!
//! ## Cost-Based Eviction
//!
//! ```rust,ignore
//! use liblevenshtein::prelude::*;
//! use liblevenshtein::dictionary::MappedDictionary;
//! use liblevenshtein::cache::eviction::CostAware;
//!
//! let dict = PathMapDictionary::from_terms_with_values([
//! ("old_rarely_used", 1),
//! ("new_frequently_used", 2),
//! ]);
//!
//! let cost_aware = CostAware::new(dict);
//!
//! // Access patterns affect cost scores
//! cost_aware.get_value("new_frequently_used");
//! cost_aware.get_value("new_frequently_used");
//! cost_aware.get_value("new_frequently_used");
//!
//! // Old, rarely used entries have higher cost scores
//! let highest_cost = cost_aware.find_highest_cost(&[
//! "old_rarely_used",
//! "new_frequently_used"
//! ]);
//! ```
//!
//! ## Lazy Initialization
//!
//! ```rust,ignore
//! use liblevenshtein::prelude::*;
//! use liblevenshtein::dictionary::MappedDictionary;
//! use liblevenshtein::cache::eviction::LazyInit;
//!
//! // Create dictionary with lazy initializer for missing values
//! let dict: PathMapDictionary<i32> = PathMapDictionary::from_terms_with_values([
//! ("deferred", 42),
//! ]);
//!
//! // Wrap dictionary with lazy initializer
//! let mut lazy = LazyInit::new(dict, || {
//! 0i32 // Default value for missing terms
//! });
//!
//! // Access existing value
//! assert_eq!(lazy.get_value("deferred"), Some(42));
//! ```
//!
//! # Use Cases
//!
//! - **Code Completion**: Use `Lru` or `Lfu` to keep frequently accessed identifiers
//! - **Documentation Search**: Use `CostAware` to balance relevance and recency
//! - **AI Code Chat**: Use `Ttl + MemoryPressure` to manage LLM response caching
//! - **Error Solutions**: Use `Lfu` to keep common error solutions cached
//! - **Large Value Caching**: Use `MemoryPressure` for embeddings, ASTs, etc.
//!
//! # Thread Safety
//!
//! All wrappers are thread-safe. Metadata is protected by `Arc<RwLock<>>`, allowing:
//! - Multiple concurrent readers (shared read locks)
//! - Exclusive writer access for updates (write locks)
//!
//! # Performance
//!
//! - **Zero-cost abstraction**: `Noop` wrapper has no runtime overhead
//! - **Metadata overhead**: Each wrapper adds ~100 bytes per entry for metadata
//! - **Lock contention**: Write-heavy workloads may experience contention on metadata locks
//!
//! # Design Patterns
//!
//! ## Wrapper Stacking Order
//!
//! Stack wrappers from most specific to least specific:
//!
//! ```text
//! Lru<Ttl<MemoryPressure<PathMapDictionary>>>
//! ^ ^ ^ ^
//! | | | └─ Base dictionary
//! | | └─ Memory tracking
//! | └─ Time-based filtering
//! └─ Recency tracking
//! ```
pub use ;
pub use Noop;
// Placeholder modules for other eviction strategies
// These will be implemented in subsequent steps
pub use Age;
pub use CostAware;
pub use Lfu;
pub use Lru;
pub use LruOptimized;
pub use MemoryPressure;
pub use Ttl;