1use core::{
4 borrow::Borrow,
5 cmp::Ordering,
6 fmt,
7 marker::PhantomData,
8 mem::{size_of, MaybeUninit},
9 ops::{ControlFlow, Index},
10 ptr::addr_of_mut,
11 slice,
12};
13
14use munge::munge;
15use rancor::{fail, Fallible, Source};
16
17use crate::{
18 collections::util::IteratorLengthMismatch,
19 primitive::{ArchivedUsize, FixedUsize},
20 seal::Seal,
21 ser::{Allocator, Writer, WriterExt as _},
22 traits::NoUndef,
23 util::{InlineVec, SerVec},
24 Place, Portable, RelPtr, Serialize,
25};
26
27#[cfg(feature = "alloc")]
29mod iter;
30
31#[cfg(feature = "alloc")]
32pub use self::iter::*;
33
34const fn nodes_in_level<const E: usize>(i: u32) -> usize {
44 (E + 1).pow(i)
49}
50
51const fn entries_in_full_tree<const E: usize>(h: u32) -> usize {
52 nodes_in_level::<E>(h) - 1
65}
66
67const fn entries_to_height<const E: usize>(n: usize) -> u32 {
68 1 + n.ilog(E + 1)
104}
105
106const fn ll_entries<const E: usize>(height: u32, n: usize) -> usize {
107 n - entries_in_full_tree::<E>(height - 1)
112}
113
114#[derive(Clone, Copy, Portable)]
115#[cfg_attr(feature = "bytecheck", derive(bytecheck::CheckBytes))]
116#[rkyv(crate)]
117#[repr(u8)]
118enum NodeKind {
119 Leaf,
120 Inner,
121}
122
123unsafe impl NoUndef for NodeKind {}
126
127#[derive(Portable)]
128#[rkyv(crate)]
129#[repr(C)]
130struct Node<K, V, const E: usize> {
131 kind: NodeKind,
132 keys: [MaybeUninit<K>; E],
133 values: [MaybeUninit<V>; E],
134}
135
136#[derive(Portable)]
137#[rkyv(crate)]
138#[repr(C)]
139struct LeafNode<K, V, const E: usize> {
140 node: Node<K, V, E>,
141 len: ArchivedUsize,
142}
143
144#[cfg_attr(feature = "bytecheck", derive(bytecheck::CheckBytes))]
145#[derive(Portable)]
146#[rkyv(crate)]
147#[repr(C)]
148struct InnerNode<K, V, const E: usize> {
149 node: Node<K, V, E>,
150 lesser_nodes: [RelPtr<Node<K, V, E>>; E],
151 greater_node: RelPtr<Node<K, V, E>>,
152}
153
154const DEFAULT_ENTRIES_PER_NODE: usize = 5;
155
156#[cfg_attr(
158 feature = "bytecheck",
159 derive(bytecheck::CheckBytes),
160 bytecheck(verify)
161)]
162#[derive(Portable)]
163#[rkyv(crate)]
164#[repr(C)]
165pub struct ArchivedBTreeMap<K, V, const E: usize = DEFAULT_ENTRIES_PER_NODE> {
166 root: RelPtr<Node<K, V, E>>,
172 len: ArchivedUsize,
173 _phantom: PhantomData<(K, V)>,
174}
175
176impl<K, V, const E: usize> ArchivedBTreeMap<K, V, E> {
177 pub fn contains_key<Q>(&self, key: &Q) -> bool
179 where
180 Q: Ord + ?Sized,
181 K: Borrow<Q> + Ord,
182 {
183 self.get_key_value(key).is_some()
184 }
185
186 pub fn get<Q>(&self, key: &Q) -> Option<&V>
189 where
190 Q: Ord + ?Sized,
191 K: Borrow<Q> + Ord,
192 {
193 Some(self.get_key_value(key)?.1)
194 }
195
196 pub fn get_seal<'a, Q>(this: Seal<'a, Self>, key: &Q) -> Option<Seal<'a, V>>
199 where
200 Q: Ord + ?Sized,
201 K: Borrow<Q> + Ord,
202 {
203 Some(Self::get_key_value_seal(this, key)?.1)
204 }
205
206 pub fn is_empty(&self) -> bool {
208 self.len() == 0
209 }
210
211 pub fn len(&self) -> usize {
213 self.len.to_native() as usize
214 }
215
216 pub fn get_key_value<Q>(&self, key: &Q) -> Option<(&K, &V)>
219 where
220 Q: Ord + ?Sized,
221 K: Borrow<Q> + Ord,
222 {
223 self.get_key_value_with(key, |q, k| q.cmp(k.borrow()))
224 }
225
226 pub fn get_key_value_with<Q, C>(&self, key: &Q, cmp: C) -> Option<(&K, &V)>
232 where
233 Q: Ord + ?Sized,
234 C: Fn(&Q, &K) -> Ordering,
235 K: Ord,
236 {
237 let this = (self as *const Self).cast_mut();
238 Self::get_key_value_raw(this, key, cmp)
239 .map(|(k, v)| (unsafe { &*k }, unsafe { &*v }))
240 }
241
242 pub fn get_key_value_seal<'a, Q>(
245 this: Seal<'a, Self>,
246 key: &Q,
247 ) -> Option<(&'a K, Seal<'a, V>)>
248 where
249 Q: Ord + ?Sized,
250 K: Borrow<Q> + Ord,
251 {
252 Self::get_key_value_seal_with(this, key, |q, k| q.cmp(k.borrow()))
253 }
254
255 pub fn get_key_value_seal_with<'a, Q, C>(
261 this: Seal<'a, Self>,
262 key: &Q,
263 cmp: C,
264 ) -> Option<(&'a K, Seal<'a, V>)>
265 where
266 Q: Ord + ?Sized,
267 C: Fn(&Q, &K) -> Ordering,
268 K: Ord,
269 {
270 let this = unsafe { Seal::unseal_unchecked(this) as *mut Self };
271 Self::get_key_value_raw(this, key, cmp)
272 .map(|(k, v)| (unsafe { &*k }, Seal::new(unsafe { &mut *v })))
273 }
274
275 fn get_key_value_raw<Q, C>(
276 this: *mut Self,
277 key: &Q,
278 cmp: C,
279 ) -> Option<(*mut K, *mut V)>
280 where
281 Q: Ord + ?Sized,
282 C: Fn(&Q, &K) -> Ordering,
283 K: Ord,
284 {
285 let len = unsafe { (*this).len.to_native() };
286 if len == 0 {
287 return None;
288 }
289
290 let root_ptr = unsafe { addr_of_mut!((*this).root) };
291 let mut current = unsafe { RelPtr::as_ptr_raw(root_ptr) };
292 'outer: loop {
293 let kind = unsafe { (*current).kind };
294
295 match kind {
296 NodeKind::Leaf => {
297 let leaf = current.cast::<LeafNode<K, V, E>>();
298 let len = unsafe { (*leaf).len };
299
300 for i in 0..len.to_native() as usize {
301 let k = unsafe {
302 addr_of_mut!((*current).keys[i]).cast::<K>()
303 };
304 let ordering = cmp(key, unsafe { &*k });
305
306 match ordering {
307 Ordering::Equal => {
308 let v = unsafe {
309 addr_of_mut!((*current).values[i])
310 .cast::<V>()
311 };
312 return Some((k, v));
313 }
314 Ordering::Less => return None,
315 Ordering::Greater => (),
316 }
317 }
318
319 return None;
320 }
321 NodeKind::Inner => {
322 let inner = current.cast::<InnerNode<K, V, E>>();
323
324 for i in 0..E {
325 let k = unsafe {
326 addr_of_mut!((*current).keys[i]).cast::<K>()
327 };
328 let ordering = cmp(key, unsafe { &*k });
329
330 match ordering {
331 Ordering::Equal => {
332 let v = unsafe {
333 addr_of_mut!((*current).values[i])
334 .cast::<V>()
335 };
336 return Some((k, v));
337 }
338 Ordering::Less => {
339 let lesser = unsafe {
340 addr_of_mut!((*inner).lesser_nodes[i])
341 };
342 let lesser_is_invalid =
343 unsafe { RelPtr::is_invalid_raw(lesser) };
344 if !lesser_is_invalid {
345 current =
346 unsafe { RelPtr::as_ptr_raw(lesser) };
347 continue 'outer;
348 } else {
349 return None;
350 }
351 }
352 Ordering::Greater => (),
353 }
354 }
355
356 let inner = current.cast::<InnerNode<K, V, E>>();
357 let greater =
358 unsafe { addr_of_mut!((*inner).greater_node) };
359 let greater_is_invalid =
360 unsafe { RelPtr::is_invalid_raw(greater) };
361 if !greater_is_invalid {
362 current = unsafe { RelPtr::as_ptr_raw(greater) };
363 } else {
364 return None;
365 }
366 }
367 }
368 }
369 }
370
371 pub fn resolve_from_len(
374 len: usize,
375 resolver: BTreeMapResolver,
376 out: Place<Self>,
377 ) {
378 munge!(let ArchivedBTreeMap { root, len: out_len, _phantom: _ } = out);
379
380 if len == 0 {
381 RelPtr::emplace_invalid(root);
382 } else {
383 RelPtr::emplace(resolver.root_node_pos as usize, root);
384 }
385
386 out_len.write(ArchivedUsize::from_native(len as FixedUsize));
387 }
388
389 pub fn serialize_from_ordered_iter<I, BKU, BVU, KU, VU, S>(
391 mut iter: I,
392 serializer: &mut S,
393 ) -> Result<BTreeMapResolver, S::Error>
394 where
395 I: ExactSizeIterator<Item = (BKU, BVU)>,
396 BKU: Borrow<KU>,
397 BVU: Borrow<VU>,
398 KU: Serialize<S, Archived = K>,
399 VU: Serialize<S, Archived = V>,
400 S: Fallible + Allocator + Writer + ?Sized,
401 S::Error: Source,
402 {
403 let len = iter.len();
404
405 if len == 0 {
406 let actual = iter.count();
407 if actual != 0 {
408 fail!(IteratorLengthMismatch {
409 expected: 0,
410 actual,
411 });
412 }
413 return Ok(BTreeMapResolver { root_node_pos: 0 });
414 }
415
416 let height = entries_to_height::<E>(len);
417 let ll_entries = ll_entries::<E>(height, len);
418
419 SerVec::with_capacity(
420 serializer,
421 height as usize - 1,
422 |open_inners, serializer| {
423 for _ in 0..height - 1 {
424 open_inners
425 .push(InlineVec::<(BKU, BVU, Option<usize>), E>::new());
426 }
427
428 let mut open_leaf = InlineVec::<(BKU, BVU), E>::new();
429
430 let mut child_node_pos = None;
431 let mut leaf_entries = 0;
432 while let Some((key, value)) = iter.next() {
433 open_leaf.push((key, value));
434 leaf_entries += 1;
435
436 if leaf_entries == ll_entries
437 || open_leaf.len() == open_leaf.capacity()
438 {
439 child_node_pos =
441 Some(Self::close_leaf(&open_leaf, serializer)?);
442 open_leaf.clear();
443
444 if leaf_entries == ll_entries {
446 if let Some(mut inner) = open_inners.pop() {
447 while inner.len() < inner.capacity() {
448 if let Some((k, v)) = iter.next() {
449 inner.push((k, v, child_node_pos));
450 child_node_pos = None;
451 } else {
452 break;
453 }
454 }
455
456 child_node_pos = Some(Self::close_inner(
457 &inner,
458 child_node_pos,
459 serializer,
460 )?);
461 }
462 }
463
464 let mut popped = 0;
466 while let Some(last_inner) = open_inners.last_mut() {
467 if last_inner.len() == last_inner.capacity() {
468 child_node_pos = Some(Self::close_inner(
470 last_inner,
471 child_node_pos,
472 serializer,
473 )?);
474 open_inners.pop();
475 popped += 1;
476 } else {
477 let (key, value) = iter.next().unwrap();
478 last_inner.push((key, value, child_node_pos));
479 child_node_pos = None;
480 for _ in 0..popped {
481 open_inners.push(InlineVec::default());
482 }
483 break;
484 }
485 }
486 }
487 }
488
489 if !open_leaf.is_empty() {
490 child_node_pos =
492 Some(Self::close_leaf(&open_leaf, serializer)?);
493 open_leaf.clear();
494 }
495
496 while let Some(inner) = open_inners.pop() {
498 child_node_pos = Some(Self::close_inner(
499 &inner,
500 child_node_pos,
501 serializer,
502 )?);
503 }
504
505 debug_assert!(open_inners.is_empty());
506 debug_assert!(open_leaf.is_empty());
507
508 let leftovers = iter.count();
509 if leftovers != 0 {
510 fail!(IteratorLengthMismatch {
511 expected: len,
512 actual: len + leftovers,
513 });
514 }
515
516 Ok(BTreeMapResolver {
517 root_node_pos: child_node_pos.unwrap() as FixedUsize,
518 })
519 },
520 )?
521 }
522
523 fn close_leaf<BKU, BVU, KU, VU, S>(
524 items: &[(BKU, BVU)],
525 serializer: &mut S,
526 ) -> Result<usize, S::Error>
527 where
528 BKU: Borrow<KU>,
529 BVU: Borrow<VU>,
530 KU: Serialize<S, Archived = K>,
531 VU: Serialize<S, Archived = V>,
532 S: Writer + Fallible + ?Sized,
533 {
534 let mut resolvers = InlineVec::<(KU::Resolver, VU::Resolver), E>::new();
535 for (key, value) in items {
536 resolvers.push((
537 key.borrow().serialize(serializer)?,
538 value.borrow().serialize(serializer)?,
539 ));
540 }
541
542 let pos = serializer.align_for::<LeafNode<K, V, E>>()?;
543 let mut node = MaybeUninit::<LeafNode<K, V, E>>::uninit();
544 unsafe {
547 node.as_mut_ptr().write_bytes(0, 1);
548 }
549
550 let node_place =
551 unsafe { Place::new_unchecked(pos, node.as_mut_ptr()) };
552
553 munge! {
554 let LeafNode {
555 node: Node {
556 kind,
557 keys,
558 values,
559 },
560 len,
561 } = node_place;
562 }
563 kind.write(NodeKind::Leaf);
564 len.write(ArchivedUsize::from_native(items.len() as FixedUsize));
565 for (i, ((k, v), (kr, vr))) in
566 items.iter().zip(resolvers.drain()).enumerate()
567 {
568 let out_key = unsafe { keys.index(i).cast_unchecked() };
569 k.borrow().resolve(kr, out_key);
570 let out_value = unsafe { values.index(i).cast_unchecked() };
571 v.borrow().resolve(vr, out_value);
572 }
573
574 let bytes = unsafe {
575 slice::from_raw_parts(
576 node.as_ptr().cast::<u8>(),
577 size_of::<LeafNode<K, V, E>>(),
578 )
579 };
580 serializer.write(bytes)?;
581
582 Ok(pos)
583 }
584
585 fn close_inner<BKU, BVU, KU, VU, S>(
586 items: &[(BKU, BVU, Option<usize>)],
587 greater_node_pos: Option<usize>,
588 serializer: &mut S,
589 ) -> Result<usize, S::Error>
590 where
591 BKU: Borrow<KU>,
592 BVU: Borrow<VU>,
593 KU: Serialize<S, Archived = K>,
594 VU: Serialize<S, Archived = V>,
595 S: Writer + Fallible + ?Sized,
596 {
597 debug_assert_eq!(items.len(), E);
598
599 let mut resolvers = InlineVec::<(KU::Resolver, VU::Resolver), E>::new();
600 for (key, value, _) in items {
601 resolvers.push((
602 key.borrow().serialize(serializer)?,
603 value.borrow().serialize(serializer)?,
604 ));
605 }
606
607 let pos = serializer.align_for::<InnerNode<K, V, E>>()?;
608 let mut node = MaybeUninit::<InnerNode<K, V, E>>::uninit();
609 unsafe {
612 node.as_mut_ptr().write_bytes(0, 1);
613 }
614
615 let node_place =
616 unsafe { Place::new_unchecked(pos, node.as_mut_ptr()) };
617
618 munge! {
619 let InnerNode {
620 node: Node {
621 kind,
622 keys,
623 values,
624 },
625 lesser_nodes,
626 greater_node,
627 } = node_place;
628 }
629
630 kind.write(NodeKind::Inner);
631 for (i, ((k, v, l), (kr, vr))) in
632 items.iter().zip(resolvers.drain()).enumerate()
633 {
634 let out_key = unsafe { keys.index(i).cast_unchecked() };
635 k.borrow().resolve(kr, out_key);
636 let out_value = unsafe { values.index(i).cast_unchecked() };
637 v.borrow().resolve(vr, out_value);
638
639 let out_lesser_node = unsafe { lesser_nodes.index(i) };
640 if let Some(lesser_node) = l {
641 RelPtr::emplace(*lesser_node, out_lesser_node);
642 } else {
643 RelPtr::emplace_invalid(out_lesser_node);
644 }
645 }
646
647 if let Some(greater_node_pos) = greater_node_pos {
648 RelPtr::emplace(greater_node_pos, greater_node);
649 } else {
650 RelPtr::emplace_invalid(greater_node);
651 }
652
653 let bytes = unsafe {
654 slice::from_raw_parts(
655 node.as_ptr().cast::<u8>(),
656 size_of::<InnerNode<K, V, E>>(),
657 )
658 };
659 serializer.write(bytes)?;
660
661 Ok(pos)
662 }
663
664 pub fn visit<T>(
670 &self,
671 mut f: impl FnMut(&K, &V) -> ControlFlow<T>,
672 ) -> Option<T> {
673 if self.is_empty() {
674 None
675 } else {
676 let root = &self.root;
677 let root_ptr = unsafe { root.as_ptr().cast::<Node<K, V, E>>() };
678 let mut call_inner = |k: *mut K, v: *mut V| unsafe { f(&*k, &*v) };
679 match Self::visit_raw(root_ptr.cast_mut(), &mut call_inner) {
680 ControlFlow::Continue(()) => None,
681 ControlFlow::Break(x) => Some(x),
682 }
683 }
684 }
685
686 pub fn visit_seal<T>(
692 this: Seal<'_, Self>,
693 mut f: impl FnMut(&K, Seal<'_, V>) -> ControlFlow<T>,
694 ) -> Option<T> {
695 if this.is_empty() {
696 None
697 } else {
698 munge!(let Self { root, .. } = this);
699 let root_ptr =
700 unsafe { RelPtr::as_mut_ptr(root).cast::<Node<K, V, E>>() };
701 let mut call_inner =
702 |k: *mut K, v: *mut V| unsafe { f(&*k, Seal::new(&mut *v)) };
703 match Self::visit_raw(root_ptr, &mut call_inner) {
704 ControlFlow::Continue(()) => None,
705 ControlFlow::Break(x) => Some(x),
706 }
707 }
708 }
709
710 fn visit_raw<T>(
711 current: *mut Node<K, V, E>,
712 f: &mut impl FnMut(*mut K, *mut V) -> ControlFlow<T>,
713 ) -> ControlFlow<T> {
714 let kind = unsafe { (*current).kind };
715
716 match kind {
717 NodeKind::Leaf => {
718 let leaf = current.cast::<LeafNode<K, V, E>>();
719 let len = unsafe { (*leaf).len };
720 for i in 0..len.to_native() as usize {
721 Self::visit_key_value_raw(current, i, f)?;
722 }
723 }
724 NodeKind::Inner => {
725 let inner = current.cast::<InnerNode<K, V, E>>();
726
727 for i in 0..E {
729 let lesser =
730 unsafe { addr_of_mut!((*inner).lesser_nodes[i]) };
731 let lesser_is_invalid =
732 unsafe { RelPtr::is_invalid_raw(lesser) };
733 if !lesser_is_invalid {
734 let lesser_ptr = unsafe { RelPtr::as_ptr_raw(lesser) };
735 Self::visit_raw(lesser_ptr, f)?;
736 }
737 Self::visit_key_value_raw(current, i, f)?;
738 }
739
740 let greater = unsafe { addr_of_mut!((*inner).greater_node) };
742 let greater_is_invalid =
743 unsafe { RelPtr::is_invalid_raw(greater) };
744 if !greater_is_invalid {
745 let greater_ptr = unsafe {
746 RelPtr::as_ptr_raw(greater).cast::<Node<K, V, E>>()
747 };
748 Self::visit_raw(greater_ptr, f)?;
749 }
750 }
751 }
752
753 ControlFlow::Continue(())
754 }
755
756 fn visit_key_value_raw<T>(
757 current: *mut Node<K, V, E>,
758 i: usize,
759 f: &mut impl FnMut(*mut K, *mut V) -> ControlFlow<T>,
760 ) -> ControlFlow<T> {
761 let key_ptr = unsafe { addr_of_mut!((*current).keys[i]).cast::<K>() };
762 let value_ptr =
763 unsafe { addr_of_mut!((*current).values[i]).cast::<V>() };
764 f(key_ptr, value_ptr)
765 }
766}
767
768impl<K, V, const E: usize> fmt::Debug for ArchivedBTreeMap<K, V, E>
769where
770 K: fmt::Debug,
771 V: fmt::Debug,
772{
773 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
774 let mut map = f.debug_map();
775 self.visit(|k, v| {
776 map.entry(k, v);
777 ControlFlow::<()>::Continue(())
778 });
779 map.finish()
780 }
781}
782
783#[cfg(feature = "alloc")]
785impl<K, V, const E: usize> Eq for ArchivedBTreeMap<K, V, E>
786where
787 K: PartialEq,
788 V: PartialEq,
789{
790}
791
792impl<K, V, Q, const E: usize> Index<&Q> for ArchivedBTreeMap<K, V, E>
793where
794 Q: Ord + ?Sized,
795 K: Borrow<Q> + Ord,
796{
797 type Output = V;
798
799 fn index(&self, key: &Q) -> &Self::Output {
800 self.get(key).unwrap()
801 }
802}
803
804#[cfg(feature = "alloc")]
806impl<K, V, const E1: usize, const E2: usize>
807 PartialEq<ArchivedBTreeMap<K, V, E2>> for ArchivedBTreeMap<K, V, E1>
808where
809 K: PartialEq,
810 V: PartialEq,
811{
812 fn eq(&self, other: &ArchivedBTreeMap<K, V, E2>) -> bool {
813 if self.len() != other.len() {
814 return false;
815 }
816 let mut i = other.iter();
817 self.visit(|lk, lv| {
818 let (rk, rv) = i.next().unwrap();
819 if lk != rk || lv != rv {
820 ControlFlow::Break(())
821 } else {
822 ControlFlow::Continue(())
823 }
824 })
825 .is_none()
826 }
827}
828
829impl<K: core::hash::Hash, V: core::hash::Hash, const E: usize> core::hash::Hash
830 for ArchivedBTreeMap<K, V, E>
831{
832 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
833 self.visit(|k, v| {
834 (*k).hash(state);
835 (*v).hash(state);
836 ControlFlow::<()>::Continue(())
837 });
838 }
839}
840
841pub struct BTreeMapResolver {
843 root_node_pos: FixedUsize,
844}
845
846#[cfg(feature = "bytecheck")]
847mod verify {
848 use core::{alloc::Layout, error::Error, fmt, ptr::addr_of};
849
850 use bytecheck::{CheckBytes, Verify};
851 use rancor::{fail, Fallible, Source};
852
853 use super::{ArchivedBTreeMap, InnerNode, Node};
854 use crate::{
855 collections::btree_map::{LeafNode, NodeKind},
856 validation::{ArchiveContext, ArchiveContextExt as _},
857 RelPtr,
858 };
859
860 #[derive(Debug)]
861 struct InvalidLength {
862 len: usize,
863 maximum: usize,
864 }
865
866 impl fmt::Display for InvalidLength {
867 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
868 write!(
869 f,
870 "Invalid length in B-tree node: len {} was greater than \
871 maximum {}",
872 self.len, self.maximum
873 )
874 }
875 }
876
877 impl Error for InvalidLength {}
878
879 #[derive(Debug)]
880 struct EntriesLengthMismatch {
881 entries: usize,
882 len: usize,
883 }
884
885 impl fmt::Display for EntriesLengthMismatch {
886 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
887 write!(
888 f,
889 "B-tree map claimed to have {} entries, but actually had {}",
890 self.len, self.entries,
891 )
892 }
893 }
894
895 impl Error for EntriesLengthMismatch {}
896
897 unsafe impl<C, K, V, const E: usize> Verify<C> for ArchivedBTreeMap<K, V, E>
898 where
899 C: Fallible + ArchiveContext + ?Sized,
900 C::Error: Source,
901 K: CheckBytes<C>,
902 V: CheckBytes<C>,
903 {
904 fn verify(&self, context: &mut C) -> Result<(), C::Error> {
905 let len = self.len();
906
907 if len == 0 {
908 return Ok(());
909 }
910
911 let entries =
912 check_node_rel_ptr::<C, K, V, E>(&self.root, context)?;
913 if entries != len {
914 fail!(EntriesLengthMismatch { entries, len });
915 }
916
917 Ok(())
918 }
919 }
920
921 fn check_node_rel_ptr<C, K, V, const E: usize>(
922 node_rel_ptr: &RelPtr<Node<K, V, E>>,
923 context: &mut C,
924 ) -> Result<usize, C::Error>
925 where
926 C: Fallible + ArchiveContext + ?Sized,
927 C::Error: Source,
928 K: CheckBytes<C>,
929 V: CheckBytes<C>,
930 {
931 let node_ptr = node_rel_ptr.as_ptr_wrapping().cast::<Node<K, V, E>>();
932 context.check_subtree_ptr(
933 node_ptr.cast::<u8>(),
934 &Layout::new::<Node<K, V, E>>(),
935 )?;
936
937 let kind_ptr = unsafe { addr_of!((*node_ptr).kind) };
940 unsafe {
943 CheckBytes::check_bytes(kind_ptr, context)?;
944 }
945 let kind = unsafe { kind_ptr.read() };
948
949 match kind {
950 NodeKind::Leaf => {
951 unsafe {
956 check_leaf_node::<C, K, V, E>(node_ptr.cast(), context)
957 }
958 }
959 NodeKind::Inner => {
960 unsafe {
964 check_inner_node::<C, K, V, E>(node_ptr.cast(), context)
965 }
966 }
967 }
968 }
969
970 unsafe fn check_leaf_node<C, K, V, const E: usize>(
975 node_ptr: *const LeafNode<K, V, E>,
976 context: &mut C,
977 ) -> Result<usize, C::Error>
978 where
979 C: Fallible + ArchiveContext + ?Sized,
980 C::Error: Source,
981 K: CheckBytes<C>,
982 V: CheckBytes<C>,
983 {
984 context.in_subtree(node_ptr, |context| {
985 let len_ptr = unsafe { addr_of!((*node_ptr).len) };
989 unsafe {
992 CheckBytes::check_bytes(len_ptr, context)?;
993 }
994 let len = unsafe { &*len_ptr };
998 let len = len.to_native() as usize;
999 if len > E {
1000 fail!(InvalidLength { len, maximum: E });
1001 }
1002
1003 let node_ptr = unsafe { addr_of!((*node_ptr).node) };
1006 unsafe {
1011 check_node_entries(node_ptr, len, context)?;
1012 }
1013
1014 Ok(len)
1015 })
1016 }
1017
1018 unsafe fn check_node_entries<C, K, V, const E: usize>(
1023 node_ptr: *const Node<K, V, E>,
1024 len: usize,
1025 context: &mut C,
1026 ) -> Result<(), C::Error>
1027 where
1028 C: Fallible + ArchiveContext + ?Sized,
1029 C::Error: Source,
1030 K: CheckBytes<C>,
1031 V: CheckBytes<C>,
1032 {
1033 for i in 0..len {
1034 let key_ptr = unsafe { addr_of!((*node_ptr).keys[i]).cast::<K>() };
1037 let value_ptr =
1040 unsafe { addr_of!((*node_ptr).values[i]).cast::<V>() };
1041 unsafe {
1042 K::check_bytes(key_ptr, context)?;
1043 }
1044 unsafe {
1047 V::check_bytes(value_ptr, context)?;
1048 }
1049 }
1050
1051 Ok(())
1052 }
1053
1054 unsafe fn check_inner_node<C, K, V, const E: usize>(
1059 node_ptr: *const InnerNode<K, V, E>,
1060 context: &mut C,
1061 ) -> Result<usize, C::Error>
1062 where
1063 C: Fallible + ArchiveContext + ?Sized,
1064 C::Error: Source,
1065 K: CheckBytes<C>,
1066 V: CheckBytes<C>,
1067 {
1068 context.in_subtree(node_ptr, |context| {
1069 let mut total = E;
1070
1071 for i in 0..E {
1072 let lesser_node_ptr =
1075 unsafe { addr_of!((*node_ptr).lesser_nodes[i]) };
1076 unsafe {
1080 RelPtr::check_bytes(lesser_node_ptr, context)?;
1081 }
1082 let lesser_node = unsafe { &*lesser_node_ptr };
1085 if !lesser_node.is_invalid() {
1086 total +=
1087 check_node_rel_ptr::<C, K, V, E>(lesser_node, context)?;
1088 }
1089 }
1090 let greater_node_ptr =
1093 unsafe { addr_of!((*node_ptr).greater_node) };
1094 unsafe {
1098 RelPtr::check_bytes(greater_node_ptr, context)?;
1099 }
1100 let greater_node = unsafe { &*greater_node_ptr };
1103 if !greater_node.is_invalid() {
1104 total +=
1105 check_node_rel_ptr::<C, K, V, E>(greater_node, context)?;
1106 }
1107
1108 let node_ptr = unsafe { addr_of!((*node_ptr).node) };
1111 unsafe {
1117 check_node_entries::<C, K, V, E>(node_ptr, E, context)?;
1118 }
1119
1120 Ok(total)
1121 })
1122 }
1123}
1124
1125#[cfg(all(test, feature = "alloc"))]
1126mod tests {
1127 use core::hash::{Hash, Hasher};
1128
1129 use ahash::AHasher;
1130
1131 use crate::{
1132 alloc::{collections::BTreeMap, string::ToString},
1133 api::test::to_archived,
1134 primitive::ArchivedU32,
1135 };
1136
1137 #[test]
1138 fn test_hash() {
1139 let mut map = BTreeMap::new();
1140 map.insert("a".to_string(), 1);
1141 map.insert("b".to_string(), 2);
1142
1143 to_archived(&map, |archived_map| {
1144 let mut hasher = AHasher::default();
1145 archived_map.hash(&mut hasher);
1146 let hash_value = hasher.finish();
1147
1148 let mut expected_hasher = AHasher::default();
1149 for (k, v) in &map {
1150 k.hash(&mut expected_hasher);
1151 v.hash(&mut expected_hasher);
1152 }
1153 let expected_hash_value = expected_hasher.finish();
1154
1155 assert_eq!(hash_value, expected_hash_value);
1156 });
1157 }
1158
1159 #[cfg(feature = "bytecheck")]
1160 #[test]
1161 fn iterator_len_mismatch_skips_leaf_entries() {
1162 use core::{mem::size_of, num::NonZeroU32};
1163
1164 use super::{
1165 ArchivedBTreeMap, LeafNode, Node, DEFAULT_ENTRIES_PER_NODE,
1166 };
1167 use crate::{
1168 access, api::test::to_bytes, primitive::ArchivedNonZeroU32,
1169 };
1170
1171 fn find_unique_subslice(haystack: &[u8], needle: &[u8]) -> usize {
1172 let mut matches = haystack
1173 .windows(needle.len())
1174 .enumerate()
1175 .filter_map(|(i, window)| (window == needle).then_some(i));
1176
1177 let result = matches.next().unwrap();
1178 assert!(matches.next().is_none());
1179 result
1180 }
1181
1182 let mut map = BTreeMap::new();
1185 map.insert(NonZeroU32::new(7).unwrap(), 11u32);
1186 to_bytes(&map, |bytes| {
1187 #[cfg(feature = "big_endian")]
1188 let key_bytes = [0, 0, 0, 7];
1189 #[cfg(not(feature = "big_endian"))]
1190 let key_bytes = [7, 0, 0, 0];
1191
1192 let first_key_offset = find_unique_subslice(&bytes, &key_bytes);
1193 let first_key_in_leaf = core::mem::offset_of!(
1194 LeafNode<
1195 ArchivedNonZeroU32,
1196 ArchivedU32,
1197 DEFAULT_ENTRIES_PER_NODE,
1198 >,
1199 node
1200 ) + core::mem::offset_of!(
1201 Node<ArchivedNonZeroU32, ArchivedU32, DEFAULT_ENTRIES_PER_NODE>,
1202 keys
1203 );
1204 let leaf_base = first_key_offset - first_key_in_leaf;
1205 let leaf_len_offset = leaf_base
1206 + core::mem::offset_of!(
1207 LeafNode<
1208 ArchivedNonZeroU32,
1209 ArchivedU32,
1210 DEFAULT_ENTRIES_PER_NODE,
1211 >,
1212 len
1213 );
1214
1215 #[cfg(feature = "pointer_width_16")]
1216 let zero_len_bytes = [0, 0];
1217 #[cfg(not(any(
1218 feature = "pointer_width_16",
1219 feature = "pointer_width_64",
1220 )))]
1221 let zero_len_bytes = [0, 0, 0, 0];
1222 #[cfg(feature = "pointer_width_64")]
1223 let zero_len_bytes = [0, 0, 0, 0, 0, 0, 0, 0];
1224
1225 bytes[leaf_len_offset..leaf_len_offset + zero_len_bytes.len()]
1226 .copy_from_slice(&zero_len_bytes);
1227 bytes[first_key_offset
1228 ..first_key_offset + size_of::<ArchivedNonZeroU32>()]
1229 .fill(0);
1230
1231 access::<
1232 ArchivedBTreeMap<ArchivedNonZeroU32, ArchivedU32>,
1233 rancor::Error,
1234 >(&bytes)
1235 .unwrap_err();
1236 });
1237 }
1238
1239 #[test]
1240 fn test_range_empty() {
1241 let map = BTreeMap::<char, char>::new();
1242 to_archived(&map, |archived_map| {
1243 for _ in archived_map.range(..) {
1244 panic!("ArchivedBTreeMap should be empty");
1245 }
1246 });
1247 }
1248
1249 #[test]
1250 fn test_range_one() {
1251 let mut map = BTreeMap::<i32, i32>::new();
1252 map.insert(1, 1);
1253 to_archived(&map, |archived_map| {
1254 for _ in archived_map.range_with(2.., |q, k| q.cmp(&k.to_native()))
1255 {
1256 panic!("ArchivedBTreeMap range should be empty");
1257 }
1258 })
1259 }
1260
1261 #[test]
1262 fn test_range_open() {
1263 let mut map = BTreeMap::new();
1264 for i in 'a'..'z' {
1265 map.insert(i, i);
1266 }
1267
1268 to_archived(&map, |archived_map| {
1269 for _ in
1270 archived_map.range_with(..'a', |q, k| q.cmp(&k.to_native()))
1271 {
1272 panic!("Range should be empty");
1273 }
1274 for _ in
1275 archived_map.range_with('|'.., |q, k| q.cmp(&k.to_native()))
1276 {
1277 panic!("Range should be empty");
1278 }
1279 });
1280 }
1281
1282 #[test]
1283 fn test_range_str() {
1284 let mut map = BTreeMap::new();
1285 for i in 'a'..'z' {
1286 map.insert(i.to_string(), i.to_string());
1287 }
1288
1289 to_archived(&map, |archived_map| {
1290 let start = 'd';
1291 let end = 'w';
1292
1293 for ((k, v), expected) in archived_map
1294 .range_with(start..end, |q, k| {
1295 q.cmp(&k.chars().next().unwrap())
1296 })
1297 .zip(start..end)
1298 {
1299 let expected = expected.to_string();
1300 assert_eq!(k.as_str(), expected);
1301 assert_eq!(v.as_str(), expected);
1302 }
1303 });
1304 }
1305
1306 #[test]
1307 fn test_range_u32() {
1308 let mut map = BTreeMap::new();
1309 for i in 0..200 {
1310 map.insert(i as u32, i as u32);
1311 }
1312
1313 to_archived(&map, |archived_map| {
1314 const START: u32 = 32;
1315 const END: u32 = 100;
1316 let start = ArchivedU32::from_native(START);
1317 let end = ArchivedU32::from_native(END);
1318
1319 for ((k, v), expected) in
1320 archived_map.range(start..end).zip(START..END)
1321 {
1322 assert_eq!(k.to_native(), expected);
1323 assert_eq!(v.to_native(), expected);
1324 }
1325 });
1326 }
1327}