1use super::{
5 Memory, Storable,
6 error::{CollectionError as Error, Result, ensure},
7 record,
8};
9use serde::{Deserialize, Serialize};
10use std::{
11 borrow::Cow,
12 cell::{Cell, RefCell},
13 cmp::Ordering,
14 collections::BTreeMap,
15 marker::PhantomData,
16 ops::{Bound, RangeBounds},
17};
18
19pub const MAGIC: [u8; 8] = *b"ICMAP001";
20const NODE: [u8; 8] = *b"ICNODE01";
21const FREE: [u8; 8] = *b"ICFREE01";
22const BINS: usize = 32;
23const MAX_DEPTH: usize = 96;
24
25#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize)]
26struct Pointer {
27 offset: u64,
28 order: u8,
29}
30impl Pointer {
31 fn capacity(self) -> u64 {
32 1_u64 << self.order
33 }
34 fn check(self, cursor: u64) -> Result<()> {
35 ensure(
36 (8..32).contains(&self.order),
37 Error::Corrupt("tree block order"),
38 )?;
39 ensure(
40 self.offset >= record::HEADER_BYTES
41 && self
42 .offset
43 .checked_add(self.capacity())
44 .is_some_and(|end| end <= cursor),
45 Error::Corrupt("tree block bounds"),
46 )?;
47 Ok(())
48 }
49}
50
51#[derive(Clone, Serialize, Deserialize)]
52struct Root {
53 top: Option<Pointer>,
54 length: u64,
55 cursor: u64,
56 free: Vec<Option<Pointer>>,
57 key_bound: Option<(u32, bool)>,
58 value_bound: Option<(u32, bool)>,
59}
60
61#[derive(Clone, Serialize, Deserialize)]
62struct Node {
63 left: Option<Pointer>,
64 right: Option<Pointer>,
65 height: u8,
66 key: Vec<u8>,
67 value: Vec<u8>,
68}
69
70pub struct Tree<K, V, M: Memory> {
71 pub memory: M,
72 root: RefCell<Root>,
73 poisoned: Cell<bool>,
74 types: PhantomData<(K, V)>,
75}
76
77impl<K: Storable + Ord + Clone, V: Storable, M: Memory> Tree<K, V, M> {
78 pub fn reset(memory: M) -> Result<Self> {
79 let root = Root {
80 top: None,
81 length: 0,
82 cursor: record::HEADER_BYTES,
83 free: vec![None; BINS],
84 key_bound: record::bound::<K>(),
85 value_bound: record::bound::<V>(),
86 };
87 let bytes = record::encode(MAGIC, &root)?;
88 ensure(
89 bytes.len() as u64 <= record::HEADER_BYTES,
90 Error::Corrupt("map invariant"),
91 )?;
92 record::reserve(&memory, record::HEADER_BYTES)?;
93 memory.write(0, &bytes);
94 Ok(Self {
95 memory,
96 root: RefCell::new(root),
97 poisoned: Cell::new(false),
98 types: PhantomData,
99 })
100 }
101
102 pub fn load(memory: M) -> Result<Self> {
103 let root: Root = record::read(&memory, 0, record::HEADER_BYTES, MAGIC)?;
104 ensure(
105 root.key_bound == record::bound::<K>(),
106 Error::Corrupt("map key bound changed"),
107 )?;
108 ensure(
109 root.value_bound == record::bound::<V>(),
110 Error::Corrupt("map value bound changed"),
111 )?;
112 ensure(
113 root.free.len() == BINS
114 && root.cursor >= record::HEADER_BYTES
115 && root.cursor <= memory.size() * crate::WASM_PAGE_SIZE_BYTES,
116 Error::Corrupt("map allocator bounds"),
117 )?;
118 ensure(
119 root.top.is_none() == (root.length == 0),
120 Error::Corrupt("map root/count disagree"),
121 )?;
122 if let Some(pointer) = root.top {
123 pointer.check(root.cursor)?;
124 }
125 for (order, pointer) in root.free.iter().enumerate() {
126 if let Some(pointer) = pointer {
127 pointer.check(root.cursor)?;
128 ensure(
129 usize::from(pointer.order) == order,
130 Error::Corrupt("free block order"),
131 )?;
132 }
133 }
134 Ok(Self {
135 memory,
136 root: RefCell::new(root),
137 poisoned: Cell::new(false),
138 types: PhantomData,
139 })
140 }
141
142 fn healthy(&self) -> Result<()> {
143 ensure(!self.poisoned.get(), Error::Poisoned)
144 }
145 pub fn len(&self) -> u64 {
146 self.healthy().expect("map owner is poisoned");
147 self.root.borrow().length
148 }
149 fn node(&self, pointer: Pointer) -> Result<Node> {
150 pointer.check(self.root.borrow().cursor)?;
151 let node: Node = record::read(&self.memory, pointer.offset, pointer.capacity(), NODE)?;
152 validate_node::<K, V>(&node, self.root.borrow().cursor)?;
153 Ok(node)
154 }
155
156 pub fn get(&self, key: &K) -> Result<Option<V>> {
157 self.healthy()?;
158 let mut current = self.root.borrow().top;
159 for _ in 0..MAX_DEPTH {
160 let Some(pointer) = current else {
161 return Ok(None);
162 };
163 let node = self.node(pointer)?;
164 match key.cmp(&decode::<K>(node.key)?) {
165 Ordering::Less => current = node.left,
166 Ordering::Greater => current = node.right,
167 Ordering::Equal => return decode(node.value).map(Some),
168 }
169 }
170 Err(Error::Corrupt("map path exceeds height bound"))
171 }
172
173 pub fn insert(&mut self, key: K, value: V) -> Result<Option<V>> {
174 self.healthy()?;
175 let key_bytes = key.to_bytes_checked()?.into_owned();
176 let value_bytes = value.into_bytes_checked()?;
177 let mut transaction = Transaction::<K, V, M>::new(self);
178 let (root, previous) =
179 transaction.insert(transaction.root.top, &key, &key_bytes, &value_bytes, 0)?;
180 transaction.root.top = Some(root);
181 drop(key);
182 let previous = previous.map(decode).transpose()?;
183 transaction.commit()?;
184 Ok(previous)
185 }
186
187 pub fn remove(&mut self, key: &K) -> Result<Option<V>> {
188 self.healthy()?;
189 let mut transaction = Transaction::<K, V, M>::new(self);
190 let (root, previous) = transaction.remove(transaction.root.top, key, 0)?;
191 transaction.root.top = root;
192 let previous = previous.map(decode).transpose()?;
193 if previous.is_some() {
194 transaction.commit()?;
195 }
196 Ok(previous)
197 }
198
199 pub fn clear(&mut self) -> Result<()> {
200 self.healthy()?;
201 let mut transaction = Transaction::<K, V, M>::new(self);
202 transaction.root.top = None;
203 transaction.root.length = 0;
204 transaction.root.cursor = record::HEADER_BYTES;
205 transaction.root.free.fill(None);
206 transaction.commit()
207 }
208
209 fn seek_path(&self, bound: &Bound<K>, forward: bool) -> Result<Vec<Pointer>> {
210 self.healthy()?;
211 let mut current = self.root.borrow().top;
212 let mut path = Vec::new();
213 for _ in 0..MAX_DEPTH {
214 let Some(pointer) = current else {
215 return Ok(path);
216 };
217 let node = self.node(pointer)?;
218 let key = decode::<K>(node.key)?;
219 let accepted = match bound {
220 Bound::Unbounded => true,
221 Bound::Included(limit) => {
222 if forward {
223 key >= *limit
224 } else {
225 key <= *limit
226 }
227 }
228 Bound::Excluded(limit) => {
229 if forward {
230 key > *limit
231 } else {
232 key < *limit
233 }
234 }
235 };
236 if accepted {
237 current = if forward { node.left } else { node.right };
238 path.push(pointer);
239 } else {
240 current = if forward { node.right } else { node.left };
241 }
242 }
243 Err(Error::Corrupt("map path exceeds height bound"))
244 }
245
246 fn advance_path(
247 &self,
248 path: &mut Vec<Pointer>,
249 forward: bool,
250 ) -> Result<Option<MapEntry<K, V>>> {
251 self.healthy()?;
252 let Some(pointer) = path.pop() else {
253 return Ok(None);
254 };
255 let node = self.node(pointer)?;
256 let mut child = if forward { node.right } else { node.left };
257 let mut depth = 0;
258 while let Some(pointer) = child {
259 ensure(
260 depth < MAX_DEPTH && path.len() < MAX_DEPTH,
261 Error::Corrupt("map cursor exceeds height bound"),
262 )?;
263 depth += 1;
264 path.push(pointer);
265 let child_node = self.node(pointer)?;
266 child = if forward {
267 child_node.left
268 } else {
269 child_node.right
270 };
271 }
272 Ok(Some(MapEntry {
273 key: decode(node.key)?,
274 bytes: node.value,
275 value: PhantomData,
276 }))
277 }
278
279 pub fn range(&self, bounds: impl RangeBounds<K>) -> TreeIter<'_, K, V, M> {
280 let lower = bounds.start_bound().cloned();
281 let upper = bounds.end_bound().cloned();
282 let invalid = match (&lower, &upper) {
283 (Bound::Included(a) | Bound::Excluded(a), Bound::Included(b) | Bound::Excluded(b)) => {
284 a > b
285 || (a == b
286 && matches!((&lower, &upper), (Bound::Excluded(_), Bound::Excluded(_))))
287 }
288 _ => false,
289 };
290 TreeIter {
291 tree: self,
292 lower,
293 upper,
294 front: None,
295 back: None,
296 exhausted: false,
297 invalid,
298 }
299 }
300}
301
302fn decode<T: Storable>(bytes: Vec<u8>) -> Result<T> {
303 T::check_bounds(&bytes)?;
304 Ok(T::from_bytes(Cow::Owned(bytes))?)
305}
306fn validate_node<K: Storable, V: Storable>(node: &Node, cursor: u64) -> Result<()> {
307 ensure(
308 (1..=96).contains(&node.height),
309 Error::Corrupt("map node height"),
310 )?;
311 K::check_bounds(&node.key)?;
312 V::check_bounds(&node.value)?;
313 for pointer in [node.left, node.right].into_iter().flatten() {
314 pointer.check(cursor)?;
315 }
316 Ok(())
317}
318
319struct Transaction<'a, K, V, M: Memory> {
320 tree: &'a Tree<K, V, M>,
321 root: Root,
322 writes: BTreeMap<u64, Vec<u8>>,
323}
324
325impl<'a, K: Storable + Ord + Clone, V: Storable, M: Memory> Transaction<'a, K, V, M> {
326 fn new(tree: &'a Tree<K, V, M>) -> Self {
327 Self {
328 tree,
329 root: tree.root.borrow().clone(),
330 writes: BTreeMap::new(),
331 }
332 }
333 fn read<T: serde::de::DeserializeOwned>(&self, pointer: Pointer, magic: [u8; 8]) -> Result<T> {
334 pointer.check(self.root.cursor)?;
335 if let Some(bytes) = self.writes.get(&pointer.offset) {
336 record::decode(magic, bytes)
337 } else {
338 record::read(&self.tree.memory, pointer.offset, pointer.capacity(), magic)
339 }
340 }
341 fn node(&self, pointer: Pointer) -> Result<Node> {
342 let node: Node = self.read(pointer, NODE)?;
343 validate_node::<K, V>(&node, self.root.cursor)?;
344 Ok(node)
345 }
346 fn height(&self, pointer: Option<Pointer>) -> Result<u8> {
347 pointer.map_or(Ok(0), |pointer| Ok(self.node(pointer)?.height))
348 }
349 fn free(&mut self, pointer: Pointer) -> Result<()> {
350 let index = usize::from(pointer.order);
351 self.writes.insert(
352 pointer.offset,
353 record::encode(FREE, &self.root.free[index])?,
354 );
355 self.root.free[index] = Some(pointer);
356 Ok(())
357 }
358 fn allocate(&mut self, length: usize) -> Result<Pointer> {
359 let capacity = length
360 .max(256)
361 .checked_next_power_of_two()
362 .ok_or(Error::Budget)?;
363 let order = usize::try_from(capacity.trailing_zeros()).unwrap();
364 ensure(order < BINS, Error::Corrupt("map record too large"))?;
365 for bin in order..BINS {
366 if let Some(pointer) = self.root.free[bin] {
367 let next: Option<Pointer> = self.read(pointer, FREE)?;
368 if let Some(next) = next {
369 next.check(self.root.cursor)?;
370 ensure(
371 next.order == pointer.order,
372 Error::Corrupt("free block order"),
373 )?;
374 ensure(next != pointer, Error::Corrupt("map free-list cycle"))?;
375 }
376 self.root.free[bin] = next;
377 return Ok(pointer);
378 }
379 }
380 let pointer = Pointer {
381 offset: self.root.cursor,
382 order: u8::try_from(order).unwrap(),
383 };
384 self.root.cursor = self
385 .root
386 .cursor
387 .checked_add(pointer.capacity())
388 .ok_or(Error::Budget)?;
389 Ok(pointer)
390 }
391 fn save(&mut self, previous: Option<Pointer>, node: &Node) -> Result<Pointer> {
392 let bytes = record::encode(NODE, node)?;
393 let pointer = if let Some(pointer) =
394 previous.filter(|pointer| pointer.capacity() >= bytes.len() as u64)
395 {
396 pointer
397 } else {
398 if let Some(pointer) = previous {
399 self.free(pointer)?;
400 }
401 self.allocate(bytes.len())?
402 };
403 self.writes.insert(pointer.offset, bytes);
404 Ok(pointer)
405 }
406 fn rotate_left(&mut self, pointer: Pointer, mut node: Node) -> Result<Pointer> {
407 let right_pointer = node.right.ok_or(Error::Corrupt("map rotation child"))?;
408 let mut right = self.node(right_pointer)?;
409 node.right = right.left;
410 node.height = 1 + self.height(node.left)?.max(self.height(node.right)?);
411 right.left = Some(self.save(Some(pointer), &node)?);
412 right.height = 1 + self.height(right.left)?.max(self.height(right.right)?);
413 self.save(Some(right_pointer), &right)
414 }
415 fn rotate_right(&mut self, pointer: Pointer, mut node: Node) -> Result<Pointer> {
416 let left_pointer = node.left.ok_or(Error::Corrupt("map rotation child"))?;
417 let mut left = self.node(left_pointer)?;
418 node.left = left.right;
419 node.height = 1 + self.height(node.left)?.max(self.height(node.right)?);
420 left.right = Some(self.save(Some(pointer), &node)?);
421 left.height = 1 + self.height(left.left)?.max(self.height(left.right)?);
422 self.save(Some(left_pointer), &left)
423 }
424 fn balance(&mut self, pointer: Pointer, mut node: Node) -> Result<Pointer> {
425 let left = self.height(node.left)?;
426 let right = self.height(node.right)?;
427 node.height = 1 + left.max(right);
428 if i16::from(left) - i16::from(right) > 1 {
429 let child = node.left.unwrap();
430 let value = self.node(child)?;
431 if self.height(value.right)? > self.height(value.left)? {
432 node.left = Some(self.rotate_left(child, value)?);
433 }
434 self.rotate_right(pointer, node)
435 } else if i16::from(right) - i16::from(left) > 1 {
436 let child = node.right.unwrap();
437 let value = self.node(child)?;
438 if self.height(value.left)? > self.height(value.right)? {
439 node.right = Some(self.rotate_right(child, value)?);
440 }
441 self.rotate_left(pointer, node)
442 } else {
443 self.save(Some(pointer), &node)
444 }
445 }
446 fn insert(
447 &mut self,
448 pointer: Option<Pointer>,
449 key: &K,
450 key_bytes: &[u8],
451 value: &[u8],
452 depth: usize,
453 ) -> Result<(Pointer, Option<Vec<u8>>)> {
454 ensure(
455 depth < MAX_DEPTH,
456 Error::Corrupt("map path exceeds height bound"),
457 )?;
458 let Some(pointer) = pointer else {
459 let node = Node {
460 left: None,
461 right: None,
462 height: 1,
463 key: key_bytes.to_vec(),
464 value: value.to_vec(),
465 };
466 self.root.length = self.root.length.checked_add(1).ok_or(Error::Budget)?;
467 return Ok((self.save(None, &node)?, None));
468 };
469 let mut node = self.node(pointer)?;
470 let previous = match key.cmp(&decode::<K>(node.key.clone())?) {
471 Ordering::Less => {
472 let (child, old) = self.insert(node.left, key, key_bytes, value, depth + 1)?;
473 if old.is_some() && node.left == Some(child) {
474 return Ok((pointer, old));
475 }
476 node.left = Some(child);
477 old
478 }
479 Ordering::Greater => {
480 let (child, old) = self.insert(node.right, key, key_bytes, value, depth + 1)?;
481 if old.is_some() && node.right == Some(child) {
482 return Ok((pointer, old));
483 }
484 node.right = Some(child);
485 old
486 }
487 Ordering::Equal => Some(std::mem::replace(&mut node.value, value.to_vec())),
488 };
489 let pointer = if previous.is_some() {
491 self.save(Some(pointer), &node)?
492 } else {
493 self.balance(pointer, node)?
494 };
495 Ok((pointer, previous))
496 }
497 fn remove(
498 &mut self,
499 pointer: Option<Pointer>,
500 key: &K,
501 depth: usize,
502 ) -> Result<(Option<Pointer>, Option<Vec<u8>>)> {
503 ensure(
504 depth < MAX_DEPTH,
505 Error::Corrupt("map path exceeds height bound"),
506 )?;
507 let Some(pointer) = pointer else {
508 return Ok((None, None));
509 };
510 let mut node = self.node(pointer)?;
511 let previous = match key.cmp(&decode::<K>(node.key.clone())?) {
512 Ordering::Less => {
513 let (child, old) = self.remove(node.left, key, depth + 1)?;
514 node.left = child;
515 old
516 }
517 Ordering::Greater => {
518 let (child, old) = self.remove(node.right, key, depth + 1)?;
519 node.right = child;
520 old
521 }
522 Ordering::Equal => {
523 if node.left.is_none() || node.right.is_none() {
524 self.free(pointer)?;
525 self.root.length = self
526 .root
527 .length
528 .checked_sub(1)
529 .ok_or(Error::Corrupt("map length"))?;
530 return Ok((node.left.or(node.right), Some(node.value)));
531 }
532 let (right, successor) = self.extract_min(node.right.unwrap(), depth + 1)?;
533 node.right = right;
534 node.key = successor.key;
535 Some(std::mem::replace(&mut node.value, successor.value))
536 }
537 };
538 if previous.is_none() {
539 Ok((Some(pointer), None))
540 } else {
541 Ok((Some(self.balance(pointer, node)?), previous))
542 }
543 }
544 fn extract_min(&mut self, pointer: Pointer, depth: usize) -> Result<(Option<Pointer>, Node)> {
545 ensure(
546 depth < MAX_DEPTH,
547 Error::Corrupt("map path exceeds height bound"),
548 )?;
549 let mut node = self.node(pointer)?;
550 let Some(left) = node.left else {
551 self.free(pointer)?;
552 self.root.length = self
553 .root
554 .length
555 .checked_sub(1)
556 .ok_or(Error::Corrupt("map length"))?;
557 return Ok((node.right, node));
558 };
559 let (child, minimum) = self.extract_min(left, depth + 1)?;
560 node.left = child;
561 Ok((Some(self.balance(pointer, node)?), minimum))
562 }
563 fn commit(self) -> Result<()> {
564 let header = record::encode(MAGIC, &self.root)?;
565 ensure(
566 header.len() as u64 <= record::HEADER_BYTES,
567 Error::Corrupt("map invariant"),
568 )?;
569 record::reserve(&self.tree.memory, self.root.cursor)?;
570 self.tree.poisoned.set(true);
571 for (offset, bytes) in self.writes {
572 self.tree.memory.write(offset, &bytes);
573 }
574 self.tree.memory.write(0, &header);
575 *self.tree.root.borrow_mut() = self.root;
576 self.tree.poisoned.set(false);
577 Ok(())
578 }
579}
580
581pub struct MapEntry<K, V> {
587 key: K,
588 bytes: Vec<u8>,
589 value: PhantomData<V>,
590}
591impl<K, V: Storable> MapEntry<K, V> {
592 pub const fn key(&self) -> &K {
594 &self.key
595 }
596 pub fn value(&self) -> Result<V> {
601 decode(self.bytes.clone())
602 }
603 pub fn into_pair(self) -> Result<(K, V)> {
608 Ok((self.key, decode(self.bytes)?))
609 }
610 pub fn into_key(self) -> K {
612 self.key
613 }
614 pub fn into_value(self) -> Result<V> {
619 decode(self.bytes)
620 }
621}
622
623pub struct TreeIter<'a, K, V, M: Memory> {
630 tree: &'a Tree<K, V, M>,
631 lower: Bound<K>,
632 upper: Bound<K>,
633 front: Option<Vec<Pointer>>,
634 back: Option<Vec<Pointer>>,
635 exhausted: bool,
636 invalid: bool,
637}
638impl<K: Storable + Ord + Clone, V: Storable, M: Memory> TreeIter<'_, K, V, M> {
639 fn step(&mut self, forward: bool) -> Result<Option<MapEntry<K, V>>> {
640 ensure(!self.invalid, Error::Bounds)?;
641 let (path, bound) = if forward {
642 (&mut self.front, &self.lower)
643 } else {
644 (&mut self.back, &self.upper)
645 };
646 if path.is_none() {
647 *path = Some(self.tree.seek_path(bound, forward)?);
648 }
649 let entry = self.tree.advance_path(path.as_mut().unwrap(), forward)?;
650 if let Some(entry) = &entry {
651 let after = match &self.lower {
652 Bound::Unbounded => true,
653 Bound::Included(k) => entry.key >= *k,
654 Bound::Excluded(k) => entry.key > *k,
655 };
656 let before = match &self.upper {
657 Bound::Unbounded => true,
658 Bound::Included(k) => entry.key <= *k,
659 Bound::Excluded(k) => entry.key < *k,
660 };
661 ensure(
662 if forward { after } else { before },
663 Error::Corrupt("map cursor key order"),
664 )?;
665 if !(after && before) {
666 return Ok(None);
667 }
668 if forward {
669 self.lower = Bound::Excluded(entry.key.clone());
670 } else {
671 self.upper = Bound::Excluded(entry.key.clone());
672 }
673 }
674 Ok(entry)
675 }
676 fn advance(&mut self, forward: bool) -> Option<Result<MapEntry<K, V>>> {
677 if self.exhausted {
678 return None;
679 }
680 match self.step(forward) {
681 Ok(Some(entry)) => Some(Ok(entry)),
682 Ok(None) => {
683 self.exhausted = true;
684 None
685 }
686 Err(error) => {
687 self.exhausted = true;
688 Some(Err(error))
689 }
690 }
691 }
692}
693impl<K: Storable + Ord + Clone, V: Storable, M: Memory> Iterator for TreeIter<'_, K, V, M> {
694 type Item = Result<MapEntry<K, V>>;
695 fn next(&mut self) -> Option<Self::Item> {
696 self.advance(true)
697 }
698}
699impl<K: Storable + Ord + Clone, V: Storable, M: Memory> DoubleEndedIterator
700 for TreeIter<'_, K, V, M>
701{
702 fn next_back(&mut self) -> Option<Self::Item> {
703 self.advance(false)
704 }
705}
706impl<K: Storable + Ord + Clone, V: Storable, M: Memory> std::iter::FusedIterator
707 for TreeIter<'_, K, V, M>
708{
709}