agentic_evolve_core/optimization/
optimizer.rs1use crate::types::pattern::Pattern;
4
5#[derive(Debug, Clone)]
7pub struct OptimizationReport {
8 pub patterns_before: usize,
9 pub patterns_after: usize,
10 pub duplicates_removed: usize,
11 pub pruned: usize,
12 pub merged: usize,
13 pub bytes_saved: usize,
14}
15
16#[derive(Debug, Default)]
18pub struct PatternOptimizer;
19
20impl PatternOptimizer {
21 pub fn new() -> Self {
22 Self
23 }
24
25 pub fn find_duplicates(&self, patterns: &[&Pattern]) -> Vec<(String, String)> {
26 let mut duplicates = Vec::new();
27 for i in 0..patterns.len() {
28 for j in (i + 1)..patterns.len() {
29 if patterns[i].content_hash == patterns[j].content_hash {
30 duplicates.push((
31 patterns[i].id.as_str().to_string(),
32 patterns[j].id.as_str().to_string(),
33 ));
34 }
35 }
36 }
37 duplicates
38 }
39
40 pub fn find_similar(
41 &self,
42 patterns: &[&Pattern],
43 threshold: f64,
44 ) -> Vec<(String, String, f64)> {
45 let mut similar = Vec::new();
46 for i in 0..patterns.len() {
47 for j in (i + 1)..patterns.len() {
48 let sim = template_similarity(&patterns[i].template, &patterns[j].template);
49 if sim >= threshold && patterns[i].content_hash != patterns[j].content_hash {
50 similar.push((
51 patterns[i].id.as_str().to_string(),
52 patterns[j].id.as_str().to_string(),
53 sim,
54 ));
55 }
56 }
57 }
58 similar
59 }
60
61 pub fn suggest_pruning(
62 &self,
63 patterns: &[&Pattern],
64 min_confidence: f64,
65 min_uses: u64,
66 ) -> Vec<String> {
67 patterns
68 .iter()
69 .filter(|p| p.confidence < min_confidence && p.usage_count < min_uses)
70 .map(|p| p.id.as_str().to_string())
71 .collect()
72 }
73
74 pub fn optimize_report(&self, patterns: &[&Pattern]) -> OptimizationReport {
75 let duplicates = self.find_duplicates(patterns);
76 let prunable = self.suggest_pruning(patterns, 0.2, 2);
77
78 OptimizationReport {
79 patterns_before: patterns.len(),
80 patterns_after: patterns.len() - duplicates.len() - prunable.len(),
81 duplicates_removed: duplicates.len(),
82 pruned: prunable.len(),
83 merged: 0,
84 bytes_saved: (duplicates.len() + prunable.len()) * 1024, }
86 }
87}
88
89fn template_similarity(a: &str, b: &str) -> f64 {
90 let a_lines: Vec<&str> = a.lines().collect();
91 let b_lines: Vec<&str> = b.lines().collect();
92 let max_lines = a_lines.len().max(b_lines.len());
93 if max_lines == 0 {
94 return 1.0;
95 }
96 let matching = a_lines
97 .iter()
98 .zip(b_lines.iter())
99 .filter(|(a, b)| a.trim() == b.trim())
100 .count();
101 matching as f64 / max_lines as f64
102}