1use super::*;
2use core::sync::atomic;
3use core::sync::atomic::Ordering::Acquire;
4use core::sync::atomic::Ordering::Relaxed;
5use core::sync::atomic::Ordering::Release;
6use std::alloc::alloc_zeroed;
7use std::alloc::dealloc;
8use std::alloc::handle_alloc_error;
9use std::alloc::Layout;
10use std::ops::Deref;
11use std::ops::DerefMut;
12use std::ptr::addr_of;
13use std::ptr::addr_of_mut;
14use std::sync::Arc;
15
16const BRANCH_ALIGN: usize = 16;
17const BRANCH_BASE_SIZE: usize = 64;
18const TABLE_ENTRY_SIZE: usize = 8;
19
20pub trait ArchiveOwner: Send + Sync + 'static {}
29
30impl<T: Send + Sync + 'static + ?Sized> ArchiveOwner for T {}
31
32#[inline]
33pub(crate) fn dst_len<T>(ptr: *const [T]) -> usize {
34 let ptr: *const [()] = ptr as _;
35 let slice: &[()] = unsafe { &*ptr };
37 slice.len()
38}
39
40pub(crate) type BranchNN<const KEY_LEN: usize, O, V> =
45 NonNull<Branch<KEY_LEN, O, [Option<Head<KEY_LEN, O, V>>], V>>;
46
47pub(crate) struct BranchMut<'a, const KEY_LEN: usize, O: KeySchema<KEY_LEN>, V> {
48 head: &'a mut Head<KEY_LEN, O, V>,
49 branch_nn: BranchNN<KEY_LEN, O, V>,
50}
51
52impl<'a, const KEY_LEN: usize, O: KeySchema<KEY_LEN>, V> BranchMut<'a, KEY_LEN, O, V> {
53 pub(crate) fn from_head(head: &'a mut Head<KEY_LEN, O, V>) -> Self {
54 match head.body_mut() {
55 BodyMut::Branch(branch_ref) => {
56 let nn = unsafe { NonNull::new_unchecked(branch_ref as *mut _) };
57 Self {
58 head,
59 branch_nn: nn,
60 }
61 }
62 BodyMut::Leaf(_) | BodyMut::LocalLeaf(_) => {
63 panic!("BranchMut requires a Branch body")
64 }
65 }
66 }
67
68 #[allow(dead_code)]
69 pub(crate) fn from_slot(slot: &'a mut Option<Head<KEY_LEN, O, V>>) -> Self {
70 let head = slot.as_mut().expect("slot should not be empty");
71 Self::from_head(head)
72 }
73
74 pub fn modify_child<F>(&mut self, key: u8, f: F)
75 where
76 F: FnOnce(Option<Head<KEY_LEN, O, V>>) -> Option<Head<KEY_LEN, O, V>>,
77 {
78 Branch::modify_child(&mut self.branch_nn, key, f);
81 }
82
83 pub fn modify_child_with_inserted_hint<F>(&mut self, key: u8, inserted_hash: u128, f: F)
94 where
95 F: FnOnce(Option<Head<KEY_LEN, O, V>>) -> Option<Head<KEY_LEN, O, V>>,
96 {
97 Branch::modify_child_with_inserted_hint(&mut self.branch_nn, key, inserted_hash, f);
98 }
99
100 #[cfg_attr(not(feature = "parallel"), allow(dead_code))]
104 pub fn install_child_growing(&mut self, head: Head<KEY_LEN, O, V>) {
105 unsafe {
106 Branch::install_child_growing(&mut self.branch_nn, head);
107 }
108 }
109
110 #[cfg_attr(not(feature = "parallel"), allow(dead_code))]
114 pub fn recompute_aggregates(&mut self) {
115 unsafe {
116 Branch::recompute_aggregates(&mut self.branch_nn);
117 }
118 }
119}
120
121impl<'a, const KEY_LEN: usize, O: KeySchema<KEY_LEN>, V> Deref for BranchMut<'a, KEY_LEN, O, V> {
122 type Target = Branch<KEY_LEN, O, [Option<Head<KEY_LEN, O, V>>], V>;
123
124 fn deref(&self) -> &Self::Target {
125 unsafe { self.branch_nn.as_ref() }
126 }
127}
128
129impl<'a, const KEY_LEN: usize, O: KeySchema<KEY_LEN>, V> DerefMut for BranchMut<'a, KEY_LEN, O, V> {
130 fn deref_mut(&mut self) -> &mut Self::Target {
131 unsafe { self.branch_nn.as_mut() }
132 }
133}
134
135impl<'a, const KEY_LEN: usize, O: KeySchema<KEY_LEN>, V> Drop for BranchMut<'a, KEY_LEN, O, V> {
136 fn drop(&mut self) {
137 self.head.set_body(self.branch_nn);
139 }
140}
141
142#[repr(C, align(16))]
143pub(crate) struct Branch<const KEY_LEN: usize, O: KeySchema<KEY_LEN>, Table: ?Sized, V> {
144 key_ordering: PhantomData<O>,
145 key_segments: PhantomData<O::Segmentation>,
146 _value: PhantomData<fn() -> V>,
152
153 rc: atomic::AtomicU32,
154 pub end_depth: u32,
155 pub childleaf: *const [u8; KEY_LEN],
162 pub leaf_count: u64,
163 pub segment_count: u64,
164 pub hash: u128,
165 pub owner: Option<Arc<dyn ArchiveOwner>>,
170 pub child_table: Table,
171}
172
173impl<const KEY_LEN: usize, O: KeySchema<KEY_LEN>, Table: ?Sized + core::fmt::Debug, V: core::fmt::Debug>
176 core::fmt::Debug for Branch<KEY_LEN, O, Table, V>
177{
178 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
179 f.debug_struct("Branch")
180 .field("rc", &self.rc)
181 .field("end_depth", &self.end_depth)
182 .field("childleaf", &self.childleaf)
183 .field("leaf_count", &self.leaf_count)
184 .field("segment_count", &self.segment_count)
185 .field("hash", &self.hash)
186 .field("owner", &self.owner.as_ref().map(|_| "<archive owner>"))
187 .field("child_table", &&self.child_table)
188 .finish()
189 }
190}
191
192impl<const KEY_LEN: usize, O: KeySchema<KEY_LEN>, Table: ?Sized, V> Branch<KEY_LEN, O, Table, V> {
193 pub fn childleaf_key(&self) -> &[u8; KEY_LEN] {
198 unsafe { &*self.childleaf }
199 }
200
201 pub fn childleaf_ptr(&self) -> *const [u8; KEY_LEN] {
206 self.childleaf
207 }
208}
209
210impl<const KEY_LEN: usize, O: KeySchema<KEY_LEN>, V> Body
211 for Branch<KEY_LEN, O, [Option<Head<KEY_LEN, O, V>>], V>
212{
213 fn tag(body: NonNull<Self>) -> HeadTag {
214 unsafe {
215 let ptr = addr_of!((*body.as_ptr()).child_table);
216 let exp = dst_len(ptr).ilog2() as u8;
217 debug_assert!((1..=8).contains(&exp));
218 HeadTag::from_raw(exp)
219 }
220 }
221}
222
223impl<const KEY_LEN: usize, O: KeySchema<KEY_LEN>, V>
224 Branch<KEY_LEN, O, [Option<Head<KEY_LEN, O, V>>], V>
225{
226 pub(super) fn new(
227 end_depth: usize,
228 lchild: Head<KEY_LEN, O, V>,
229 rchild: Head<KEY_LEN, O, V>,
230 ) -> NonNull<Self> {
231 Self::new_with_owner(end_depth, lchild, rchild, None)
232 }
233
234 pub(super) fn new_with_owner(
238 end_depth: usize,
239 lchild: Head<KEY_LEN, O, V>,
240 rchild: Head<KEY_LEN, O, V>,
241 owner: Option<Arc<dyn ArchiveOwner>>,
242 ) -> NonNull<Self> {
243 let rchild_hash = rchild.hash();
248 Self::new_with_owner_and_rchild_hash(end_depth, lchild, rchild, owner, rchild_hash)
249 }
250
251 pub(super) fn new_with_owner_and_rchild_hash(
262 end_depth: usize,
263 lchild: Head<KEY_LEN, O, V>,
264 rchild: Head<KEY_LEN, O, V>,
265 owner: Option<Arc<dyn ArchiveOwner>>,
266 rchild_hash: u128,
267 ) -> NonNull<Self> {
268 unsafe {
269 let size = 2;
270 let layout = Layout::from_size_align_unchecked(
273 BRANCH_BASE_SIZE + (TABLE_ENTRY_SIZE * size),
274 BRANCH_ALIGN,
275 );
276 let Some(ptr) =
277 NonNull::new(std::ptr::slice_from_raw_parts(alloc_zeroed(layout), size)
278 as *mut Branch<KEY_LEN, O, [Option<Head<KEY_LEN, O, V>>], V>)
279 else {
280 handle_alloc_error(layout);
281 };
282 addr_of_mut!((*ptr.as_ptr()).rc).write(atomic::AtomicU32::new(1));
283 addr_of_mut!((*ptr.as_ptr()).end_depth).write(end_depth as u32);
284 addr_of_mut!((*ptr.as_ptr()).childleaf).write(lchild.childleaf_ptr());
285 addr_of_mut!((*ptr.as_ptr()).leaf_count).write(lchild.count() + rchild.count());
286 addr_of_mut!((*ptr.as_ptr()).segment_count)
287 .write(lchild.count_segment(end_depth) + rchild.count_segment(end_depth));
288 addr_of_mut!((*ptr.as_ptr()).hash).write(lchild.hash() ^ rchild_hash);
289 addr_of_mut!((*ptr.as_ptr()).owner).write(owner);
290 (*ptr.as_ptr()).child_table[0] = Some(lchild);
291 (*ptr.as_ptr()).child_table[1] = Some(rchild);
292
293 ptr
294 }
295 }
296
297 pub(super) unsafe fn rc_inc(branch: NonNull<Self>) -> NonNull<Self> {
298 unsafe {
299 let branch = branch.as_ptr();
300 let mut current = (*branch).rc.load(Relaxed);
301 loop {
302 if current == u32::MAX {
303 panic!("max refcount exceeded");
304 }
305 match (*branch)
306 .rc
307 .compare_exchange(current, current + 1, Relaxed, Relaxed)
308 {
309 Ok(_) => return NonNull::new_unchecked(branch),
310 Err(v) => current = v,
311 }
312 }
313 }
314 }
315
316 pub(super) unsafe fn rc_dec(branch: NonNull<Self>) {
317 unsafe {
318 let branch = branch.as_ptr();
319 if (*branch).rc.fetch_sub(1, Release) != 1 {
320 return;
321 }
322 (*branch).rc.load(Acquire);
323
324 let size = dst_len(addr_of!((*branch).child_table));
325
326 std::ptr::drop_in_place(branch);
327
328 let layout = Layout::from_size_align_unchecked(
331 BRANCH_BASE_SIZE + (TABLE_ENTRY_SIZE * size),
332 BRANCH_ALIGN,
333 );
334 let ptr = branch as *mut u8;
335 dealloc(ptr, layout);
336 }
337 }
338
339 pub(super) unsafe fn rc_cow(branch_nn: &mut NonNull<Self>) -> Option<()> {
344 unsafe {
345 let branch = branch_nn.as_ptr();
346 if (*branch).rc.load(Acquire) == 1 {
347 None
348 } else {
349 let size = dst_len(addr_of!((*branch).child_table));
350 let layout = Layout::from_size_align_unchecked(
353 BRANCH_BASE_SIZE + (TABLE_ENTRY_SIZE * size),
354 BRANCH_ALIGN,
355 );
356 if let Some(ptr) =
357 NonNull::new(std::ptr::slice_from_raw_parts(alloc_zeroed(layout), size)
358 as *mut Branch<KEY_LEN, O, [Option<Head<KEY_LEN, O, V>>], V>)
359 {
360 addr_of_mut!((*ptr.as_ptr()).rc).write(atomic::AtomicU32::new(1));
361 addr_of_mut!((*ptr.as_ptr()).end_depth).write((*branch).end_depth);
362 addr_of_mut!((*ptr.as_ptr()).childleaf).write((*branch).childleaf);
363 addr_of_mut!((*ptr.as_ptr()).leaf_count).write((*branch).leaf_count);
364 addr_of_mut!((*ptr.as_ptr()).segment_count).write((*branch).segment_count);
365 addr_of_mut!((*ptr.as_ptr()).hash).write((*branch).hash);
366 addr_of_mut!((*ptr.as_ptr()).owner).write((*branch).owner.clone());
367 (*ptr.as_ptr())
368 .child_table
369 .clone_from_slice(&(*branch).child_table);
370
371 Self::rc_dec(NonNull::new_unchecked(branch));
372 *branch_nn = ptr;
373 Some(())
374 } else {
375 handle_alloc_error(layout);
376 }
377 }
378 }
379 }
380
381 pub(crate) fn grow(branch_nn: &mut NonNull<Self>) {
386 unsafe {
387 let branch = branch_nn.as_ptr();
388 let old_size = dst_len(addr_of!((*branch).child_table));
389 let new_size = old_size * 2;
390 assert!(new_size <= 256);
391
392 let layout = Layout::from_size_align_unchecked(
395 BRANCH_BASE_SIZE + (TABLE_ENTRY_SIZE * new_size),
396 BRANCH_ALIGN,
397 );
398 if let Some(ptr) = NonNull::new(std::ptr::slice_from_raw_parts(
399 alloc_zeroed(layout),
400 new_size,
401 )
402 as *mut Branch<KEY_LEN, O, [Option<Head<KEY_LEN, O, V>>], V>)
403 {
404 addr_of_mut!((*ptr.as_ptr()).rc).write(atomic::AtomicU32::new(1));
405 addr_of_mut!((*ptr.as_ptr()).end_depth).write((*branch).end_depth);
406 addr_of_mut!((*ptr.as_ptr()).leaf_count).write((*branch).leaf_count);
407 addr_of_mut!((*ptr.as_ptr()).segment_count).write((*branch).segment_count);
408 addr_of_mut!((*ptr.as_ptr()).childleaf).write((*branch).childleaf);
409 addr_of_mut!((*ptr.as_ptr()).hash).write((*branch).hash);
410 addr_of_mut!((*ptr.as_ptr()).owner).write((*branch).owner.clone());
411 (*branch)
414 .child_table
415 .table_grow(&mut (*ptr.as_ptr()).child_table);
416
417 Branch::<KEY_LEN, O, [Option<Head<KEY_LEN, O, V>>], V>::rc_dec(
418 NonNull::new_unchecked(branch),
419 );
420
421 *branch_nn = ptr;
422 } else {
423 handle_alloc_error(layout);
424 }
425 }
426 }
427
428 pub(super) fn modify_child<F>(branch_nn: &mut NonNull<Self>, key: u8, f: F)
440 where
441 F: FnOnce(Option<Head<KEY_LEN, O, V>>) -> Option<Head<KEY_LEN, O, V>>,
442 {
443 unsafe {
444 let branch = branch_nn.as_ptr();
445 let end_depth = (*branch).end_depth as usize;
446
447 if let Some(slot) = (*branch).child_table.table_get_slot(key) {
449 let child = slot.take().unwrap();
450 let old_child_hash = child.hash();
451 let old_child_segment_count = child.count_segment(end_depth);
452 let old_child_leaf_count = child.count();
453
454 let replaced_childleaf = child.childleaf_ptr() == (*branch).childleaf;
455
456 if let Some(new_child) = f(Some(child)) {
457 (*branch).hash = ((*branch).hash ^ old_child_hash) ^ new_child.hash();
459 (*branch).segment_count = ((*branch).segment_count - old_child_segment_count)
460 + new_child.count_segment(end_depth);
461 (*branch).leaf_count =
462 ((*branch).leaf_count - old_child_leaf_count) + new_child.count();
463
464 if replaced_childleaf {
465 (*branch).childleaf = new_child.childleaf_ptr();
466 }
467
468 if slot.replace(new_child.with_key(key)).is_some() {
469 unreachable!();
470 }
471 } else {
472 (*branch).hash ^= old_child_hash;
474 (*branch).segment_count -= old_child_segment_count;
475 (*branch).leaf_count -= old_child_leaf_count;
476
477 if replaced_childleaf {
478 if let Some(other) = (*branch).child_table.iter().find_map(|s| s.as_ref()) {
479 (*branch).childleaf = other.childleaf_ptr();
480 }
481 }
482 }
483 } else {
484 if let Some(mut inserted) = f(None) {
486 (*branch).leaf_count += inserted.count();
490 (*branch).segment_count += inserted.count_segment(end_depth);
491 (*branch).hash ^= inserted.hash();
492
493 let mut branch_ptr = branch_nn.as_ptr();
495 while let Some(new_displaced) = (*branch_ptr).child_table.table_insert(inserted)
496 {
497 inserted = new_displaced;
498 Self::grow(branch_nn);
499 branch_ptr = branch_nn.as_ptr();
501 }
502 }
503 }
504 #[cfg(debug_assertions)]
506 branch_nn.as_ref().debug_check_invariants();
507 }
508 }
509
510 pub(super) fn modify_child_with_inserted_hint<F>(
517 branch_nn: &mut NonNull<Self>,
518 key: u8,
519 inserted_hash: u128,
520 f: F,
521 )
522 where
523 F: FnOnce(Option<Head<KEY_LEN, O, V>>) -> Option<Head<KEY_LEN, O, V>>,
524 {
525 unsafe {
526 let branch = branch_nn.as_ptr();
527 let end_depth = (*branch).end_depth as usize;
528
529 if let Some(slot) = (*branch).child_table.table_get_slot(key) {
530 let child = slot.take().unwrap();
531 let old_child_hash = child.hash();
532 let old_child_segment_count = child.count_segment(end_depth);
533 let old_child_leaf_count = child.count();
534
535 let replaced_childleaf = child.childleaf_ptr() == (*branch).childleaf;
536
537 if let Some(new_child) = f(Some(child)) {
538 (*branch).hash = ((*branch).hash ^ old_child_hash) ^ new_child.hash();
542 (*branch).segment_count = ((*branch).segment_count - old_child_segment_count)
543 + new_child.count_segment(end_depth);
544 (*branch).leaf_count =
545 ((*branch).leaf_count - old_child_leaf_count) + new_child.count();
546
547 if replaced_childleaf {
548 (*branch).childleaf = new_child.childleaf_ptr();
549 }
550
551 if slot.replace(new_child.with_key(key)).is_some() {
552 unreachable!();
553 }
554 } else {
555 (*branch).hash ^= old_child_hash;
556 (*branch).segment_count -= old_child_segment_count;
557 (*branch).leaf_count -= old_child_leaf_count;
558
559 if replaced_childleaf {
560 if let Some(other) = (*branch).child_table.iter().find_map(|s| s.as_ref()) {
561 (*branch).childleaf = other.childleaf_ptr();
562 }
563 }
564 }
565 } else {
566 if let Some(mut inserted) = f(None) {
567 (*branch).leaf_count += inserted.count();
570 (*branch).segment_count += inserted.count_segment(end_depth);
571 (*branch).hash ^= inserted_hash;
572
573 let mut branch_ptr = branch_nn.as_ptr();
574 while let Some(new_displaced) = (*branch_ptr).child_table.table_insert(inserted)
575 {
576 inserted = new_displaced;
577 Self::grow(branch_nn);
578 branch_ptr = branch_nn.as_ptr();
579 }
580 }
581 }
582 #[cfg(debug_assertions)]
583 branch_nn.as_ref().debug_check_invariants();
584 }
585 }
586
587 #[cfg_attr(not(feature = "parallel"), allow(dead_code))]
599 pub(crate) unsafe fn install_child_growing(
600 branch_nn: &mut NonNull<Self>,
601 head: Head<KEY_LEN, O, V>,
602 ) {
603 let mut to_insert = head;
604 let mut branch_ptr = branch_nn.as_ptr();
605 while let Some(displaced) = (*branch_ptr).child_table.table_insert(to_insert) {
606 to_insert = displaced;
607 Self::grow(branch_nn);
608 branch_ptr = branch_nn.as_ptr();
609 }
610 }
611
612 #[cfg_attr(not(feature = "parallel"), allow(dead_code))]
617 pub(crate) unsafe fn recompute_aggregates(branch_nn: &mut NonNull<Self>) {
618 let branch = branch_nn.as_ptr();
619 let end_depth = (*branch).end_depth as usize;
620 let mut agg_leaf_count: u64 = 0;
621 let mut agg_segment_count: u64 = 0;
622 let mut agg_hash: u128 = 0;
623 let mut first_childleaf: *const [u8; KEY_LEN] = std::ptr::null();
624
625 for child in (*branch).child_table.iter().flatten() {
626 agg_leaf_count += child.count();
627 agg_segment_count += child.count_segment(end_depth);
628 agg_hash ^= child.hash();
629 if first_childleaf.is_null() {
630 first_childleaf = child.childleaf_ptr();
631 }
632 }
633
634 (*branch).leaf_count = agg_leaf_count;
635 (*branch).segment_count = agg_segment_count;
636 (*branch).hash = agg_hash;
637 if !first_childleaf.is_null() {
638 (*branch).childleaf = first_childleaf;
639 }
640
641 #[cfg(debug_assertions)]
642 branch_nn.as_ref().debug_check_invariants();
643 }
644
645 pub fn count_segment(&self, at_depth: usize) -> u64 {
646 let node_end = self.end_depth as usize;
647 if !O::same_segment_tree(at_depth, node_end) {
648 1
649 } else {
650 self.segment_count
651 }
652 }
653
654 #[cfg(debug_assertions)]
659 pub fn debug_check_invariants(&self) {
660 let end_depth: usize = self.end_depth as usize;
661 let mut agg_leaf_count: u64 = 0;
662 let mut agg_segment_count: u64 = 0;
663 let mut agg_hash: u128 = 0;
664 let mut match_found = false;
665
666 for child in self.child_table.iter().flatten() {
667 agg_leaf_count = agg_leaf_count.saturating_add(child.count());
668 agg_segment_count = agg_segment_count.saturating_add(child.count_segment(end_depth));
669 agg_hash ^= child.hash();
670 if child.childleaf_ptr() == self.childleaf {
671 match_found = true;
672 }
673 }
674
675 debug_assert_eq!(
676 agg_leaf_count, self.leaf_count,
677 "branch.leaf_count mismatch"
678 );
679 debug_assert_eq!(
680 agg_segment_count, self.segment_count,
681 "branch.segment_count mismatch"
682 );
683 debug_assert_eq!(agg_hash, self.hash, "branch.hash mismatch");
684
685 if agg_leaf_count > 0 {
691 debug_assert!(match_found, "branch.childleaf pointer mismatch");
692 }
693 }
694
695 pub fn infixes<const PREFIX_LEN: usize, const INFIX_LEN: usize, F>(
698 &self,
699 prefix: &[u8; PREFIX_LEN],
700 at_depth: usize,
701 f: &mut F,
702 ) where
703 F: FnMut(&[u8; INFIX_LEN]),
704 {
705 let node_end_depth = self.end_depth as usize;
708 let limit = std::cmp::min(PREFIX_LEN, node_end_depth);
709 if !super::leaf::key_ops::has_prefix::<KEY_LEN, O>(self.childleaf_key(), at_depth, &prefix[..limit]) {
714 return;
715 }
716
717 if PREFIX_LEN + INFIX_LEN <= node_end_depth {
719 let infix: [u8; INFIX_LEN] =
720 core::array::from_fn(|i| self.childleaf_key()[O::TREE_TO_KEY[PREFIX_LEN + i]]);
721 f(&infix);
722 return;
723 }
724 if PREFIX_LEN > node_end_depth {
726 if let Some(child) = self.child_table.table_get(prefix[node_end_depth]) {
727 child.infixes(prefix, node_end_depth, f);
728 }
729 return;
730 }
731
732 for entry in self.child_table.iter().flatten() {
734 entry.infixes(prefix, node_end_depth, f);
735 }
736 }
737
738 pub fn infixes_range<const PREFIX_LEN: usize, const INFIX_LEN: usize, F>(
745 &self,
746 prefix: &[u8; PREFIX_LEN],
747 at_depth: usize,
748 min_infix: &[u8; INFIX_LEN],
749 max_infix: &[u8; INFIX_LEN],
750 f: &mut F,
751 ) where
752 F: FnMut(&[u8; INFIX_LEN]),
753 {
754 let node_end_depth = self.end_depth as usize;
755 let limit = std::cmp::min(PREFIX_LEN, node_end_depth);
756 if !super::leaf::key_ops::has_prefix::<KEY_LEN, O>(self.childleaf_key(), at_depth, &prefix[..limit]) {
757 return;
758 }
759
760 if PREFIX_LEN + INFIX_LEN <= node_end_depth {
762 let infix: [u8; INFIX_LEN] =
763 core::array::from_fn(|i| self.childleaf_key()[O::TREE_TO_KEY[PREFIX_LEN + i]]);
764 if &infix >= min_infix && &infix <= max_infix {
765 f(&infix);
766 }
767 return;
768 }
769
770 if PREFIX_LEN > node_end_depth {
772 if let Some(child) = self.child_table.table_get(prefix[node_end_depth]) {
773 child.infixes_range(prefix, node_end_depth, min_infix, max_infix, f);
774 }
775 return;
776 }
777
778 let infix_byte_idx = node_end_depth - PREFIX_LEN;
782 let mut min_tight = true; let mut max_tight = true; for i in 0..infix_byte_idx {
785 let path_byte = self.childleaf_key()[O::TREE_TO_KEY[PREFIX_LEN + i]];
786 if min_tight {
787 if path_byte < min_infix[i] {
788 return;
789 } if path_byte > min_infix[i] {
791 min_tight = false;
792 } }
794 if max_tight {
795 if path_byte > max_infix[i] {
796 return;
797 } if path_byte < max_infix[i] {
799 max_tight = false;
800 } }
802 }
803
804 for entry in self.child_table.iter().flatten() {
807 let child_byte = entry.key();
808 if min_tight && infix_byte_idx < INFIX_LEN && child_byte < min_infix[infix_byte_idx] {
809 continue;
810 }
811 if max_tight && infix_byte_idx < INFIX_LEN && child_byte > max_infix[infix_byte_idx] {
812 continue;
813 }
814 entry.infixes_range(prefix, node_end_depth, min_infix, max_infix, f);
815 }
816 }
817
818 pub fn count_range<const PREFIX_LEN: usize, const INFIX_LEN: usize>(
829 &self,
830 prefix: &[u8; PREFIX_LEN],
831 at_depth: usize,
832 min_infix: &[u8; INFIX_LEN],
833 max_infix: &[u8; INFIX_LEN],
834 ) -> u64 {
835 let node_end_depth = self.end_depth as usize;
836 let limit = std::cmp::min(PREFIX_LEN, node_end_depth);
837 if !super::leaf::key_ops::has_prefix::<KEY_LEN, O>(self.childleaf_key(), at_depth, &prefix[..limit]) {
838 return 0;
839 }
840
841 if PREFIX_LEN + INFIX_LEN <= node_end_depth {
845 let infix: [u8; INFIX_LEN] =
846 core::array::from_fn(|i| self.childleaf_key()[O::TREE_TO_KEY[PREFIX_LEN + i]]);
847 return if &infix >= min_infix && &infix <= max_infix {
848 1
849 } else {
850 0
851 };
852 }
853
854 if PREFIX_LEN > node_end_depth {
856 if let Some(child) = self.child_table.table_get(prefix[node_end_depth]) {
857 return child.count_range(prefix, node_end_depth, min_infix, max_infix);
858 }
859 return 0;
860 }
861
862 let infix_byte_idx = node_end_depth - PREFIX_LEN;
865 let mut min_tight = true;
866 let mut max_tight = true;
867 for i in 0..infix_byte_idx {
868 let path_byte = self.childleaf_key()[O::TREE_TO_KEY[PREFIX_LEN + i]];
869 if min_tight {
870 if path_byte < min_infix[i] {
871 return 0;
872 }
873 if path_byte > min_infix[i] {
874 min_tight = false;
875 }
876 }
877 if max_tight {
878 if path_byte > max_infix[i] {
879 return 0;
880 }
881 if path_byte < max_infix[i] {
882 max_tight = false;
883 }
884 }
885 }
886
887 let mut total = 0u64;
888 for entry in self.child_table.iter().flatten() {
889 let child_byte = entry.key();
890 let below_min = min_tight && child_byte < min_infix[infix_byte_idx];
891 let above_max = max_tight && child_byte > max_infix[infix_byte_idx];
892 if below_min || above_max {
893 continue;
894 }
895 let on_min = min_tight && child_byte == min_infix[infix_byte_idx];
896 let on_max = max_tight && child_byte == max_infix[infix_byte_idx];
897 if on_min || on_max {
898 total += entry.count_range(prefix, node_end_depth, min_infix, max_infix);
899 } else {
900 total += entry.count_segment(node_end_depth);
901 }
902 }
903 total
904 }
905
906 pub fn has_prefix<const PREFIX_LEN: usize>(
907 &self,
908 at_depth: usize,
909 prefix: &[u8; PREFIX_LEN],
910 ) -> bool {
911 const {
912 assert!(PREFIX_LEN <= KEY_LEN);
913 }
914 let node_end_depth = self.end_depth as usize;
915 let limit = std::cmp::min(PREFIX_LEN, node_end_depth);
916 if !super::leaf::key_ops::has_prefix::<KEY_LEN, O>(self.childleaf_key(), at_depth, &prefix[..limit]) {
917 return false;
918 }
919
920 if PREFIX_LEN <= node_end_depth {
921 return true;
922 }
923
924 if let Some(child) = self.child_table.table_get(prefix[node_end_depth]) {
925 return child.has_prefix::<PREFIX_LEN>(node_end_depth, prefix);
926 }
927
928 false
929 }
930
931 pub fn get<'a>(&'a self, at_depth: usize, key: &[u8; KEY_LEN]) -> Option<&'a V>
932 where
933 O: 'a,
934 {
935 let node_end_depth = self.end_depth as usize;
936 let limit = std::cmp::min(KEY_LEN, node_end_depth);
937 if !super::leaf::key_ops::has_prefix::<KEY_LEN, O>(self.childleaf_key(), at_depth, &key[..limit]) {
938 return None;
939 }
940 if node_end_depth >= KEY_LEN {
941 if std::mem::size_of::<V>() == 0 {
948 return Some(unsafe { std::ptr::NonNull::<V>::dangling().as_ref() });
949 }
950 let leaf_ptr = self.childleaf as *const Leaf<KEY_LEN, V>;
951 return Some(unsafe { &(*leaf_ptr).value });
952 }
953
954 if let Some(child) = self.child_table.table_get(key[node_end_depth]) {
955 return child.get(node_end_depth, key);
956 }
957 None
958 }
959
960 pub fn segmented_len<const PREFIX_LEN: usize>(
961 &self,
962 at_depth: usize,
963 prefix: &[u8; PREFIX_LEN],
964 ) -> u64 {
965 let node_end_depth = self.end_depth as usize;
966 let limit = std::cmp::min(PREFIX_LEN, node_end_depth);
967 if !super::leaf::key_ops::has_prefix::<KEY_LEN, O>(self.childleaf_key(), at_depth, &prefix[..limit]) {
968 return 0;
969 }
970 if PREFIX_LEN <= node_end_depth {
971 if !O::same_segment_tree(PREFIX_LEN, node_end_depth) {
972 return 1;
973 } else {
974 return self.segment_count;
975 }
976 }
977 if let Some(child) = self.child_table.table_get(prefix[node_end_depth]) {
978 child.segmented_len::<PREFIX_LEN>(node_end_depth, prefix)
979 } else {
980 0
981 }
982 }
983
984 }
989
990#[cfg(test)]
991mod tests {
992 use super::*;
993
994 #[test]
1003 fn option_arc_dyn_archive_owner_is_sixteen_bytes() {
1004 assert_eq!(
1005 std::mem::size_of::<Option<Arc<dyn ArchiveOwner>>>(),
1006 16,
1007 "Option<Arc<dyn ArchiveOwner>> must niche-optimize to 16 bytes"
1008 );
1009 }
1010}