aether/
cache.rs

1// src/cache.rs
2//! AST缓存机制,减少重复解析
3
4use crate::ast::Program;
5use serde::{Deserialize, Serialize};
6use std::collections::HashMap;
7use std::collections::hash_map::DefaultHasher;
8use std::hash::{Hash, Hasher};
9
10/// AST缓存,用于存储已解析的程序
11#[derive(Debug)]
12pub struct ASTCache {
13    /// 缓存存储: hash -> 解析后的AST
14    cache: HashMap<u64, Program>,
15    /// 缓存大小限制
16    max_size: usize,
17    /// 缓存命中统计
18    hits: usize,
19    /// 缓存未命中统计
20    misses: usize,
21}
22
23impl ASTCache {
24    /// 创建新的AST缓存
25    pub fn new() -> Self {
26        Self::with_capacity(100)
27    }
28
29    /// 创建指定容量的AST缓存
30    pub fn with_capacity(max_size: usize) -> Self {
31        ASTCache {
32            cache: HashMap::with_capacity(max_size.min(100)),
33            max_size,
34            hits: 0,
35            misses: 0,
36        }
37    }
38
39    /// 计算代码的哈希值
40    fn hash_code(code: &str) -> u64 {
41        let mut hasher = DefaultHasher::new();
42        code.hash(&mut hasher);
43        hasher.finish()
44    }
45
46    /// 从缓存中获取AST
47    pub fn get(&mut self, code: &str) -> Option<Program> {
48        let hash = Self::hash_code(code);
49        if let Some(program) = self.cache.get(&hash) {
50            self.hits += 1;
51            Some(program.clone())
52        } else {
53            self.misses += 1;
54            None
55        }
56    }
57
58    /// 将AST存入缓存
59    pub fn insert(&mut self, code: &str, program: Program) {
60        let hash = Self::hash_code(code);
61
62        // 如果缓存已满,使用简单的FIFO策略清理
63        if self.cache.len() >= self.max_size {
64            // 清理最早的10%条目
65            let to_remove = (self.max_size / 10).max(1);
66            let keys_to_remove: Vec<u64> = self.cache.keys().take(to_remove).copied().collect();
67            for key in keys_to_remove {
68                self.cache.remove(&key);
69            }
70        }
71
72        self.cache.insert(hash, program);
73    }
74
75    /// 清空缓存
76    pub fn clear(&mut self) {
77        self.cache.clear();
78        self.hits = 0;
79        self.misses = 0;
80    }
81
82    /// 获取缓存统计信息
83    pub fn stats(&self) -> CacheStats {
84        CacheStats {
85            size: self.cache.len(),
86            max_size: self.max_size,
87            hits: self.hits,
88            misses: self.misses,
89            hit_rate: if self.hits + self.misses > 0 {
90                self.hits as f64 / (self.hits + self.misses) as f64
91            } else {
92                0.0
93            },
94        }
95    }
96}
97
98impl Default for ASTCache {
99    fn default() -> Self {
100        Self::new()
101    }
102}
103
104/// 缓存统计信息
105#[derive(Debug, Clone, Serialize, Deserialize)]
106pub struct CacheStats {
107    /// 当前缓存大小
108    pub size: usize,
109    /// 最大缓存大小
110    pub max_size: usize,
111    /// 缓存命中次数
112    pub hits: usize,
113    /// 缓存未命中次数
114    pub misses: usize,
115    /// 缓存命中率
116    pub hit_rate: f64,
117}
118
119impl std::fmt::Display for CacheStats {
120    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
121        write!(
122            f,
123            "Cache Stats: size={}/{}, hits={}, misses={}, hit_rate={:.2}%",
124            self.size,
125            self.max_size,
126            self.hits,
127            self.misses,
128            self.hit_rate * 100.0
129        )
130    }
131}