hamst/
mutable.rs

1use super::hash::{Hash, HashedKey, Hasher};
2use super::immutable::Hamt;
3use super::node::{
4    insert_rec, remove_eq_rec, remove_rec, replace_rec, replace_with_rec, update_rec,
5};
6use std::iter::FromIterator;
7use std::marker::PhantomData;
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub enum InsertError {
11    EntryExists,
12}
13
14#[derive(Debug, Clone, Copy, PartialEq, Eq)]
15pub enum RemoveError {
16    KeyNotFound,
17    ValueNotMatching,
18}
19
20#[derive(Debug, Clone, Copy, PartialEq, Eq)]
21pub enum UpdateError<T> {
22    KeyNotFound,
23    ValueCallbackError(T),
24}
25
26#[derive(Debug, Clone, Copy, PartialEq, Eq)]
27pub enum ReplaceError {
28    KeyNotFound,
29}
30
31/// Mutable HAMT data structure
32///
33/// This is created after a thaw of an immutable HAMT,
34/// and right after the creation, all the node are
35/// still shared with the immutable HAMT.
36///
37/// Once modification happens, then each nodes from
38/// root to leaf will be modified and kept in an
39/// efficient mutable format until freezing.
40pub struct HamtMut<K, V, H> {
41    root: Hamt<K, V, H>,
42}
43
44impl<H, K, V> Clone for HamtMut<K, V, H> {
45    fn clone(&self) -> Self {
46        Self {
47            root: self.root.clone(),
48        }
49    }
50}
51
52impl<'a, H, K, V> From<&'a Hamt<K, V, H>> for HamtMut<K, V, H> {
53    fn from(t: &'a Hamt<K, V, H>) -> Self {
54        HamtMut { root: t.clone() }
55    }
56}
57
58impl<H: Hasher + Default, K: Clone + Eq + Hash, V: Clone> HamtMut<K, V, H> {
59    /// Create a new empty mutable HAMT
60    pub fn new() -> Self {
61        HamtMut { root: Hamt::new() }
62    }
63}
64
65impl<H, K, V> HamtMut<K, V, H> {
66    /// Freeze the mutable HAMT back into an immutable HAMT
67    ///
68    /// This recursively freeze all the mutable nodes
69    pub fn freeze(self) -> Hamt<K, V, H> {
70        self.root
71    }
72}
73
74impl<H: Hasher + Default, K: Clone + Eq + Hash, V: Clone> HamtMut<K, V, H> {
75    /// Insert a new key into the HAMT
76    ///
77    /// If the key already exists, then an InsertError is returned.
78    ///
79    /// To simulaneously manipulate a key, either to insert or update, use 'insert_or_update'
80    pub fn insert(&mut self, k: K, v: V) -> Result<(), InsertError> {
81        let h = HashedKey::compute(self.root.hasher, &k);
82        let newroot = insert_rec(&self.root.root, h, 0, k, v)?;
83        self.root = Hamt {
84            root: newroot,
85            hasher: PhantomData,
86        };
87        Ok(())
88    }
89}
90
91impl<H: Hasher + Default, K: Eq + Hash + Clone, V: PartialEq + Clone> HamtMut<K, V, H> {
92    /// Remove a key from the HAMT, if it also matching the value V
93    ///
94    /// If the key doesn't exist, then RemoveError::KeyNotFound will be returned
95    /// and otherwise if the key exists but the value doesn't match, RemoveError::ValueNotMatching
96    /// will be returned.
97    pub fn remove_match(&mut self, k: &K, v: &V) -> Result<(), RemoveError> {
98        let h = HashedKey::compute(self.root.hasher, &k);
99        let newroot = remove_eq_rec(&self.root.root, h, 0, k, v)?;
100        match newroot {
101            None => self.root = Hamt::new(),
102            Some(r) => {
103                self.root = Hamt {
104                    root: r,
105                    hasher: PhantomData,
106                }
107            }
108        };
109        Ok(())
110    }
111}
112
113impl<H: Hasher + Default, K: Clone + Eq + Hash, V: Clone> HamtMut<K, V, H> {
114    /// Remove a key from the HAMT
115    ///
116    /// If the key doesn't exist, then RemoveError::KeyNotFound will be returned
117    pub fn remove(&mut self, k: &K) -> Result<(), RemoveError> {
118        let h = HashedKey::compute(self.root.hasher, &k);
119        let newroot = remove_rec(&self.root.root, h, 0, k)?;
120        match newroot {
121            None => self.root = Hamt::new(),
122            Some(r) => {
123                self.root = Hamt {
124                    root: r,
125                    hasher: PhantomData,
126                }
127            }
128        }
129        Ok(())
130    }
131}
132
133impl<H: Hasher + Default, K: Eq + Hash + Clone, V: Clone> HamtMut<K, V, H> {
134    /// Replace the element at the key by the v and return the new tree
135    /// and the old value.
136    pub fn replace(&mut self, k: &K, v: V) -> Result<V, ReplaceError> {
137        let h = HashedKey::compute(self.root.hasher, &k);
138        let (newroot, oldv) = replace_rec(&self.root.root, h, 0, k, v)?;
139        self.root = Hamt {
140            root: newroot,
141            hasher: PhantomData,
142        };
143        Ok(oldv)
144    }
145
146    /// Replace the element at the key by the v and return the new tree
147    /// and the old value.
148    pub fn replace_with<F>(&mut self, k: &K, f: F) -> Result<(), ReplaceError>
149    where
150        F: FnOnce(&V) -> V,
151    {
152        let h = HashedKey::compute(self.root.hasher, &k);
153        let newroot = replace_with_rec(&self.root.root, h, 0, k, f)?;
154        self.root = Hamt {
155            root: newroot,
156            hasher: PhantomData,
157        };
158        Ok(())
159    }
160}
161
162impl<H: Hasher + Default, K: Eq + Hash + Clone, V: Clone> HamtMut<K, V, H> {
163    /// Update the element at the key K.
164    ///
165    /// If the closure F in parameter returns None, then the key is deleted.
166    ///
167    /// If the key is not present then UpdateError::KeyNotFound is returned
168    pub fn update<F, U>(&mut self, k: &K, f: F) -> Result<(), UpdateError<U>>
169    where
170        F: FnOnce(&V) -> Result<Option<V>, U>,
171    {
172        let h = HashedKey::compute(self.root.hasher, &k);
173        let newroot = update_rec(&self.root.root, h, 0, k, f)?;
174        match newroot {
175            None => self.root = Hamt::new(),
176            Some(r) => {
177                self.root = Hamt {
178                    root: r,
179                    hasher: PhantomData,
180                }
181            }
182        };
183        Ok(())
184    }
185
186    /// Update or insert the element at the key K
187    ///
188    /// If the element is not present, then V is added, otherwise the closure F is apply
189    /// to the found element. If the closure returns None, then the key is deleted
190    pub fn insert_or_update<F, E>(&mut self, k: K, v: V, f: F) -> Result<(), E>
191    where
192        F: FnOnce(&V) -> Result<Option<V>, E>,
193        V: Clone,
194    {
195        match self.update(&k, f) {
196            Ok(new_self) => Ok(new_self),
197            Err(UpdateError::KeyNotFound) =>
198            // unwrap is safe: only error than can be raised is an EntryExist which is fundamentally impossible in this error case handling
199            {
200                Ok(self.insert(k, v).unwrap())
201            }
202            Err(UpdateError::ValueCallbackError(x)) => Err(x),
203        }
204    }
205
206    /// Update or insert the element at the key K
207    ///
208    /// If the element is not present, then V is added, otherwise the closure F is apply
209    /// to the found element. If the closure returns None, then the key is deleted.
210    ///
211    /// This is similar to 'insert_or_update' except the closure shouldn't be failing
212    pub fn insert_or_update_simple<F>(&mut self, k: K, v: V, f: F) -> ()
213    where
214        F: for<'a> FnOnce(&'a V) -> Option<V>,
215        V: Clone,
216    {
217        match self.update(&k, |x| Ok(f(x))) {
218            Ok(new_self) => new_self,
219            Err(UpdateError::ValueCallbackError(())) => unreachable!(), // callback always wrapped in Ok
220            Err(UpdateError::KeyNotFound) => {
221                // unwrap is safe: only error than can be raised is an EntryExist which is fundamentally impossible in this error case handling
222                self.insert(k, v).unwrap()
223            }
224        }
225    }
226}
227
228impl<H: Default + Hasher, K: Eq + Hash + Clone, V: Clone> FromIterator<(K, V)>
229    for HamtMut<K, V, H>
230{
231    fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {
232        let mut h = HamtMut::new();
233        for (k, v) in iter {
234            match h.insert(k, v) {
235                Err(_) => {}
236                Ok(()) => (),
237            }
238        }
239        h
240    }
241}