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