Skip to main content

rkyv/collections/btree/map/
mod.rs

1//! [`Archive`](crate::Archive) implementation for B-tree maps.
2
3use 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// TODO(#515): Get Iterator APIs working without the `alloc` feature enabled
28#[cfg(feature = "alloc")]
29mod iter;
30
31#[cfg(feature = "alloc")]
32pub use self::iter::*;
33
34// B-trees are typically characterized as having a branching factor of B.
35// However, in this implementation our B-trees are characterized as having a
36// number of entries per node E where E = B - 1. This is done because it's
37// easier to add an additional node pointer to each inner node than it is to
38// store one less entry per inner node. Because generic const exprs are not
39// stable, we can't declare a field `entries: [Entry; { B - 1 }]`. But we can
40// declare `branches: [RelPtr; E]` and then add another `last: RelPtr`
41// field. When the branching factor B is needed, it will be calculated as E + 1.
42
43const fn nodes_in_level<const E: usize>(i: u32) -> usize {
44    // The root of the tree has one node, and each level down has B times as
45    // many nodes at the last. Therefore, the number of nodes in the I-th level
46    // is equal to B^I.
47
48    (E + 1).pow(i)
49}
50
51const fn entries_in_full_tree<const E: usize>(h: u32) -> usize {
52    // The number of nodes in each layer I of a B-tree is equal to B^I. At layer
53    // I = 0, the number of nodes is exactly one. At layer I = 1, the number of
54    // nodes is B, at layer I = 2 the number of nodes is B^2, and so on. The
55    // total number of nodes is equal to the sum from 0 to H - 1 of B^I. Since
56    // this is the sum of a geometric progression, we have the closed-form
57    // solution N = (B^H - 1) / (B - 1). Since the number of entries per node is
58    // equal to B - 1, we thus have the solution that the number of entries in a
59    // B-tree of height H is equal to B^H - 1.
60
61    // Note that this is one less than the number of nodes in the level after
62    // the final level of the B-tree.
63
64    nodes_in_level::<E>(h) - 1
65}
66
67const fn entries_to_height<const E: usize>(n: usize) -> u32 {
68    // Solving B^H - 1 = N for H yields H = log_B(N + 1). However, we'll be
69    // using an integer logarithm, and so the value of H will be rounded down
70    // which underestimates the height of the tree:
71    // => H = ilog_B(N + 1) = floor(log_B(N + 1)).
72    // To compensate for this, we'll calculate the height for a tree with a
73    // greater number of nodes and choose this greater number so that rounding
74    // down will always yield the correct result.
75
76    // The minimum value which yields a height of H is exactly B^H - 1, so we
77    // need to add a large enough correction to always be greater than or equal
78    // to that value. The maximum value which yields a height of H is one less
79    // than the number of nodes in the next-largest B-tree, which is equal to
80    // B^(H + 1) - 1. This gives the following relationships for N:
81    // => B^(H - 1) - 1 < N <= B^H - 1
82    // And the desired relationships for the corrected number of entries C(N):
83    // => B^H - 1 <= C(N) < B^(H + 1) - 1
84
85    // First, we can add 1 to the two ends of our first set of relationships
86    // to change whether equality is allowed. We can do this because all entries
87    // are integers. This makes the relationships match the desired
88    // relationships for C(N):
89    // => B^(H - 1) - 1 + 1 <= N < B^H - 1 + 1
90    // => B^(H - 1) <= N < B^H
91    // Let's choose a function to map the lower bound for N to the desired lower
92    // bound for C(N):
93    // => C(B^(H - 1)) = B^(H - 1)
94    // A straightforward choice would be C(N) = B * N - 1. Substituting yields:
95    // => C(B^(H - 1)) <= C(N) < C(B^H)
96    // => B * B^(H - 1) - 1 <= B * N - 1 < B * B^H - 1
97    // => B^H - 1 <= B * N - 1 < B^(H + 1) - 1
98    // These exactly match the desired bounds, so this is the function we want.
99
100    // Putting it all together:
101    // => H = ilog_B(C(N) + 1) = ilog_b(B * N - 1 + 1) = ilog_b(B * N)
102    // => H = 1 + ilog_b(N)
103    1 + n.ilog(E + 1)
104}
105
106const fn ll_entries<const E: usize>(height: u32, n: usize) -> usize {
107    // The number of entries not in the last level is equal to the number of
108    // entries in a full B-tree of height H - 1. The number of entries in
109    // the last level is thus the total number of entries minus the number
110    // of entries not in the last level.
111    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
123// SAFETY: `NodeKind` is `repr(u8)` and so always consists of a single
124// well-defined byte.
125unsafe 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/// An archived [`BTreeMap`](crate::alloc::collections::BTreeMap).
157#[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    // The type of the root node is determined at runtime because it may point
167    // to:
168    // - Nothing if the length is zero
169    // - A leaf node if there is only one node
170    // - Or an inner node if there are multiple nodes
171    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    /// Returns whether the B-tree map contains the given key.
178    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    /// Returns the value associated with the given key, or `None` if the key is
187    /// not present in the B-tree map.
188    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    /// Returns the mutable value associated with the given key, or `None` if
197    /// the key is not present in the B-tree map.
198    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    /// Returns true if the B-tree map contains no entries.
207    pub fn is_empty(&self) -> bool {
208        self.len() == 0
209    }
210
211    /// Returns the number of entries in the B-tree map.
212    pub fn len(&self) -> usize {
213        self.len.to_native() as usize
214    }
215
216    /// Gets the key-value pair associated with the given key, or `None` if the
217    /// key is not present in the B-tree map.
218    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    /// Gets the key-value pair associated with the given key, or `None` if the
227    /// key is not present in the B-tree map.
228    ///
229    /// This method uses the supplied comparison function to compare the key to
230    /// elements.
231    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    /// Gets the mutable key-value pair associated with the given key, or `None`
243    /// if the key is not present in the B-tree map.
244    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    /// Gets the mutable key-value pair associated with the given key, or `None`
256    /// if the key is not present in the B-tree map.
257    ///
258    /// This method uses the supplied comparison function to compare the key to
259    /// elements.
260    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    /// Resolves an `ArchivedBTreeMap` from the given length, resolver, and
372    /// output place.
373    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    /// Serializes an `ArchivedBTreeMap` from the given iterator and serializer.
390    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                        // Close open leaf
440                        child_node_pos =
441                            Some(Self::close_leaf(&open_leaf, serializer)?);
442                        open_leaf.clear();
443
444                        // If on the transition node, fill and close open inner
445                        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                        // Add closed node to open inner
465                        let mut popped = 0;
466                        while let Some(last_inner) = open_inners.last_mut() {
467                            if last_inner.len() == last_inner.capacity() {
468                                // Close open inner
469                                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                    // Close open leaf
491                    child_node_pos =
492                        Some(Self::close_leaf(&open_leaf, serializer)?);
493                    open_leaf.clear();
494                }
495
496                // Close open inners
497                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        // SAFETY: `node` is properly aligned and valid for writes of
545        // `size_of::<LeafNode<K, V, E>>()` bytes.
546        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        // SAFETY: `node` is properly aligned and valid for writes of
610        // `size_of::<InnerNode<K, V, E>>()` bytes.
611        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    /// Visits every key-value pair in the B-tree with a function.
665    ///
666    /// If `f` returns `ControlFlow::Break`, `visit` will return `Some` with the
667    /// broken value. If `f` returns `Continue` for every pair in the tree,
668    /// `visit` will return `None`.
669    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    /// Visits every mutable key-value pair in the B-tree with a function.
687    ///
688    /// If `f` returns `ControlFlow::Break`, `visit` will return `Some` with the
689    /// broken value. If `f` returns `Continue` for every pair in the tree,
690    /// `visit` will return `None`.
691    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                // Visit lesser nodes and key-value pairs
728                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                // Visit greater node
741                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// TODO(#515): ungate this impl
784#[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// TODO(#515): ungate this impl
805#[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
841/// The resolver for [`ArchivedBTreeMap`].
842pub 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        // SAFETY: We checked to make sure that `node_ptr` is properly aligned
938        // and dereferenceable by calling `check_subtree_ptr`.
939        let kind_ptr = unsafe { addr_of!((*node_ptr).kind) };
940        // SAFETY: `kind_ptr` is a pointer to a subfield of `node_ptr` and so is
941        // also properly aligned and dereferenceable.
942        unsafe {
943            CheckBytes::check_bytes(kind_ptr, context)?;
944        }
945        // SAFETY: `kind_ptr` was always properly aligned and dereferenceable,
946        // and we just checked to make sure it pointed to a valid `NodeKind`.
947        let kind = unsafe { kind_ptr.read() };
948
949        match kind {
950            NodeKind::Leaf => {
951                // SAFETY:
952                // We checked to make sure that `node_ptr` is properly aligned,
953                // dereferenceable, and contained entirely within `context`'s
954                // buffer by calling `check_subtree_ptr`.
955                unsafe {
956                    check_leaf_node::<C, K, V, E>(node_ptr.cast(), context)
957                }
958            }
959            NodeKind::Inner => {
960                // SAFETY:
961                // We checked to make sure that `node_ptr` is properly aligned
962                // and dereferenceable.
963                unsafe {
964                    check_inner_node::<C, K, V, E>(node_ptr.cast(), context)
965                }
966            }
967        }
968    }
969
970    /// # Safety
971    ///
972    /// `node_ptr` must be properly aligned, dereferenceable, and contained
973    /// within `context`'s buffer.
974    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            // SAFETY: We checked to make sure that `node_ptr` is properly
986            // aligned and dereferenceable by calling
987            // `check_subtree_ptr`.
988            let len_ptr = unsafe { addr_of!((*node_ptr).len) };
989            // SAFETY: `len_ptr` is a pointer to a subfield of `node_ptr` and so
990            // is also properly aligned and dereferenceable.
991            unsafe {
992                CheckBytes::check_bytes(len_ptr, context)?;
993            }
994            // SAFETY: `len_ptr` was always properly aligned and
995            // dereferenceable, and we just checked to make sure it
996            // pointed to a valid `ArchivedUsize`.
997            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            // SAFETY: We checked that `node_ptr` is properly-aligned and
1004            // dereferenceable.
1005            let node_ptr = unsafe { addr_of!((*node_ptr).node) };
1006            // SAFETY:
1007            // - We checked that `node_ptr` is properly aligned and
1008            //   dereferenceable.
1009            // - We checked that `len` is less than or equal to `E`.
1010            unsafe {
1011                check_node_entries(node_ptr, len, context)?;
1012            }
1013
1014            Ok(len)
1015        })
1016    }
1017
1018    /// # Safety
1019    ///
1020    /// - `node_ptr` must point to a valid `Node<K, V, E>`.
1021    /// - `len` must be less than or equal to `E`.
1022    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            // SAFETY: The caller has guaranteed that `node_ptr` is properly
1035            // aligned and dereferenceable.
1036            let key_ptr = unsafe { addr_of!((*node_ptr).keys[i]).cast::<K>() };
1037            // SAFETY: The caller has guaranteed that `node_ptr` is properly
1038            // aligned and dereferenceable.
1039            let value_ptr =
1040                unsafe { addr_of!((*node_ptr).values[i]).cast::<V>() };
1041            unsafe {
1042                K::check_bytes(key_ptr, context)?;
1043            }
1044            // SAFETY: `value_ptr` is a subfield of a node, and so is guaranteed
1045            // to be properly aligned and point to enough bytes for a `V`.
1046            unsafe {
1047                V::check_bytes(value_ptr, context)?;
1048            }
1049        }
1050
1051        Ok(())
1052    }
1053
1054    /// # Safety
1055    ///
1056    /// - `node_ptr` must be properly aligned and dereferenceable.
1057    /// - `len` must be less than or equal to `E`.
1058    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                // SAFETY: `in_subtree` guarantees that `node_ptr` is properly
1073                // aligned and dereferenceable.
1074                let lesser_node_ptr =
1075                    unsafe { addr_of!((*node_ptr).lesser_nodes[i]) };
1076                // SAFETY: `lesser_node_ptr` is a subfield of an inner node, and
1077                // so is guaranteed to be properly aligned and point to enough
1078                // bytes for a `RelPtr`.
1079                unsafe {
1080                    RelPtr::check_bytes(lesser_node_ptr, context)?;
1081                }
1082                // SAFETY: We just checked the `lesser_node_ptr` and it
1083                // succeeded, so it's safe to dereference.
1084                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            // SAFETY: We checked that `node_ptr` is properly aligned and
1091            // dereferenceable.
1092            let greater_node_ptr =
1093                unsafe { addr_of!((*node_ptr).greater_node) };
1094            // SAFETY: `greater_node_ptr` is a subfield of an inner node, and so
1095            // is guaranteed to be properly aligned and point to enough bytes
1096            // for a `RelPtr`.
1097            unsafe {
1098                RelPtr::check_bytes(greater_node_ptr, context)?;
1099            }
1100            // SAFETY: We just checked the `greater_node_ptr` and it succeeded,
1101            // so it's safe to dereference.
1102            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            // SAFETY: We checked that `node_ptr` is properly aligned and
1109            // dereferenceable.
1110            let node_ptr = unsafe { addr_of!((*node_ptr).node) };
1111            // SAFETY:
1112            // - The caller has guaranteed that `node_ptr` points to a valid
1113            //   `Node<K, V, E>`.
1114            // - All inner nodes have `E` items, and `E` is less than or equal
1115            //   to `E`.
1116            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        // This test ensures that `ArchivedBTreeMap` checks that the number of
1183        // entries matches the number claimed by the top-level structure.
1184        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}