1use std::borrow::Cow;
12use std::collections::BTreeMap;
13use std::fmt::Debug;
14
15use slotmap::{DenseSlotMap, Key};
16use snafu::prelude::*;
17
18#[derive(Clone, Debug, Snafu)]
20#[snafu(visibility(pub))]
21pub enum Error {
22 ValueAlreadyExists,
24 InvalidKey,
26 ValueDoesNotExist,
28}
29
30pub trait Interner<K: Copy + Debug, V: Clone + Debug> {
34 fn intern(&mut self, value: Cow<'_, V>) -> K;
36
37 fn try_intern(&mut self, value: Cow<'_, V>) -> Result<K, Error>;
39
40 fn intern_owned(&mut self, value: V) -> K {
42 self.intern(Cow::Owned(value))
43 }
44
45 fn intern_borrowed(&mut self, value: &V) -> K {
47 self.intern(Cow::Borrowed(value))
48 }
49
50 fn remove_key(&mut self, key: K) -> Option<V>;
52
53 fn try_remove_key(&mut self, key: K) -> Result<V, Error> {
55 match self.remove_key(key) {
56 Some(value) => Ok(value),
57 None => InvalidKeySnafu.fail(),
58 }
59 }
60
61 fn try_update(&mut self, key: K, value: Cow<'_, V>) -> Result<V, Error>;
64
65 fn remove_value(&mut self, value: &V) -> Option<K>;
67
68 fn try_remove_value(&mut self, value: &V) -> Result<K, Error> {
70 self.remove_value(value).context(ValueDoesNotExistSnafu)
71 }
72
73 fn clear(&mut self);
75
76 fn len(&self) -> usize;
78
79 fn is_empty(&self) -> bool;
81
82 fn contains_key(&self, key: K) -> bool;
84
85 fn contains_value(&self, value: &V) -> bool;
87
88 fn get_key(&self, value: &V) -> Option<K>;
90
91 fn try_get_key(&self, value: &V) -> Result<K, Error> {
93 self.get_key(value).context(ValueDoesNotExistSnafu)
94 }
95
96 fn get_value(&self, key: K) -> Option<&V>;
98
99 fn try_get_value(&self, key: K) -> Result<&V, Error> {
101 self.get_value(key).context(InvalidKeySnafu)
102 }
103
104 fn keys(&self) -> impl Iterator<Item = K>;
106
107 fn values<'a>(&'a self) -> impl Iterator<Item = &'a V>
109 where
110 V: 'a;
111
112 fn items<'a>(&'a self) -> impl Iterator<Item = (K, &'a V)>
114 where
115 V: 'a;
116}
117
118#[derive(Clone, Debug, bon::Builder)]
120#[cfg_attr(
121 feature = "serde",
122 derive(serde::Serialize, serde::Deserialize),
123 serde(default, rename_all = "camelCase")
124)]
125#[cfg_attr(feature = "reactive", derive(reactive_stores::Store))]
126pub struct DenseSlottedBTreeInterner<K, V>
127where
128 K: Key + Debug,
129 V: Clone + Debug + Ord,
130{
131 values_by_key: DenseSlotMap<K, V>,
133
134 keys_by_value: BTreeMap<V, K>,
136}
137
138impl<K, V> Default for DenseSlottedBTreeInterner<K, V>
139where
140 K: Key + Debug,
141 V: Clone + Debug + Ord,
142{
143 fn default() -> Self {
144 Self {
145 values_by_key: Default::default(),
146 keys_by_value: Default::default(),
147 }
148 }
149}
150
151impl<K, V> DenseSlottedBTreeInterner<K, V>
152where
153 K: Key + Debug,
154 V: Clone + Debug + Ord,
155{
156 pub fn new() -> Self {
158 Self::default()
159 }
160}
161
162impl<K, V> Interner<K, V> for DenseSlottedBTreeInterner<K, V>
163where
164 K: Key + Debug,
165 V: Clone + Debug + Ord,
166{
167 fn intern(&mut self, value: Cow<'_, V>) -> K {
168 if let Some(key) = self.keys_by_value.get(&value) {
169 *key
170 } else {
171 let value = value.into_owned();
172 let key = self.values_by_key.insert(value.clone());
173 self.keys_by_value.insert(value, key);
174 key
175 }
176 }
177
178 fn try_intern(&mut self, value: Cow<'_, V>) -> Result<K, Error> {
179 if self.contains_value(&value) {
180 ValueAlreadyExistsSnafu.fail()
181 } else {
182 let value = value.into_owned();
183 let key = self.values_by_key.insert(value.clone());
184 self.keys_by_value.insert(value, key);
185 Ok(key)
186 }
187 }
188
189 fn try_update(&mut self, key: K, value: Cow<'_, V>) -> Result<V, Error> {
190 if self.contains_value(&value) {
191 ValueAlreadyExistsSnafu.fail()
192 } else {
193 let value = value.into_owned();
194 let old = self
195 .values_by_key
196 .get_mut(key)
197 .map(|v| std::mem::replace(v, value.clone()))
198 .context(InvalidKeySnafu)?;
199 self.keys_by_value.remove(&old);
200 self.keys_by_value.insert(value, key);
201 Ok(old)
202 }
203 }
204
205 fn remove_key(&mut self, key: K) -> Option<V> {
206 let value = self.values_by_key.remove(key);
207 if let Some(value) = value.as_ref() {
208 self.keys_by_value.remove(value);
209 }
210 value
211 }
212
213 fn remove_value(&mut self, value: &V) -> Option<K> {
214 let key = self.keys_by_value.remove(value);
215 if let Some(key) = key {
216 self.values_by_key.remove(key);
217 }
218 key
219 }
220
221 fn clear(&mut self) {
222 self.keys_by_value.clear();
223 self.values_by_key.clear();
224 }
225
226 fn len(&self) -> usize {
227 self.keys_by_value.len()
228 }
229
230 fn is_empty(&self) -> bool {
231 self.keys_by_value.is_empty()
232 }
233
234 fn contains_key(&self, key: K) -> bool {
235 self.values_by_key.contains_key(key)
236 }
237
238 fn contains_value(&self, value: &V) -> bool {
239 self.keys_by_value.contains_key(value)
240 }
241
242 fn get_key(&self, value: &V) -> Option<K> {
243 self.keys_by_value.get(value).copied()
244 }
245
246 fn get_value(&self, key: K) -> Option<&V> {
247 self.values_by_key.get(key)
248 }
249
250 fn keys(&self) -> impl Iterator<Item = K> {
251 self.values_by_key.keys()
252 }
253
254 fn values<'a>(&'a self) -> impl Iterator<Item = &'a V>
255 where
256 V: 'a,
257 {
258 self.keys_by_value.keys()
259 }
260
261 fn items<'a>(&'a self) -> impl Iterator<Item = (K, &'a V)>
262 where
263 V: 'a,
264 {
265 self.keys_by_value.iter().map(|(v, &k)| (k, v))
266 }
267}
268
269#[cfg(test)]
270mod tests {
271 #[allow(unused_imports)]
272 use pretty_assertions::{assert_eq, assert_ne, assert_str_eq};
273 use slotmap::DefaultKey;
274
275 #[allow(unused_imports)]
276 use super::*;
277
278 #[test]
279 fn test_dense_slotted_btree_interner() {
280 let mut interner = DenseSlottedBTreeInterner::<DefaultKey, String>::default();
281
282 let key1 = interner.intern_owned("foo".to_string());
284 let key2 = interner.intern_owned("bar".to_string());
285 assert_ne!(key1, key2);
286
287 let key3 = interner.intern_borrowed(&"foo".to_string());
289 let key4 = interner.intern_borrowed(&"bar".to_string());
290 assert_eq!(key3, key1);
291 assert_eq!(key4, key2);
292
293 assert_eq!(interner.len(), 2);
295
296 assert_eq!(interner.values().collect::<Vec<_>>(), vec!["bar", "foo"]);
298 }
299
300 #[test]
301 fn test_dense_slotted_btree_interner_try_intern() {
302 let mut interner = DenseSlottedBTreeInterner::<DefaultKey, String>::default();
303
304 let key1 = interner.try_intern(Cow::Owned("foo".to_string())).unwrap();
306 assert_eq!(interner.len(), 1);
307
308 let result = interner.try_intern(Cow::Owned("foo".to_string()));
310 assert!(matches!(result, Err(Error::ValueAlreadyExists)));
311 assert_eq!(interner.len(), 1);
312
313 let key2 = interner
315 .try_intern(Cow::Borrowed(&"bar".to_string()))
316 .unwrap();
317 assert_eq!(interner.len(), 2);
318 assert_ne!(key1, key2);
319 }
320
321 #[test]
322 fn test_dense_slotted_btree_interner_try_update() {
323 let mut interner = DenseSlottedBTreeInterner::<DefaultKey, String>::default();
324
325 let result = interner.try_update(DefaultKey::null(), Cow::Owned("foo".to_string()));
327 assert!(matches!(result, Err(Error::InvalidKey)));
328
329 let key1 = interner.intern_owned("foo".to_string());
331 let old_value = interner
332 .try_update(key1, Cow::Owned("bar".to_string()))
333 .unwrap();
334 assert_eq!(old_value, "foo");
335 assert_eq!(interner.get_value(key1), Some(&"bar".to_string()));
336
337 let key2 = interner.intern_owned("baz".to_string());
339 let result = interner.try_update(key2, Cow::Owned("baz".to_string()));
340 assert!(matches!(result, Err(Error::ValueAlreadyExists)));
341 assert_eq!(interner.get_value(key2), Some(&"baz".to_string()));
342 }
343
344 #[test]
345 fn test_dense_slotted_btree_interner_remove() {
346 let mut interner = DenseSlottedBTreeInterner::<DefaultKey, String>::default();
347
348 assert_eq!(interner.remove_key(DefaultKey::null()), None);
350
351 let key1 = interner.intern_owned("foo".to_string());
353 assert_eq!(interner.remove_key(key1), Some("foo".to_string()));
354 assert_eq!(interner.len(), 0);
355
356 assert_eq!(interner.remove_value(&"bar".to_string()), None);
358
359 let key2 = interner.intern_owned("bar".to_string());
361 assert_eq!(interner.remove_value(&"bar".to_string()), Some(key2));
362 assert_eq!(interner.len(), 0);
363 }
364
365 #[test]
366 fn test_dense_slotted_btree_interner_try_remove() {
367 let mut interner = DenseSlottedBTreeInterner::<DefaultKey, String>::default();
368
369 let result = interner.try_remove_key(DefaultKey::null());
371 assert!(matches!(result, Err(Error::InvalidKey)));
372
373 let key1 = interner.intern_owned("foo".to_string());
375 assert_eq!(interner.try_remove_key(key1).unwrap(), "foo".to_string());
376 assert_eq!(interner.len(), 0);
377
378 let result = interner.try_remove_value(&"bar".to_string());
380 assert!(matches!(result, Err(Error::ValueDoesNotExist)));
381
382 let key2 = interner.intern_owned("bar".to_string());
384 assert_eq!(interner.try_remove_value(&"bar".to_string()).unwrap(), key2);
385 assert_eq!(interner.len(), 0);
386 }
387
388 #[test]
389 fn test_dense_slotted_btree_interner_try_get() {
390 let mut interner = DenseSlottedBTreeInterner::<DefaultKey, String>::default();
391
392 let result = interner.try_get_key(&"foo".to_string());
394 assert!(matches!(result, Err(Error::ValueDoesNotExist)));
395
396 let key1 = interner.intern_owned("foo".to_string());
398 assert_eq!(interner.try_get_key(&"foo".to_string()).unwrap(), key1);
399
400 let result = interner.try_get_value(DefaultKey::null());
402 assert!(matches!(result, Err(Error::InvalidKey)));
403
404 assert_eq!(interner.try_get_value(key1).unwrap(), &"foo".to_string());
406 }
407
408 #[test]
409 fn test_dense_slotted_btree_interner_clear() {
410 let mut interner = DenseSlottedBTreeInterner::<DefaultKey, String>::default();
411
412 interner.clear();
414 assert_eq!(interner.len(), 0);
415
416 interner.intern_owned("foo".to_string());
418 interner.intern_owned("bar".to_string());
419 assert_eq!(interner.len(), 2);
420 interner.clear();
421 assert_eq!(interner.len(), 0);
422 }
423}