1use std::fmt;
4use std::hash::Hash;
5use std::ops;
6
7use safe_bump::Idx;
8
9use crate::ChampCheckpoint;
10use crate::adhash;
11use crate::arena::ChampArena;
12use crate::iter::Iter;
13use crate::node::{self, Entry, Node};
14use crate::ops::get::get_recursive;
15use crate::ops::insert::insert_recursive;
16use crate::ops::remove::{RemoveOutcome, remove_recursive};
17use crate::store::ChampStore;
18
19pub struct ChampMap<K, V> {
24 store: ChampArena<K, V>,
25 root: Option<safe_bump::Idx<crate::node::Node<K, V>>>,
26 size: usize,
27 adhash: u64,
28}
29
30impl<K, V> ChampMap<K, V> {
35 #[must_use]
37 pub const fn new() -> Self {
38 Self {
39 store: ChampArena::new(),
40 root: None,
41 size: 0,
42 adhash: 0,
43 }
44 }
45
46 #[must_use]
48 pub const fn len(&self) -> usize {
49 self.size
50 }
51
52 #[must_use]
54 pub const fn is_empty(&self) -> bool {
55 self.size == 0
56 }
57
58 #[must_use]
63 pub const fn adhash(&self) -> u64 {
64 self.adhash
65 }
66
67 #[must_use]
69 pub fn checkpoint(&self) -> ChampCheckpoint<K, V> {
70 ChampCheckpoint {
71 store: self.store.checkpoint(),
72 root: self.root,
73 size: self.size,
74 adhash: self.adhash,
75 }
76 }
77
78 #[must_use]
83 pub fn arena_len(&self) -> (usize, usize, usize) {
84 self.store.arena_len()
85 }
86
87 pub fn rollback(&mut self, cp: ChampCheckpoint<K, V>) {
91 self.store.rollback(cp.store);
92 self.root = cp.root;
93 self.size = cp.size;
94 self.adhash = cp.adhash;
95 }
96}
97
98impl<K: Hash + Eq, V> ChampMap<K, V> {
103 #[must_use]
105 pub fn get(&self, key: &K) -> Option<&V> {
106 let root = self.root?;
107 get_recursive(&self.store, root, adhash::hash_one(key), key, 0)
108 }
109
110 #[must_use]
112 pub fn contains_key(&self, key: &K) -> bool {
113 self.get(key).is_some()
114 }
115}
116
117impl<K: Hash + Eq + Clone, V: Hash + Clone> ChampMap<K, V> {
122 pub fn insert(&mut self, key: K, value: V) -> Option<V> {
131 let hash = adhash::hash_one(&key);
132 let entry = Entry { hash, key, value };
133
134 if let Some(root) = self.root {
135 let outcome = insert_recursive(&mut self.store, root, entry, 0);
136 self.root = Some(outcome.node);
137 self.adhash = self.adhash.wrapping_add(outcome.adhash_delta);
138 if outcome.old_value.is_none() {
139 self.size += 1;
140 }
141 outcome.old_value
142 } else {
143 let value_hash = adhash::hash_one(&entry.value);
144 let contribution = adhash::entry_adhash(hash, value_hash);
145 let frag = node::fragment(hash, 0);
146 let bit = node::mask(frag);
147 let data_start = self
148 .store
149 .alloc_entries(std::iter::once(entry))
150 .expect("single entry");
151 let new_node = self.store.alloc_node(Node::Inner {
152 data_map: bit,
153 node_map: 0,
154 data_start,
155 children_start: Idx::from_raw(0),
156 adhash: contribution,
157 });
158 self.root = Some(new_node);
159 self.size = 1;
160 self.adhash = contribution;
161 None
162 }
163 }
164
165 pub fn remove(&mut self, key: &K) -> Option<V> {
168 let root = self.root?;
169 let hash = adhash::hash_one(key);
170 match remove_recursive(&mut self.store, root, hash, key, 0) {
171 RemoveOutcome::NotFound => None,
172 RemoveOutcome::Removed {
173 node,
174 adhash_delta,
175 removed_value,
176 } => {
177 self.root = node;
178 self.size -= 1;
179 self.adhash = self.adhash.wrapping_sub(adhash_delta);
180 Some(removed_value)
181 }
182 }
183 }
184}
185
186impl<K, V> ChampMap<K, V> {
191 #[must_use]
193 pub fn iter(&self) -> Iter<'_, K, V> {
194 Iter::new(&self.store, self.root)
195 }
196}
197
198impl<K, V> Default for ChampMap<K, V> {
203 fn default() -> Self {
204 Self::new()
205 }
206}
207
208impl<K, V> fmt::Debug for ChampMap<K, V> {
209 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
210 f.debug_struct("ChampMap")
211 .field("len", &self.size)
212 .field("adhash", &format_args!("{:#018x}", self.adhash))
213 .finish_non_exhaustive()
214 }
215}
216
217impl<K: Hash + Eq + Clone, V: Hash + Clone> Extend<(K, V)> for ChampMap<K, V> {
218 fn extend<I: IntoIterator<Item = (K, V)>>(&mut self, iter: I) {
219 for (k, v) in iter {
220 self.insert(k, v);
221 }
222 }
223}
224
225impl<K: Hash + Eq + Clone, V: Hash + Clone> FromIterator<(K, V)> for ChampMap<K, V> {
226 fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {
227 let mut map = Self::new();
228 map.extend(iter);
229 map
230 }
231}
232
233impl<K: Hash + Eq, V> ops::Index<&K> for ChampMap<K, V> {
234 type Output = V;
235
236 fn index(&self, key: &K) -> &V {
237 self.get(key).expect("key not found")
238 }
239}
240
241impl<'a, K, V> IntoIterator for &'a ChampMap<K, V> {
242 type Item = (&'a K, &'a V);
243 type IntoIter = Iter<'a, K, V>;
244
245 fn into_iter(self) -> Iter<'a, K, V> {
246 self.iter()
247 }
248}