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