html_translation_lib/storage/
cache.rs

1//! 缓存管理模块
2//!
3//! 提供翻译结果的内存和持久化缓存功能
4
5#![allow(dead_code)] // 暂时允许未使用代码
6
7// 重新添加必要的导入
8use crate::config::TranslationConfig;
9use crate::error::TranslationResult;
10use std::collections::HashMap;
11use std::time::{Duration, SystemTime};
12use std::path::PathBuf;
13
14/// 缓存管理器
15pub struct CacheManager {
16    /// 内存缓存
17    memory_cache: HashMap<String, CacheEntry>,
18    
19    /// 缓存配置
20    config: CacheConfig,
21    
22    /// 缓存统计
23    stats: CacheStats,
24}
25
26impl CacheManager {
27    /// 创建新的缓存管理器
28    #[cfg(feature = "async")]
29    pub async fn new(translation_config: &TranslationConfig) -> TranslationResult<Self> {
30        let config = CacheConfig {
31            enable_memory_cache: true,
32            enable_persistent_cache: false,
33            max_entries: translation_config.max_cache_entries,
34            ttl: translation_config.cache_ttl,
35            cache_dir: None,
36        };
37        
38        let mut manager = Self {
39            memory_cache: HashMap::new(),
40            config,
41            stats: CacheStats::default(),
42        };
43        
44        // 如果启用持久化缓存,尝试加载现有缓存
45        if manager.config.enable_persistent_cache {
46            manager.load_persistent_cache().await?;
47        }
48        
49        Ok(manager)
50    }
51    
52    /// 从缓存中获取翻译结果
53    #[cfg(feature = "async")]
54    pub async fn get(&self, text: &str) -> TranslationResult<Option<String>> {
55        let key = self.generate_key(text);
56        
57        // 先检查内存缓存
58        if let Some(entry) = self.memory_cache.get(&key) {
59            if entry.is_valid() {
60                return Ok(Some(entry.translation.clone()));
61            }
62        }
63        
64        // TODO: 检查持久化缓存
65        
66        Ok(None)
67    }
68    
69    /// 设置缓存项
70    #[cfg(feature = "async")]
71    pub async fn set(&mut self, text: &str, translation: String) -> TranslationResult<()> {
72        let key = self.generate_key(text);
73        let entry = CacheEntry::new(text.to_string(), translation, self.config.ttl);
74        
75        // 检查是否需要清理缓存
76        if self.memory_cache.len() >= self.config.max_entries {
77            self.cleanup_expired_entries();
78            
79            // 如果还是太多,移除最老的项
80            if self.memory_cache.len() >= self.config.max_entries {
81                self.evict_oldest_entries(self.config.max_entries / 4);
82            }
83        }
84        
85        self.memory_cache.insert(key, entry);
86        self.stats.cache_sets += 1;
87        
88        Ok(())
89    }
90    
91    /// 清理过期项
92    pub fn cleanup_expired_entries(&mut self) {
93        let now = SystemTime::now();
94        self.memory_cache.retain(|_, entry| {
95            now.duration_since(entry.created_at)
96                .map(|d| d < entry.ttl)
97                .unwrap_or(false)
98        });
99    }
100    
101    /// 移除最老的条目
102    fn evict_oldest_entries(&mut self, count: usize) {
103        let mut entries: Vec<(String, SystemTime)> = self.memory_cache
104            .iter()
105            .map(|(k, v)| (k.clone(), v.created_at))
106            .collect();
107        
108        entries.sort_by_key(|(_, time)| *time);
109        
110        for (key, _) in entries.into_iter().take(count) {
111            self.memory_cache.remove(&key);
112        }
113    }
114    
115    /// 生成缓存键
116    fn generate_key(&self, text: &str) -> String {
117        use std::collections::hash_map::DefaultHasher;
118        use std::hash::{Hash, Hasher};
119        
120        let mut hasher = DefaultHasher::new();
121        text.hash(&mut hasher);
122        format!("{:x}", hasher.finish())
123    }
124    
125    /// 获取缓存统计
126    pub fn get_stats(&self) -> &CacheStats {
127        &self.stats
128    }
129    
130    /// 清空所有缓存
131    pub fn clear(&mut self) {
132        self.memory_cache.clear();
133        self.stats.cache_clears += 1;
134    }
135    
136    /// 获取缓存大小
137    pub fn size(&self) -> usize {
138        self.memory_cache.len()
139    }
140    
141    /// 加载持久化缓存
142    #[cfg(feature = "async")]
143    async fn load_persistent_cache(&mut self) -> TranslationResult<()> {
144        // TODO: 实现持久化缓存加载
145        Ok(())
146    }
147    
148    /// 保存持久化缓存
149    #[cfg(feature = "async")]
150    pub async fn save_persistent_cache(&self) -> TranslationResult<()> {
151        // TODO: 实现持久化缓存保存
152        Ok(())
153    }
154}
155
156/// 缓存配置
157#[derive(Debug, Clone)]
158pub struct CacheConfig {
159    /// 启用内存缓存
160    pub enable_memory_cache: bool,
161    
162    /// 启用持久化缓存
163    pub enable_persistent_cache: bool,
164    
165    /// 最大缓存条目数
166    pub max_entries: usize,
167    
168    /// 缓存生存时间
169    pub ttl: Duration,
170    
171    /// 缓存目录
172    pub cache_dir: Option<PathBuf>,
173}
174
175impl Default for CacheConfig {
176    fn default() -> Self {
177        Self {
178            enable_memory_cache: true,
179            enable_persistent_cache: false,
180            max_entries: 10000,
181            ttl: Duration::from_secs(3600),
182            cache_dir: None,
183        }
184    }
185}
186
187/// 缓存条目
188#[derive(Debug, Clone)]
189pub struct CacheEntry {
190    /// 原始文本
191    pub original_text: String,
192    
193    /// 翻译结果
194    pub translation: String,
195    
196    /// 创建时间
197    pub created_at: SystemTime,
198    
199    /// 生存时间
200    pub ttl: Duration,
201    
202    /// 访问次数
203    pub access_count: u32,
204    
205    /// 最后访问时间
206    pub last_accessed: SystemTime,
207}
208
209impl CacheEntry {
210    /// 创建新的缓存条目
211    pub fn new(original_text: String, translation: String, ttl: Duration) -> Self {
212        let now = SystemTime::now();
213        Self {
214            original_text,
215            translation,
216            created_at: now,
217            ttl,
218            access_count: 0,
219            last_accessed: now,
220        }
221    }
222    
223    /// 检查缓存项是否有效
224    pub fn is_valid(&self) -> bool {
225        SystemTime::now()
226            .duration_since(self.created_at)
227            .map(|d| d < self.ttl)
228            .unwrap_or(false)
229    }
230    
231    /// 标记为已访问
232    pub fn mark_accessed(&mut self) {
233        self.access_count += 1;
234        self.last_accessed = SystemTime::now();
235    }
236    
237    /// 获取年龄(存在时间)
238    pub fn age(&self) -> Duration {
239        SystemTime::now()
240            .duration_since(self.created_at)
241            .unwrap_or(Duration::ZERO)
242    }
243    
244    /// 获取剩余生存时间
245    pub fn remaining_ttl(&self) -> Duration {
246        let age = self.age();
247        if age < self.ttl {
248            self.ttl - age
249        } else {
250            Duration::ZERO
251        }
252    }
253}
254
255/// 缓存统计信息
256#[derive(Debug, Default, Clone)]
257pub struct CacheStats {
258    /// 缓存命中次数
259    pub cache_hits: usize,
260    
261    /// 缓存未命中次数
262    pub cache_misses: usize,
263    
264    /// 缓存设置次数
265    pub cache_sets: usize,
266    
267    /// 缓存清理次数
268    pub cache_clears: usize,
269    
270    /// 过期条目清理次数
271    pub expired_cleanups: usize,
272}
273
274impl CacheStats {
275    /// 计算缓存命中率
276    pub fn hit_rate(&self) -> f32 {
277        let total = self.cache_hits + self.cache_misses;
278        if total > 0 {
279            self.cache_hits as f32 / total as f32
280        } else {
281            0.0
282        }
283    }
284    
285    /// 重置统计信息
286    pub fn reset(&mut self) {
287        *self = Default::default();
288    }
289}