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