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