Skip to main content

office_rs/xlsx/formulas/
formula_manager.rs

1//! 公式管理器
2//! 提供公式依赖关系管理、缓存和批量计算功能
3
4use super::*;
5use crate::error::{ OfficeError, Result, XlsxError };
6use crate::xlsx::cell::{ CellReference, CellValue };
7use std::collections::{ HashMap, HashSet, VecDeque };
8
9impl FormulaDependency {
10    /// 创建新的依赖关系
11    pub fn new(cell: CellReference, depends_on: Vec<CellReference>) -> Self {
12        let mut dependent_cells = HashSet::new();
13        for dep in depends_on {
14            dependent_cells.insert(dep);
15        }
16        Self {
17            formula_cell: cell,
18            dependent_cells,
19        }
20    }
21}
22
23impl FormulaManager {
24    /// 创建新的公式管理器
25    pub fn new(cell_provider: Box<dyn CellProvider>) -> Self {
26        Self {
27            formulas: HashMap::new(),
28            dependencies: HashMap::new(),
29            calculator: FormulaCalculator::new(cell_provider),
30        }
31    }
32
33    /// 设置单元格公式
34    pub fn set_formula(&mut self, cell: &CellReference, formula: &str) -> Result<()> {
35        // 解析公式
36        let expr = parse_formula(formula)?;
37
38        // 提取依赖关系
39        let dependencies = self.extract_dependencies(&expr);
40
41        // 存储公式表达式
42        self.formulas.insert(cell.clone(), expr);
43
44        // 添加依赖关系
45        if !dependencies.is_empty() {
46            let dependency = FormulaDependency::new(cell.clone(), dependencies);
47            self.dependencies.insert(cell.clone(), dependency);
48        }
49
50        Ok(())
51    }
52
53    /// 移除单元格公式
54    pub fn remove_formula(&mut self, cell: &CellReference) {
55        self.formulas.remove(cell);
56        self.dependencies.remove(cell);
57    }
58
59    /// 计算单元格公式
60    pub fn calculate_cell(&mut self, cell: &CellReference) -> Result<FormulaValue> {
61        if let Some(expr) = self.formulas.get(cell).cloned() {
62            self.calculator.evaluate(&expr)
63        } else {
64            Err(
65                OfficeError::Xlsx(XlsxError::InvalidFormula {
66                    formula: format!("No formula found for cell {}", cell.to_a1()),
67                })
68            )
69        }
70    }
71
72    /// 批量重新计算
73    pub fn recalculate_all(&mut self) -> Result<HashMap<CellReference, FormulaValue>> {
74        let mut results = HashMap::new();
75
76        // 计算所有公式
77        for cell in self.formulas.keys().cloned().collect::<Vec<_>>() {
78            let result = self.calculate_cell(&cell)?;
79            results.insert(cell, result);
80        }
81
82        Ok(results)
83    }
84
85    /// 获取依赖的单元格(简化实现)
86    pub fn get_dependents(&self, _cell: &CellReference) -> Vec<CellReference> {
87        // 简化实现:返回空列表
88        // 完整实现需要维护反向依赖关系
89        Vec::new()
90    }
91
92    /// 获取被依赖的单元格
93    pub fn get_dependencies(&self, cell: &CellReference) -> Vec<CellReference> {
94        self.dependencies
95            .get(cell)
96            .map(|dep| dep.dependent_cells.iter().cloned().collect())
97            .unwrap_or_default()
98    }
99
100    /// 检查是否存在循环依赖(简化实现)
101    pub fn has_circular_dependency(&self, _cell: &CellReference) -> bool {
102        // 简化实现:总是返回false
103        // 完整实现需要图遍历算法
104        false
105    }
106
107    /// 标记单元格为脏(简化实现)
108    pub fn mark_dirty(&mut self, _cell: &CellReference) {
109        // 简化实现:不做任何操作
110        // 完整实现需要维护脏标记状态
111    }
112
113    /// 清除缓存(简化实现)
114    pub fn clear_cache(&mut self) {
115        // 简化实现:清除公式和依赖关系
116        self.formulas.clear();
117        self.dependencies.clear();
118    }
119
120    /// 获取计算顺序(简化实现)
121    fn get_calculation_order(&self) -> Result<Vec<CellReference>> {
122        // 简化实现:返回所有公式单元格的列表
123        Ok(self.formulas.keys().cloned().collect())
124    }
125
126    /// 提取公式中的依赖关系
127    fn extract_dependencies(&self, expr: &FormulaExpression) -> Vec<CellReference> {
128        let mut dependencies = Vec::new();
129        self.extract_dependencies_recursive(expr, &mut dependencies);
130        dependencies
131    }
132
133    /// 递归提取依赖关系
134    fn extract_dependencies_recursive(
135        &self,
136        expr: &FormulaExpression,
137        dependencies: &mut Vec<CellReference>
138    ) {
139        match expr {
140            FormulaExpression::CellRef(cell_ref) => {
141                dependencies.push(cell_ref.clone());
142            }
143
144            FormulaExpression::RangeRef(start, end) => {
145                // 添加范围内的所有单元格
146                for row in start.row..=end.row {
147                    for col in start.column..=end.column {
148                        dependencies.push(CellReference::new(col, row));
149                    }
150                }
151            }
152
153            FormulaExpression::Function { args, .. } => {
154                for arg in args {
155                    self.extract_dependencies_recursive(arg, dependencies);
156                }
157            }
158
159            FormulaExpression::BinaryOp { left, right, .. } => {
160                self.extract_dependencies_recursive(left, dependencies);
161                self.extract_dependencies_recursive(right, dependencies);
162            }
163
164            FormulaExpression::UnaryOp { operand, .. } => {
165                self.extract_dependencies_recursive(operand, dependencies);
166            }
167
168            FormulaExpression::Constant(_) => {
169                // 常量不产生依赖
170            }
171        }
172    }
173
174    // 辅助方法已移除,使用简化实现
175}
176
177/// 公式缓存管理器
178pub struct FormulaCacheManager {
179    cache: HashMap<String, FormulaValue>,
180    max_size: usize,
181    access_order: VecDeque<String>,
182}
183
184impl FormulaCacheManager {
185    /// 创建新的缓存管理器
186    pub fn new(max_size: usize) -> Self {
187        Self {
188            cache: HashMap::new(),
189            max_size,
190            access_order: VecDeque::new(),
191        }
192    }
193
194    /// 获取缓存值
195    pub fn get(&mut self, key: &str) -> Option<&FormulaValue> {
196        if self.cache.contains_key(key) {
197            // 更新访问顺序
198            self.access_order.retain(|k| k != key);
199            self.access_order.push_back(key.to_string());
200
201            self.cache.get(key)
202        } else {
203            None
204        }
205    }
206
207    /// 设置缓存值
208    pub fn set(&mut self, key: String, value: FormulaValue) {
209        // 如果已存在,更新值和访问顺序
210        if self.cache.contains_key(&key) {
211            self.cache.insert(key.clone(), value);
212            self.access_order.retain(|k| k != &key);
213            self.access_order.push_back(key);
214            return;
215        }
216
217        // 如果缓存已满,移除最久未访问的项
218        if self.cache.len() >= self.max_size {
219            if let Some(oldest_key) = self.access_order.pop_front() {
220                self.cache.remove(&oldest_key);
221            }
222        }
223
224        // 添加新项
225        self.cache.insert(key.clone(), value);
226        self.access_order.push_back(key);
227    }
228
229    /// 移除缓存项
230    pub fn remove(&mut self, key: &str) {
231        self.cache.remove(key);
232        self.access_order.retain(|k| k != key);
233    }
234
235    /// 清空缓存
236    pub fn clear(&mut self) {
237        self.cache.clear();
238        self.access_order.clear();
239    }
240
241    /// 获取缓存大小
242    pub fn size(&self) -> usize {
243        self.cache.len()
244    }
245
246    /// 获取缓存命中率统计
247    pub fn get_stats(&self) -> CacheStats {
248        CacheStats {
249            size: self.cache.len(),
250            max_size: self.max_size,
251            // 这里可以添加更多统计信息
252        }
253    }
254}
255
256/// 缓存统计信息
257#[derive(Debug, Clone)]
258pub struct CacheStats {
259    pub size: usize,
260    pub max_size: usize,
261}
262
263/// 公式性能分析器
264pub struct FormulaProfiler {
265    execution_times: HashMap<String, Vec<std::time::Duration>>,
266    call_counts: HashMap<String, usize>,
267}
268
269impl FormulaProfiler {
270    /// 创建新的性能分析器
271    pub fn new() -> Self {
272        Self {
273            execution_times: HashMap::new(),
274            call_counts: HashMap::new(),
275        }
276    }
277
278    /// 记录函数执行时间
279    pub fn record_execution(&mut self, function_name: &str, duration: std::time::Duration) {
280        self.execution_times
281            .entry(function_name.to_string())
282            .or_insert_with(Vec::new)
283            .push(duration);
284
285        *self.call_counts.entry(function_name.to_string()).or_insert(0) += 1;
286    }
287
288    /// 获取函数平均执行时间
289    pub fn get_average_time(&self, function_name: &str) -> Option<std::time::Duration> {
290        if let Some(times) = self.execution_times.get(function_name) {
291            if !times.is_empty() {
292                let total: std::time::Duration = times.iter().sum();
293                Some(total / (times.len() as u32))
294            } else {
295                None
296            }
297        } else {
298            None
299        }
300    }
301
302    /// 获取函数调用次数
303    pub fn get_call_count(&self, function_name: &str) -> usize {
304        self.call_counts.get(function_name).copied().unwrap_or(0)
305    }
306
307    /// 获取性能报告
308    pub fn get_performance_report(&self) -> Vec<PerformanceReport> {
309        let mut reports = Vec::new();
310
311        for (function_name, times) in &self.execution_times {
312            if !times.is_empty() {
313                let total: std::time::Duration = times.iter().sum();
314                let average = total / (times.len() as u32);
315                let min = *times.iter().min().unwrap();
316                let max = *times.iter().max().unwrap();
317                let call_count = self.get_call_count(function_name);
318
319                reports.push(PerformanceReport {
320                    function_name: function_name.clone(),
321                    call_count,
322                    total_time: total,
323                    average_time: average,
324                    min_time: min,
325                    max_time: max,
326                });
327            }
328        }
329
330        // 按总执行时间排序
331        reports.sort_by(|a, b| b.total_time.cmp(&a.total_time));
332        reports
333    }
334
335    /// 清除统计数据
336    pub fn clear(&mut self) {
337        self.execution_times.clear();
338        self.call_counts.clear();
339    }
340}
341
342/// 性能报告
343#[derive(Debug, Clone)]
344pub struct PerformanceReport {
345    pub function_name: String,
346    pub call_count: usize,
347    pub total_time: std::time::Duration,
348    pub average_time: std::time::Duration,
349    pub min_time: std::time::Duration,
350    pub max_time: std::time::Duration,
351}
352
353#[cfg(test)]
354mod tests {
355    use super::*;
356    use crate::xlsx::cell::CellValue;
357
358    struct MockCellProvider;
359
360    impl CellProvider for MockCellProvider {
361        fn get_cell_value(&self, _reference: &CellReference) -> Result<CellValue> {
362            Ok(CellValue::Number(10.0))
363        }
364
365        fn get_range_values(
366            &self,
367            _start: &CellReference,
368            _end: &CellReference
369        ) -> Result<Vec<Vec<CellValue>>> {
370            Ok(vec![vec![CellValue::Number(10.0)]])
371        }
372    }
373
374    #[test]
375    fn test_formula_manager_dependencies() {
376        let provider = Box::new(MockCellProvider);
377        let mut manager = FormulaManager::new(provider);
378
379        let cell_a1 = CellReference::new(0, 0); // A1
380        let cell_b1 = CellReference::new(1, 0); // B1
381
382        // 设置公式 A1 = B1 + 1
383        manager.set_formula(&cell_a1, "=B1+1").unwrap();
384
385        // 检查依赖关系
386        let deps = manager.get_dependencies(&cell_a1);
387        assert_eq!(deps.len(), 1);
388        assert_eq!(deps[0], cell_b1);
389
390        // 检查反向依赖关系(简化实现总是返回空列表)
391        let dependents = manager.get_dependents(&cell_b1);
392        assert_eq!(dependents.len(), 0);
393    }
394
395    #[test]
396    fn test_formula_storage() {
397        let provider = Box::new(MockCellProvider);
398        let mut manager = FormulaManager::new(provider);
399        let cell_a1 = CellReference::new(0, 0); // A1
400
401        // 设置简单公式
402        manager.set_formula(&cell_a1, "=42").unwrap();
403
404        // 验证公式已存储
405        assert!(manager.formulas.contains_key(&cell_a1));
406
407        // 移除公式
408        manager.remove_formula(&cell_a1);
409        assert!(!manager.formulas.contains_key(&cell_a1));
410    }
411
412    #[test]
413    fn test_cache_manager() {
414        let mut cache = FormulaCacheManager::new(2);
415
416        // 添加缓存项
417        cache.set("key1".to_string(), FormulaValue::Number(1.0));
418        cache.set("key2".to_string(), FormulaValue::Number(2.0));
419
420        // 检查缓存
421        assert!(cache.get("key1").is_some());
422        assert!(cache.get("key2").is_some());
423
424        // 添加第三个项,应该移除最久未访问的项
425        cache.set("key3".to_string(), FormulaValue::Number(3.0));
426
427        // key1应该被移除(最久未访问)
428        assert!(cache.get("key1").is_none());
429        assert!(cache.get("key2").is_some());
430        assert!(cache.get("key3").is_some());
431    }
432
433    #[test]
434    fn test_profiler() {
435        let mut profiler = FormulaProfiler::new();
436
437        // 记录执行时间
438        profiler.record_execution("SUM", std::time::Duration::from_millis(10));
439        profiler.record_execution("SUM", std::time::Duration::from_millis(20));
440        profiler.record_execution("AVERAGE", std::time::Duration::from_millis(15));
441
442        // 检查统计
443        assert_eq!(profiler.get_call_count("SUM"), 2);
444        assert_eq!(profiler.get_call_count("AVERAGE"), 1);
445
446        let avg_time = profiler.get_average_time("SUM").unwrap();
447        assert_eq!(avg_time, std::time::Duration::from_millis(15));
448
449        // 测试性能报告
450        let reports = profiler.get_performance_report();
451        assert_eq!(reports.len(), 2);
452    }
453}