reifydb_catalog/materialized/
dictionary.rs1use reifydb_core::{
5 CommitVersion,
6 interface::{DictionaryDef, DictionaryId, NamespaceId},
7};
8
9use crate::materialized::{MaterializedCatalog, MultiVersionDictionaryDef};
10
11impl MaterializedCatalog {
12 pub fn find_dictionary(&self, dictionary: DictionaryId, version: CommitVersion) -> Option<DictionaryDef> {
14 self.dictionaries.get(&dictionary).and_then(|entry| {
15 let multi = entry.value();
16 multi.get(version)
17 })
18 }
19
20 pub fn find_dictionary_by_name(
22 &self,
23 namespace: NamespaceId,
24 name: &str,
25 version: CommitVersion,
26 ) -> Option<DictionaryDef> {
27 self.dictionaries_by_name.get(&(namespace, name.to_string())).and_then(|entry| {
28 let dictionary_id = *entry.value();
29 self.find_dictionary(dictionary_id, version)
30 })
31 }
32
33 pub fn set_dictionary(&self, id: DictionaryId, version: CommitVersion, dictionary: Option<DictionaryDef>) {
34 if let Some(entry) = self.dictionaries.get(&id) {
35 if let Some(pre) = entry.value().get_latest() {
36 self.dictionaries_by_name.remove(&(pre.namespace, pre.name.clone()));
38 }
39 }
40
41 let multi = self.dictionaries.get_or_insert_with(id, MultiVersionDictionaryDef::new);
42 if let Some(new) = dictionary {
43 self.dictionaries_by_name.insert((new.namespace, new.name.clone()), id);
44 multi.value().insert(version, new);
45 } else {
46 multi.value().remove(version);
47 }
48 }
49}
50
51#[cfg(test)]
52mod tests {
53 use reifydb_type::Type;
54
55 use super::*;
56
57 fn create_test_dictionary(id: DictionaryId, namespace: NamespaceId, name: &str) -> DictionaryDef {
58 DictionaryDef {
59 id,
60 namespace,
61 name: name.to_string(),
62 value_type: Type::Utf8,
63 id_type: Type::Uint4,
64 }
65 }
66
67 #[test]
68 fn test_set_and_find_dictionary() {
69 let catalog = MaterializedCatalog::new();
70 let dict_id = DictionaryId(1);
71 let namespace_id = NamespaceId(1);
72 let dict = create_test_dictionary(dict_id, namespace_id, "test_dict");
73
74 catalog.set_dictionary(dict_id, CommitVersion(1), Some(dict.clone()));
76
77 let found = catalog.find_dictionary(dict_id, CommitVersion(1));
79 assert_eq!(found, Some(dict.clone()));
80
81 let found = catalog.find_dictionary(dict_id, CommitVersion(5));
83 assert_eq!(found, Some(dict));
84
85 let found = catalog.find_dictionary(dict_id, CommitVersion(0));
87 assert_eq!(found, None);
88 }
89
90 #[test]
91 fn test_find_dictionary_by_name() {
92 let catalog = MaterializedCatalog::new();
93 let dict_id = DictionaryId(1);
94 let namespace_id = NamespaceId(1);
95 let dict = create_test_dictionary(dict_id, namespace_id, "named_dict");
96
97 catalog.set_dictionary(dict_id, CommitVersion(1), Some(dict.clone()));
99
100 let found = catalog.find_dictionary_by_name(namespace_id, "named_dict", CommitVersion(1));
102 assert_eq!(found, Some(dict));
103
104 let found = catalog.find_dictionary_by_name(namespace_id, "wrong_name", CommitVersion(1));
106 assert_eq!(found, None);
107
108 let found = catalog.find_dictionary_by_name(NamespaceId(2), "named_dict", CommitVersion(1));
110 assert_eq!(found, None);
111 }
112
113 #[test]
114 fn test_dictionary_rename() {
115 let catalog = MaterializedCatalog::new();
116 let dict_id = DictionaryId(1);
117 let namespace_id = NamespaceId(1);
118
119 let dict_v1 = create_test_dictionary(dict_id, namespace_id, "old_name");
121 catalog.set_dictionary(dict_id, CommitVersion(1), Some(dict_v1.clone()));
122
123 assert!(catalog.find_dictionary_by_name(namespace_id, "old_name", CommitVersion(1)).is_some());
125 assert!(catalog.find_dictionary_by_name(namespace_id, "new_name", CommitVersion(1)).is_none());
126
127 let mut dict_v2 = dict_v1.clone();
129 dict_v2.name = "new_name".to_string();
130 catalog.set_dictionary(dict_id, CommitVersion(2), Some(dict_v2.clone()));
131
132 assert!(catalog.find_dictionary_by_name(namespace_id, "old_name", CommitVersion(2)).is_none());
134
135 assert_eq!(
137 catalog.find_dictionary_by_name(namespace_id, "new_name", CommitVersion(2)),
138 Some(dict_v2.clone())
139 );
140
141 assert_eq!(catalog.find_dictionary(dict_id, CommitVersion(1)), Some(dict_v1));
143
144 assert_eq!(catalog.find_dictionary(dict_id, CommitVersion(2)), Some(dict_v2));
146 }
147
148 #[test]
149 fn test_dictionary_move_between_namespaces() {
150 let catalog = MaterializedCatalog::new();
151 let dict_id = DictionaryId(1);
152 let namespace1 = NamespaceId(1);
153 let namespace2 = NamespaceId(2);
154
155 let dict_v1 = create_test_dictionary(dict_id, namespace1, "movable_dict");
157 catalog.set_dictionary(dict_id, CommitVersion(1), Some(dict_v1.clone()));
158
159 assert!(catalog.find_dictionary_by_name(namespace1, "movable_dict", CommitVersion(1)).is_some());
161 assert!(catalog.find_dictionary_by_name(namespace2, "movable_dict", CommitVersion(1)).is_none());
162
163 let mut dict_v2 = dict_v1.clone();
165 dict_v2.namespace = namespace2;
166 catalog.set_dictionary(dict_id, CommitVersion(2), Some(dict_v2.clone()));
167
168 assert!(catalog.find_dictionary_by_name(namespace1, "movable_dict", CommitVersion(2)).is_none());
170
171 assert!(catalog.find_dictionary_by_name(namespace2, "movable_dict", CommitVersion(2)).is_some());
173 }
174
175 #[test]
176 fn test_dictionary_deletion() {
177 let catalog = MaterializedCatalog::new();
178 let dict_id = DictionaryId(1);
179 let namespace_id = NamespaceId(1);
180
181 let dict = create_test_dictionary(dict_id, namespace_id, "deletable_dict");
183 catalog.set_dictionary(dict_id, CommitVersion(1), Some(dict.clone()));
184
185 assert_eq!(catalog.find_dictionary(dict_id, CommitVersion(1)), Some(dict.clone()));
187 assert!(catalog.find_dictionary_by_name(namespace_id, "deletable_dict", CommitVersion(1)).is_some());
188
189 catalog.set_dictionary(dict_id, CommitVersion(2), None);
191
192 assert_eq!(catalog.find_dictionary(dict_id, CommitVersion(2)), None);
194 assert!(catalog.find_dictionary_by_name(namespace_id, "deletable_dict", CommitVersion(2)).is_none());
195
196 assert_eq!(catalog.find_dictionary(dict_id, CommitVersion(1)), Some(dict));
198 }
199
200 #[test]
201 fn test_multiple_dictionaries_in_namespace() {
202 let catalog = MaterializedCatalog::new();
203 let namespace_id = NamespaceId(1);
204
205 let dict1 = create_test_dictionary(DictionaryId(1), namespace_id, "dict1");
206 let dict2 = create_test_dictionary(DictionaryId(2), namespace_id, "dict2");
207 let dict3 = create_test_dictionary(DictionaryId(3), namespace_id, "dict3");
208
209 catalog.set_dictionary(DictionaryId(1), CommitVersion(1), Some(dict1.clone()));
211 catalog.set_dictionary(DictionaryId(2), CommitVersion(1), Some(dict2.clone()));
212 catalog.set_dictionary(DictionaryId(3), CommitVersion(1), Some(dict3.clone()));
213
214 assert_eq!(catalog.find_dictionary_by_name(namespace_id, "dict1", CommitVersion(1)), Some(dict1));
216 assert_eq!(catalog.find_dictionary_by_name(namespace_id, "dict2", CommitVersion(1)), Some(dict2));
217 assert_eq!(catalog.find_dictionary_by_name(namespace_id, "dict3", CommitVersion(1)), Some(dict3));
218 }
219
220 #[test]
221 fn test_dictionary_versioning() {
222 let catalog = MaterializedCatalog::new();
223 let dict_id = DictionaryId(1);
224 let namespace_id = NamespaceId(1);
225
226 let dict_v1 = create_test_dictionary(dict_id, namespace_id, "dict_v1");
228 let mut dict_v2 = dict_v1.clone();
229 dict_v2.name = "dict_v2".to_string();
230 let mut dict_v3 = dict_v2.clone();
231 dict_v3.name = "dict_v3".to_string();
232
233 catalog.set_dictionary(dict_id, CommitVersion(10), Some(dict_v1.clone()));
235 catalog.set_dictionary(dict_id, CommitVersion(20), Some(dict_v2.clone()));
236 catalog.set_dictionary(dict_id, CommitVersion(30), Some(dict_v3.clone()));
237
238 assert_eq!(catalog.find_dictionary(dict_id, CommitVersion(5)), None);
240 assert_eq!(catalog.find_dictionary(dict_id, CommitVersion(10)), Some(dict_v1.clone()));
241 assert_eq!(catalog.find_dictionary(dict_id, CommitVersion(15)), Some(dict_v1));
242 assert_eq!(catalog.find_dictionary(dict_id, CommitVersion(20)), Some(dict_v2.clone()));
243 assert_eq!(catalog.find_dictionary(dict_id, CommitVersion(25)), Some(dict_v2));
244 assert_eq!(catalog.find_dictionary(dict_id, CommitVersion(30)), Some(dict_v3.clone()));
245 assert_eq!(catalog.find_dictionary(dict_id, CommitVersion(100)), Some(dict_v3));
246 }
247}