1use bytemuck::cast_slice;
4use patricia_tree::map::PatriciaMap;
5
6pub type TrieKeyElement = u16;
7
8#[derive(Debug, Clone)]
9pub struct Trie<T> {
10 inner: patricia_tree::map::PatriciaMap<T>,
11}
12
13#[derive(Debug, Copy, Clone, PartialEq, Eq)]
14pub enum GetOrDescendentExistsResult<T> {
15 NotInTrie,
16 InTrie,
17 HasValue(T),
18}
19
20use GetOrDescendentExistsResult::*;
21
22impl<T> Default for Trie<T> {
23 fn default() -> Self {
24 Self::new()
25 }
26}
27
28fn key_len(k: impl AsRef<[u16]>) -> usize {
29 debug_assert!(std::mem::size_of::<TrieKeyElement>() == 2 * std::mem::size_of::<u8>());
30 k.as_ref().len() * 2
31}
32
33impl<T> Trie<T> {
34 pub fn new() -> Self {
35 Self {
36 inner: PatriciaMap::new(),
37 }
38 }
39
40 pub fn ancestor_exists(&self, key: impl AsRef<[u16]>) -> bool {
41 self.inner
42 .get_longest_common_prefix(cast_slice(key.as_ref()))
43 .is_some()
44 }
45
46 pub fn descendant_exists(&self, key: impl AsRef<[u16]>) -> bool {
47 self.inner
49 .longest_common_prefix_len(cast_slice(key.as_ref()))
50 == key_len(key)
51 }
52
53 pub fn insert(&mut self, key: impl AsRef<[u16]>, val: T) {
54 self.inner.insert(cast_slice(key.as_ref()), val);
55 }
56
57 pub fn get_or_descendant_exists(&self, key: impl AsRef<[u16]>) -> GetOrDescendentExistsResult<T>
58 where
59 T: Clone,
60 {
61 let mut descendants = self.inner.iter_prefix(cast_slice(key.as_ref()));
62 match descendants.next() {
63 None => NotInTrie,
64 Some(descendant) => {
65 if descendant.0.len() == key_len(key.as_ref()) {
66 HasValue(descendant.1.clone())
67 } else {
68 InTrie
69 }
70 }
71 }
72 }
73
74 pub fn is_empty(&self) -> bool {
75 self.inner.is_empty()
76 }
77}