1mod owned;
10mod shared;
11#[cfg(test)]
12mod tests;
13mod tree;
14
15pub use owned::{OwnedMap, OwnedMapIntoIter, OwnedSet, OwnedSetIntoIter, OwnedSetIter};
16pub use shared::{BudgetedSharedMap, BudgetedSharedMapIter};
17
18use std::borrow::Borrow;
19
20use super::{Budgeted, MemoryBudget, MemoryError, MemoryReservation};
21
22struct OwnedNode<K, V> {
23 value: Box<Node<K, V>>,
24 memory: Option<MemoryReservation>,
26}
27
28impl<K, V> std::ops::Deref for OwnedNode<K, V> {
29 type Target = Box<Node<K, V>>;
30
31 fn deref(&self) -> &Self::Target {
32 &self.value
33 }
34}
35
36impl<K, V> OwnedNode<K, V> {
37 fn into_parts(self) -> (Box<Node<K, V>>, Option<MemoryReservation>) {
38 (self.value, self.memory)
39 }
40}
41type Link<K, V> = Option<OwnedNode<K, V>>;
42
43struct Node<K, V> {
44 key: K,
45 value: V,
46 left: Link<K, V>,
47 right: Link<K, V>,
48 height: u8,
49}
50
51pub struct BudgetedMap<K, V> {
53 root: Link<K, V>,
54 len: usize,
55 memory: MemoryBudget,
56}
57
58pub struct PreparedMapEntry<K, V> {
60 node: OwnedNode<K, V>,
61}
62
63impl<K, V> BudgetedMap<K, V> {
64 pub fn new(memory: &MemoryBudget) -> Self {
65 Self {
66 root: None,
67 len: 0,
68 memory: memory.clone(),
69 }
70 }
71
72 pub fn len(&self) -> usize {
73 self.len
74 }
75
76 pub fn is_empty(&self) -> bool {
77 self.len == 0
78 }
79
80 pub fn budget(&self) -> &MemoryBudget {
81 &self.memory
82 }
83
84 pub fn prepare_entry(&self, key: K, value: V) -> Result<PreparedMapEntry<K, V>, MemoryError> {
85 let memory = self.memory.reserve(size_of::<Node<K, V>>())?;
86 let node = Box::new(Node {
87 key,
88 value,
89 left: None,
90 right: None,
91 height: 1,
92 });
93 Ok(PreparedMapEntry {
94 node: OwnedNode {
95 value: node,
96 memory: Some(memory),
97 },
98 })
99 }
100
101 pub fn for_each_mut(&mut self, mut visit: impl FnMut(&K, &mut V)) {
103 tree::for_each_mut(&mut self.root, &mut visit);
104 }
105
106 pub fn iter(&self) -> BudgetedMapIter<'_, K, V> {
107 BudgetedMapIter::new(&self.root, self.len)
108 }
109}
110
111impl<K: Ord, V> BudgetedMap<K, V> {
112 pub fn get<Q: Ord + ?Sized>(&self, key: &Q) -> Option<&V>
113 where
114 K: Borrow<Q>,
115 {
116 tree::get(&self.root, key).map(|node| &node.value)
117 }
118
119 pub fn get_mut<Q: Ord + ?Sized>(&mut self, key: &Q) -> Option<&mut V>
120 where
121 K: Borrow<Q>,
122 {
123 tree::get_mut(&mut self.root, key).map(|node| &mut node.value)
124 }
125
126 pub fn contains_key<Q: Ord + ?Sized>(&self, key: &Q) -> bool
127 where
128 K: Borrow<Q>,
129 {
130 self.get(key).is_some()
131 }
132
133 pub fn insert_prepared(&mut self, entry: PreparedMapEntry<K, V>) -> Option<V> {
135 assert!(
136 self.memory.shares_allowance(
137 entry
138 .node
139 .memory
140 .as_ref()
141 .expect("prepared node is admitted")
142 .budget()
143 ),
144 "different memory allowances"
145 );
146 let previous = tree::insert(&mut self.root, entry.node);
147 self.len += usize::from(previous.is_none());
148 previous
149 }
150
151 pub fn insert(&mut self, key: K, value: V) -> Result<Option<V>, MemoryError> {
153 if let Some(previous) = self.get_mut(&key) {
154 return Ok(Some(std::mem::replace(previous, value)));
155 }
156 let entry = self.prepare_entry(key, value)?;
157 Ok(self.insert_prepared(entry))
158 }
159
160 pub fn remove<Q: Ord + ?Sized>(&mut self, key: &Q) -> Option<V>
161 where
162 K: Borrow<Q>,
163 {
164 let removed = tree::remove(&mut self.root, key);
165 self.len -= usize::from(removed.is_some());
166 removed.map(|(_, value)| value)
167 }
168}
169
170impl<K: Ord + Borrow<Q>, V, Q: Ord + ?Sized> std::ops::Index<&Q> for BudgetedMap<K, V> {
171 type Output = V;
172
173 fn index(&self, key: &Q) -> &V {
174 self.get(key).expect("missing budgeted map key")
175 }
176}
177
178const MAX_HEIGHT: usize = usize::BITS as usize * 2;
180
181pub struct BudgetedMapIter<'a, K, V> {
182 stack: [Option<&'a Node<K, V>>; MAX_HEIGHT],
183 depth: usize,
184 remaining: usize,
185}
186
187impl<'a, K, V> BudgetedMapIter<'a, K, V> {
188 fn new(root: &'a Link<K, V>, len: usize) -> Self {
189 let mut iter = Self {
190 stack: [None; MAX_HEIGHT],
191 depth: 0,
192 remaining: len,
193 };
194 iter.push_left(root.as_ref().map(|node| &***node));
195 iter
196 }
197
198 fn push_left(&mut self, mut node: Option<&'a Node<K, V>>) {
199 while let Some(current) = node {
200 self.stack[self.depth] = Some(current);
201 self.depth += 1;
202 node = current.left.as_ref().map(|node| &***node);
203 }
204 }
205}
206
207impl<'a, K, V> Iterator for BudgetedMapIter<'a, K, V> {
208 type Item = (&'a K, &'a V);
209
210 fn next(&mut self) -> Option<Self::Item> {
211 self.depth = self.depth.checked_sub(1)?;
212 let node = self.stack[self.depth].take().expect("retained map node");
213 self.push_left(node.right.as_ref().map(|node| &***node));
214 self.remaining -= 1;
215 Some((&node.key, &node.value))
216 }
217
218 fn size_hint(&self) -> (usize, Option<usize>) {
219 (self.remaining, Some(self.remaining))
220 }
221}
222
223impl<K, V> ExactSizeIterator for BudgetedMapIter<'_, K, V> {}
224impl<K, V> std::iter::FusedIterator for BudgetedMapIter<'_, K, V> {}
225
226impl<'a, K, V> IntoIterator for &'a BudgetedMap<K, V> {
227 type Item = (&'a K, &'a V);
228 type IntoIter = BudgetedMapIter<'a, K, V>;
229
230 fn into_iter(self) -> Self::IntoIter {
231 self.iter()
232 }
233}