Skip to main content

triblespace_core/
patch.rs

1//! Persistent Adaptive Trie with Cuckoo-compression and
2//! Hash-maintenance (PATCH).
3//!
4//! See the [PATCH](../book/src/deep-dive/patch.md) chapter of the Tribles Book
5//! for the full design description and hashing scheme.
6//!
7//! Values stored in leaves are not part of hashing or equality comparisons.
8//! Two `PATCH`es are considered equal if they contain the same set of keys,
9//! even if the associated values differ. This allows using the structure as an
10//! idempotent blobstore where a value's hash determines its key.
11//!
12#![allow(unstable_name_collisions)]
13
14mod branch;
15pub mod bytetable;
16mod entry;
17mod leaf;
18
19use arrayvec::ArrayVec;
20
21use branch::*;
22pub use entry::Entry;
23use leaf::*;
24
25pub use bytetable::*;
26use rand::thread_rng;
27use rand::RngCore;
28use std::cmp::Reverse;
29use std::convert::TryInto;
30use std::fmt;
31use std::fmt::Debug;
32use std::marker::PhantomData;
33use std::mem::transmute;
34use std::ptr::NonNull;
35use std::sync::Once;
36
37#[cfg(not(target_pointer_width = "64"))]
38compile_error!("PATCH tagged pointers require 64-bit targets");
39
40static mut SIP_KEY: [u8; 16] = [0; 16];
41static INIT: Once = Once::new();
42
43/// Initializes the SIP key used for key hashing.
44/// This function is called automatically when a new PATCH is created.
45fn init_sip_key() {
46    INIT.call_once(|| {
47        bytetable::init();
48
49        let mut rng = thread_rng();
50        unsafe {
51            rng.fill_bytes(&mut SIP_KEY[..]);
52        }
53    });
54}
55
56/// Builds a per-byte segment map from the segment lengths.
57///
58/// The returned table maps each key byte to its segment index.
59pub const fn build_segmentation<const N: usize, const M: usize>(lens: [usize; M]) -> [usize; N] {
60    let mut res = [0; N];
61    let mut seg = 0;
62    let mut off = 0;
63    while seg < M {
64        let len = lens[seg];
65        let mut i = 0;
66        while i < len {
67            res[off + i] = seg;
68            i += 1;
69        }
70        off += len;
71        seg += 1;
72    }
73    res
74}
75
76/// Builds an identity permutation table of length `N`.
77pub const fn identity_map<const N: usize>() -> [usize; N] {
78    let mut res = [0; N];
79    let mut i = 0;
80    while i < N {
81        res[i] = i;
82        i += 1;
83    }
84    res
85}
86
87/// Builds a table translating indices from key order to tree order.
88///
89/// `lens` describes the segment lengths in key order and `perm` is the
90/// permutation of those segments in tree order.
91pub const fn build_key_to_tree<const N: usize, const M: usize>(
92    lens: [usize; M],
93    perm: [usize; M],
94) -> [usize; N] {
95    let mut key_starts = [0; M];
96    let mut off = 0;
97    let mut i = 0;
98    while i < M {
99        key_starts[i] = off;
100        off += lens[i];
101        i += 1;
102    }
103
104    let mut tree_starts = [0; M];
105    off = 0;
106    i = 0;
107    while i < M {
108        let seg = perm[i];
109        tree_starts[seg] = off;
110        off += lens[seg];
111        i += 1;
112    }
113
114    let mut res = [0; N];
115    let mut seg = 0;
116    while seg < M {
117        let len = lens[seg];
118        let ks = key_starts[seg];
119        let ts = tree_starts[seg];
120        let mut j = 0;
121        while j < len {
122            res[ks + j] = ts + j;
123            j += 1;
124        }
125        seg += 1;
126    }
127    res
128}
129
130/// Inverts a permutation table.
131pub const fn invert<const N: usize>(arr: [usize; N]) -> [usize; N] {
132    let mut res = [0; N];
133    let mut i = 0;
134    while i < N {
135        res[arr[i]] = i;
136        i += 1;
137    }
138    res
139}
140
141#[doc(hidden)]
142#[macro_export]
143macro_rules! key_segmentation {
144    (@count $($e:expr),* $(,)?) => {
145        <[()]>::len(&[$($crate::key_segmentation!(@sub $e)),*])
146    };
147    (@sub $e:expr) => { () };
148    ($name:ident, $len:expr, [$($seg_len:expr),+ $(,)?]) => {
149        #[derive(Copy, Clone, Debug)]
150        pub struct $name;
151        impl $name {
152            pub const SEG_LENS: [usize; $crate::key_segmentation!(@count $($seg_len),*)] = [$($seg_len),*];
153        }
154        impl $crate::patch::KeySegmentation<$len> for $name {
155            const SEGMENTS: [usize; $len] = $crate::patch::build_segmentation::<$len, {$crate::key_segmentation!(@count $($seg_len),*)}>(Self::SEG_LENS);
156        }
157    };
158}
159
160#[doc(hidden)]
161#[macro_export]
162macro_rules! key_schema {
163    (@count $($e:expr),* $(,)?) => {
164        <[()]>::len(&[$($crate::key_schema!(@sub $e)),*])
165    };
166    (@sub $e:expr) => { () };
167    ($name:ident, $seg:ty, $len:expr, [$($perm:expr),+ $(,)?]) => {
168        #[derive(Copy, Clone, Debug)]
169        pub struct $name;
170        impl $crate::patch::KeySchema<$len> for $name {
171            type Segmentation = $seg;
172            const SEGMENT_PERM: &'static [usize] = &[$($perm),*];
173            const KEY_TO_TREE: [usize; $len] = $crate::patch::build_key_to_tree::<$len, {$crate::key_schema!(@count $($perm),*)}>(<$seg>::SEG_LENS, [$($perm),*]);
174            const TREE_TO_KEY: [usize; $len] = $crate::patch::invert(Self::KEY_TO_TREE);
175        }
176    };
177}
178
179/// A trait is used to provide a re-ordered view of the keys stored in the PATCH.
180/// This allows for different PATCH instances share the same leaf nodes,
181/// independent of the key ordering used in the tree.
182pub trait KeySchema<const KEY_LEN: usize>: Copy + Clone + Debug {
183    /// The segmentation this ordering operates over.
184    type Segmentation: KeySegmentation<KEY_LEN>;
185    /// Order of segments from key layout to tree layout.
186    const SEGMENT_PERM: &'static [usize];
187    /// Maps each key index to its position in the tree view.
188    const KEY_TO_TREE: [usize; KEY_LEN];
189    /// Maps each tree index to its position in the key view.
190    const TREE_TO_KEY: [usize; KEY_LEN];
191
192    /// Reorders the key from the shared key ordering to the tree ordering.
193    fn tree_ordered(key: &[u8; KEY_LEN]) -> [u8; KEY_LEN] {
194        let mut new_key = [0; KEY_LEN];
195        let mut i = 0;
196        while i < KEY_LEN {
197            new_key[Self::KEY_TO_TREE[i]] = key[i];
198            i += 1;
199        }
200        new_key
201    }
202
203    /// Reorders the key from the tree ordering to the shared key ordering.
204    fn key_ordered(tree_key: &[u8; KEY_LEN]) -> [u8; KEY_LEN] {
205        let mut new_key = [0; KEY_LEN];
206        let mut i = 0;
207        while i < KEY_LEN {
208            new_key[Self::TREE_TO_KEY[i]] = tree_key[i];
209            i += 1;
210        }
211        new_key
212    }
213
214    /// Return the segment index for the byte at `at_depth` in tree ordering.
215    ///
216    /// Default implementation reads the static segmentation table and the
217    /// tree->key mapping. Having this as a method makes call sites clearer and
218    /// reduces the verbosity of expressions that access the segmentation table.
219    fn segment_of_tree_depth(at_depth: usize) -> usize {
220        <Self::Segmentation as KeySegmentation<KEY_LEN>>::SEGMENTS[Self::TREE_TO_KEY[at_depth]]
221    }
222
223    /// Return true if the tree-ordered bytes at `a` and `b` belong to the same
224    /// logical segment.
225    fn same_segment_tree(a: usize, b: usize) -> bool {
226        <Self::Segmentation as KeySegmentation<KEY_LEN>>::SEGMENTS[Self::TREE_TO_KEY[a]]
227            == <Self::Segmentation as KeySegmentation<KEY_LEN>>::SEGMENTS[Self::TREE_TO_KEY[b]]
228    }
229}
230
231/// This trait is used to segment keys stored in the PATCH.
232/// The segmentation is used to determine sub-fields of the key,
233/// allowing for segment based operations, like counting the number
234/// of elements in a segment with a given prefix without traversing the tree.
235///
236/// Note that the segmentation is defined on the shared key ordering,
237/// and should thus be only implemented once, independent of additional key orderings.
238///
239/// See [TribleSegmentation](crate::trible::TribleSegmentation) for an example that segments keys into entity,
240/// attribute, and value segments.
241pub trait KeySegmentation<const KEY_LEN: usize>: Copy + Clone + Debug {
242    /// Segment index for each position in the key.
243    const SEGMENTS: [usize; KEY_LEN];
244}
245
246/// A `KeySchema` that does not reorder the keys.
247/// This is useful for keys that are already ordered in the desired way.
248/// This is the default ordering.
249#[derive(Copy, Clone, Debug)]
250pub struct IdentitySchema {}
251
252/// A `KeySegmentation` that does not segment the keys.
253/// This is useful for keys that do not have a segment structure.
254/// This is the default segmentation.
255#[derive(Copy, Clone, Debug)]
256pub struct SingleSegmentation {}
257impl<const KEY_LEN: usize> KeySchema<KEY_LEN> for IdentitySchema {
258    type Segmentation = SingleSegmentation;
259    const SEGMENT_PERM: &'static [usize] = &[0];
260    const KEY_TO_TREE: [usize; KEY_LEN] = identity_map::<KEY_LEN>();
261    const TREE_TO_KEY: [usize; KEY_LEN] = identity_map::<KEY_LEN>();
262}
263
264impl<const KEY_LEN: usize> KeySegmentation<KEY_LEN> for SingleSegmentation {
265    const SEGMENTS: [usize; KEY_LEN] = [0; KEY_LEN];
266}
267
268#[allow(dead_code)]
269#[derive(Debug, PartialEq, Copy, Clone)]
270#[repr(u8)]
271pub(crate) enum HeadTag {
272    // Bit 0-3: Branching factor
273    Branch2 = 1,
274    Branch4 = 2,
275    Branch8 = 3,
276    Branch16 = 4,
277    Branch32 = 5,
278    Branch64 = 6,
279    Branch128 = 7,
280    Branch256 = 8,
281    // Bit 4 indicates that the node is a leaf.
282    Leaf = 16,
283}
284
285pub(crate) enum BodyPtr<const KEY_LEN: usize, O: KeySchema<KEY_LEN>, V> {
286    Leaf(NonNull<Leaf<KEY_LEN, V>>),
287    Branch(branch::BranchNN<KEY_LEN, O, V>),
288}
289
290/// Immutable borrow view of a Head body.
291/// Returned by `body_ref()` and tied to the lifetime of the `&Head`.
292pub(crate) enum BodyRef<'a, const KEY_LEN: usize, O: KeySchema<KEY_LEN>, V> {
293    Leaf(&'a Leaf<KEY_LEN, V>),
294    Branch(&'a Branch<KEY_LEN, O, [Option<Head<KEY_LEN, O, V>>], V>),
295}
296
297/// Mutable borrow view of a Head body.
298/// Returned by `body_mut()` and tied to the lifetime of the `&mut Head`.
299pub(crate) enum BodyMut<'a, const KEY_LEN: usize, O: KeySchema<KEY_LEN>, V> {
300    Leaf(&'a mut Leaf<KEY_LEN, V>),
301    Branch(&'a mut Branch<KEY_LEN, O, [Option<Head<KEY_LEN, O, V>>], V>),
302}
303
304pub(crate) trait Body {
305    fn tag(body: NonNull<Self>) -> HeadTag;
306}
307
308#[repr(C)]
309pub(crate) struct Head<const KEY_LEN: usize, O: KeySchema<KEY_LEN>, V> {
310    tptr: std::ptr::NonNull<u8>,
311    key_ordering: PhantomData<O>,
312    key_segments: PhantomData<O::Segmentation>,
313    value: PhantomData<V>,
314}
315
316unsafe impl<const KEY_LEN: usize, O: KeySchema<KEY_LEN>, V> Send for Head<KEY_LEN, O, V> {}
317unsafe impl<const KEY_LEN: usize, O: KeySchema<KEY_LEN>, V> Sync for Head<KEY_LEN, O, V> {}
318
319impl<const KEY_LEN: usize, O: KeySchema<KEY_LEN>, V> Head<KEY_LEN, O, V> {
320    pub(crate) fn new<T: Body + ?Sized>(key: u8, body: NonNull<T>) -> Self {
321        unsafe {
322            let tptr =
323                std::ptr::NonNull::new_unchecked((body.as_ptr() as *mut u8).map_addr(|addr| {
324                    ((addr as u64 & 0x00_00_ff_ff_ff_ff_ff_ffu64)
325                        | ((key as u64) << 48)
326                        | ((<T as Body>::tag(body) as u64) << 56)) as usize
327                }));
328            Self {
329                tptr,
330                key_ordering: PhantomData,
331                key_segments: PhantomData,
332                value: PhantomData,
333            }
334        }
335    }
336
337    #[inline]
338    pub(crate) fn tag(&self) -> HeadTag {
339        unsafe { transmute((self.tptr.as_ptr() as u64 >> 56) as u8) }
340    }
341
342    #[inline]
343    pub(crate) fn key(&self) -> u8 {
344        (self.tptr.as_ptr() as u64 >> 48) as u8
345    }
346
347    #[inline]
348    pub(crate) fn with_key(mut self, key: u8) -> Self {
349        self.tptr = std::ptr::NonNull::new(self.tptr.as_ptr().map_addr(|addr| {
350            ((addr as u64 & 0xff_00_ff_ff_ff_ff_ff_ffu64) | ((key as u64) << 48)) as usize
351        }))
352        .unwrap();
353        self
354    }
355
356    #[inline]
357    pub(crate) fn set_body<T: Body + ?Sized>(&mut self, body: NonNull<T>) {
358        unsafe {
359            self.tptr = NonNull::new_unchecked((body.as_ptr() as *mut u8).map_addr(|addr| {
360                ((addr as u64 & 0x00_00_ff_ff_ff_ff_ff_ffu64)
361                    | (self.tptr.as_ptr() as u64 & 0x00_ff_00_00_00_00_00_00u64)
362                    | ((<T as Body>::tag(body) as u64) << 56)) as usize
363            }))
364        }
365    }
366
367    pub(crate) fn with_start(self, new_start_depth: usize) -> Head<KEY_LEN, O, V> {
368        let leaf_key = self.childleaf_key();
369        let i = O::TREE_TO_KEY[new_start_depth];
370        let key = leaf_key[i];
371        self.with_key(key)
372    }
373
374    // Removed childleaf_matches_key_from in favor of composing the existing
375    // has_prefix primitives directly at call sites. Use
376    // `self.has_prefix::<KEY_LEN>(at_depth, key)` or for partial checks
377    // `self.childleaf().has_prefix::<O>(at_depth, &key[..limit])` instead.
378
379    pub(crate) fn body(&self) -> BodyPtr<KEY_LEN, O, V> {
380        unsafe {
381            let ptr = NonNull::new_unchecked(
382                self.tptr
383                    .as_ptr()
384                    // Clear the key/tag bytes (bits 48..64) we store in `tptr`.
385                    //
386                    // Do NOT sign-extend bit 47 here: on Linux/aarch64 user-space
387                    // pointers are typically zero-extended even when bit 47 is set
388                    // (e.g. `0xaaaa...`). Sign-extending would yield a different
389                    // address (`0xffffaaaa...`) and break decoding.
390                    .map_addr(|addr| ((addr as u64) & 0x00_00_ff_ff_ff_ff_ff_ffu64) as usize),
391            );
392            match self.tag() {
393                HeadTag::Leaf => BodyPtr::Leaf(ptr.cast()),
394                branch_tag => {
395                    let count = 1 << (branch_tag as usize);
396                    BodyPtr::Branch(NonNull::new_unchecked(std::ptr::slice_from_raw_parts(
397                        ptr.as_ptr(),
398                        count,
399                    )
400                        as *mut Branch<KEY_LEN, O, [Option<Head<KEY_LEN, O, V>>], V>))
401                }
402            }
403        }
404    }
405
406    pub(crate) fn body_mut(&mut self) -> BodyMut<'_, KEY_LEN, O, V> {
407        unsafe {
408            match self.body() {
409                BodyPtr::Leaf(mut leaf) => BodyMut::Leaf(leaf.as_mut()),
410                BodyPtr::Branch(mut branch) => {
411                    // Ensure ownership: try copy-on-write and update local pointer if needed.
412                    let mut branch_nn = branch;
413                    if Branch::rc_cow(&mut branch_nn).is_some() {
414                        self.set_body(branch_nn);
415                        BodyMut::Branch(branch_nn.as_mut())
416                    } else {
417                        BodyMut::Branch(branch.as_mut())
418                    }
419                }
420            }
421        }
422    }
423
424    /// Returns an immutable borrow of the body (Leaf or Branch) tied to &self.
425    pub(crate) fn body_ref(&self) -> BodyRef<'_, KEY_LEN, O, V> {
426        match self.body() {
427            BodyPtr::Leaf(nn) => BodyRef::Leaf(unsafe { nn.as_ref() }),
428            BodyPtr::Branch(nn) => BodyRef::Branch(unsafe { nn.as_ref() }),
429        }
430    }
431
432    pub(crate) fn count(&self) -> u64 {
433        match self.body_ref() {
434            BodyRef::Leaf(_) => 1,
435            BodyRef::Branch(branch) => branch.leaf_count,
436        }
437    }
438
439    pub(crate) fn count_segment(&self, at_depth: usize) -> u64 {
440        match self.body_ref() {
441            BodyRef::Leaf(_) => 1,
442            BodyRef::Branch(branch) => branch.count_segment(at_depth),
443        }
444    }
445
446    pub(crate) fn hash(&self) -> u128 {
447        match self.body_ref() {
448            BodyRef::Leaf(leaf) => leaf.hash,
449            BodyRef::Branch(branch) => branch.hash,
450        }
451    }
452
453    pub(crate) fn end_depth(&self) -> usize {
454        match self.body_ref() {
455            BodyRef::Leaf(_) => KEY_LEN,
456            BodyRef::Branch(branch) => branch.end_depth as usize,
457        }
458    }
459
460    /// Return the raw pointer to the child leaf for use in low-level
461    /// operations (for example when constructing a Branch). Prefer
462    /// `childleaf_key()` or other safe accessors when you only need the
463    /// key or value; those avoid unsafe dereferences.
464    pub(crate) fn childleaf_ptr(&self) -> *const Leaf<KEY_LEN, V> {
465        match self.body_ref() {
466            BodyRef::Leaf(leaf) => leaf as *const Leaf<KEY_LEN, V>,
467            BodyRef::Branch(branch) => branch.childleaf_ptr(),
468        }
469    }
470
471    pub(crate) fn childleaf_key(&self) -> &[u8; KEY_LEN] {
472        match self.body_ref() {
473            BodyRef::Leaf(leaf) => &leaf.key,
474            BodyRef::Branch(branch) => &branch.childleaf().key,
475        }
476    }
477
478    // Slot wrapper defined at module level (moved to below the impl block)
479
480    /// Find the first depth in [start_depth, limit) where the tree-ordered
481    /// bytes of `self` and `other` differ. The comparison limit is computed
482    /// as min(self.end_depth(), other.end_depth(), KEY_LEN) which is the
483    /// natural bound for comparing two heads. Returns `Some((depth, a, b))`
484    /// where `a` and `b` are the differing bytes at that depth, or `None`
485    /// if no divergence is found in the range.
486    pub(crate) fn first_divergence(
487        &self,
488        other: &Self,
489        start_depth: usize,
490    ) -> Option<(usize, u8, u8)> {
491        let limit = std::cmp::min(std::cmp::min(self.end_depth(), other.end_depth()), KEY_LEN);
492        debug_assert!(limit <= KEY_LEN);
493        let this_key = self.childleaf_key();
494        let other_key = other.childleaf_key();
495        let mut depth = start_depth;
496        while depth < limit {
497            let i = O::TREE_TO_KEY[depth];
498            let a = this_key[i];
499            let b = other_key[i];
500            if a != b {
501                return Some((depth, a, b));
502            }
503            depth += 1;
504        }
505        None
506    }
507
508    // Mutable access to the child slots for this head. If the head is a
509    // branch, returns a mutable slice referencing the underlying child table
510    // (each element is Option<Head>). If the head is a leaf an empty slice
511    // is returned.
512    //
513    // The caller receives a &mut slice tied to the borrow of `self` and may
514    // reorder entries in-place (e.g., sort_unstable) and then take them using
515    // `Option::take()` to extract Head values. The call uses `body_mut()` so
516    // COW semantics are preserved and callers have exclusive access to the
517    // branch storage while the mutable borrow lasts.
518    // NOTE: mut_children removed — prefer matching on BodyRef returned by
519    // `body_mut()` and operating directly on the `&mut Branch` reference.
520
521    pub(crate) fn remove_leaf(
522        slot: &mut Option<Self>,
523        leaf_key: &[u8; KEY_LEN],
524        start_depth: usize,
525    ) {
526        if let Some(this) = slot {
527            let end_depth = std::cmp::min(this.end_depth(), KEY_LEN);
528            // Check reachable equality by asking the head to test the prefix
529            // up to its end_depth. Using the head/leaf primitive centralises the
530            // unsafe deref into Branch::childleaf()/Leaf::has_prefix.
531            if !this.has_prefix::<KEY_LEN>(start_depth, leaf_key) {
532                return;
533            }
534            if this.tag() == HeadTag::Leaf {
535                slot.take();
536            } else {
537                let mut ed = crate::patch::branch::BranchMut::from_head(this);
538                let key = leaf_key[end_depth];
539                ed.modify_child(key, |mut opt| {
540                    Self::remove_leaf(&mut opt, leaf_key, end_depth);
541                    opt
542                });
543
544                // If the branch now contains a single remaining child we
545                // collapse the branch upward into that child. We must pull
546                // the remaining child out while `ed` is still borrowed,
547                // then drop `ed` before writing back into `slot` to avoid
548                // double mutable borrows of the slot.
549                if ed.leaf_count == 1 {
550                    let mut remaining: Option<Head<KEY_LEN, O, V>> = None;
551                    for slot_child in &mut ed.child_table {
552                        if let Some(child) = slot_child.take() {
553                            remaining = Some(child.with_start(start_depth));
554                            break;
555                        }
556                    }
557                    drop(ed);
558                    if let Some(child) = remaining {
559                        slot.replace(child);
560                    }
561                } else {
562                    // ensure we drop the editor when not collapsing so the
563                    // final pointer is committed back into the head.
564                    drop(ed);
565                }
566            }
567        }
568    }
569
570    // NOTE: slot-level wrappers removed; callers should take the slot and call
571    // the owned helpers (insert_leaf / replace_leaf / union)
572    // directly. This reduces the indirection and keeps ownership semantics
573    // explicit at the call site.
574
575    // Owned variants of the slot-based helpers. These accept the existing
576    // Head by value and return the new Head after performing the
577    // modification. They are used with the split `insert_child` /
578    // `update_child` APIs so we no longer need `Branch::upsert_child`.
579    pub(crate) fn insert_leaf(mut this: Self, leaf: Self, start_depth: usize) -> Self {
580        if let Some((depth, this_byte_key, leaf_byte_key)) =
581            this.first_divergence(&leaf, start_depth)
582        {
583            let old_key = this.key();
584            let new_body = Branch::new(
585                depth,
586                this.with_key(this_byte_key),
587                leaf.with_key(leaf_byte_key),
588            );
589            return Head::new(old_key, new_body);
590        }
591
592        let end_depth = this.end_depth();
593        if end_depth != KEY_LEN {
594            // Use the editable BranchMut view to perform mutations without
595            // exposing pointer juggling at the call site.
596            let mut ed = crate::patch::branch::BranchMut::from_head(&mut this);
597            let inserted = leaf.with_start(ed.end_depth as usize);
598            let key = inserted.key();
599            ed.modify_child(key, |opt| match opt {
600                Some(old) => Some(Head::insert_leaf(old, inserted, end_depth)),
601                None => Some(inserted),
602            });
603        }
604        this
605    }
606
607    pub(crate) fn replace_leaf(mut this: Self, leaf: Self, start_depth: usize) -> Self {
608        if let Some((depth, this_byte_key, leaf_byte_key)) =
609            this.first_divergence(&leaf, start_depth)
610        {
611            let old_key = this.key();
612            let new_body = Branch::new(
613                depth,
614                this.with_key(this_byte_key),
615                leaf.with_key(leaf_byte_key),
616            );
617
618            return Head::new(old_key, new_body);
619        }
620
621        let end_depth = this.end_depth();
622        if end_depth == KEY_LEN {
623            let old_key = this.key();
624            return leaf.with_key(old_key);
625        } else {
626            // Use the editor view for branch mutation instead of raw pointer ops.
627            let mut ed = crate::patch::branch::BranchMut::from_head(&mut this);
628            let inserted = leaf.with_start(ed.end_depth as usize);
629            let key = inserted.key();
630            ed.modify_child(key, |opt| match opt {
631                Some(old) => Some(Head::replace_leaf(old, inserted, end_depth)),
632                None => Some(inserted),
633            });
634        }
635        this
636    }
637
638    pub(crate) fn union(mut this: Self, mut other: Self, at_depth: usize) -> Self {
639        if this.hash() == other.hash() {
640            return this;
641        }
642
643        if let Some((depth, this_byte_key, other_byte_key)) =
644            this.first_divergence(&other, at_depth)
645        {
646            let old_key = this.key();
647            let new_body = Branch::new(
648                depth,
649                this.with_key(this_byte_key),
650                other.with_key(other_byte_key),
651            );
652
653            return Head::new(old_key, new_body);
654        }
655
656        let this_depth = this.end_depth();
657        let other_depth = other.end_depth();
658        if this_depth < other_depth {
659            // Use BranchMut to edit `this` safely and avoid pointer juggling.
660            let mut ed = crate::patch::branch::BranchMut::from_head(&mut this);
661            let inserted = other.with_start(ed.end_depth as usize);
662            let key = inserted.key();
663            ed.modify_child(key, |opt| match opt {
664                Some(old) => Some(Head::union(old, inserted, this_depth)),
665                None => Some(inserted),
666            });
667
668            drop(ed);
669            return this;
670        }
671
672        if other_depth < this_depth {
673            let old_key = this.key();
674            let this_head = this;
675            let mut ed = crate::patch::branch::BranchMut::from_head(&mut other);
676            let inserted = this_head.with_start(ed.end_depth as usize);
677            let key = inserted.key();
678            ed.modify_child(key, |opt| match opt {
679                Some(old) => Some(Head::union(old, inserted, other_depth)),
680                None => Some(inserted),
681            });
682            drop(ed);
683
684            return other.with_key(old_key);
685        }
686
687        // both depths are equal and the hashes differ: merge children
688        let BodyMut::Branch(other_branch_ref) = other.body_mut() else {
689            unreachable!();
690        };
691        {
692            // Editable branch view: construct a BranchMut from the owned `this`
693            // head and perform all mutations via that editor. The editor
694            // performs COW up-front and writes the final pointer back into
695            // `this` when it is dropped.
696            let mut ed = crate::patch::branch::BranchMut::from_head(&mut this);
697            for other_child in other_branch_ref
698                .child_table
699                .iter_mut()
700                .filter_map(Option::take)
701            {
702                let inserted = other_child.with_start(ed.end_depth as usize);
703                let key = inserted.key();
704                ed.modify_child(key, |opt| match opt {
705                    Some(old) => Some(Head::union(old, inserted, this_depth)),
706                    None => Some(inserted),
707                });
708            }
709        }
710        this
711    }
712
713    pub(crate) fn infixes<const PREFIX_LEN: usize, const INFIX_LEN: usize, F>(
714        &self,
715        prefix: &[u8; PREFIX_LEN],
716        at_depth: usize,
717        f: &mut F,
718    ) where
719        F: FnMut(&[u8; INFIX_LEN]),
720    {
721        match self.body_ref() {
722            BodyRef::Leaf(leaf) => leaf.infixes::<PREFIX_LEN, INFIX_LEN, O, F>(prefix, at_depth, f),
723            BodyRef::Branch(branch) => {
724                branch.infixes::<PREFIX_LEN, INFIX_LEN, F>(prefix, at_depth, f)
725            }
726        }
727    }
728
729    pub(crate) fn has_prefix<const PREFIX_LEN: usize>(
730        &self,
731        at_depth: usize,
732        prefix: &[u8; PREFIX_LEN],
733    ) -> bool {
734        const {
735            assert!(PREFIX_LEN <= KEY_LEN);
736        }
737        match self.body_ref() {
738            BodyRef::Leaf(leaf) => leaf.has_prefix::<O>(at_depth, prefix),
739            BodyRef::Branch(branch) => branch.has_prefix::<PREFIX_LEN>(at_depth, prefix),
740        }
741    }
742
743    pub(crate) fn get<'a>(&'a self, at_depth: usize, key: &[u8; KEY_LEN]) -> Option<&'a V>
744    where
745        O: 'a,
746    {
747        match self.body_ref() {
748            BodyRef::Leaf(leaf) => leaf.get::<O>(at_depth, key),
749            BodyRef::Branch(branch) => branch.get(at_depth, key),
750        }
751    }
752
753    pub(crate) fn segmented_len<const PREFIX_LEN: usize>(
754        &self,
755        at_depth: usize,
756        prefix: &[u8; PREFIX_LEN],
757    ) -> u64 {
758        match self.body_ref() {
759            BodyRef::Leaf(leaf) => leaf.segmented_len::<O, PREFIX_LEN>(at_depth, prefix),
760            BodyRef::Branch(branch) => branch.segmented_len::<PREFIX_LEN>(at_depth, prefix),
761        }
762    }
763
764    // NOTE: slot-level union wrapper removed; callers should take the slot and
765    // call the owned helper `union` directly.
766
767    pub(crate) fn intersect(&self, other: &Self, at_depth: usize) -> Option<Self> {
768        if self.hash() == other.hash() {
769            return Some(self.clone());
770        }
771
772        if self.first_divergence(other, at_depth).is_some() {
773            return None;
774        }
775
776        let self_depth = self.end_depth();
777        let other_depth = other.end_depth();
778        if self_depth < other_depth {
779            // This means that there can be at most one child in self
780            // that might intersect with other.
781            let BodyRef::Branch(branch) = self.body_ref() else {
782                unreachable!();
783            };
784            return branch
785                .child_table
786                .table_get(other.childleaf_key()[O::TREE_TO_KEY[self_depth]])
787                .and_then(|self_child| other.intersect(self_child, self_depth));
788        }
789
790        if other_depth < self_depth {
791            // This means that there can be at most one child in other
792            // that might intersect with self.
793            // If the depth of other is less than the depth of self, then it can't be a leaf.
794            let BodyRef::Branch(other_branch) = other.body_ref() else {
795                unreachable!();
796            };
797            return other_branch
798                .child_table
799                .table_get(self.childleaf_key()[O::TREE_TO_KEY[other_depth]])
800                .and_then(|other_child| self.intersect(other_child, other_depth));
801        }
802
803        // If we reached this point then the depths are equal. The only way to have a leaf
804        // is if the other is a leaf as well, which is already handled by the hash check if they are equal,
805        // and by the key check if they are not equal.
806        // If one of them is a leaf and the other is a branch, then they would also have different depths,
807        // which is already handled by the above code.
808        let BodyRef::Branch(self_branch) = self.body_ref() else {
809            unreachable!();
810        };
811        let BodyRef::Branch(other_branch) = other.body_ref() else {
812            unreachable!();
813        };
814
815        let mut intersected_children = self_branch
816            .child_table
817            .iter()
818            .filter_map(Option::as_ref)
819            .filter_map(|self_child| {
820                let other_child = other_branch.child_table.table_get(self_child.key())?;
821                self_child.intersect(other_child, self_depth)
822            });
823        let first_child = intersected_children.next()?;
824        let Some(second_child) = intersected_children.next() else {
825            return Some(first_child);
826        };
827        let new_branch = Branch::new(
828            self_depth,
829            first_child.with_start(self_depth),
830            second_child.with_start(self_depth),
831        );
832        // Use a BranchMut editor to perform all child insertions via the
833        // safe editor API instead of manipulating the NonNull pointer
834        // directly. The editor will perform COW and commit the final
835        // pointer into the Head when it is dropped.
836        let mut head_for_branch = Head::new(0, new_branch);
837        {
838            let mut ed = crate::patch::branch::BranchMut::from_head(&mut head_for_branch);
839            for child in intersected_children {
840                let inserted = child.with_start(self_depth);
841                let k = inserted.key();
842                ed.modify_child(k, |_opt| Some(inserted));
843            }
844            // ed dropped here commits the final branch pointer into head_for_branch
845        }
846        Some(head_for_branch)
847    }
848
849    /// Returns the difference between self and other.
850    /// This is the set of elements that are in self but not in other.
851    /// If the difference is empty, None is returned.
852    pub(crate) fn difference(&self, other: &Self, at_depth: usize) -> Option<Self> {
853        if self.hash() == other.hash() {
854            return None;
855        }
856
857        if self.first_divergence(other, at_depth).is_some() {
858            return Some(self.clone());
859        }
860
861        let self_depth = self.end_depth();
862        let other_depth = other.end_depth();
863        if self_depth < other_depth {
864            // This means that there can be at most one child in self
865            // that might intersect with other. It's the only child that may not be in the difference.
866            // The other children are definitely in the difference, as they have no corresponding byte in other.
867            // Thus the cheapest way to compute the difference is compute the difference of the only child
868            // that might intersect with other, copy self with it's correctly filled byte table, then
869            // remove the old child, and insert the new child.
870            let mut new_branch = self.clone();
871            let other_byte_key = other.childleaf_key()[O::TREE_TO_KEY[self_depth]];
872            {
873                let mut ed = crate::patch::branch::BranchMut::from_head(&mut new_branch);
874                ed.modify_child(other_byte_key, |opt| {
875                    opt.and_then(|child| child.difference(other, self_depth))
876                });
877            }
878            return Some(new_branch);
879        }
880
881        if other_depth < self_depth {
882            // This means that we need to check if there is a child in other
883            // that matches the path at the current depth of self.
884            // There is no such child, then then self must be in the difference.
885            // If there is such a child, then we have to compute the difference
886            // between self and that child.
887            // We know that other must be a branch.
888            let BodyRef::Branch(other_branch) = other.body_ref() else {
889                unreachable!();
890            };
891            let self_byte_key = self.childleaf_key()[O::TREE_TO_KEY[other_depth]];
892            if let Some(other_child) = other_branch.child_table.table_get(self_byte_key) {
893                return self.difference(other_child, at_depth);
894            } else {
895                return Some(self.clone());
896            }
897        }
898
899        // If we reached this point then the depths are equal. The only way to have a leaf
900        // is if the other is a leaf as well, which is already handled by the hash check if they are equal,
901        // and by the key check if they are not equal.
902        // If one of them is a leaf and the other is a branch, then they would also have different depths,
903        // which is already handled by the above code.
904        let BodyRef::Branch(self_branch) = self.body_ref() else {
905            unreachable!();
906        };
907        let BodyRef::Branch(other_branch) = other.body_ref() else {
908            unreachable!();
909        };
910
911        let mut differenced_children = self_branch
912            .child_table
913            .iter()
914            .filter_map(Option::as_ref)
915            .filter_map(|self_child| {
916                if let Some(other_child) = other_branch.child_table.table_get(self_child.key()) {
917                    self_child.difference(other_child, self_depth)
918                } else {
919                    Some(self_child.clone())
920                }
921            });
922
923        let first_child = differenced_children.next()?;
924        let second_child = match differenced_children.next() {
925            Some(sc) => sc,
926            None => return Some(first_child),
927        };
928
929        let new_branch = Branch::new(
930            self_depth,
931            first_child.with_start(self_depth),
932            second_child.with_start(self_depth),
933        );
934        let mut head_for_branch = Head::new(0, new_branch);
935        {
936            let mut ed = crate::patch::branch::BranchMut::from_head(&mut head_for_branch);
937            for child in differenced_children {
938                let inserted = child.with_start(self_depth);
939                let k = inserted.key();
940                ed.modify_child(k, |_opt| Some(inserted));
941            }
942            // ed dropped here commits the final branch pointer into head_for_branch
943        }
944        // The key will be set later, because we don't know it yet.
945        // The difference might remove multiple levels of branches,
946        // so we can't just take the key from self or other.
947        Some(head_for_branch)
948    }
949}
950
951unsafe impl<const KEY_LEN: usize, O: KeySchema<KEY_LEN>, V> ByteEntry for Head<KEY_LEN, O, V> {
952    fn key(&self) -> u8 {
953        self.key()
954    }
955}
956
957impl<const KEY_LEN: usize, O: KeySchema<KEY_LEN>, V> fmt::Debug for Head<KEY_LEN, O, V> {
958    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
959        self.tag().fmt(f)
960    }
961}
962
963impl<const KEY_LEN: usize, O: KeySchema<KEY_LEN>, V> Clone for Head<KEY_LEN, O, V> {
964    fn clone(&self) -> Self {
965        unsafe {
966            match self.body() {
967                BodyPtr::Leaf(leaf) => Self::new(self.key(), Leaf::rc_inc(leaf)),
968                BodyPtr::Branch(branch) => Self::new(self.key(), Branch::rc_inc(branch)),
969            }
970        }
971    }
972}
973
974// The Slot wrapper was removed in favor of using BranchMut::from_slot(&mut
975// Option<Head<...>>) directly. This keeps the API surface smaller and
976// avoids an extra helper type that simply forwarded to BranchMut.
977
978impl<const KEY_LEN: usize, O: KeySchema<KEY_LEN>, V> Drop for Head<KEY_LEN, O, V> {
979    fn drop(&mut self) {
980        unsafe {
981            match self.body() {
982                BodyPtr::Leaf(leaf) => Leaf::rc_dec(leaf),
983                BodyPtr::Branch(branch) => Branch::rc_dec(branch),
984            }
985        }
986    }
987}
988
989/// A PATCH is a persistent data structure that stores a set of keys.
990/// Each key can be reordered and segmented, based on the provided key ordering and segmentation.
991///
992/// The patch supports efficient set operations, like union, intersection, and difference,
993/// because it efficiently maintains a hash for all keys that are part of a sub-tree.
994///
995/// The tree itself is a path- and node-compressed a 256-ary trie.
996/// Each nodes stores its children in a byte oriented cuckoo hash table,
997/// allowing for O(1) access to children, while keeping the memory overhead low.
998/// Table sizes are powers of two, starting at 2.
999///
1000/// Having a single node type for all branching factors simplifies the implementation,
1001/// compared to other adaptive trie implementations, like ARTs or Judy Arrays
1002///
1003/// The PATCH allows for cheap copy-on-write operations, with `clone` being O(1).
1004#[derive(Debug)]
1005pub struct PATCH<const KEY_LEN: usize, O = IdentitySchema, V = ()>
1006where
1007    O: KeySchema<KEY_LEN>,
1008{
1009    root: Option<Head<KEY_LEN, O, V>>,
1010}
1011
1012impl<const KEY_LEN: usize, O, V> Clone for PATCH<KEY_LEN, O, V>
1013where
1014    O: KeySchema<KEY_LEN>,
1015{
1016    fn clone(&self) -> Self {
1017        Self {
1018            root: self.root.clone(),
1019        }
1020    }
1021}
1022
1023impl<const KEY_LEN: usize, O, V> Default for PATCH<KEY_LEN, O, V>
1024where
1025    O: KeySchema<KEY_LEN>,
1026{
1027    fn default() -> Self {
1028        Self::new()
1029    }
1030}
1031
1032impl<const KEY_LEN: usize, O, V> PATCH<KEY_LEN, O, V>
1033where
1034    O: KeySchema<KEY_LEN>,
1035{
1036    /// Creates a new empty PATCH.
1037    pub fn new() -> Self {
1038        init_sip_key();
1039        PATCH { root: None }
1040    }
1041
1042    /// Inserts a shared key into the PATCH.
1043    ///
1044    /// Takes an [Entry] object that can be created from a key,
1045    /// and inserted into multiple PATCH instances.
1046    ///
1047    /// If the key is already present, this is a no-op.
1048    pub fn insert(&mut self, entry: &Entry<KEY_LEN, V>) {
1049        if self.root.is_some() {
1050            let this = self.root.take().expect("root should not be empty");
1051            let new_head = Head::insert_leaf(this, entry.leaf(), 0);
1052            self.root.replace(new_head);
1053        } else {
1054            self.root.replace(entry.leaf());
1055        }
1056    }
1057
1058    /// Inserts a key into the PATCH, replacing the value if it already exists.
1059    pub fn replace(&mut self, entry: &Entry<KEY_LEN, V>) {
1060        if self.root.is_some() {
1061            let this = self.root.take().expect("root should not be empty");
1062            let new_head = Head::replace_leaf(this, entry.leaf(), 0);
1063            self.root.replace(new_head);
1064        } else {
1065            self.root.replace(entry.leaf());
1066        }
1067    }
1068
1069    /// Removes a key from the PATCH.
1070    ///
1071    /// If the key is not present, this is a no-op.
1072    pub fn remove(&mut self, key: &[u8; KEY_LEN]) {
1073        Head::remove_leaf(&mut self.root, key, 0);
1074    }
1075
1076    /// Returns the number of keys in the PATCH.
1077    pub fn len(&self) -> u64 {
1078        if let Some(root) = &self.root {
1079            root.count()
1080        } else {
1081            0
1082        }
1083    }
1084
1085    /// Returns true if the PATCH contains no keys.
1086    pub fn is_empty(&self) -> bool {
1087        self.len() == 0
1088    }
1089
1090    pub(crate) fn root_hash(&self) -> Option<u128> {
1091        self.root.as_ref().map(|root| root.hash())
1092    }
1093
1094    /// Returns the value associated with `key` if present.
1095    pub fn get(&self, key: &[u8; KEY_LEN]) -> Option<&V> {
1096        self.root.as_ref().and_then(|root| root.get(0, key))
1097    }
1098
1099    /// Allows iteratig over all infixes of a given length with a given prefix.
1100    /// Each infix is passed to the provided closure.
1101    ///
1102    /// The entire operation is performed over the tree view ordering of the keys.
1103    ///
1104    /// The length of the prefix and the infix is provided as type parameters,
1105    /// but will usually inferred from the arguments.
1106    ///
1107    /// The sum of `PREFIX_LEN` and `INFIX_LEN` must be less than or equal to `KEY_LEN`
1108    /// or a compile-time assertion will fail.
1109    ///
1110    /// Because all infixes are iterated in one go, less bookkeeping is required,
1111    /// than when using an Iterator, allowing for better performance.
1112    pub fn infixes<const PREFIX_LEN: usize, const INFIX_LEN: usize, F>(
1113        &self,
1114        prefix: &[u8; PREFIX_LEN],
1115        mut for_each: F,
1116    ) where
1117        F: FnMut(&[u8; INFIX_LEN]),
1118    {
1119        const {
1120            assert!(PREFIX_LEN + INFIX_LEN <= KEY_LEN);
1121        }
1122        assert!(
1123            O::same_segment_tree(PREFIX_LEN, PREFIX_LEN + INFIX_LEN - 1)
1124                && (PREFIX_LEN + INFIX_LEN == KEY_LEN
1125                    || !O::same_segment_tree(PREFIX_LEN + INFIX_LEN - 1, PREFIX_LEN + INFIX_LEN)),
1126            "INFIX_LEN must cover a whole segment"
1127        );
1128        if let Some(root) = &self.root {
1129            root.infixes(prefix, 0, &mut for_each);
1130        }
1131    }
1132
1133    /// Returns true if the PATCH has a key with the given prefix.
1134    ///
1135    /// `PREFIX_LEN` must be less than or equal to `KEY_LEN` or a compile-time
1136    /// assertion will fail.
1137    pub fn has_prefix<const PREFIX_LEN: usize>(&self, prefix: &[u8; PREFIX_LEN]) -> bool {
1138        const {
1139            assert!(PREFIX_LEN <= KEY_LEN);
1140        }
1141        if let Some(root) = &self.root {
1142            root.has_prefix(0, prefix)
1143        } else {
1144            PREFIX_LEN == 0
1145        }
1146    }
1147
1148    /// Returns the number of unique segments in keys with the given prefix.
1149    pub fn segmented_len<const PREFIX_LEN: usize>(&self, prefix: &[u8; PREFIX_LEN]) -> u64 {
1150        const {
1151            assert!(PREFIX_LEN <= KEY_LEN);
1152            if PREFIX_LEN > 0 && PREFIX_LEN < KEY_LEN {
1153                assert!(
1154                    <O as KeySchema<KEY_LEN>>::Segmentation::SEGMENTS
1155                        [O::TREE_TO_KEY[PREFIX_LEN - 1]]
1156                        != <O as KeySchema<KEY_LEN>>::Segmentation::SEGMENTS
1157                            [O::TREE_TO_KEY[PREFIX_LEN]],
1158                    "PREFIX_LEN must align to segment boundary",
1159                );
1160            }
1161        }
1162        if let Some(root) = &self.root {
1163            root.segmented_len(0, prefix)
1164        } else {
1165            0
1166        }
1167    }
1168
1169    /// Iterates over all keys in the PATCH.
1170    /// The keys are returned in key ordering but random order.
1171    pub fn iter<'a>(&'a self) -> PATCHIterator<'a, KEY_LEN, O, V> {
1172        PATCHIterator::new(self)
1173    }
1174
1175    /// Iterates over all keys in the PATCH in key order.
1176    ///
1177    /// The traversal visits every key in lexicographic key order, without
1178    /// accepting a prefix filter. For prefix-aware iteration, see
1179    /// [`PATCH::iter_prefix_count`].
1180    pub fn iter_ordered<'a>(&'a self) -> PATCHOrderedIterator<'a, KEY_LEN, O, V> {
1181        PATCHOrderedIterator::new(self)
1182    }
1183
1184    /// Iterate over all prefixes of the given length in the PATCH.
1185    /// The prefixes are naturally returned in tree ordering and tree order.
1186    /// A count of the number of elements for the given prefix is also returned.
1187    pub fn iter_prefix_count<'a, const PREFIX_LEN: usize>(
1188        &'a self,
1189    ) -> PATCHPrefixIterator<'a, KEY_LEN, PREFIX_LEN, O, V> {
1190        PATCHPrefixIterator::new(self)
1191    }
1192
1193    /// Unions this PATCH with another PATCH.
1194    ///
1195    /// The other PATCH is consumed, and this PATCH is updated in place.
1196    pub fn union(&mut self, other: Self) {
1197        if let Some(other) = other.root {
1198            if self.root.is_some() {
1199                let this = self.root.take().expect("root should not be empty");
1200                let merged = Head::union(this, other, 0);
1201                self.root.replace(merged);
1202            } else {
1203                self.root.replace(other);
1204            }
1205        }
1206    }
1207
1208    /// Intersects this PATCH with another PATCH.
1209    ///
1210    /// Returns a new PATCH that contains only the keys that are present in both PATCHes.
1211    pub fn intersect(&self, other: &Self) -> Self {
1212        if let Some(root) = &self.root {
1213            if let Some(other_root) = &other.root {
1214                return Self {
1215                    root: root.intersect(other_root, 0).map(|root| root.with_start(0)),
1216                };
1217            }
1218        }
1219        Self::new()
1220    }
1221
1222    /// Returns the difference between this PATCH and another PATCH.
1223    ///
1224    /// Returns a new PATCH that contains only the keys that are present in this PATCH,
1225    /// but not in the other PATCH.
1226    pub fn difference(&self, other: &Self) -> Self {
1227        if let Some(root) = &self.root {
1228            if let Some(other_root) = &other.root {
1229                Self {
1230                    root: root.difference(other_root, 0),
1231                }
1232            } else {
1233                (*self).clone()
1234            }
1235        } else {
1236            (*other).clone()
1237        }
1238    }
1239
1240    /// Calculates the average fill level for branch nodes grouped by their
1241    /// branching factor. The returned array contains eight entries for branch
1242    /// sizes `2`, `4`, `8`, `16`, `32`, `64`, `128` and `256` in that order.
1243    //#[cfg(debug_assertions)]
1244    pub fn debug_branch_fill(&self) -> [f32; 8] {
1245        let mut counts = [0u64; 8];
1246        let mut used = [0u64; 8];
1247
1248        if let Some(root) = &self.root {
1249            let mut stack = Vec::new();
1250            stack.push(root);
1251
1252            while let Some(head) = stack.pop() {
1253                match head.body_ref() {
1254                    BodyRef::Leaf(_) => {}
1255                    BodyRef::Branch(b) => {
1256                        let size = b.child_table.len();
1257                        let idx = size.trailing_zeros() as usize - 1;
1258                        counts[idx] += 1;
1259                        used[idx] += b.child_table.iter().filter(|c| c.is_some()).count() as u64;
1260                        for child in b.child_table.iter().filter_map(|c| c.as_ref()) {
1261                            stack.push(child);
1262                        }
1263                    }
1264                }
1265            }
1266        }
1267
1268        let mut avg = [0f32; 8];
1269        for i in 0..8 {
1270            if counts[i] > 0 {
1271                let size = 1u64 << (i + 1);
1272                avg[i] = used[i] as f32 / (counts[i] as f32 * size as f32);
1273            }
1274        }
1275        avg
1276    }
1277}
1278
1279impl<const KEY_LEN: usize, O, V> PartialEq for PATCH<KEY_LEN, O, V>
1280where
1281    O: KeySchema<KEY_LEN>,
1282{
1283    fn eq(&self, other: &Self) -> bool {
1284        self.root.as_ref().map(|root| root.hash()) == other.root.as_ref().map(|root| root.hash())
1285    }
1286}
1287
1288impl<const KEY_LEN: usize, O, V> Eq for PATCH<KEY_LEN, O, V> where O: KeySchema<KEY_LEN> {}
1289
1290impl<'a, const KEY_LEN: usize, O, V> IntoIterator for &'a PATCH<KEY_LEN, O, V>
1291where
1292    O: KeySchema<KEY_LEN>,
1293{
1294    type Item = &'a [u8; KEY_LEN];
1295    type IntoIter = PATCHIterator<'a, KEY_LEN, O, V>;
1296
1297    fn into_iter(self) -> Self::IntoIter {
1298        PATCHIterator::new(self)
1299    }
1300}
1301
1302/// An iterator over all keys in a PATCH.
1303/// The keys are returned in key ordering but in random order.
1304pub struct PATCHIterator<'a, const KEY_LEN: usize, O: KeySchema<KEY_LEN>, V> {
1305    stack: ArrayVec<std::slice::Iter<'a, Option<Head<KEY_LEN, O, V>>>, KEY_LEN>,
1306    remaining: usize,
1307}
1308
1309impl<'a, const KEY_LEN: usize, O: KeySchema<KEY_LEN>, V> PATCHIterator<'a, KEY_LEN, O, V> {
1310    pub fn new(patch: &'a PATCH<KEY_LEN, O, V>) -> Self {
1311        let mut r = PATCHIterator {
1312            stack: ArrayVec::new(),
1313            remaining: patch.len().min(usize::MAX as u64) as usize,
1314        };
1315        r.stack.push(std::slice::from_ref(&patch.root).iter());
1316        r
1317    }
1318}
1319
1320impl<'a, const KEY_LEN: usize, O: KeySchema<KEY_LEN>, V> Iterator
1321    for PATCHIterator<'a, KEY_LEN, O, V>
1322{
1323    type Item = &'a [u8; KEY_LEN];
1324
1325    fn next(&mut self) -> Option<Self::Item> {
1326        let mut iter = self.stack.last_mut()?;
1327        loop {
1328            if let Some(child) = iter.next() {
1329                if let Some(child) = child {
1330                    match child.body_ref() {
1331                        BodyRef::Leaf(_) => {
1332                            self.remaining = self.remaining.saturating_sub(1);
1333                            // Use the safe accessor on the child reference to obtain the leaf key bytes.
1334                            return Some(child.childleaf_key());
1335                        }
1336                        BodyRef::Branch(branch) => {
1337                            self.stack.push(branch.child_table.iter());
1338                            iter = self.stack.last_mut()?;
1339                        }
1340                    }
1341                }
1342            } else {
1343                self.stack.pop();
1344                iter = self.stack.last_mut()?;
1345            }
1346        }
1347    }
1348
1349    fn size_hint(&self) -> (usize, Option<usize>) {
1350        (self.remaining, Some(self.remaining))
1351    }
1352}
1353
1354impl<'a, const KEY_LEN: usize, O: KeySchema<KEY_LEN>, V> ExactSizeIterator
1355    for PATCHIterator<'a, KEY_LEN, O, V>
1356{
1357}
1358
1359impl<'a, const KEY_LEN: usize, O: KeySchema<KEY_LEN>, V> std::iter::FusedIterator
1360    for PATCHIterator<'a, KEY_LEN, O, V>
1361{
1362}
1363
1364/// An iterator over every key in a PATCH, returned in key order.
1365///
1366/// Keys are yielded in lexicographic key order regardless of their physical
1367/// layout in the underlying tree. This iterator walks the full tree and does
1368/// not accept a prefix filter. For prefix-aware iteration, use
1369/// [`PATCHPrefixIterator`], constructed via [`PATCH::iter_prefix_count`].
1370pub struct PATCHOrderedIterator<'a, const KEY_LEN: usize, O: KeySchema<KEY_LEN>, V> {
1371    stack: Vec<ArrayVec<&'a Head<KEY_LEN, O, V>, 256>>,
1372    remaining: usize,
1373}
1374
1375impl<'a, const KEY_LEN: usize, O: KeySchema<KEY_LEN>, V> PATCHOrderedIterator<'a, KEY_LEN, O, V> {
1376    pub fn new(patch: &'a PATCH<KEY_LEN, O, V>) -> Self {
1377        let mut r = PATCHOrderedIterator {
1378            stack: Vec::with_capacity(KEY_LEN),
1379            remaining: patch.len().min(usize::MAX as u64) as usize,
1380        };
1381        if let Some(root) = &patch.root {
1382            r.stack.push(ArrayVec::new());
1383            match root.body_ref() {
1384                BodyRef::Leaf(_) => {
1385                    r.stack[0].push(root);
1386                }
1387                BodyRef::Branch(branch) => {
1388                    let first_level = &mut r.stack[0];
1389                    first_level.extend(branch.child_table.iter().filter_map(|c| c.as_ref()));
1390                    first_level.sort_unstable_by_key(|&k| Reverse(k.key())); // We need to reverse here because we pop from the vec.
1391                }
1392            }
1393        }
1394        r
1395    }
1396}
1397
1398// --- Owned consuming iterators ---
1399/// Iterator that owns a PATCH and yields keys in key-order. The iterator
1400/// consumes the PATCH and stores it on the heap (Box) so it can safely hold
1401/// raw pointers into the patch memory while the iterator is moved.
1402pub struct PATCHIntoIterator<const KEY_LEN: usize, O: KeySchema<KEY_LEN>, V> {
1403    queue: Vec<Head<KEY_LEN, O, V>>,
1404    remaining: usize,
1405}
1406
1407impl<const KEY_LEN: usize, O: KeySchema<KEY_LEN>, V> PATCHIntoIterator<KEY_LEN, O, V> {}
1408
1409impl<const KEY_LEN: usize, O: KeySchema<KEY_LEN>, V> Iterator for PATCHIntoIterator<KEY_LEN, O, V> {
1410    type Item = [u8; KEY_LEN];
1411
1412    fn next(&mut self) -> Option<Self::Item> {
1413        let q = &mut self.queue;
1414        while let Some(mut head) = q.pop() {
1415            // Match on the mutable body directly. For leaves we can return the
1416            // stored key (the array is Copy), for branches we take children out
1417            // of the table and push them onto the stack so they are visited
1418            // depth-first.
1419            match head.body_mut() {
1420                BodyMut::Leaf(leaf) => {
1421                    self.remaining = self.remaining.saturating_sub(1);
1422                    return Some(leaf.key);
1423                }
1424                BodyMut::Branch(branch) => {
1425                    for slot in branch.child_table.iter_mut().rev() {
1426                        if let Some(c) = slot.take() {
1427                            q.push(c);
1428                        }
1429                    }
1430                }
1431            }
1432        }
1433        None
1434    }
1435}
1436
1437/// Iterator that owns a PATCH and yields keys in key order.
1438pub struct PATCHIntoOrderedIterator<const KEY_LEN: usize, O: KeySchema<KEY_LEN>, V> {
1439    queue: Vec<Head<KEY_LEN, O, V>>,
1440    remaining: usize,
1441}
1442
1443impl<const KEY_LEN: usize, O: KeySchema<KEY_LEN>, V> Iterator
1444    for PATCHIntoOrderedIterator<KEY_LEN, O, V>
1445{
1446    type Item = [u8; KEY_LEN];
1447
1448    fn next(&mut self) -> Option<Self::Item> {
1449        let q = &mut self.queue;
1450        while let Some(mut head) = q.pop() {
1451            // Match the mutable body directly — we own `head` so calling
1452            // `body_mut()` is safe and allows returning the copied leaf key
1453            // or mutating the branch child table in-place.
1454            match head.body_mut() {
1455                BodyMut::Leaf(leaf) => {
1456                    self.remaining = self.remaining.saturating_sub(1);
1457                    return Some(leaf.key);
1458                }
1459                BodyMut::Branch(branch) => {
1460                    let slice: &mut [Option<Head<KEY_LEN, O, V>>] = &mut branch.child_table;
1461                    // Sort children by their byte-key, placing empty slots (None)
1462                    // after all occupied slots. Using `sort_unstable_by_key` with
1463                    // a simple key projection is clearer than a custom
1464                    // comparator; it also avoids allocating temporaries. The
1465                    // old comparator manually handled None/Some cases — we
1466                    // express that intent directly by sorting on the tuple
1467                    // (is_none, key_opt).
1468                    slice
1469                        .sort_unstable_by_key(|opt| (opt.is_none(), opt.as_ref().map(|h| h.key())));
1470                    for slot in slice.iter_mut().rev() {
1471                        if let Some(c) = slot.take() {
1472                            q.push(c);
1473                        }
1474                    }
1475                }
1476            }
1477        }
1478        None
1479    }
1480}
1481
1482impl<const KEY_LEN: usize, O: KeySchema<KEY_LEN>, V> IntoIterator for PATCH<KEY_LEN, O, V> {
1483    type Item = [u8; KEY_LEN];
1484    type IntoIter = PATCHIntoIterator<KEY_LEN, O, V>;
1485
1486    fn into_iter(self) -> Self::IntoIter {
1487        let remaining = self.len().min(usize::MAX as u64) as usize;
1488        let mut q = Vec::new();
1489        if let Some(root) = self.root {
1490            q.push(root);
1491        }
1492        PATCHIntoIterator {
1493            queue: q,
1494            remaining,
1495        }
1496    }
1497}
1498
1499impl<const KEY_LEN: usize, O: KeySchema<KEY_LEN>, V> PATCH<KEY_LEN, O, V> {
1500    /// Consume and return an iterator that yields keys in key order.
1501    pub fn into_iter_ordered(self) -> PATCHIntoOrderedIterator<KEY_LEN, O, V> {
1502        let remaining = self.len().min(usize::MAX as u64) as usize;
1503        let mut q = Vec::new();
1504        if let Some(root) = self.root {
1505            q.push(root);
1506        }
1507        PATCHIntoOrderedIterator {
1508            queue: q,
1509            remaining,
1510        }
1511    }
1512}
1513
1514impl<'a, const KEY_LEN: usize, O: KeySchema<KEY_LEN>, V> Iterator
1515    for PATCHOrderedIterator<'a, KEY_LEN, O, V>
1516{
1517    type Item = &'a [u8; KEY_LEN];
1518
1519    fn next(&mut self) -> Option<Self::Item> {
1520        let mut level = self.stack.last_mut()?;
1521        loop {
1522            if let Some(child) = level.pop() {
1523                match child.body_ref() {
1524                    BodyRef::Leaf(_) => {
1525                        self.remaining = self.remaining.saturating_sub(1);
1526                        return Some(child.childleaf_key());
1527                    }
1528                    BodyRef::Branch(branch) => {
1529                        self.stack.push(ArrayVec::new());
1530                        level = self.stack.last_mut()?;
1531                        level.extend(branch.child_table.iter().filter_map(|c| c.as_ref()));
1532                        level.sort_unstable_by_key(|&k| Reverse(k.key())); // We need to reverse here because we pop from the vec.
1533                    }
1534                }
1535            } else {
1536                self.stack.pop();
1537                level = self.stack.last_mut()?;
1538            }
1539        }
1540    }
1541
1542    fn size_hint(&self) -> (usize, Option<usize>) {
1543        (self.remaining, Some(self.remaining))
1544    }
1545}
1546
1547impl<'a, const KEY_LEN: usize, O: KeySchema<KEY_LEN>, V> ExactSizeIterator
1548    for PATCHOrderedIterator<'a, KEY_LEN, O, V>
1549{
1550}
1551
1552impl<'a, const KEY_LEN: usize, O: KeySchema<KEY_LEN>, V> std::iter::FusedIterator
1553    for PATCHOrderedIterator<'a, KEY_LEN, O, V>
1554{
1555}
1556
1557/// An iterator over all keys in a PATCH that have a given prefix.
1558/// The keys are returned in tree ordering and in tree order.
1559pub struct PATCHPrefixIterator<
1560    'a,
1561    const KEY_LEN: usize,
1562    const PREFIX_LEN: usize,
1563    O: KeySchema<KEY_LEN>,
1564    V,
1565> {
1566    stack: Vec<ArrayVec<&'a Head<KEY_LEN, O, V>, 256>>,
1567}
1568
1569impl<'a, const KEY_LEN: usize, const PREFIX_LEN: usize, O: KeySchema<KEY_LEN>, V>
1570    PATCHPrefixIterator<'a, KEY_LEN, PREFIX_LEN, O, V>
1571{
1572    fn new(patch: &'a PATCH<KEY_LEN, O, V>) -> Self {
1573        const {
1574            assert!(PREFIX_LEN <= KEY_LEN);
1575        }
1576        let mut r = PATCHPrefixIterator {
1577            stack: Vec::with_capacity(PREFIX_LEN),
1578        };
1579        if let Some(root) = &patch.root {
1580            r.stack.push(ArrayVec::new());
1581            if root.end_depth() >= PREFIX_LEN {
1582                r.stack[0].push(root);
1583            } else {
1584                let BodyRef::Branch(branch) = root.body_ref() else {
1585                    unreachable!();
1586                };
1587                let first_level = &mut r.stack[0];
1588                first_level.extend(branch.child_table.iter().filter_map(|c| c.as_ref()));
1589                first_level.sort_unstable_by_key(|&k| Reverse(k.key())); // We need to reverse here because we pop from the vec.
1590            }
1591        }
1592        r
1593    }
1594}
1595
1596impl<'a, const KEY_LEN: usize, const PREFIX_LEN: usize, O: KeySchema<KEY_LEN>, V> Iterator
1597    for PATCHPrefixIterator<'a, KEY_LEN, PREFIX_LEN, O, V>
1598{
1599    type Item = ([u8; PREFIX_LEN], u64);
1600
1601    fn next(&mut self) -> Option<Self::Item> {
1602        let mut level = self.stack.last_mut()?;
1603        loop {
1604            if let Some(child) = level.pop() {
1605                if child.end_depth() >= PREFIX_LEN {
1606                    let key = O::tree_ordered(child.childleaf_key());
1607                    let suffix_count = child.count();
1608                    return Some((key[0..PREFIX_LEN].try_into().unwrap(), suffix_count));
1609                } else {
1610                    let BodyRef::Branch(branch) = child.body_ref() else {
1611                        unreachable!();
1612                    };
1613                    self.stack.push(ArrayVec::new());
1614                    level = self.stack.last_mut()?;
1615                    level.extend(branch.child_table.iter().filter_map(|c| c.as_ref()));
1616                    level.sort_unstable_by_key(|&k| Reverse(k.key())); // We need to reverse here because we pop from the vec.
1617                }
1618            } else {
1619                self.stack.pop();
1620                level = self.stack.last_mut()?;
1621            }
1622        }
1623    }
1624}
1625
1626#[cfg(test)]
1627mod tests {
1628    use super::*;
1629    use itertools::Itertools;
1630    use proptest::prelude::*;
1631    use std::collections::HashSet;
1632    use std::convert::TryInto;
1633    use std::iter::FromIterator;
1634    use std::mem;
1635
1636    #[test]
1637    fn head_tag() {
1638        let head = Head::<64, IdentitySchema, ()>::new::<Leaf<64, ()>>(0, NonNull::dangling());
1639        assert_eq!(head.tag(), HeadTag::Leaf);
1640        mem::forget(head);
1641    }
1642
1643    #[test]
1644    fn head_key() {
1645        for k in 0..=255 {
1646            let head = Head::<64, IdentitySchema, ()>::new::<Leaf<64, ()>>(k, NonNull::dangling());
1647            assert_eq!(head.key(), k);
1648            mem::forget(head);
1649        }
1650    }
1651
1652    #[test]
1653    fn head_size() {
1654        assert_eq!(mem::size_of::<Head<64, IdentitySchema, ()>>(), 8);
1655    }
1656
1657    #[test]
1658    fn empty_tree() {
1659        let _tree = PATCH::<64, IdentitySchema, ()>::new();
1660    }
1661
1662    #[test]
1663    fn tree_put_one() {
1664        const KEY_SIZE: usize = 64;
1665        let mut tree = PATCH::<KEY_SIZE, IdentitySchema, ()>::new();
1666        let entry = Entry::new(&[0; KEY_SIZE]);
1667        tree.insert(&entry);
1668    }
1669
1670    #[test]
1671    fn tree_clone_one() {
1672        const KEY_SIZE: usize = 64;
1673        let mut tree = PATCH::<KEY_SIZE, IdentitySchema, ()>::new();
1674        let entry = Entry::new(&[0; KEY_SIZE]);
1675        tree.insert(&entry);
1676        let _clone = tree.clone();
1677    }
1678
1679    #[test]
1680    fn tree_put_same() {
1681        const KEY_SIZE: usize = 64;
1682        let mut tree = PATCH::<KEY_SIZE, IdentitySchema, ()>::new();
1683        let entry = Entry::new(&[0; KEY_SIZE]);
1684        tree.insert(&entry);
1685        tree.insert(&entry);
1686    }
1687
1688    #[test]
1689    fn tree_replace_existing() {
1690        const KEY_SIZE: usize = 64;
1691        let key = [1u8; KEY_SIZE];
1692        let mut tree = PATCH::<KEY_SIZE, IdentitySchema, u32>::new();
1693        let entry1 = Entry::with_value(&key, 1);
1694        tree.insert(&entry1);
1695        let entry2 = Entry::with_value(&key, 2);
1696        tree.replace(&entry2);
1697        assert_eq!(tree.get(&key), Some(&2));
1698    }
1699
1700    #[test]
1701    fn tree_replace_childleaf_updates_branch() {
1702        const KEY_SIZE: usize = 64;
1703        let key1 = [0u8; KEY_SIZE];
1704        let key2 = [1u8; KEY_SIZE];
1705        let mut tree = PATCH::<KEY_SIZE, IdentitySchema, u32>::new();
1706        let entry1 = Entry::with_value(&key1, 1);
1707        let entry2 = Entry::with_value(&key2, 2);
1708        tree.insert(&entry1);
1709        tree.insert(&entry2);
1710        let entry1b = Entry::with_value(&key1, 3);
1711        tree.replace(&entry1b);
1712        assert_eq!(tree.get(&key1), Some(&3));
1713        assert_eq!(tree.get(&key2), Some(&2));
1714    }
1715
1716    #[test]
1717    fn update_child_refreshes_childleaf_on_replace() {
1718        const KEY_SIZE: usize = 4;
1719        let mut tree = PATCH::<KEY_SIZE, IdentitySchema, u32>::new();
1720
1721        let key1 = [0u8; KEY_SIZE];
1722        let key2 = [1u8; KEY_SIZE];
1723        tree.insert(&Entry::with_value(&key1, 1));
1724        tree.insert(&Entry::with_value(&key2, 2));
1725
1726        // Determine which child currently provides the branch childleaf.
1727        let root_ref = tree.root.as_ref().expect("root exists");
1728        let before_childleaf = *root_ref.childleaf_key();
1729
1730        // Find the slot key (the byte index used in the branch table) for the child
1731        // that currently provides the childleaf.
1732        let slot_key = match root_ref.body_ref() {
1733            BodyRef::Branch(branch) => branch
1734                .child_table
1735                .iter()
1736                .filter_map(|c| c.as_ref())
1737                .find(|c| c.childleaf_key() == &before_childleaf)
1738                .expect("child exists")
1739                .key(),
1740            BodyRef::Leaf(_) => panic!("root should be a branch"),
1741        };
1742
1743        // Replace that child with a new leaf that has a different childleaf key.
1744        let new_key = [2u8; KEY_SIZE];
1745        {
1746            let mut ed = crate::patch::branch::BranchMut::from_slot(&mut tree.root);
1747            ed.modify_child(slot_key, |_| {
1748                Some(Entry::with_value(&new_key, 42).leaf::<IdentitySchema>())
1749            });
1750            // drop(ed) commits
1751        }
1752
1753        let after = tree.root.as_ref().expect("root exists");
1754        assert_eq!(after.childleaf_key(), &new_key);
1755    }
1756
1757    #[test]
1758    fn remove_childleaf_updates_branch() {
1759        const KEY_SIZE: usize = 4;
1760        let mut tree = PATCH::<KEY_SIZE, IdentitySchema, u32>::new();
1761
1762        let key1 = [0u8; KEY_SIZE];
1763        let key2 = [1u8; KEY_SIZE];
1764        tree.insert(&Entry::with_value(&key1, 1));
1765        tree.insert(&Entry::with_value(&key2, 2));
1766
1767        let childleaf_before = *tree.root.as_ref().unwrap().childleaf_key();
1768        // remove the leaf that currently provides the branch.childleaf
1769        tree.remove(&childleaf_before);
1770
1771        // Ensure the removed key is gone and the other key remains and is now the childleaf.
1772        let other = if childleaf_before == key1 { key2 } else { key1 };
1773        assert_eq!(tree.get(&childleaf_before), None);
1774        assert_eq!(tree.get(&other), Some(&2u32));
1775        let after_childleaf = tree.root.as_ref().unwrap().childleaf_key();
1776        assert_eq!(after_childleaf, &other);
1777    }
1778
1779    #[test]
1780    fn remove_collapses_branch_to_single_child() {
1781        const KEY_SIZE: usize = 4;
1782        let mut tree = PATCH::<KEY_SIZE, IdentitySchema, u32>::new();
1783
1784        let key1 = [0u8; KEY_SIZE];
1785        let key2 = [1u8; KEY_SIZE];
1786        tree.insert(&Entry::with_value(&key1, 1));
1787        tree.insert(&Entry::with_value(&key2, 2));
1788
1789        // Remove one key and ensure the root collapses to the remaining child.
1790        tree.remove(&key1);
1791        assert_eq!(tree.get(&key1), None);
1792        assert_eq!(tree.get(&key2), Some(&2u32));
1793        let root = tree.root.as_ref().expect("root exists");
1794        match root.body_ref() {
1795            BodyRef::Leaf(_) => {}
1796            BodyRef::Branch(_) => panic!("root should have collapsed to a leaf"),
1797        }
1798    }
1799
1800    #[test]
1801    fn branch_size() {
1802        assert_eq!(
1803            mem::size_of::<Branch<64, IdentitySchema, [Option<Head<64, IdentitySchema, ()>>; 2], ()>>(
1804            ),
1805            64
1806        );
1807        assert_eq!(
1808            mem::size_of::<Branch<64, IdentitySchema, [Option<Head<64, IdentitySchema, ()>>; 4], ()>>(
1809            ),
1810            48 + 16 * 2
1811        );
1812        assert_eq!(
1813            mem::size_of::<Branch<64, IdentitySchema, [Option<Head<64, IdentitySchema, ()>>; 8], ()>>(
1814            ),
1815            48 + 16 * 4
1816        );
1817        assert_eq!(
1818            mem::size_of::<
1819                Branch<64, IdentitySchema, [Option<Head<64, IdentitySchema, ()>>; 16], ()>,
1820            >(),
1821            48 + 16 * 8
1822        );
1823        assert_eq!(
1824            mem::size_of::<
1825                Branch<64, IdentitySchema, [Option<Head<32, IdentitySchema, ()>>; 32], ()>,
1826            >(),
1827            48 + 16 * 16
1828        );
1829        assert_eq!(
1830            mem::size_of::<
1831                Branch<64, IdentitySchema, [Option<Head<64, IdentitySchema, ()>>; 64], ()>,
1832            >(),
1833            48 + 16 * 32
1834        );
1835        assert_eq!(
1836            mem::size_of::<
1837                Branch<64, IdentitySchema, [Option<Head<64, IdentitySchema, ()>>; 128], ()>,
1838            >(),
1839            48 + 16 * 64
1840        );
1841        assert_eq!(
1842            mem::size_of::<
1843                Branch<64, IdentitySchema, [Option<Head<64, IdentitySchema, ()>>; 256], ()>,
1844            >(),
1845            48 + 16 * 128
1846        );
1847    }
1848
1849    /// Checks what happens if we join two PATCHes that
1850    /// only contain a single element each, that differs in the last byte.
1851    #[test]
1852    fn tree_union_single() {
1853        const KEY_SIZE: usize = 8;
1854        let mut left = PATCH::<KEY_SIZE, IdentitySchema, ()>::new();
1855        let mut right = PATCH::<KEY_SIZE, IdentitySchema, ()>::new();
1856        let left_entry = Entry::new(&[0, 0, 0, 0, 0, 0, 0, 0]);
1857        let right_entry = Entry::new(&[0, 0, 0, 0, 0, 0, 0, 1]);
1858        left.insert(&left_entry);
1859        right.insert(&right_entry);
1860        left.union(right);
1861        assert_eq!(left.len(), 2);
1862    }
1863
1864    // Small unit tests that ensure BranchMut-based editing is used by
1865    // the higher-level set operations like intersect/difference. These are
1866    // ordinary unit tests (not proptest) and must appear outside the
1867    // `proptest!` macro below.
1868
1869    proptest! {
1870        #[test]
1871        fn tree_insert(keys in prop::collection::vec(prop::collection::vec(0u8..=255, 64), 1..1024)) {
1872            let mut tree = PATCH::<64, IdentitySchema, ()>::new();
1873            for key in keys {
1874                let key: [u8; 64] = key.try_into().unwrap();
1875                let entry = Entry::new(&key);
1876                tree.insert(&entry);
1877            }
1878        }
1879
1880        #[test]
1881        fn tree_len(keys in prop::collection::vec(prop::collection::vec(0u8..=255, 64), 1..1024)) {
1882            let mut tree = PATCH::<64, IdentitySchema, ()>::new();
1883            let mut set = HashSet::new();
1884            for key in keys {
1885                let key: [u8; 64] = key.try_into().unwrap();
1886                let entry = Entry::new(&key);
1887                tree.insert(&entry);
1888                set.insert(key);
1889            }
1890
1891            prop_assert_eq!(set.len() as u64, tree.len())
1892        }
1893
1894        #[test]
1895        fn tree_infixes(keys in prop::collection::vec(prop::collection::vec(0u8..=255, 64), 1..1024)) {
1896            let mut tree = PATCH::<64, IdentitySchema, ()>::new();
1897            let mut set = HashSet::new();
1898            for key in keys {
1899                let key: [u8; 64] = key.try_into().unwrap();
1900                let entry = Entry::new(&key);
1901                tree.insert(&entry);
1902                set.insert(key);
1903            }
1904            let mut set_vec = Vec::from_iter(set.into_iter());
1905            let mut tree_vec = vec![];
1906            tree.infixes(&[0; 0], &mut |&x: &[u8; 64]| tree_vec.push(x));
1907
1908            set_vec.sort();
1909            tree_vec.sort();
1910
1911            prop_assert_eq!(set_vec, tree_vec);
1912        }
1913
1914        #[test]
1915        fn tree_iter(keys in prop::collection::vec(prop::collection::vec(0u8..=255, 64), 1..1024)) {
1916            let mut tree = PATCH::<64, IdentitySchema, ()>::new();
1917            let mut set = HashSet::new();
1918            for key in keys {
1919                let key: [u8; 64] = key.try_into().unwrap();
1920                let entry = Entry::new(&key);
1921                tree.insert(&entry);
1922                set.insert(key);
1923            }
1924            let mut set_vec = Vec::from_iter(set.into_iter());
1925            let mut tree_vec = vec![];
1926            for key in &tree {
1927                tree_vec.push(*key);
1928            }
1929
1930            set_vec.sort();
1931            tree_vec.sort();
1932
1933            prop_assert_eq!(set_vec, tree_vec);
1934        }
1935
1936        #[test]
1937        fn tree_union(left in prop::collection::vec(prop::collection::vec(0u8..=255, 64), 200),
1938                        right in prop::collection::vec(prop::collection::vec(0u8..=255, 64), 200)) {
1939            let mut set = HashSet::new();
1940
1941            let mut left_tree = PATCH::<64, IdentitySchema, ()>::new();
1942            for entry in left {
1943                let mut key = [0; 64];
1944                key.iter_mut().set_from(entry.iter().cloned());
1945                let entry = Entry::new(&key);
1946                left_tree.insert(&entry);
1947                set.insert(key);
1948            }
1949
1950            let mut right_tree = PATCH::<64, IdentitySchema, ()>::new();
1951            for entry in right {
1952                let mut key = [0; 64];
1953                key.iter_mut().set_from(entry.iter().cloned());
1954                let entry = Entry::new(&key);
1955                right_tree.insert(&entry);
1956                set.insert(key);
1957            }
1958
1959            left_tree.union(right_tree);
1960
1961            let mut set_vec = Vec::from_iter(set.into_iter());
1962            let mut tree_vec = vec![];
1963            left_tree.infixes(&[0; 0], &mut |&x: &[u8;64]| tree_vec.push(x));
1964
1965            set_vec.sort();
1966            tree_vec.sort();
1967
1968            prop_assert_eq!(set_vec, tree_vec);
1969            }
1970
1971        #[test]
1972        fn tree_union_empty(left in prop::collection::vec(prop::collection::vec(0u8..=255, 64), 2)) {
1973            let mut set = HashSet::new();
1974
1975            let mut left_tree = PATCH::<64, IdentitySchema, ()>::new();
1976            for entry in left {
1977                let mut key = [0; 64];
1978                key.iter_mut().set_from(entry.iter().cloned());
1979                let entry = Entry::new(&key);
1980                left_tree.insert(&entry);
1981                set.insert(key);
1982            }
1983
1984            let right_tree = PATCH::<64, IdentitySchema, ()>::new();
1985
1986            left_tree.union(right_tree);
1987
1988            let mut set_vec = Vec::from_iter(set.into_iter());
1989            let mut tree_vec = vec![];
1990            left_tree.infixes(&[0; 0], &mut |&x: &[u8;64]| tree_vec.push(x));
1991
1992            set_vec.sort();
1993            tree_vec.sort();
1994
1995            prop_assert_eq!(set_vec, tree_vec);
1996            }
1997
1998        // I got a feeling that we're not testing COW properly.
1999        // We should check if a tree remains the same after a clone of it
2000        // is modified by inserting new keys.
2001
2002    #[test]
2003    fn cow_on_insert(base_keys in prop::collection::vec(prop::collection::vec(0u8..=255, 8), 1..1024),
2004                         new_keys in prop::collection::vec(prop::collection::vec(0u8..=255, 8), 1..1024)) {
2005            // Note that we can't compare the trees directly, as that uses the hash,
2006            // which might not be affected by nodes in lower levels being changed accidentally.
2007            // Instead we need to iterate over the keys and check if they are the same.
2008
2009            let mut tree = PATCH::<8, IdentitySchema, ()>::new();
2010            for key in base_keys {
2011                let key: [u8; 8] = key[..].try_into().unwrap();
2012                let entry = Entry::new(&key);
2013                tree.insert(&entry);
2014            }
2015            let base_tree_content: Vec<[u8; 8]> = tree.iter().copied().collect();
2016
2017            let mut tree_clone = tree.clone();
2018            for key in new_keys {
2019                let key: [u8; 8] = key[..].try_into().unwrap();
2020                let entry = Entry::new(&key);
2021                tree_clone.insert(&entry);
2022            }
2023
2024            let new_tree_content: Vec<[u8; 8]> = tree.iter().copied().collect();
2025            prop_assert_eq!(base_tree_content, new_tree_content);
2026        }
2027
2028        #[test]
2029    fn cow_on_union(base_keys in prop::collection::vec(prop::collection::vec(0u8..=255, 8), 1..1024),
2030                         new_keys in prop::collection::vec(prop::collection::vec(0u8..=255, 8), 1..1024)) {
2031            // Note that we can't compare the trees directly, as that uses the hash,
2032            // which might not be affected by nodes in lower levels being changed accidentally.
2033            // Instead we need to iterate over the keys and check if they are the same.
2034
2035            let mut tree = PATCH::<8, IdentitySchema, ()>::new();
2036            for key in base_keys {
2037                let key: [u8; 8] = key[..].try_into().unwrap();
2038                let entry = Entry::new(&key);
2039                tree.insert(&entry);
2040            }
2041            let base_tree_content: Vec<[u8; 8]> = tree.iter().copied().collect();
2042
2043            let mut tree_clone = tree.clone();
2044            let mut new_tree = PATCH::<8, IdentitySchema, ()>::new();
2045            for key in new_keys {
2046                let key: [u8; 8] = key[..].try_into().unwrap();
2047                let entry = Entry::new(&key);
2048                new_tree.insert(&entry);
2049            }
2050            tree_clone.union(new_tree);
2051
2052            let new_tree_content: Vec<[u8; 8]> = tree.iter().copied().collect();
2053            prop_assert_eq!(base_tree_content, new_tree_content);
2054        }
2055    }
2056
2057    #[test]
2058    fn intersect_multiple_common_children_commits_branchmut() {
2059        const KEY_SIZE: usize = 4;
2060        let mut left = PATCH::<KEY_SIZE, IdentitySchema, u32>::new();
2061        let mut right = PATCH::<KEY_SIZE, IdentitySchema, u32>::new();
2062
2063        let a = [0u8, 0u8, 0u8, 1u8];
2064        let b = [0u8, 0u8, 0u8, 2u8];
2065        let c = [0u8, 0u8, 0u8, 3u8];
2066        let d = [2u8, 0u8, 0u8, 0u8];
2067        let e = [3u8, 0u8, 0u8, 0u8];
2068
2069        left.insert(&Entry::with_value(&a, 1));
2070        left.insert(&Entry::with_value(&b, 2));
2071        left.insert(&Entry::with_value(&c, 3));
2072        left.insert(&Entry::with_value(&d, 4));
2073
2074        right.insert(&Entry::with_value(&a, 10));
2075        right.insert(&Entry::with_value(&b, 11));
2076        right.insert(&Entry::with_value(&c, 12));
2077        right.insert(&Entry::with_value(&e, 13));
2078
2079        let res = left.intersect(&right);
2080        // A, B, C are common
2081        assert_eq!(res.len(), 3);
2082        assert!(res.get(&a).is_some());
2083        assert!(res.get(&b).is_some());
2084        assert!(res.get(&c).is_some());
2085    }
2086
2087    #[test]
2088    fn difference_multiple_children_commits_branchmut() {
2089        const KEY_SIZE: usize = 4;
2090        let mut left = PATCH::<KEY_SIZE, IdentitySchema, u32>::new();
2091        let mut right = PATCH::<KEY_SIZE, IdentitySchema, u32>::new();
2092
2093        let a = [0u8, 0u8, 0u8, 1u8];
2094        let b = [0u8, 0u8, 0u8, 2u8];
2095        let c = [0u8, 0u8, 0u8, 3u8];
2096        let d = [2u8, 0u8, 0u8, 0u8];
2097        let e = [3u8, 0u8, 0u8, 0u8];
2098
2099        left.insert(&Entry::with_value(&a, 1));
2100        left.insert(&Entry::with_value(&b, 2));
2101        left.insert(&Entry::with_value(&c, 3));
2102        left.insert(&Entry::with_value(&d, 4));
2103
2104        right.insert(&Entry::with_value(&a, 10));
2105        right.insert(&Entry::with_value(&b, 11));
2106        right.insert(&Entry::with_value(&c, 12));
2107        right.insert(&Entry::with_value(&e, 13));
2108
2109        let res = left.difference(&right);
2110        // left only has d
2111        assert_eq!(res.len(), 1);
2112        assert!(res.get(&d).is_some());
2113    }
2114
2115    #[test]
2116    fn slot_edit_branchmut_insert_update() {
2117        // Small unit test demonstrating the Slot::edit -> BranchMut insert/update pattern.
2118        const KEY_SIZE: usize = 8;
2119        let mut tree = PATCH::<KEY_SIZE, IdentitySchema, u32>::new();
2120
2121        let entry1 = Entry::with_value(&[0u8; KEY_SIZE], 1u32);
2122        let entry2 = Entry::with_value(&[1u8; KEY_SIZE], 2u32);
2123        tree.insert(&entry1);
2124        tree.insert(&entry2);
2125        assert_eq!(tree.len(), 2);
2126
2127        // Edit the root slot in-place using the BranchMut editor.
2128        {
2129            let mut ed = crate::patch::branch::BranchMut::from_slot(&mut tree.root);
2130
2131            // Compute the insertion start depth first to avoid borrowing `ed` inside the closure.
2132            let start_depth = ed.end_depth as usize;
2133            let inserted = Entry::with_value(&[2u8; KEY_SIZE], 3u32)
2134                .leaf::<IdentitySchema>()
2135                .with_start(start_depth);
2136            let key = inserted.key();
2137
2138            ed.modify_child(key, |opt| match opt {
2139                Some(old) => Some(Head::insert_leaf(old, inserted, start_depth)),
2140                None => Some(inserted),
2141            });
2142            // BranchMut is dropped here and commits the updated branch pointer back into the head.
2143        }
2144
2145        assert_eq!(tree.len(), 3);
2146        assert_eq!(tree.get(&[2u8; KEY_SIZE]), Some(&3u32));
2147    }
2148}