1use crate::RefCounter;
2pub struct Trie<T = u8, U = bool> {
3 pub(crate) stored_value: Vec<RefCounter<U>>,
4 pub(crate) adjecent_nodes: Vec<(T, RefCounter<Trie<T, U>>)>,
5}
6
7impl<T: Clone, U> Clone for Trie<T, U> {
8 fn clone(&self) -> Self {
9 Self {
10 stored_value: self.stored_value.clone(),
11 adjecent_nodes: self.adjecent_nodes.clone(),
12 }
13 }
14}
15
16impl<T: PartialEq + Clone, U> Trie<T, U> {
17 pub(crate) fn empty_store() -> Trie<T, U> {
18 Trie {
19 stored_value: Vec::new(),
20 adjecent_nodes: Vec::new(),
21 }
22 }
23 pub fn empty() -> Trie<T, U> {
24 Trie {
25 stored_value: Vec::new(),
26 adjecent_nodes: Vec::new(),
27 }
28 }
29 pub fn insert_store<Slc: AsRef<[T]>>(&self, value: Slc, store: U) -> Self {
30 let value_ref = value.as_ref();
31 let mut new_trie = self.clone();
32 if value_ref.is_empty() {
33 new_trie.stored_value.push(RefCounter::new(store));
34 return new_trie;
35 }
36 let head = &value_ref[0];
37 let tail = &value_ref[1..];
38 for (k, v) in new_trie.adjecent_nodes.iter_mut() {
39 if k == head {
40 *v = RefCounter::new(v.insert_store(tail, store));
41 return new_trie;
42 }
43 }
44 new_trie.adjecent_nodes.push((
45 head.clone(),
46 RefCounter::new(Trie::empty_store().insert_store(tail, store)),
47 ));
48 new_trie
49 }
50 pub fn get_store<Slc: AsRef<[T]>>(&self, value: Slc) -> Option<Box<[&U]>> {
51 let value_ref = value.as_ref();
52 if value_ref.is_empty() {
53 let mut vr = Vec::new();
54 for v in self.stored_value.iter() {
55 vr.push(v.as_ref());
56 }
57 if vr.is_empty() {
58 return Option::None;
59 }
60 return Option::Some(vr.into_boxed_slice());
61 }
62 let head = &value_ref[0];
63 let tail = &value_ref[1..];
64 for (k, v) in &self.adjecent_nodes {
65 if k == head {
66 return v.get_store(tail);
67 }
68 }
69 return Option::None;
70 }
71}
72
73impl<T: PartialEq + Clone, U: PartialEq> Trie<T, U> {
74 pub fn delete_store<Slc: AsRef<[T]>>(&self, value: Slc, store: &U) -> Option<Self> {
75 let value_ref = value.as_ref();
76 let mut new_trie = self.clone();
77 if value_ref.is_empty() {
78 new_trie.stored_value.retain(|v| {
79 let retain = v.as_ref() != store;
80 retain
81 });
82 if self.stored_value.len() == new_trie.stored_value.len() {
83 return Option::None;
84 } else {
85 return Option::Some(new_trie);
86 }
87 }
88 let head = &value_ref[0];
89 let tail = &value_ref[1..];
90 for (k, v) in new_trie.adjecent_nodes.iter_mut() {
91 if k == head {
92 let subt = v.delete_store(tail, store)?;
93 *v = RefCounter::new(subt);
94 return Option::Some(new_trie);
95 }
96 }
97 return Option::None;
98 }
99}
100
101impl<T: PartialEq + Copy> Trie<T> {
102 pub fn insert<Slc: AsRef<[T]>>(&self, value: Slc) -> Self {
103 self.insert_store(value, true)
104 }
105 pub fn search<Slc: AsRef<[T]>>(&self, value: Slc) -> bool {
106 self.get_store(value).is_some()
107 }
108 pub fn delete<Slc: AsRef<[T]>>(&self, value: Slc) -> Option<Self> {
109 self.delete_store(value, &true)
110 }
111}
112
113#[cfg(test)]
114mod tests {
115
116 use std::vec;
117
118 use super::*;
119
120 #[test]
121 fn test_trie_store() {
122 let t = Trie::empty_store().insert_store("aab", 123);
123 let t2 = t.insert_store("adc", 459);
124 let boxed_array: Box<[&i32]> = Box::new([&123]);
125 let boxed_array_2: Box<[&i32]> = Box::new([&459]);
126 assert_eq!(t.get_store("aab"), Option::Some(boxed_array.clone()));
127 assert!(t.get_store("adc").is_none());
128 assert_eq!(t2.get_store("aab"), Option::Some(boxed_array));
129 assert_eq!(t2.get_store("adc"), Option::Some(boxed_array_2));
130 }
131
132 #[test]
133 fn test_trie_persistance_simple() {
134 let t = Trie::empty().insert("aab").insert("adc");
135 assert!(t.search("aab"));
136 assert!(t.search("adc"));
137 }
138
139 #[test]
140 fn test_trie_persistance() {
141 let vs = vec!["aab", "adc", "acd", "dca"];
142 let snapshots: Vec<_> = vs
143 .iter()
144 .scan(Trie::empty(), |tree, value| {
145 *tree = tree.insert(value);
146 Option::Some(tree.clone())
147 })
148 .collect();
149 for (index, tree) in snapshots.iter().enumerate() {
150 let found = vs
151 .iter()
152 .map(|s| tree.search(s))
153 .filter(|found| *found == true)
154 .count();
155 assert_eq!(found, index + 1);
156 }
157 }
158
159 #[test]
160 fn test_search_present() {
161 let v = vec![1, 5, 9];
162 let not_v = vec![1, 15, 9];
163 let t = Trie::empty().insert(&v);
164 assert!(t.search(v));
165 assert!(!t.search(not_v));
166 }
167
168 #[test]
169 fn test_search_absent() {
170 let s = "test";
171 let not_s = "tett";
172 let t = Trie::empty().insert(s);
173 assert!(t.search(s));
174 assert!(!t.search(not_s));
175 }
176
177 #[test]
178 fn test_trie_deletion() {
179 let t = Trie::empty().insert("aab").delete("aab");
180 assert!(t.is_some());
181 assert_eq!(t.unwrap().search("aab"), false);
182 let t2 = Trie::empty();
183 assert!(t2.delete("a").is_none());
184 }
185
186 #[test]
187 fn test_insert_empty_string() {
188 let t = Trie::empty().insert("");
189 assert!(t.search(""));
190 }
191
192 #[test]
193 fn test_multiple_values_for_same_key() {
194 let t = Trie::empty_store()
195 .insert_store("key", 1)
196 .insert_store("key", 2);
197 let values = t.get_store("key").unwrap();
198 assert!(values.contains(&&1) && values.contains(&&2));
199 }
200
201 #[test]
202 fn test_delete_internal_node() {
203 let t = Trie::empty()
204 .insert("abc")
205 .insert("ab")
206 .delete("ab")
207 .unwrap();
208 assert!(!t.search("ab"));
209 assert!(t.search("abc"));
210 }
211
212 #[test]
213 fn test_persistence_after_delete() {
214 let t1 = Trie::empty().insert("key");
215 let t2 = t1.delete("key").unwrap_or_else(|| t1.clone());
216 assert!(t1.search("key"));
217 assert!(!t2.search("key"));
218 }
219
220 #[test]
221 fn test_search_nonexistent_key() {
222 let t = Trie::empty().insert("key");
223 assert!(!t.search("not_key"));
224 }
225
226 #[test]
227 fn test_delete_nonexistent_key() {
228 let t = Trie::empty().insert("key");
229 assert!(t.delete("not_key").is_none());
230 }
231
232 #[test]
233 fn test_readme() {
234 let mut trie = Trie::empty().insert("apple").insert("app").insert("banana");
236
237 let snapshot = trie.clone();
239
240 trie = trie.insert("grape").insert("banana-split");
242
243 assert_eq!(trie.search("grape"), true);
245
246 trie = snapshot;
248
249 assert_eq!(trie.search("grape"), false);
251 }
252}