1use super::{
8 Memory, Storable,
9 error::{CollectionError as Error, Result, ensure},
10 record,
11};
12use serde::{Deserialize, Serialize};
13use std::{
14 borrow::Cow,
15 cell::{Cell, RefCell},
16 collections::BTreeMap,
17 marker::PhantomData,
18 ops::{Bound, RangeBounds},
19 rc::Rc,
20};
21mod read;
22use read::{NodeCache, ReadNode};
23
24pub const MAGIC: [u8; 8] = *b"ICMAP002";
25const NODE: [u8; 8] = *b"ICBTND01";
26const VALUE: [u8; 8] = *b"ICBTVAL1";
27const FREE: [u8; 8] = *b"ICFREE01";
28const BINS: usize = 32;
29const MAX_DEPTH: usize = 32;
30const DEGREE: usize = 6;
31const MAX_ENTRIES: usize = DEGREE * 2 - 1;
32const MIN_ENTRIES: usize = DEGREE - 1;
33const INLINE: usize = 32;
34
35#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize)]
36struct Pointer {
37 offset: u64,
38 order: u8,
39}
40impl Pointer {
41 const fn capacity(self) -> u64 {
42 1_u64 << self.order
43 }
44 fn check(self, cursor: u64) -> Result<()> {
45 ensure(
46 (8..32).contains(&self.order),
47 Error::Corrupt("tree block order"),
48 )?;
49 ensure(
50 self.offset >= record::HEADER_BYTES
51 && self
52 .offset
53 .checked_add(self.capacity())
54 .is_some_and(|end| end <= cursor),
55 Error::Corrupt("tree block bounds"),
56 )
57 }
58 fn put(self, bytes: &mut Vec<u8>) {
59 bytes.extend_from_slice(&self.offset.to_le_bytes());
60 bytes.push(self.order);
61 }
62}
63#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
64struct Root {
65 top: Option<Pointer>,
66 length: u64,
67 cursor: u64,
68 free: Vec<Option<Pointer>>,
69 key_bound: Option<(u32, bool)>,
70 value_bound: Option<(u32, bool)>,
71}
72#[derive(Clone)]
73enum Value {
74 Inline(Vec<u8>),
75 External(Pointer),
76}
77#[derive(Clone)]
78struct Entry {
79 key: Vec<u8>,
80 value: Value,
81}
82#[derive(Clone, Default)]
83struct Node {
84 entries: Vec<Entry>,
85 children: Vec<Pointer>,
86}
87impl Node {
88 fn encode(&self) -> Result<Vec<u8>> {
89 ensure(
90 self.entries.len() <= MAX_ENTRIES,
91 Error::Corrupt("B-tree node capacity"),
92 )?;
93 ensure(
94 self.children.is_empty() || self.children.len() == self.entries.len() + 1,
95 Error::Corrupt("B-tree child count"),
96 )?;
97 let capacity =
98 self.entries
99 .iter()
100 .try_fold(2 + self.children.len() * 9, |size, entry| {
101 let value_size = match &entry.value {
102 Value::Inline(v) => v.len(),
103 Value::External(_) => 9,
104 };
105 size.checked_add(5)
106 .and_then(|n| n.checked_add(entry.key.len()))
107 .and_then(|n| n.checked_add(value_size))
108 .ok_or(Error::Budget)
109 })?;
110 record::encode_payload_with(NODE, capacity, |bytes| {
111 bytes.extend_from_slice(&[
112 u8::try_from(self.entries.len()).unwrap(),
113 u8::from(!self.children.is_empty()),
114 ]);
115 for p in &self.children {
116 p.put(bytes);
117 }
118 for entry in &self.entries {
119 bytes.extend_from_slice(
120 &u32::try_from(entry.key.len())
121 .map_err(|_| Error::Budget)?
122 .to_le_bytes(),
123 );
124 bytes.extend_from_slice(&entry.key);
125 match &entry.value {
126 Value::Inline(value) => {
127 bytes.push(u8::try_from(value.len()).unwrap());
128 bytes.extend_from_slice(value);
129 }
130 Value::External(p) => {
131 bytes.push(255);
132 p.put(bytes);
133 }
134 }
135 }
136 Ok(())
137 })
138 }
139}
140struct Reader<'a>(&'a [u8]);
141impl<'a> Reader<'a> {
142 fn take(&mut self, n: usize) -> Result<&'a [u8]> {
143 ensure(n <= self.0.len(), Error::Corrupt("truncated B-tree node"))?;
144 let (a, b) = self.0.split_at(n);
145 self.0 = b;
146 Ok(a)
147 }
148 fn byte(&mut self) -> Result<u8> {
149 Ok(self.take(1)?[0])
150 }
151 fn pointer(&mut self, cursor: u64) -> Result<Pointer> {
152 let offset = u64::from_le_bytes(self.take(8)?.try_into().unwrap());
153 let p = Pointer {
154 offset,
155 order: self.byte()?,
156 };
157 p.check(cursor)?;
158 Ok(p)
159 }
160}
161
162pub struct Tree<K, V, M: Memory> {
163 pub memory: M,
164 root: RefCell<Root>,
165 poisoned: Cell<bool>,
166 cache: RefCell<NodeCache>,
167 types: PhantomData<(K, V)>,
168}
169impl<K: Storable + Ord + Clone, V: Storable, M: Memory> Tree<K, V, M> {
170 pub fn reset(memory: M) -> Result<Self> {
171 let root = Root {
172 top: None,
173 length: 0,
174 cursor: record::HEADER_BYTES,
175 free: vec![None; BINS],
176 key_bound: record::bound::<K>(),
177 value_bound: record::bound::<V>(),
178 };
179 let bytes = record::encode(MAGIC, &root)?;
180 ensure(bytes.len() as u64 <= record::HEADER_BYTES, Error::Budget)?;
181 record::reserve(&memory, record::HEADER_BYTES)?;
182 memory.write(0, &bytes);
183 Ok(Self {
184 memory,
185 root: RefCell::new(root),
186 poisoned: Cell::new(false),
187 cache: RefCell::default(),
188 types: PhantomData,
189 })
190 }
191 pub fn load(memory: M) -> Result<Self> {
192 let root: Root = record::read(&memory, 0, record::HEADER_BYTES, MAGIC)?;
193 ensure(
194 root.key_bound == record::bound::<K>() && root.value_bound == record::bound::<V>(),
195 Error::Corrupt("map codec bound changed"),
196 )?;
197 ensure(
198 root.free.len() == BINS
199 && root.cursor >= record::HEADER_BYTES
200 && root.cursor
201 <= memory
202 .size()
203 .checked_mul(crate::WASM_PAGE_SIZE_BYTES)
204 .ok_or(Error::Budget)?,
205 Error::Corrupt("map allocator bounds"),
206 )?;
207 ensure(
208 root.top.is_none() == (root.length == 0),
209 Error::Corrupt("map root/count disagree"),
210 )?;
211 if let Some(p) = root.top {
212 p.check(root.cursor)?;
213 }
214 for (order, p) in root.free.iter().enumerate() {
215 if let Some(p) = p {
216 p.check(root.cursor)?;
217 ensure(
218 usize::from(p.order) == order,
219 Error::Corrupt("free block order"),
220 )?;
221 }
222 }
223 Ok(Self {
224 memory,
225 root: RefCell::new(root),
226 poisoned: Cell::new(false),
227 cache: RefCell::default(),
228 types: PhantomData,
229 })
230 }
231 fn healthy(&self) -> Result<()> {
232 ensure(!self.poisoned.get(), Error::Poisoned)?;
233 let capacity = self
236 .memory
237 .size()
238 .checked_mul(crate::WASM_PAGE_SIZE_BYTES)
239 .ok_or(Error::Budget)?;
240 ensure(
241 self.root.borrow().cursor <= capacity,
242 Error::Corrupt("map allocator bounds"),
243 )
244 }
245 pub fn len(&self) -> u64 {
246 self.healthy().expect("map owner is poisoned");
247 self.root.borrow().length
248 }
249 pub fn set_cache_budget(&mut self, bytes: usize) {
250 self.cache.get_mut().configure(bytes);
251 }
252 fn read_node(&self, p: Pointer, depth: usize) -> Result<Rc<ReadNode>> {
253 let cursor = self.root.borrow().cursor;
254 p.check(cursor)?;
255 if let Some(node) = self.cache.borrow_mut().get(p, depth) {
256 return Ok(node);
257 }
258 let node = Rc::new(ReadNode::decode::<K, V>(
259 record::read_bytes(&self.memory, p.offset, p.capacity(), NODE)?,
260 cursor,
261 )?);
262 self.cache.borrow_mut().put(p, Rc::clone(&node), depth);
263 Ok(node)
264 }
265 fn value(&self, v: Value) -> Result<Vec<u8>> {
266 let bytes = match v {
267 Value::Inline(bytes) => bytes,
268 Value::External(p) => {
269 p.check(self.root.borrow().cursor)?;
270 record::read_payload(&self.memory, p.offset, p.capacity(), VALUE)?
271 }
272 };
273 V::check_bounds(&bytes)?;
274 Ok(bytes)
275 }
276 fn find(&self, key: &K) -> Result<Option<(Rc<ReadNode>, usize)>> {
277 self.healthy()?;
278 let mut p = self.root.borrow().top;
279 for depth in 0..MAX_DEPTH {
280 let Some(current) = p else { return Ok(None) };
281 let node = self.read_node(current, depth)?;
282 match node.search(key)? {
283 Ok(i) => return Ok(Some((node, i))),
284 Err(i) => p = node.children.get(i).copied(),
285 }
286 }
287 Err(Error::Corrupt("map path exceeds height bound"))
288 }
289 pub fn get(&self, key: &K) -> Result<Option<V>> {
290 let Some((node, index)) = self.find(key)? else {
291 return Ok(None);
292 };
293 if let Some(bytes) = node.inline_value(index) {
294 V::check_bounds(bytes)?;
295 Ok(Some(V::from_bytes(Cow::Borrowed(bytes))?))
296 } else {
297 let value = node.value(index);
298 drop(node);
301 decode(self.value(value)?).map(Some)
302 }
303 }
304 pub fn contains_key(&self, key: &K) -> Result<bool> {
305 Ok(self.find(key)?.is_some())
306 }
307 #[expect(
308 clippy::needless_pass_by_ref_mut,
309 reason = "Mutations require exclusive collection access despite internal transactional borrowing."
310 )]
311 pub fn insert(&mut self, key: K, value: V) -> Result<Option<V>> {
312 self.healthy()?;
313 let key_bytes = key.to_bytes_checked()?.into_owned();
314 let bytes = value.into_bytes_checked()?;
315 let mut tx = Transaction::new(self);
316 let (top, split, old) = tx.insert(tx.root.top, &key, key_bytes, bytes, 0)?;
317 tx.root.top = Some(if let Some((entry, right)) = split {
318 tx.save(
319 None,
320 &Node {
321 entries: vec![entry],
322 children: vec![top, right],
323 },
324 )?
325 } else {
326 top
327 });
328 drop(key);
329 let old = old.map(decode).transpose()?;
330 tx.commit()?;
331 Ok(old)
332 }
333 #[expect(
334 clippy::needless_pass_by_ref_mut,
335 reason = "Mutations require exclusive collection access despite internal transactional borrowing."
336 )]
337 pub fn remove(&mut self, key: &K) -> Result<Option<V>> {
338 self.healthy()?;
339 let mut tx = Transaction::new(self);
340 let Some(top) = tx.root.top else {
341 return Ok(None);
342 };
343 let (changed, old) = tx.remove(top, key, 0)?;
344 let Some(old) = old else { return Ok(None) };
345 let value = decode(old)?;
346 if let Some(node) = changed {
347 tx.root.top = if node.entries.is_empty() {
348 tx.free(top)?;
349 node.children.first().copied()
350 } else {
351 Some(tx.save(Some(top), &node)?)
352 };
353 }
354 tx.root.length -= 1;
355 tx.commit()?;
356 Ok(Some(value))
357 }
358 #[expect(
359 clippy::needless_pass_by_ref_mut,
360 reason = "Mutations require exclusive collection access despite internal transactional borrowing."
361 )]
362 pub fn clear(&mut self) -> Result<()> {
363 self.healthy()?;
364 let mut tx = Transaction::new(self);
365 tx.root.top = None;
366 tx.root.length = 0;
367 tx.root.cursor = record::HEADER_BYTES;
368 tx.root.free.fill(None);
369 tx.commit()
370 }
371 fn seek_path(&self, bound: &Bound<K>, forward: bool) -> Result<Vec<Frame>> {
372 self.healthy()?;
373 let mut path = Vec::new();
374 let mut pointer = self.root.borrow().top;
375 while let Some(p) = pointer {
376 ensure(
377 path.len() < MAX_DEPTH,
378 Error::Corrupt("map cursor exceeds height bound"),
379 )?;
380 let node = self.read_node(p, path.len())?;
381 let index = match bound {
382 Bound::Unbounded => {
383 if forward {
384 0
385 } else {
386 node.len()
387 }
388 }
389 Bound::Included(k) => match node.search(k)? {
390 Ok(i) => {
391 if forward {
392 i
393 } else {
394 i + 1
395 }
396 }
397 Err(i) => i,
398 },
399 Bound::Excluded(k) => match node.search(k)? {
400 Ok(i) => {
401 if forward {
402 i + 1
403 } else {
404 i
405 }
406 }
407 Err(i) => i,
408 },
409 };
410 pointer = node.children.get(index).copied();
411 path.push(Frame {
412 node,
413 index,
414 descend: false,
415 });
416 }
417 Ok(path)
418 }
419 fn advance_path(
420 &self,
421 path: &mut Vec<Frame>,
422 forward: bool,
423 keys_only: bool,
424 ) -> Result<Option<(K, Option<Value>)>> {
425 self.healthy()?;
426 while let Some(frame) = path.last_mut() {
427 if frame.descend {
428 frame.descend = false;
429 let mut child = frame.node.children.get(frame.index).copied();
430 while let Some(p) = child {
431 ensure(
432 path.len() < MAX_DEPTH,
433 Error::Corrupt("map cursor exceeds height bound"),
434 )?;
435 let node = self.read_node(p, path.len())?;
436 let index = if forward { 0 } else { node.len() };
437 child = node.children.get(index).copied();
438 path.push(Frame {
439 node,
440 index,
441 descend: false,
442 });
443 }
444 continue;
445 }
446 let index = if forward {
447 frame.index
448 } else {
449 if frame.index == 0 {
450 path.pop();
451 continue;
452 }
453 frame.index - 1
454 };
455 if index >= frame.node.len() {
456 path.pop();
457 continue;
458 }
459 let bytes = frame.node.key_bytes(index);
460 K::check_bounds(bytes)?;
461 let key = K::from_bytes(Cow::Borrowed(bytes))?;
462 let value = (!keys_only).then(|| frame.node.value(index));
463 frame.index = if forward { index + 1 } else { index };
464 frame.descend = !frame.node.children.is_empty();
467 return Ok(Some((key, value)));
468 }
469 Ok(None)
470 }
471 pub fn range(&self, bounds: impl RangeBounds<K>) -> TreeIter<'_, K, V, M> {
472 let lower = bounds.start_bound().cloned();
473 let upper = bounds.end_bound().cloned();
474 let invalid = match (&lower, &upper) {
475 (Bound::Included(a) | Bound::Excluded(a), Bound::Included(b) | Bound::Excluded(b)) => {
476 a > b
477 || (a == b
478 && matches!((&lower, &upper), (Bound::Excluded(_), Bound::Excluded(_))))
479 }
480 _ => false,
481 };
482 TreeIter {
483 tree: self,
484 lower,
485 upper,
486 front: None,
487 back: None,
488 exhausted: false,
489 invalid,
490 keys_only: false,
491 }
492 }
493 pub fn keys_range(
494 &self,
495 bounds: impl RangeBounds<K>,
496 ) -> impl DoubleEndedIterator<Item = Result<K>> + '_ {
497 let mut iter = self.range(bounds);
498 iter.keys_only = true;
499 iter.map(|e| e.map(MapEntry::into_key))
500 }
501}
502struct Frame {
503 node: Rc<ReadNode>,
504 index: usize,
505 descend: bool,
506}
507fn decode<T: Storable>(bytes: Vec<u8>) -> Result<T> {
508 T::check_bounds(&bytes)?;
509 Ok(T::from_bytes(Cow::Owned(bytes))?)
510}
511
512type Split = Option<(Entry, Pointer)>;
513struct Transaction<'a, K, V, M: Memory> {
514 tree: &'a Tree<K, V, M>,
515 root: Root,
516 writes: BTreeMap<u64, Vec<u8>>,
517}
518impl<'a, K: Storable + Ord + Clone, V: Storable, M: Memory> Transaction<'a, K, V, M> {
519 fn new(tree: &'a Tree<K, V, M>) -> Self {
520 Self {
521 tree,
522 root: tree.root.borrow().clone(),
523 writes: BTreeMap::new(),
524 }
525 }
526 fn bytes(&self, p: Pointer, magic: [u8; 8]) -> Result<Vec<u8>> {
527 p.check(self.root.cursor)?;
528 self.writes.get(&p.offset).map_or_else(
529 || record::read_bytes(&self.tree.memory, p.offset, p.capacity(), magic),
530 |bytes| Ok(bytes.clone()),
531 )
532 }
533 fn node(&self, p: Pointer, depth: usize) -> Result<Node> {
534 Ok(self.read_node(p, depth)?.owned())
535 }
536 fn read_node(&self, p: Pointer, depth: usize) -> Result<Rc<ReadNode>> {
537 if let Some(bytes) = self.writes.get(&p.offset) {
538 Ok(Rc::new(ReadNode::decode::<K, V>(
539 bytes.clone(),
540 self.root.cursor,
541 )?))
542 } else {
543 self.tree.read_node(p, depth)
544 }
545 }
546 fn value(&self, v: &Value) -> Result<Vec<u8>> {
547 let bytes = match v {
548 Value::Inline(b) => b.clone(),
549 Value::External(p) => {
550 p.check(self.root.cursor)?;
551 if let Some(bytes) = self.writes.get(&p.offset) {
552 record::decode_payload(VALUE, bytes)?.to_vec()
553 } else {
554 record::read_payload(&self.tree.memory, p.offset, p.capacity(), VALUE)?
555 }
556 }
557 };
558 V::check_bounds(&bytes)?;
559 Ok(bytes)
560 }
561 fn free(&mut self, p: Pointer) -> Result<()> {
562 let index = usize::from(p.order);
563 self.writes
564 .insert(p.offset, record::encode(FREE, &self.root.free[index])?);
565 self.root.free[index] = Some(p);
566 Ok(())
567 }
568 fn allocate(&mut self, len: usize) -> Result<Pointer> {
569 let size = len
570 .max(256)
571 .checked_next_power_of_two()
572 .ok_or(Error::Budget)?;
573 let order = size.trailing_zeros() as usize;
574 ensure(order < BINS, Error::Budget)?;
575 for bin in order..BINS {
576 if let Some(mut p) = self.root.free[bin] {
577 let next: Option<Pointer> = record::decode(FREE, &self.bytes(p, FREE)?)?;
578 if let Some(next) = next {
579 next.check(self.root.cursor)?;
580 ensure(
581 next.order == p.order && next != p,
582 Error::Corrupt("map free-list link"),
583 )?;
584 }
585 self.root.free[bin] = next;
586 while usize::from(p.order) > order {
589 p.order -= 1;
590 let sibling = Pointer {
591 offset: p.offset + p.capacity(),
592 order: p.order,
593 };
594 self.free(sibling)?;
595 }
596 return Ok(p);
597 }
598 }
599 let p = Pointer {
600 offset: self.root.cursor,
601 order: u8::try_from(order).unwrap(),
602 };
603 self.root.cursor = self
604 .root
605 .cursor
606 .checked_add(p.capacity())
607 .ok_or(Error::Budget)?;
608 Ok(p)
609 }
610 fn save_bytes(&mut self, previous: Option<Pointer>, bytes: Vec<u8>) -> Result<Pointer> {
611 let p = if let Some(p) = previous.filter(|p| p.capacity() >= bytes.len() as u64) {
612 let needed = bytes.len().max(256).next_power_of_two() as u64;
613 let smaller_available = (needed.trailing_zeros() as usize..usize::from(p.order))
617 .any(|order| self.root.free[order].is_some());
618 if p.capacity() / needed >= 4 && smaller_available {
619 let smaller = self.allocate(bytes.len())?;
620 self.free(p)?;
621 smaller
622 } else {
623 p
624 }
625 } else {
626 if let Some(p) = previous {
627 self.free(p)?;
628 }
629 self.allocate(bytes.len())?
630 };
631 self.writes.insert(p.offset, bytes);
632 Ok(p)
633 }
634 fn save(&mut self, p: Option<Pointer>, node: &Node) -> Result<Pointer> {
635 self.save_bytes(p, node.encode()?)
636 }
637 fn save_value(&mut self, previous: Option<&Value>, bytes: Vec<u8>) -> Result<Value> {
638 let old = match previous {
639 Some(Value::External(p)) => Some(*p),
640 _ => None,
641 };
642 if bytes.len() <= INLINE {
643 if let Some(p) = old {
644 self.free(p)?;
645 }
646 Ok(Value::Inline(bytes))
647 } else {
648 Ok(Value::External(
649 self.save_bytes(old, record::encode_payload(VALUE, &bytes)?)?,
650 ))
651 }
652 }
653 fn insert(
654 &mut self,
655 p: Option<Pointer>,
656 key: &K,
657 key_bytes: Vec<u8>,
658 bytes: Vec<u8>,
659 depth: usize,
660 ) -> Result<(Pointer, Split, Option<Vec<u8>>)> {
661 ensure(
662 depth < MAX_DEPTH,
663 Error::Corrupt("map path exceeds height bound"),
664 )?;
665 let read = p.map(|p| self.read_node(p, depth)).transpose()?;
666 let search = read.as_ref().map_or(Ok(Err(0)), |node| node.search(key))?;
667 let (mut node, old) = match search {
668 Ok(i) => {
669 let read = read.as_ref().unwrap();
670 let previous = read.value(i);
671 let old = self.value(&previous)?;
672 let value = self.save_value(Some(&previous), bytes)?;
673 let same_pointer =
674 matches!((&previous,&value),(Value::External(a),Value::External(b)) if a==b);
675 if same_pointer {
676 return Ok((p.unwrap(), None, Some(old)));
677 }
678 if let (Value::Inline(_), Value::Inline(bytes)) = (&previous, &value) {
679 let next = self.save_bytes(p, read.replace_inline(i, bytes)?)?;
680 return Ok((next, None, Some(old)));
681 }
682 let mut node = read.owned();
683 node.entries[i].value = value;
684 (node, Some(old))
685 }
686 Err(i) => {
687 if let Some(child) = read.as_ref().and_then(|node| node.children.get(i)).copied() {
688 let (next, split, old) =
689 self.insert(Some(child), key, key_bytes, bytes, depth + 1)?;
690 if split.is_none() && next == child {
691 return Ok((p.unwrap(), None, old));
692 }
693 let mut node = read.as_ref().unwrap().owned();
694 node.children[i] = next;
695 if let Some((entry, right)) = split {
696 node.entries.insert(i, entry);
697 node.children.insert(i + 1, right);
698 }
699 (node, old)
700 } else {
701 let value = self.save_value(None, bytes)?;
702 let mut node = read
703 .as_ref()
704 .map_or_else(Node::default, |node| node.owned());
705 node.entries.insert(
706 i,
707 Entry {
708 key: key_bytes,
709 value,
710 },
711 );
712 self.root.length = self.root.length.checked_add(1).ok_or(Error::Budget)?;
713 (node, None)
714 }
715 }
716 };
717 let split = if node.entries.len() > MAX_ENTRIES {
718 let right_entries = node.entries.split_off(DEGREE + 1);
719 let median = node.entries.pop().unwrap();
720 let children = if node.children.is_empty() {
721 vec![]
722 } else {
723 node.children.split_off(DEGREE + 1)
724 };
725 let right = self.save(
726 None,
727 &Node {
728 entries: right_entries,
729 children,
730 },
731 )?;
732 Some((median, right))
733 } else {
734 None
735 };
736 Ok((self.save(p, &node)?, split, old))
737 }
738 fn remove(
741 &mut self,
742 p: Pointer,
743 key: &K,
744 depth: usize,
745 ) -> Result<(Option<Node>, Option<Vec<u8>>)> {
746 ensure(
747 depth < MAX_DEPTH,
748 Error::Corrupt("map path exceeds height bound"),
749 )?;
750 let read = self.read_node(p, depth)?;
751 match read.search(key)? {
752 Ok(i) => {
753 let mut node = read.owned();
754 let old = self.value(&node.entries[i].value)?;
755 if let Value::External(p) = node.entries[i].value {
756 self.free(p)?;
757 }
758 if node.children.is_empty() {
759 node.entries.remove(i);
760 } else {
761 let child_pointer = node.children[i + 1];
762 let (child, entry) = self.extract_min(child_pointer, depth + 1)?;
763 node.entries[i] = entry;
764 if let Some(child) = child {
765 self.finish_child(&mut node, i + 1, child, depth)?;
766 }
767 }
768 Ok((Some(node), Some(old)))
769 }
770 Err(i) => {
771 let Some(child_pointer) = read.children.get(i).copied() else {
772 return Ok((None, None));
773 };
774 let (child, old) = self.remove(child_pointer, key, depth + 1)?;
775 let node = child
776 .map(|child| self.changed_parent(&read, i, child, depth))
777 .transpose()?
778 .flatten();
779 Ok((node, old))
780 }
781 }
782 }
783 fn extract_min(&mut self, p: Pointer, depth: usize) -> Result<(Option<Node>, Entry)> {
784 ensure(
785 depth < MAX_DEPTH,
786 Error::Corrupt("map path exceeds height bound"),
787 )?;
788 let read = self.read_node(p, depth)?;
789 ensure(read.len() != 0, Error::Corrupt("empty successor node"))?;
790 if read.children.is_empty() {
791 let mut node = read.owned();
792 let entry = node.entries.remove(0);
793 Ok((Some(node), entry))
794 } else {
795 let (child, entry) = self.extract_min(read.children[0], depth + 1)?;
796 let node = child
797 .map(|child| self.changed_parent(&read, 0, child, depth))
798 .transpose()?
799 .flatten();
800 Ok((node, entry))
801 }
802 }
803 fn changed_parent(
806 &mut self,
807 read: &ReadNode,
808 i: usize,
809 child: Node,
810 depth: usize,
811 ) -> Result<Option<Node>> {
812 if child.entries.len() >= MIN_ENTRIES {
813 let previous = read.children[i];
814 let next = self.save(Some(previous), &child)?;
815 if next == previous {
816 return Ok(None);
817 }
818 let mut parent = read.owned();
819 parent.children[i] = next;
820 Ok(Some(parent))
821 } else {
822 let mut parent = read.owned();
823 self.rebalance(&mut parent, i, child, depth)?;
824 Ok(Some(parent))
825 }
826 }
827 fn finish_child(
828 &mut self,
829 parent: &mut Node,
830 i: usize,
831 child: Node,
832 depth: usize,
833 ) -> Result<()> {
834 if child.entries.len() >= MIN_ENTRIES {
835 parent.children[i] = self.save(Some(parent.children[i]), &child)?;
836 Ok(())
837 } else {
838 self.rebalance(parent, i, child, depth)
839 }
840 }
841 fn rebalance(
842 &mut self,
843 parent: &mut Node,
844 i: usize,
845 mut child: Node,
846 parent_depth: usize,
847 ) -> Result<()> {
848 let depth = parent_depth + 1;
849 let p = parent.children[i];
850 let mut left = if i > 0 {
851 Some(self.node(parent.children[i - 1], depth)?)
852 } else {
853 None
854 };
855 if let Some(left) = &mut left {
856 ensure(
857 left.children.is_empty() == child.children.is_empty(),
858 Error::Corrupt("B-tree sibling levels"),
859 )?;
860 if left.entries.len() > MIN_ENTRIES {
861 child.entries.insert(
862 0,
863 std::mem::replace(&mut parent.entries[i - 1], left.entries.pop().unwrap()),
864 );
865 if let Some(p) = left.children.pop() {
866 child.children.insert(0, p);
867 }
868 parent.children[i - 1] = self.save(Some(parent.children[i - 1]), left)?;
869 parent.children[i] = self.save(Some(p), &child)?;
870 return Ok(());
871 }
872 }
873 let mut right = if i + 1 < parent.children.len() {
874 Some(self.node(parent.children[i + 1], depth)?)
875 } else {
876 None
877 };
878 if let Some(right) = &mut right {
879 ensure(
880 right.children.is_empty() == child.children.is_empty(),
881 Error::Corrupt("B-tree sibling levels"),
882 )?;
883 if right.entries.len() > MIN_ENTRIES {
884 child.entries.push(std::mem::replace(
885 &mut parent.entries[i],
886 right.entries.remove(0),
887 ));
888 if !right.children.is_empty() {
889 child.children.push(right.children.remove(0));
890 }
891 parent.children[i + 1] = self.save(Some(parent.children[i + 1]), right)?;
892 parent.children[i] = self.save(Some(p), &child)?;
893 return Ok(());
894 }
895 }
896 let (left_index, mut left, right) = if let Some(left) = left {
897 (i - 1, left, child)
898 } else {
899 (
900 i,
901 child,
902 right.ok_or(Error::Corrupt("B-tree missing separator"))?,
903 )
904 };
905 ensure(
906 left_index < parent.entries.len(),
907 Error::Corrupt("B-tree missing separator"),
908 )?;
909 let left_p = parent.children[left_index];
910 let right_p = parent.children[left_index + 1];
911 left.entries.push(parent.entries.remove(left_index));
912 left.entries.extend(right.entries);
913 left.children.extend(right.children);
914 self.free(right_p)?;
915 parent.children[left_index] = self.save(Some(left_p), &left)?;
916 parent.children.remove(left_index + 1);
917 Ok(())
918 }
919 fn commit(self) -> Result<()> {
920 let changed = self.root != *self.tree.root.borrow();
921 let header = if changed {
922 Some(record::encode(MAGIC, &self.root)?)
923 } else {
924 None
925 };
926 if let Some(h) = &header {
927 ensure(h.len() as u64 <= record::HEADER_BYTES, Error::Budget)?;
928 }
929 record::reserve(&self.tree.memory, self.root.cursor)?;
930 self.tree.poisoned.set(true);
931 if self.root.cursor < self.tree.root.borrow().cursor
932 || self.root.top != self.tree.root.borrow().top
933 {
934 self.tree.cache.borrow_mut().clear();
935 }
936 for (offset, bytes) in self.writes {
937 self.tree.cache.borrow_mut().invalidate(offset);
938 self.tree.memory.write(offset, &bytes);
939 }
940 if let Some(h) = header {
941 self.tree.memory.write(0, &h);
942 }
943 *self.tree.root.borrow_mut() = self.root;
944 self.tree.poisoned.set(false);
945 Ok(())
946 }
947}
948pub struct MapEntry<K, V> {
954 key: K,
955 bytes: Vec<u8>,
956 value: PhantomData<V>,
957}
958impl<K, V: Storable> MapEntry<K, V> {
959 pub const fn key(&self) -> &K {
961 &self.key
962 }
963 pub fn value(&self) -> Result<V> {
968 V::check_bounds(&self.bytes)?;
969 Ok(V::from_bytes(Cow::Borrowed(&self.bytes))?)
970 }
971 pub fn into_pair(self) -> Result<(K, V)> {
976 Ok((self.key, decode(self.bytes)?))
977 }
978 pub fn into_key(self) -> K {
980 self.key
981 }
982 pub fn into_value(self) -> Result<V> {
987 decode(self.bytes)
988 }
989}
990
991pub struct TreeIter<'a, K, V, M: Memory> {
998 tree: &'a Tree<K, V, M>,
999 lower: Bound<K>,
1000 upper: Bound<K>,
1001 front: Option<Vec<Frame>>,
1002 back: Option<Vec<Frame>>,
1003 exhausted: bool,
1004 invalid: bool,
1005 keys_only: bool,
1006}
1007impl<K: Storable + Ord + Clone, V: Storable, M: Memory> TreeIter<'_, K, V, M> {
1008 fn step(&mut self, forward: bool) -> Result<Option<MapEntry<K, V>>> {
1009 ensure(!self.invalid, Error::Bounds)?;
1010 self.tree.healthy()?;
1011 let empty = match (&self.lower, &self.upper) {
1012 (Bound::Included(a), Bound::Included(b)) => a > b,
1013 (Bound::Included(a) | Bound::Excluded(a), Bound::Included(b) | Bound::Excluded(b)) => {
1014 a >= b
1015 }
1016 _ => false,
1017 };
1018 if empty {
1019 return Ok(None);
1020 }
1021 let (path, bound) = if forward {
1022 (&mut self.front, &self.lower)
1023 } else {
1024 (&mut self.back, &self.upper)
1025 };
1026 if path.is_none() {
1027 *path = Some(self.tree.seek_path(bound, forward)?);
1028 }
1029 let entry = self
1030 .tree
1031 .advance_path(path.as_mut().unwrap(), forward, self.keys_only)?;
1032 if let Some((key, value)) = entry {
1033 let after = match &self.lower {
1034 Bound::Unbounded => true,
1035 Bound::Included(k) => key >= *k,
1036 Bound::Excluded(k) => key > *k,
1037 };
1038 let before = match &self.upper {
1039 Bound::Unbounded => true,
1040 Bound::Included(k) => key <= *k,
1041 Bound::Excluded(k) => key < *k,
1042 };
1043 ensure(
1044 if forward { after } else { before },
1045 Error::Corrupt("map cursor key order"),
1046 )?;
1047 if !(after && before) {
1048 return Ok(None);
1049 }
1050 if forward {
1051 self.lower = Bound::Excluded(key.clone());
1052 } else {
1053 self.upper = Bound::Excluded(key.clone());
1054 }
1055 return Ok(Some(MapEntry {
1056 key,
1057 bytes: value
1058 .map(|value| self.tree.value(value))
1059 .transpose()?
1060 .unwrap_or_default(),
1061 value: PhantomData,
1062 }));
1063 }
1064 Ok(None)
1065 }
1066 fn advance(&mut self, forward: bool) -> Option<Result<MapEntry<K, V>>> {
1067 if self.exhausted {
1068 return None;
1069 }
1070 match self.step(forward) {
1071 Ok(Some(entry)) => Some(Ok(entry)),
1072 Ok(None) => {
1073 self.exhausted = true;
1074 None
1075 }
1076 Err(error) => {
1077 self.exhausted = true;
1078 Some(Err(error))
1079 }
1080 }
1081 }
1082}
1083impl<K: Storable + Ord + Clone, V: Storable, M: Memory> Iterator for TreeIter<'_, K, V, M> {
1084 type Item = Result<MapEntry<K, V>>;
1085 fn next(&mut self) -> Option<Self::Item> {
1086 self.advance(true)
1087 }
1088}
1089impl<K: Storable + Ord + Clone, V: Storable, M: Memory> DoubleEndedIterator
1090 for TreeIter<'_, K, V, M>
1091{
1092 fn next_back(&mut self) -> Option<Self::Item> {
1093 self.advance(false)
1094 }
1095}
1096impl<K: Storable + Ord + Clone, V: Storable, M: Memory> std::iter::FusedIterator
1097 for TreeIter<'_, K, V, M>
1098{
1099}
1100
1101#[cfg(test)]
1102mod tests;