agentic_evolve_core/storage/
index.rs1use std::collections::{HashMap, HashSet};
4
5use crate::types::pattern::Pattern;
6
7#[derive(Debug, Default)]
9pub struct PatternIndex {
10 by_name: HashMap<String, HashSet<String>>,
11 by_domain: HashMap<String, HashSet<String>>,
12 by_language: HashMap<String, HashSet<String>>,
13 by_tag: HashMap<String, HashSet<String>>,
14 by_return_type: HashMap<String, HashSet<String>>,
15}
16
17impl PatternIndex {
18 pub fn new() -> Self {
19 Self::default()
20 }
21
22 pub fn add(&mut self, pattern: &Pattern) {
23 let id = pattern.id.as_str().to_string();
24
25 self.by_name
26 .entry(pattern.name.to_lowercase())
27 .or_default()
28 .insert(id.clone());
29
30 self.by_domain
31 .entry(pattern.domain.to_lowercase())
32 .or_default()
33 .insert(id.clone());
34
35 self.by_language
36 .entry(pattern.language.as_str().to_string())
37 .or_default()
38 .insert(id.clone());
39
40 for tag in &pattern.tags {
41 self.by_tag
42 .entry(tag.to_lowercase())
43 .or_default()
44 .insert(id.clone());
45 }
46
47 if let Some(ret) = &pattern.signature.return_type {
48 self.by_return_type
49 .entry(ret.to_lowercase())
50 .or_default()
51 .insert(id.clone());
52 }
53 }
54
55 pub fn remove(&mut self, pattern: &Pattern) {
56 let id = pattern.id.as_str();
57 self.by_name.values_mut().for_each(|s| {
58 s.remove(id);
59 });
60 self.by_domain.values_mut().for_each(|s| {
61 s.remove(id);
62 });
63 self.by_language.values_mut().for_each(|s| {
64 s.remove(id);
65 });
66 self.by_tag.values_mut().for_each(|s| {
67 s.remove(id);
68 });
69 self.by_return_type.values_mut().for_each(|s| {
70 s.remove(id);
71 });
72 }
73
74 pub fn find_by_name(&self, name: &str) -> Vec<String> {
75 self.by_name
76 .get(&name.to_lowercase())
77 .map(|s| s.iter().cloned().collect())
78 .unwrap_or_default()
79 }
80
81 pub fn find_by_domain(&self, domain: &str) -> Vec<String> {
82 self.by_domain
83 .get(&domain.to_lowercase())
84 .map(|s| s.iter().cloned().collect())
85 .unwrap_or_default()
86 }
87
88 pub fn find_by_language(&self, language: &str) -> Vec<String> {
89 self.by_language
90 .get(language)
91 .map(|s| s.iter().cloned().collect())
92 .unwrap_or_default()
93 }
94
95 pub fn find_by_tag(&self, tag: &str) -> Vec<String> {
96 self.by_tag
97 .get(&tag.to_lowercase())
98 .map(|s| s.iter().cloned().collect())
99 .unwrap_or_default()
100 }
101
102 pub fn find_by_return_type(&self, return_type: &str) -> Vec<String> {
103 self.by_return_type
104 .get(&return_type.to_lowercase())
105 .map(|s| s.iter().cloned().collect())
106 .unwrap_or_default()
107 }
108
109 pub fn search(&self, query: &str) -> HashSet<String> {
110 let query_lower = query.to_lowercase();
111 let mut results = HashSet::new();
112
113 for (key, ids) in &self.by_name {
114 if key.contains(&query_lower) {
115 results.extend(ids.iter().cloned());
116 }
117 }
118 for (key, ids) in &self.by_domain {
119 if key.contains(&query_lower) {
120 results.extend(ids.iter().cloned());
121 }
122 }
123 for (key, ids) in &self.by_tag {
124 if key.contains(&query_lower) {
125 results.extend(ids.iter().cloned());
126 }
127 }
128 results
129 }
130
131 pub fn total_indexed(&self) -> usize {
132 let mut all = HashSet::new();
133 for ids in self.by_name.values() {
134 all.extend(ids.iter().cloned());
135 }
136 all.len()
137 }
138
139 pub fn clear(&mut self) {
140 self.by_name.clear();
141 self.by_domain.clear();
142 self.by_language.clear();
143 self.by_tag.clear();
144 self.by_return_type.clear();
145 }
146}