1#![no_std]
8
9use core::mem;
11use core::ops::{Deref, DerefMut};
12
13use canonical::{Canon, CanonError, Id};
14use canonical_derive::Canon;
15
16use microkelvin::{
17    Annotation, Branch, BranchMut, Child, ChildMut, Compound, GenericChild,
18    GenericTree, Link, Step, Walker,
19};
20
21#[derive(Clone, Debug, Canon)]
22pub struct KvPair<K, V> {
23    pub key: K,
24    pub val: V,
25}
26
27#[derive(Clone, Canon, Debug)]
28enum Bucket<K, V, A>
29where
30    A: Annotation<KvPair<K, V>>,
31{
32    Empty,
33    Leaf(KvPair<K, V>),
34    Node(Link<Hamt<K, V, A>, A>),
35}
36
37#[derive(Clone, Canon, Debug)]
38pub struct Hamt<K, V, A>([Bucket<K, V, A>; 4])
39where
40    A: Annotation<KvPair<K, V>>;
41
42pub type Map<K, V> = Hamt<K, V, ()>;
43
44impl<K, V, A> Compound<A> for Hamt<K, V, A>
45where
46    A: Annotation<KvPair<K, V>>,
47    K: Canon,
48    V: Canon,
49    A: Canon,
50{
51    type Leaf = KvPair<K, V>;
52
53    fn child(&self, ofs: usize) -> Child<Self, A> {
54        match self.0.get(ofs) {
55            Some(Bucket::Empty) => Child::Empty,
56            Some(Bucket::Leaf(ref kv)) => Child::Leaf(kv),
57            Some(Bucket::Node(ref nd)) => Child::Node(nd),
58            None => Child::EndOfNode,
59        }
60    }
61
62    fn child_mut(&mut self, ofs: usize) -> ChildMut<Self, A> {
63        match self.0.get_mut(ofs) {
64            Some(Bucket::Empty) => ChildMut::Empty,
65            Some(Bucket::Leaf(ref mut kv)) => ChildMut::Leaf(kv),
66            Some(Bucket::Node(ref mut nd)) => ChildMut::Node(nd),
67            None => ChildMut::EndOfNode,
68        }
69    }
70
71    fn from_generic(generic: &GenericTree) -> Result<Self, CanonError> {
72        let mut s = Self::default();
73        for (i, child) in generic.children().iter().enumerate() {
74            match child {
75                GenericChild::Empty => (),
76                GenericChild::Leaf(leaf) => s.0[i] = Bucket::Leaf(leaf.cast()?),
77                GenericChild::Link(id, a) => {
78                    s.0[i] = Bucket::Node(Link::new_persisted(*id, a.cast()?));
79                }
80            }
81        }
82        Ok(s)
83    }
84}
85
86impl<K, V, A> Bucket<K, V, A>
87where
88    A: Annotation<KvPair<K, V>>,
89{
90    fn take(&mut self) -> Self {
91        mem::replace(self, Bucket::Empty)
92    }
93}
94
95impl<K, V, A> Default for Bucket<K, V, A>
96where
97    A: Annotation<KvPair<K, V>>,
98{
99    fn default() -> Self {
100        Bucket::Empty
101    }
102}
103
104impl<K, V, A> Default for Hamt<K, V, A>
105where
106    A: Annotation<KvPair<K, V>>,
107{
108    fn default() -> Self {
109        Hamt(Default::default())
110    }
111}
112
113fn slot<H>(hash: &H, depth: usize) -> usize
114where
115    H: AsRef<[u8]>,
116{
117    (hash.as_ref()[depth] % 4) as usize
119}
120
121struct PathWalker<'a> {
122    hash: &'a [u8; 32],
123    depth: usize,
124}
125
126impl<'a> PathWalker<'a> {
127    fn new(hash: &'a [u8; 32]) -> Self {
128        PathWalker { hash, depth: 0 }
129    }
130}
131
132impl<'a, C, A> Walker<C, A> for PathWalker<'a>
133where
134    C: Compound<A>,
135{
136    fn walk(&mut self, walk: microkelvin::Walk<C, A>) -> microkelvin::Step {
137        let slot = slot(self.hash, self.depth);
138        self.depth += 1;
139        match walk.child(slot) {
140            Child::Leaf(_) => Step::Found(slot),
141            Child::Node(_) => Step::Into(slot),
142            Child::Empty | Child::EndOfNode => Step::Abort,
143        }
144    }
145}
146
147impl<K, V, A> Hamt<K, V, A>
148where
149    K: Eq + Canon,
150    V: Canon,
151    A: Annotation<KvPair<K, V>> + Canon,
152{
153    pub fn new() -> Self {
155        Self::default()
156    }
157
158    pub fn insert(&mut self, key: K, val: V) -> Result<Option<V>, CanonError> {
159        let hash = Id::new(&key).hash();
160        self._insert(key, val, hash, 0)
161    }
162
163    fn _insert(
164        &mut self,
165        key: K,
166        val: V,
167        hash: [u8; 32],
168        depth: usize,
169    ) -> Result<Option<V>, CanonError> {
170        let slot = slot(&hash, depth);
171        let bucket = &mut self.0[slot];
172
173        match bucket.take() {
174            Bucket::Empty => {
175                *bucket = Bucket::Leaf(KvPair { key, val });
176                Ok(None)
177            }
178            Bucket::Leaf(KvPair {
179                key: old_key,
180                val: old_val,
181            }) => {
182                if key == old_key {
183                    *bucket = Bucket::Leaf(KvPair { key, val });
184                    Ok(Some(old_val))
185                } else {
186                    let mut new_node = Hamt::new();
187                    let old_hash = Id::new(&old_key).hash();
188
189                    new_node._insert(key, val, hash, depth + 1)?;
190                    new_node._insert(old_key, old_val, old_hash, depth + 1)?;
191                    *bucket = Bucket::Node(Link::new(new_node));
192                    Ok(None)
193                }
194            }
195            Bucket::Node(mut node) => {
196                let result =
197                    node.inner_mut()?._insert(key, val, hash, depth + 1);
198                *bucket = Bucket::Node(node);
200                result
201            }
202        }
203    }
204
205    fn collapse(&mut self) -> Option<(K, V)> {
207        match &mut self.0 {
208            [leaf @ Bucket::Leaf(..), Bucket::Empty, Bucket::Empty, Bucket::Empty]
209            | [Bucket::Empty, leaf @ Bucket::Leaf(..), Bucket::Empty, Bucket::Empty]
210            | [Bucket::Empty, Bucket::Empty, leaf @ Bucket::Leaf(..), Bucket::Empty]
211            | [Bucket::Empty, Bucket::Empty, Bucket::Empty, leaf @ Bucket::Leaf(..)] => {
212                if let Bucket::Leaf(KvPair { key, val }) =
213                    mem::replace(leaf, Bucket::Empty)
214                {
215                    Some((key, val))
216                } else {
217                    unreachable!("Match above guarantees a `Bucket::Leaf`")
218                }
219            }
220            _ => None,
221        }
222    }
223
224    pub fn remove(&mut self, key: &K) -> Result<Option<V>, CanonError> {
225        let hash = Id::new(key).hash();
226        self._remove(key, hash, 0)
227    }
228
229    fn _remove(
230        &mut self,
231        key: &K,
232        hash: [u8; 32],
233        depth: usize,
234    ) -> Result<Option<V>, CanonError> {
235        let slot = slot(&hash, depth);
236        let bucket = &mut self.0[slot];
237
238        match bucket.take() {
239            Bucket::Empty => Ok(None),
240            Bucket::Leaf(KvPair {
241                key: old_key,
242                val: old_val,
243            }) => {
244                if *key == old_key {
245                    Ok(Some(old_val))
246                } else {
247                    Ok(None)
248                }
249            }
250
251            Bucket::Node(mut link) => {
252                let mut node = link.inner_mut()?;
253                let result = node._remove(key, hash, depth + 1);
254                if let Some((key, val)) = node.collapse() {
256                    *bucket = Bucket::Leaf(KvPair { key, val });
257                } else {
258                    drop(node);
259                    *bucket = Bucket::Node(link);
260                }
261                result
262            }
263        }
264    }
265
266    pub fn get<'a>(
267        &'a self,
268        key: &K,
269    ) -> Result<Option<impl Deref<Target = V> + 'a>, CanonError> {
270        let hash = Id::new(key).hash();
271
272        Ok(Branch::walk(self, PathWalker::new(&hash))?
273            .filter(|branch| &(*branch).key == key)
274            .map(|b| b.map_leaf(|leaf| &leaf.val)))
275    }
276
277    pub fn get_mut<'a>(
278        &'a mut self,
279        key: &K,
280    ) -> Result<Option<impl DerefMut<Target = V> + 'a>, CanonError> {
281        let hash = Id::new(key).hash();
282        Ok(BranchMut::walk(self, PathWalker::new(&hash))?
283            .filter(|branch| &(*branch).key == key)
284            .map(|b| b.map_leaf(|leaf| &mut leaf.val)))
285    }
286}