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 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 pub fn insert(&mut self, key: K, value: V) -> Result<Option<V>> {
308 self.healthy()?;
309 let key_bytes = key.to_bytes_checked()?.into_owned();
310 let bytes = value.into_bytes_checked()?;
311 let mut tx = Transaction::new(self);
312 let (top, split, old) = tx.insert(tx.root.top, &key, key_bytes, bytes, 0)?;
313 tx.root.top = Some(if let Some((entry, right)) = split {
314 tx.save(
315 None,
316 &Node {
317 entries: vec![entry],
318 children: vec![top, right],
319 },
320 )?
321 } else {
322 top
323 });
324 drop(key);
325 let old = old.map(decode).transpose()?;
326 tx.commit()?;
327 Ok(old)
328 }
329 pub fn remove(&mut self, key: &K) -> Result<Option<V>> {
330 self.healthy()?;
331 let mut tx = Transaction::new(self);
332 let Some(top) = tx.root.top else {
333 return Ok(None);
334 };
335 let (changed, old) = tx.remove(top, key, 0)?;
336 let Some(old) = old else { return Ok(None) };
337 let value = decode(old)?;
338 if let Some(node) = changed {
339 tx.root.top = if node.entries.is_empty() {
340 tx.free(top)?;
341 node.children.first().copied()
342 } else {
343 Some(tx.save(Some(top), &node)?)
344 };
345 }
346 tx.root.length -= 1;
347 tx.commit()?;
348 Ok(Some(value))
349 }
350 pub fn clear(&mut self) -> Result<()> {
351 self.healthy()?;
352 let mut tx = Transaction::new(self);
353 tx.root.top = None;
354 tx.root.length = 0;
355 tx.root.cursor = record::HEADER_BYTES;
356 tx.root.free.fill(None);
357 tx.commit()
358 }
359 fn seek_path(&self, bound: &Bound<K>, forward: bool) -> Result<Vec<Frame>> {
360 self.healthy()?;
361 let mut path = Vec::new();
362 let mut pointer = self.root.borrow().top;
363 while let Some(p) = pointer {
364 ensure(
365 path.len() < MAX_DEPTH,
366 Error::Corrupt("map cursor exceeds height bound"),
367 )?;
368 let node = self.read_node(p, path.len())?;
369 let index = match bound {
370 Bound::Unbounded => {
371 if forward {
372 0
373 } else {
374 node.len()
375 }
376 }
377 Bound::Included(k) => match node.search(k)? {
378 Ok(i) => {
379 if forward {
380 i
381 } else {
382 i + 1
383 }
384 }
385 Err(i) => i,
386 },
387 Bound::Excluded(k) => match node.search(k)? {
388 Ok(i) => {
389 if forward {
390 i + 1
391 } else {
392 i
393 }
394 }
395 Err(i) => i,
396 },
397 };
398 pointer = node.children.get(index).copied();
399 path.push(Frame {
400 node,
401 index,
402 descend: false,
403 });
404 }
405 Ok(path)
406 }
407 fn advance_path(
408 &self,
409 path: &mut Vec<Frame>,
410 forward: bool,
411 keys_only: bool,
412 ) -> Result<Option<(K, Option<Value>)>> {
413 self.healthy()?;
414 while let Some(frame) = path.last_mut() {
415 if frame.descend {
416 frame.descend = false;
417 let mut child = frame.node.children.get(frame.index).copied();
418 while let Some(p) = child {
419 ensure(
420 path.len() < MAX_DEPTH,
421 Error::Corrupt("map cursor exceeds height bound"),
422 )?;
423 let node = self.read_node(p, path.len())?;
424 let index = if forward { 0 } else { node.len() };
425 child = node.children.get(index).copied();
426 path.push(Frame {
427 node,
428 index,
429 descend: false,
430 });
431 }
432 continue;
433 }
434 let index = if forward {
435 frame.index
436 } else {
437 if frame.index == 0 {
438 path.pop();
439 continue;
440 }
441 frame.index - 1
442 };
443 if index >= frame.node.len() {
444 path.pop();
445 continue;
446 }
447 let bytes = frame.node.key_bytes(index);
448 K::check_bounds(bytes)?;
449 let key = K::from_bytes(Cow::Borrowed(bytes))?;
450 let value = (!keys_only).then(|| frame.node.value(index));
451 frame.index = if forward { index + 1 } else { index };
452 frame.descend = !frame.node.children.is_empty();
455 return Ok(Some((key, value)));
456 }
457 Ok(None)
458 }
459 pub fn range(&self, bounds: impl RangeBounds<K>) -> TreeIter<'_, K, V, M> {
460 let lower = bounds.start_bound().cloned();
461 let upper = bounds.end_bound().cloned();
462 let invalid = match (&lower, &upper) {
463 (Bound::Included(a) | Bound::Excluded(a), Bound::Included(b) | Bound::Excluded(b)) => {
464 a > b
465 || (a == b
466 && matches!((&lower, &upper), (Bound::Excluded(_), Bound::Excluded(_))))
467 }
468 _ => false,
469 };
470 TreeIter {
471 tree: self,
472 lower,
473 upper,
474 front: None,
475 back: None,
476 exhausted: false,
477 invalid,
478 keys_only: false,
479 }
480 }
481 pub fn keys_range(
482 &self,
483 bounds: impl RangeBounds<K>,
484 ) -> impl DoubleEndedIterator<Item = Result<K>> + '_ {
485 let mut iter = self.range(bounds);
486 iter.keys_only = true;
487 iter.map(|e| e.map(MapEntry::into_key))
488 }
489}
490struct Frame {
491 node: Rc<ReadNode>,
492 index: usize,
493 descend: bool,
494}
495fn decode<T: Storable>(bytes: Vec<u8>) -> Result<T> {
496 T::check_bounds(&bytes)?;
497 Ok(T::from_bytes(Cow::Owned(bytes))?)
498}
499
500type Split = Option<(Entry, Pointer)>;
501struct Transaction<'a, K, V, M: Memory> {
502 tree: &'a Tree<K, V, M>,
503 root: Root,
504 writes: BTreeMap<u64, Vec<u8>>,
505}
506impl<'a, K: Storable + Ord + Clone, V: Storable, M: Memory> Transaction<'a, K, V, M> {
507 fn new(tree: &'a Tree<K, V, M>) -> Self {
508 Self {
509 tree,
510 root: tree.root.borrow().clone(),
511 writes: BTreeMap::new(),
512 }
513 }
514 fn bytes(&self, p: Pointer, magic: [u8; 8]) -> Result<Vec<u8>> {
515 p.check(self.root.cursor)?;
516 if let Some(bytes) = self.writes.get(&p.offset) {
517 Ok(bytes.clone())
518 } else {
519 record::read_bytes(&self.tree.memory, p.offset, p.capacity(), magic)
520 }
521 }
522 fn node(&self, p: Pointer, depth: usize) -> Result<Node> {
523 Ok(self.read_node(p, depth)?.owned())
524 }
525 fn read_node(&self, p: Pointer, depth: usize) -> Result<Rc<ReadNode>> {
526 if let Some(bytes) = self.writes.get(&p.offset) {
527 Ok(Rc::new(ReadNode::decode::<K, V>(
528 bytes.clone(),
529 self.root.cursor,
530 )?))
531 } else {
532 self.tree.read_node(p, depth)
533 }
534 }
535 fn value(&self, v: &Value) -> Result<Vec<u8>> {
536 let bytes = match v {
537 Value::Inline(b) => b.clone(),
538 Value::External(p) => {
539 p.check(self.root.cursor)?;
540 if let Some(bytes) = self.writes.get(&p.offset) {
541 record::decode_payload(VALUE, bytes)?.to_vec()
542 } else {
543 record::read_payload(&self.tree.memory, p.offset, p.capacity(), VALUE)?
544 }
545 }
546 };
547 V::check_bounds(&bytes)?;
548 Ok(bytes)
549 }
550 fn free(&mut self, p: Pointer) -> Result<()> {
551 let index = usize::from(p.order);
552 self.writes
553 .insert(p.offset, record::encode(FREE, &self.root.free[index])?);
554 self.root.free[index] = Some(p);
555 Ok(())
556 }
557 fn allocate(&mut self, len: usize) -> Result<Pointer> {
558 let size = len
559 .max(256)
560 .checked_next_power_of_two()
561 .ok_or(Error::Budget)?;
562 let order = size.trailing_zeros() as usize;
563 ensure(order < BINS, Error::Budget)?;
564 for bin in order..BINS {
565 if let Some(mut p) = self.root.free[bin] {
566 let next: Option<Pointer> = record::decode(FREE, &self.bytes(p, FREE)?)?;
567 if let Some(next) = next {
568 next.check(self.root.cursor)?;
569 ensure(
570 next.order == p.order && next != p,
571 Error::Corrupt("map free-list link"),
572 )?;
573 }
574 self.root.free[bin] = next;
575 while usize::from(p.order) > order {
578 p.order -= 1;
579 let sibling = Pointer {
580 offset: p.offset + p.capacity(),
581 order: p.order,
582 };
583 self.free(sibling)?;
584 }
585 return Ok(p);
586 }
587 }
588 let p = Pointer {
589 offset: self.root.cursor,
590 order: u8::try_from(order).unwrap(),
591 };
592 self.root.cursor = self
593 .root
594 .cursor
595 .checked_add(p.capacity())
596 .ok_or(Error::Budget)?;
597 Ok(p)
598 }
599 fn save_bytes(&mut self, previous: Option<Pointer>, bytes: Vec<u8>) -> Result<Pointer> {
600 let p = if let Some(p) = previous.filter(|p| p.capacity() >= bytes.len() as u64) {
601 let needed = bytes.len().max(256).next_power_of_two() as u64;
602 let smaller_available = (needed.trailing_zeros() as usize..usize::from(p.order))
606 .any(|order| self.root.free[order].is_some());
607 if p.capacity() / needed >= 4 && smaller_available {
608 let smaller = self.allocate(bytes.len())?;
609 self.free(p)?;
610 smaller
611 } else {
612 p
613 }
614 } else {
615 if let Some(p) = previous {
616 self.free(p)?;
617 }
618 self.allocate(bytes.len())?
619 };
620 self.writes.insert(p.offset, bytes);
621 Ok(p)
622 }
623 fn save(&mut self, p: Option<Pointer>, node: &Node) -> Result<Pointer> {
624 self.save_bytes(p, node.encode()?)
625 }
626 fn save_value(&mut self, previous: Option<&Value>, bytes: Vec<u8>) -> Result<Value> {
627 let old = match previous {
628 Some(Value::External(p)) => Some(*p),
629 _ => None,
630 };
631 if bytes.len() <= INLINE {
632 if let Some(p) = old {
633 self.free(p)?;
634 }
635 Ok(Value::Inline(bytes))
636 } else {
637 Ok(Value::External(
638 self.save_bytes(old, record::encode_payload(VALUE, &bytes)?)?,
639 ))
640 }
641 }
642 fn insert(
643 &mut self,
644 p: Option<Pointer>,
645 key: &K,
646 key_bytes: Vec<u8>,
647 bytes: Vec<u8>,
648 depth: usize,
649 ) -> Result<(Pointer, Split, Option<Vec<u8>>)> {
650 ensure(
651 depth < MAX_DEPTH,
652 Error::Corrupt("map path exceeds height bound"),
653 )?;
654 let read = p.map(|p| self.read_node(p, depth)).transpose()?;
655 let search = read.as_ref().map_or(Ok(Err(0)), |node| node.search(key))?;
656 let (mut node, old) = match search {
657 Ok(i) => {
658 let read = read.as_ref().unwrap();
659 let previous = read.value(i);
660 let old = self.value(&previous)?;
661 let value = self.save_value(Some(&previous), bytes)?;
662 let same_pointer =
663 matches!((&previous,&value),(Value::External(a),Value::External(b)) if a==b);
664 if same_pointer {
665 return Ok((p.unwrap(), None, Some(old)));
666 }
667 if let (Value::Inline(_), Value::Inline(bytes)) = (&previous, &value) {
668 let next = self.save_bytes(p, read.replace_inline(i, bytes)?)?;
669 return Ok((next, None, Some(old)));
670 }
671 let mut node = read.owned();
672 node.entries[i].value = value;
673 (node, Some(old))
674 }
675 Err(i) => {
676 if let Some(child) = read.as_ref().and_then(|node| node.children.get(i)).copied() {
677 let (next, split, old) =
678 self.insert(Some(child), key, key_bytes, bytes, depth + 1)?;
679 if split.is_none() && next == child {
680 return Ok((p.unwrap(), None, old));
681 }
682 let mut node = read.as_ref().unwrap().owned();
683 node.children[i] = next;
684 if let Some((entry, right)) = split {
685 node.entries.insert(i, entry);
686 node.children.insert(i + 1, right);
687 }
688 (node, old)
689 } else {
690 let value = self.save_value(None, bytes)?;
691 let mut node = read
692 .as_ref()
693 .map_or_else(Node::default, |node| node.owned());
694 node.entries.insert(
695 i,
696 Entry {
697 key: key_bytes,
698 value,
699 },
700 );
701 self.root.length = self.root.length.checked_add(1).ok_or(Error::Budget)?;
702 (node, None)
703 }
704 }
705 };
706 let split = if node.entries.len() > MAX_ENTRIES {
707 let right_entries = node.entries.split_off(DEGREE + 1);
708 let median = node.entries.pop().unwrap();
709 let children = if node.children.is_empty() {
710 vec![]
711 } else {
712 node.children.split_off(DEGREE + 1)
713 };
714 let right = self.save(
715 None,
716 &Node {
717 entries: right_entries,
718 children,
719 },
720 )?;
721 Some((median, right))
722 } else {
723 None
724 };
725 Ok((self.save(p, &node)?, split, old))
726 }
727 fn remove(
730 &mut self,
731 p: Pointer,
732 key: &K,
733 depth: usize,
734 ) -> Result<(Option<Node>, Option<Vec<u8>>)> {
735 ensure(
736 depth < MAX_DEPTH,
737 Error::Corrupt("map path exceeds height bound"),
738 )?;
739 let read = self.read_node(p, depth)?;
740 match read.search(key)? {
741 Ok(i) => {
742 let mut node = read.owned();
743 let old = self.value(&node.entries[i].value)?;
744 if let Value::External(p) = node.entries[i].value {
745 self.free(p)?;
746 }
747 if node.children.is_empty() {
748 node.entries.remove(i);
749 } else {
750 let child_pointer = node.children[i + 1];
751 let (child, entry) = self.extract_min(child_pointer, depth + 1)?;
752 node.entries[i] = entry;
753 if let Some(child) = child {
754 self.finish_child(&mut node, i + 1, child, depth)?;
755 }
756 }
757 Ok((Some(node), Some(old)))
758 }
759 Err(i) => {
760 let Some(child_pointer) = read.children.get(i).copied() else {
761 return Ok((None, None));
762 };
763 let (child, old) = self.remove(child_pointer, key, depth + 1)?;
764 let node = child
765 .map(|child| self.changed_parent(&read, i, child, depth))
766 .transpose()?
767 .flatten();
768 Ok((node, old))
769 }
770 }
771 }
772 fn extract_min(&mut self, p: Pointer, depth: usize) -> Result<(Option<Node>, Entry)> {
773 ensure(
774 depth < MAX_DEPTH,
775 Error::Corrupt("map path exceeds height bound"),
776 )?;
777 let read = self.read_node(p, depth)?;
778 ensure(read.len() != 0, Error::Corrupt("empty successor node"))?;
779 if read.children.is_empty() {
780 let mut node = read.owned();
781 let entry = node.entries.remove(0);
782 Ok((Some(node), entry))
783 } else {
784 let (child, entry) = self.extract_min(read.children[0], depth + 1)?;
785 let node = child
786 .map(|child| self.changed_parent(&read, 0, child, depth))
787 .transpose()?
788 .flatten();
789 Ok((node, entry))
790 }
791 }
792 fn changed_parent(
795 &mut self,
796 read: &ReadNode,
797 i: usize,
798 child: Node,
799 depth: usize,
800 ) -> Result<Option<Node>> {
801 if child.entries.len() >= MIN_ENTRIES {
802 let previous = read.children[i];
803 let next = self.save(Some(previous), &child)?;
804 if next == previous {
805 return Ok(None);
806 }
807 let mut parent = read.owned();
808 parent.children[i] = next;
809 Ok(Some(parent))
810 } else {
811 let mut parent = read.owned();
812 self.rebalance(&mut parent, i, child, depth)?;
813 Ok(Some(parent))
814 }
815 }
816 fn finish_child(
817 &mut self,
818 parent: &mut Node,
819 i: usize,
820 child: Node,
821 depth: usize,
822 ) -> Result<()> {
823 if child.entries.len() >= MIN_ENTRIES {
824 parent.children[i] = self.save(Some(parent.children[i]), &child)?;
825 Ok(())
826 } else {
827 self.rebalance(parent, i, child, depth)
828 }
829 }
830 fn rebalance(
831 &mut self,
832 parent: &mut Node,
833 i: usize,
834 mut child: Node,
835 parent_depth: usize,
836 ) -> Result<()> {
837 let depth = parent_depth + 1;
838 let p = parent.children[i];
839 let mut left = if i > 0 {
840 Some(self.node(parent.children[i - 1], depth)?)
841 } else {
842 None
843 };
844 if let Some(left) = &mut left {
845 ensure(
846 left.children.is_empty() == child.children.is_empty(),
847 Error::Corrupt("B-tree sibling levels"),
848 )?;
849 if left.entries.len() > MIN_ENTRIES {
850 child.entries.insert(
851 0,
852 std::mem::replace(&mut parent.entries[i - 1], left.entries.pop().unwrap()),
853 );
854 if let Some(p) = left.children.pop() {
855 child.children.insert(0, p);
856 }
857 parent.children[i - 1] = self.save(Some(parent.children[i - 1]), left)?;
858 parent.children[i] = self.save(Some(p), &child)?;
859 return Ok(());
860 }
861 }
862 let mut right = if i + 1 < parent.children.len() {
863 Some(self.node(parent.children[i + 1], depth)?)
864 } else {
865 None
866 };
867 if let Some(right) = &mut right {
868 ensure(
869 right.children.is_empty() == child.children.is_empty(),
870 Error::Corrupt("B-tree sibling levels"),
871 )?;
872 if right.entries.len() > MIN_ENTRIES {
873 child.entries.push(std::mem::replace(
874 &mut parent.entries[i],
875 right.entries.remove(0),
876 ));
877 if !right.children.is_empty() {
878 child.children.push(right.children.remove(0));
879 }
880 parent.children[i + 1] = self.save(Some(parent.children[i + 1]), right)?;
881 parent.children[i] = self.save(Some(p), &child)?;
882 return Ok(());
883 }
884 }
885 let (left_index, mut left, right) = if let Some(left) = left {
886 (i - 1, left, child)
887 } else {
888 (
889 i,
890 child,
891 right.ok_or(Error::Corrupt("B-tree missing separator"))?,
892 )
893 };
894 ensure(
895 left_index < parent.entries.len(),
896 Error::Corrupt("B-tree missing separator"),
897 )?;
898 let left_p = parent.children[left_index];
899 let right_p = parent.children[left_index + 1];
900 left.entries.push(parent.entries.remove(left_index));
901 left.entries.extend(right.entries);
902 left.children.extend(right.children);
903 self.free(right_p)?;
904 parent.children[left_index] = self.save(Some(left_p), &left)?;
905 parent.children.remove(left_index + 1);
906 Ok(())
907 }
908 fn commit(self) -> Result<()> {
909 let changed = self.root != *self.tree.root.borrow();
910 let header = if changed {
911 Some(record::encode(MAGIC, &self.root)?)
912 } else {
913 None
914 };
915 if let Some(h) = &header {
916 ensure(h.len() as u64 <= record::HEADER_BYTES, Error::Budget)?;
917 }
918 record::reserve(&self.tree.memory, self.root.cursor)?;
919 self.tree.poisoned.set(true);
920 if self.root.cursor < self.tree.root.borrow().cursor
921 || self.root.top != self.tree.root.borrow().top
922 {
923 self.tree.cache.borrow_mut().clear();
924 }
925 for (offset, bytes) in self.writes {
926 self.tree.cache.borrow_mut().invalidate(offset);
927 self.tree.memory.write(offset, &bytes);
928 }
929 if let Some(h) = header {
930 self.tree.memory.write(0, &h);
931 }
932 *self.tree.root.borrow_mut() = self.root;
933 self.tree.poisoned.set(false);
934 Ok(())
935 }
936}
937pub struct MapEntry<K, V> {
943 key: K,
944 bytes: Vec<u8>,
945 value: PhantomData<V>,
946}
947impl<K, V: Storable> MapEntry<K, V> {
948 pub const fn key(&self) -> &K {
950 &self.key
951 }
952 pub fn value(&self) -> Result<V> {
957 V::check_bounds(&self.bytes)?;
958 Ok(V::from_bytes(Cow::Borrowed(&self.bytes))?)
959 }
960 pub fn into_pair(self) -> Result<(K, V)> {
965 Ok((self.key, decode(self.bytes)?))
966 }
967 pub fn into_key(self) -> K {
969 self.key
970 }
971 pub fn into_value(self) -> Result<V> {
976 decode(self.bytes)
977 }
978}
979
980pub struct TreeIter<'a, K, V, M: Memory> {
987 tree: &'a Tree<K, V, M>,
988 lower: Bound<K>,
989 upper: Bound<K>,
990 front: Option<Vec<Frame>>,
991 back: Option<Vec<Frame>>,
992 exhausted: bool,
993 invalid: bool,
994 keys_only: bool,
995}
996impl<K: Storable + Ord + Clone, V: Storable, M: Memory> TreeIter<'_, K, V, M> {
997 fn step(&mut self, forward: bool) -> Result<Option<MapEntry<K, V>>> {
998 ensure(!self.invalid, Error::Bounds)?;
999 self.tree.healthy()?;
1000 let empty = match (&self.lower, &self.upper) {
1001 (Bound::Included(a), Bound::Included(b)) => a > b,
1002 (Bound::Included(a) | Bound::Excluded(a), Bound::Included(b) | Bound::Excluded(b)) => {
1003 a >= b
1004 }
1005 _ => false,
1006 };
1007 if empty {
1008 return Ok(None);
1009 }
1010 let (path, bound) = if forward {
1011 (&mut self.front, &self.lower)
1012 } else {
1013 (&mut self.back, &self.upper)
1014 };
1015 if path.is_none() {
1016 *path = Some(self.tree.seek_path(bound, forward)?);
1017 }
1018 let entry = self
1019 .tree
1020 .advance_path(path.as_mut().unwrap(), forward, self.keys_only)?;
1021 if let Some((key, value)) = entry {
1022 let after = match &self.lower {
1023 Bound::Unbounded => true,
1024 Bound::Included(k) => key >= *k,
1025 Bound::Excluded(k) => key > *k,
1026 };
1027 let before = match &self.upper {
1028 Bound::Unbounded => true,
1029 Bound::Included(k) => key <= *k,
1030 Bound::Excluded(k) => key < *k,
1031 };
1032 ensure(
1033 if forward { after } else { before },
1034 Error::Corrupt("map cursor key order"),
1035 )?;
1036 if !(after && before) {
1037 return Ok(None);
1038 }
1039 if forward {
1040 self.lower = Bound::Excluded(key.clone());
1041 } else {
1042 self.upper = Bound::Excluded(key.clone());
1043 }
1044 return Ok(Some(MapEntry {
1045 key,
1046 bytes: value
1047 .map(|value| self.tree.value(value))
1048 .transpose()?
1049 .unwrap_or_default(),
1050 value: PhantomData,
1051 }));
1052 }
1053 Ok(None)
1054 }
1055 fn advance(&mut self, forward: bool) -> Option<Result<MapEntry<K, V>>> {
1056 if self.exhausted {
1057 return None;
1058 }
1059 match self.step(forward) {
1060 Ok(Some(entry)) => Some(Ok(entry)),
1061 Ok(None) => {
1062 self.exhausted = true;
1063 None
1064 }
1065 Err(error) => {
1066 self.exhausted = true;
1067 Some(Err(error))
1068 }
1069 }
1070 }
1071}
1072impl<K: Storable + Ord + Clone, V: Storable, M: Memory> Iterator for TreeIter<'_, K, V, M> {
1073 type Item = Result<MapEntry<K, V>>;
1074 fn next(&mut self) -> Option<Self::Item> {
1075 self.advance(true)
1076 }
1077}
1078impl<K: Storable + Ord + Clone, V: Storable, M: Memory> DoubleEndedIterator
1079 for TreeIter<'_, K, V, M>
1080{
1081 fn next_back(&mut self) -> Option<Self::Item> {
1082 self.advance(false)
1083 }
1084}
1085impl<K: Storable + Ord + Clone, V: Storable, M: Memory> std::iter::FusedIterator
1086 for TreeIter<'_, K, V, M>
1087{
1088}
1089
1090#[cfg(test)]
1091mod tests;