pub struct LeafNode15<P: LeafPolicy> { /* private fields */ }Expand description
B-link leaf node with 15 slots, parameterized over LeafPolicy.
Implementations§
Source§impl<P: LeafPolicy> LeafNode15<P>
impl<P: LeafPolicy> LeafNode15<P>
Sourcepub const WIDTH: usize = WIDTH_15
pub const WIDTH: usize = WIDTH_15
Node width (number of slots). Matches TreeLeafNode::WIDTH.
Sourcepub fn new_with_root(is_root: bool) -> Self
pub fn new_with_root(is_root: bool) -> Self
Create a new leaf node (unboxed).
Sourcepub fn make_layer_root(&self)
pub fn make_layer_root(&self)
Convert this leaf into a layer root.
Sourcepub fn new_layer_root() -> Box<Self>
pub fn new_layer_root() -> Box<Self>
Create a new leaf node configured as a layer root.
Sourcepub fn new_boxed() -> Box<Self>
pub fn new_boxed() -> Box<Self>
Inherent alias for TreeLeafNode::new_boxed.
Sourcepub fn new_root_boxed() -> Box<Self>
pub fn new_root_boxed() -> Box<Self>
Inherent alias for TreeLeafNode::new_root_boxed.
Sourcepub fn new_layer_root_boxed() -> Box<Self>
pub fn new_layer_root_boxed() -> Box<Self>
Inherent alias for TreeLeafNode::new_layer_root_boxed.
Sourcepub fn load_value(&self, slot: usize) -> Option<P::Output>
pub fn load_value(&self, slot: usize) -> Option<P::Output>
Load the terminal value at a slot.
Sourcepub fn load_value_relaxed(&self, slot: usize) -> Option<P::Output>
pub fn load_value_relaxed(&self, slot: usize) -> Option<P::Output>
Load the terminal value with Relaxed ordering. For use under lock where the lock’s Acquire provides visibility.
Sourcepub fn store_value(&self, slot: usize, output: &P::Output)
pub fn store_value(&self, slot: usize, output: &P::Output)
Store a terminal value at a slot.
Sourcepub fn store_value_relaxed(&self, slot: usize, output: &P::Output)
pub fn store_value_relaxed(&self, slot: usize, output: &P::Output)
Store a terminal value with Relaxed ordering.
Sourcepub fn update_value_in_place(
&self,
slot: usize,
output: &P::Output,
) -> RetireHandle
pub fn update_value_in_place( &self, slot: usize, output: &P::Output, ) -> RetireHandle
Update an existing terminal value in place, returning a retire handle.
Sourcepub fn update_value_in_place_relaxed(
&self,
slot: usize,
output: &P::Output,
) -> RetireHandle
pub fn update_value_in_place_relaxed( &self, slot: usize, output: &P::Output, ) -> RetireHandle
Update an existing terminal value with Relaxed store ordering. For use under lock where the lock’s Release on drop provides synchronization.
Sourcepub fn take_value(&self, slot: usize) -> Option<P::Output>
pub fn take_value(&self, slot: usize) -> Option<P::Output>
Take the terminal value from a slot, leaving it empty.
Sourcepub unsafe fn write_through_update_value(
&self,
slot: usize,
new_value: &P::Value,
) -> P::Value
pub unsafe fn write_through_update_value( &self, slot: usize, new_value: &P::Value, ) -> P::Value
Write-through update: atomically read old value and write new value.
Bypasses Box allocation and EBR retirement. Only callable when
P::CAN_WRITE_THROUGH is true.
§Safety
- Caller must hold the leaf lock.
- Slot must contain a terminal value.
Sourcepub fn load_layer(&self, slot: usize) -> *mut u8
pub fn load_layer(&self, slot: usize) -> *mut u8
Load the layer pointer at a slot.
Sourcepub fn store_layer(&self, slot: usize, ptr: *mut u8)
pub fn store_layer(&self, slot: usize, ptr: *mut u8)
Store a layer pointer at a slot.
Sourcepub fn take_value_for_layer(&self, slot: usize) -> RetireHandle
pub fn take_value_for_layer(&self, slot: usize) -> RetireHandle
Take the value at a slot when converting it to a layer pointer.
Sourcepub fn prefetch_value(&self, slot: usize)
pub fn prefetch_value(&self, slot: usize)
Prefetch the value at a slot to hide memory latency.
Sourcepub fn prefetch_suffix(&self)
pub fn prefetch_suffix(&self)
Prefetch suffix storage into cache for upcoming access.
Sourcepub unsafe fn load_value_ptr(&self, slot: usize) -> *const P::Value
pub unsafe fn load_value_ptr(&self, slot: usize) -> *const P::Value
Load the typed value pointer at a slot.
§Safety
Caller must ensure the slot contains a terminal value, not a layer.
Sourcepub fn is_slot_empty(&self, slot: usize) -> bool
pub fn is_slot_empty(&self, slot: usize) -> bool
Check if a slot is empty (no value, no layer).
Sourcepub fn is_value_empty(&self, slot: usize) -> bool
pub fn is_value_empty(&self, slot: usize) -> bool
Check if a slot has no value stored.
Sourcepub fn is_value_empty_relaxed(&self, slot: usize) -> bool
pub fn is_value_empty_relaxed(&self, slot: usize) -> bool
Relaxed empty check for OCC search loops.
The permutation Acquire load provides synchronization with writers.
The OCC has_changed() check validates after all reads.
Sourcepub fn load_layer_raw(&self, slot: usize) -> *mut u8
pub fn load_layer_raw(&self, slot: usize) -> *mut u8
Load the raw layer pointer at a slot.
Sourcepub fn load_value_raw(&self, slot: usize) -> *mut u8
pub fn load_value_raw(&self, slot: usize) -> *mut u8
Load the raw value pointer at a slot without interpretation.
Sourcepub fn load_value_raw_relaxed(&self, slot: usize) -> *mut u8
pub fn load_value_raw_relaxed(&self, slot: usize) -> *mut u8
Load the raw value pointer with Relaxed ordering.
Use when Acquire on the pointer is redundant (e.g., write-through paths where a subsequent atomic value read provides synchronization).
Sourcepub fn clear_slot(&self, slot: usize)
pub fn clear_slot(&self, slot: usize)
Clear a slot’s value and keylenx (Relaxed ordering, for use under lock).
Sourcepub fn clear_slot_and_permutation(&self, slot: usize)
pub fn clear_slot_and_permutation(&self, slot: usize)
Clear a slot’s value, keylenx, and permutation entry.
Sourcepub fn classify_slot(&self, slot: usize) -> SlotKind<P::Output>
pub fn classify_slot(&self, slot: usize) -> SlotKind<P::Output>
Classify a slot’s contents, extracting the value if present.
Sourcepub fn classify_slot_light(&self, slot: usize) -> SlotState
pub fn classify_slot_light(&self, slot: usize) -> SlotState
Lightweight slot classification without value extration.
Sourcepub fn move_value_to(&self, dst: &Self, src_slot: usize, dst_slot: usize)
pub fn move_value_to(&self, dst: &Self, src_slot: usize, dst_slot: usize)
Move a slot’s value from this leaf to another leaf.
Sourcepub fn move_value_to_relaxed(
&self,
dst: &Self,
src_slot: usize,
dst_slot: usize,
)
pub fn move_value_to_relaxed( &self, dst: &Self, src_slot: usize, dst_slot: usize, )
Move a slot’s value with Relaxed store ordering on the destination. For use under lock where the lock’s Release on drop provides synchronization.
Sourcepub fn clear_value(&self, slot: usize)
pub fn clear_value(&self, slot: usize)
Clear a slot’s value storage (without touching keylenx).
Sourcepub fn clear_value_relaxed(&self, slot: usize)
pub fn clear_value_relaxed(&self, slot: usize)
Clear a slot’s value with Relaxed ordering. For use under lock where the lock’s Release on drop provides synchronization.
Sourcepub fn ksuf_or_empty(&self, slot: usize) -> &[u8] ⓘ
pub fn ksuf_or_empty(&self, slot: usize) -> &[u8] ⓘ
Get the suffix bytes for a slot, or an empty slice if none.
Sourcepub fn ksuf_equals(&self, slot: usize, suffix: &[u8]) -> bool
pub fn ksuf_equals(&self, slot: usize, suffix: &[u8]) -> bool
Check if a slot’s suffix equals the given bytes.
Sourcepub fn ksuf_compare(&self, slot: usize, suffix: &[u8]) -> Option<Ordering>
pub fn ksuf_compare(&self, slot: usize, suffix: &[u8]) -> Option<Ordering>
Compare a slot’s suffix with the given bytes.
Sourcepub fn ksuf_matches(&self, slot: usize, ikey: u64, suffix: &[u8]) -> bool
pub fn ksuf_matches(&self, slot: usize, ikey: u64, suffix: &[u8]) -> bool
Check if a slot’s full key matches the given ikey + suffix.
Sourcepub fn ksuf_match_result(&self, slot: usize, keylenx: u8, suffix: &[u8]) -> i32
pub fn ksuf_match_result(&self, slot: usize, keylenx: u8, suffix: &[u8]) -> i32
Match a slot against a key suffix, returning a result code.
Sourcepub unsafe fn assign_ksuf(
&self,
slot: usize,
suffix: &[u8],
guard: &LocalGuard<'_>,
) -> *mut u8
pub unsafe fn assign_ksuf( &self, slot: usize, suffix: &[u8], guard: &LocalGuard<'_>, ) -> *mut u8
Sourcepub unsafe fn assign_ksuf_init(
&self,
slot: usize,
suffix: &[u8],
guard: &LocalGuard<'_>,
)
pub unsafe fn assign_ksuf_init( &self, slot: usize, suffix: &[u8], guard: &LocalGuard<'_>, )
Sourcepub unsafe fn assign_ksuf_prealloc(
&self,
slot: usize,
suffix: &[u8],
guard: &LocalGuard<'_>,
prealloc: Vec<u8>,
) -> *mut u8
pub unsafe fn assign_ksuf_prealloc( &self, slot: usize, suffix: &[u8], guard: &LocalGuard<'_>, prealloc: Vec<u8>, ) -> *mut u8
Sourcepub unsafe fn retire_suffix_bag_ptr(ptr: *mut u8, guard: &LocalGuard<'_>)
pub unsafe fn retire_suffix_bag_ptr(ptr: *mut u8, guard: &LocalGuard<'_>)
Retire a suffix bag pointer returned by assign_ksuf.
§Safety
ptr must have come from assign_ksuf and must not be null.
Sourcepub unsafe fn clear_ksuf(&self, slot: usize, guard: &LocalGuard<'_>)
pub unsafe fn clear_ksuf(&self, slot: usize, guard: &LocalGuard<'_>)
Sourcepub fn has_external_ksuf(&self) -> bool
pub fn has_external_ksuf(&self) -> bool
Check if external (overflow) suffix storage has been allocated.
Sourcepub const fn version(&self) -> &NodeVersion
pub const fn version(&self) -> &NodeVersion
Get a reference to the node’s version.
Sourcepub const fn version_mut(&mut self) -> &mut NodeVersion
pub const fn version_mut(&mut self) -> &mut NodeVersion
Get a mutable reference to the node’s version.
Sourcepub fn ikey(&self, slot: usize) -> u64
pub fn ikey(&self, slot: usize) -> u64
Get the ikey at the given physical slot.
Uses Acquire ordering to synchronize with writer’s Release stores.
§Panics
Panics in debug mode if slot >= WIDTH_15.
Sourcepub fn ikey_relaxed(&self, slot: usize) -> u64
pub fn ikey_relaxed(&self, slot: usize) -> u64
Get the ikey at the given physical slot using Relaxed ordering.
§Panics
Panics in debug mode if slot >= WIDTH_15.
Sourcepub fn prefetch_ikey(&self, slot: usize)
pub fn prefetch_ikey(&self, slot: usize)
Prefetch the ikey at the given slot into CPU cache.
§Safety
The slot must be in range [0, WIDTH_15). No bounds check in release mode.
Sourcepub fn prefetch_for_search(&self)
pub fn prefetch_for_search(&self)
Prefetch for point lookup (permutation + keys + values).
Sourcepub fn prefetch_for_search_adaptive(&self, size: usize)
pub fn prefetch_for_search_adaptive(&self, size: usize)
Size-aware prefetch: only fetch cache lines that will be accessed.
Sourcepub fn keylenx_relaxed(&self, slot: usize) -> u8
pub fn keylenx_relaxed(&self, slot: usize) -> u8
Get the keylenx with Relaxed ordering. For OCC search loops where the permutation Acquire provides synchronization.
Sourcepub fn set_keylenx(&self, slot: usize, keylenx: u8)
pub fn set_keylenx(&self, slot: usize, keylenx: u8)
Set the keylenx at the given physical slot.
Sourcepub fn ikey_bound(&self) -> u64
pub fn ikey_bound(&self) -> u64
Get the ikey bound (ikey at slot 0, used for B-link tree routing).
Sourcepub fn keylenx_bound(&self) -> u8
pub fn keylenx_bound(&self) -> u8
Get the keylenx bound for this leaf.
Sourcepub const fn keylenx_is_layer(keylenx: u8) -> bool
pub const fn keylenx_is_layer(keylenx: u8) -> bool
Check if keylenx indicates a layer pointer (static helper).
Sourcepub const fn keylenx_has_ksuf(keylenx: u8) -> bool
pub const fn keylenx_has_ksuf(keylenx: u8) -> bool
Check if keylenx indicates suffix storage (static helper).
Sourcepub fn find_ikey_matches(&self, target_ikey: u64) -> u32
pub fn find_ikey_matches(&self, target_ikey: u64) -> u32
Search all 15 ikeys for matches with target, returning a bitmask.
Sourcepub fn permutation(&self) -> Permuter15
pub fn permutation(&self) -> Permuter15
Load permutation with Acquire ordering.
Sourcepub fn set_permutation(&self, perm: Permuter15)
pub fn set_permutation(&self, perm: Permuter15)
Store permutation with Release ordering.
Sourcepub fn set_permutation_relaxed(&self, perm: Permuter15)
pub fn set_permutation_relaxed(&self, perm: Permuter15)
Store permutation with Relaxed ordering.
Sourcepub fn permutation_raw(&self) -> u64
pub fn permutation_raw(&self) -> u64
Get raw permutation value (for debugging).
Sourcepub unsafe fn store_key_data_for_cas(&self, slot: usize, ikey: u64, keylenx: u8)
pub unsafe fn store_key_data_for_cas(&self, slot: usize, ikey: u64, keylenx: u8)
Store key metadata (ikey, keylenx) for a CAS insert attempt.
§Safety
- The caller must have successfully claimed the slot via
cas_slot_valueand ensured the slot still belongs to the CAS attempt (i.e.leaf_values[slot]still equals the claimed pointer).
Sourcepub fn safe_next(&self, guard: &impl Guard) -> *mut Self
pub fn safe_next(&self, guard: &impl Guard) -> *mut Self
Get the next leaf pointer, masking the mark bit.
Sourcepub unsafe fn safe_next_unguarded(&self) -> *mut Self
pub unsafe fn safe_next_unguarded(&self) -> *mut Self
Get the next leaf pointer without guard protection.
§Safety
Caller must ensure the next pointer’s target won’t be retired during use.
Sourcepub fn next_raw(&self, guard: &impl Guard) -> *mut Self
pub fn next_raw(&self, guard: &impl Guard) -> *mut Self
Get the raw next pointer (including mark bit).
Sourcepub unsafe fn next_raw_unguarded(&self) -> *mut Self
pub unsafe fn next_raw_unguarded(&self) -> *mut Self
Get the raw next pointer without guard protection.
§Safety
Caller must ensure the next pointer’s target won’t be retired during use.
Sourcepub fn next_is_marked(&self) -> bool
pub fn next_is_marked(&self) -> bool
Check if the next pointer is marked (split in progress).
Sourcepub fn unmark_next(&self)
pub fn unmark_next(&self)
Unmark the next pointer.
Sourcepub fn wait_for_split(&self)
pub fn wait_for_split(&self)
Wait for an in-progress split to complete.
Sourcepub unsafe fn unlink_from_chain(&self)
pub unsafe fn unlink_from_chain(&self)
Unlink this leaf from the B-link doubly-linked chain.
§Safety
- Caller must hold the version lock on this leaf
self.prev()must be non-null (not the leftmost leaf)- The prev and next pointers must be valid leaves
Sourcepub unsafe fn prev_unguarded(&self) -> *mut Self
pub unsafe fn prev_unguarded(&self) -> *mut Self
Get the previous leaf pointer without guard protection.
§Safety
Caller must ensure the prev pointer’s target won’t be retired during use.
Sourcepub fn parent(&self, guard: &impl Guard) -> *mut u8
pub fn parent(&self, guard: &impl Guard) -> *mut u8
Get the parent pointer.
Uses guard protection to ensure the load participates in seize’s total order, making it safe on all architectures.
Sourcepub unsafe fn parent_unguarded(&self) -> *mut u8
pub unsafe fn parent_unguarded(&self) -> *mut u8
Get the parent pointer without guard protection.
§Safety
Caller must ensure the parent pointer’s target won’t be retired during use.
Sourcepub fn set_parent(&self, parent: *mut u8)
pub fn set_parent(&self, parent: *mut u8)
Set the parent pointer.
Sourcepub fn set_modstate(&self, state: u8)
pub fn set_modstate(&self, state: u8)
Set the modification state (overwrites all bits including queued).
Sourcepub fn modstate_relaxed(&self) -> u8
pub fn modstate_relaxed(&self) -> u8
Get the raw modification state (relaxed, for use under lock).
Sourcepub fn set_modstate_relaxed(&self, state: u8)
pub fn set_modstate_relaxed(&self, state: u8)
Set the modification state (relaxed, for use under lock).
Sourcepub fn deleted_layer(&self) -> bool
pub fn deleted_layer(&self) -> bool
Check if this layer has been deleted (garbage collected).
Sourcepub fn mark_deleted_layer(&self)
pub fn mark_deleted_layer(&self)
Mark this layer as deleted (for gc_layer). Preserves queued bit.
Sourcepub fn mark_remove(&self)
pub fn mark_remove(&self)
Mark this node as being in remove mode. Preserves queued bit.
Sourcepub fn is_removing(&self) -> bool
pub fn is_removing(&self) -> bool
Check if this node is in remove mode.
Sourcepub fn is_empty_state(&self) -> bool
pub fn is_empty_state(&self) -> bool
Check if this leaf is in empty state.
Sourcepub fn mark_empty(&self)
pub fn mark_empty(&self)
Mark this leaf as empty (all keys removed). Preserves queued bit.
Sourcepub fn clear_empty_state(&self)
pub fn clear_empty_state(&self)
Clear empty state, returning to normal insert mode. Stores 0, clearing the queued bit. Correct for insert reuse: invalidates any pending coalesce entry for this leaf.
Sourcepub fn try_mark_queued(&self) -> bool
pub fn try_mark_queued(&self) -> bool
Atomically set the queued bit. Returns true if the bit was not already set (this call won the race). This is the sole enqueue gate.
Sourcepub fn clear_queued(&self)
pub fn clear_queued(&self)
Clear the queued bit atomically. Called after gc retires or skips.
Sourcepub fn can_reuse_slot0(&self, new_ikey: u64) -> bool
pub fn can_reuse_slot0(&self, new_ikey: u64) -> bool
Check if slot 0 can be reused for a new key.
Sourcepub fn calculate_split_point(
&self,
insert_pos: usize,
insert_ikey: u64,
) -> Option<SplitPoint>
pub fn calculate_split_point( &self, insert_pos: usize, insert_ikey: u64, ) -> Option<SplitPoint>
Calculate the optimal split point for this leaf.
Sourcepub unsafe fn split_into_preallocated(
&self,
split_pos: usize,
new_leaf_ptr: *mut Self,
guard: &LocalGuard<'_>,
) -> (u64, InsertTarget)
pub unsafe fn split_into_preallocated( &self, split_pos: usize, new_leaf_ptr: *mut Self, guard: &LocalGuard<'_>, ) -> (u64, InsertTarget)
Split entries from position split_pos..size into a new leaf.
§Safety
- Caller holds the lock on
self. new_leaf_ptris valid, properly aligned, and points to an initialized (vianew_with_root(false)orinit_at) but empty leaf.new_leaf_ptris not yet visible to other threads.
Sourcepub unsafe fn split_all_to_right_preallocated(
&self,
new_leaf_ptr: *mut Self,
guard: &LocalGuard<'_>,
) -> (u64, InsertTarget)
pub unsafe fn split_all_to_right_preallocated( &self, new_leaf_ptr: *mut Self, guard: &LocalGuard<'_>, ) -> (u64, InsertTarget)
Split ALL entries to the right leaf (used for reverse-sequential pattern).
§Safety
Same as split_into_preallocated.
Sourcepub unsafe fn split_and_insert(
&self,
split_pos: usize,
new_leaf_ptr: *mut Self,
insert_pos: usize,
insert_data: &SplitInsertData<'_, P>,
guard: &LocalGuard<'_>,
) -> SplitInsertResult
pub unsafe fn split_and_insert( &self, split_pos: usize, new_leaf_ptr: *mut Self, insert_pos: usize, insert_data: &SplitInsertData<'_, P>, guard: &LocalGuard<'_>, ) -> SplitInsertResult
Atomic split + insert: split entries and insert a new key in one operation.
§Safety
Same as split_into_preallocated.
Sourcepub unsafe fn link_sibling(&self, new_sibling: *mut Self)
pub unsafe fn link_sibling(&self, new_sibling: *mut Self)
Link a new sibling after this leaf during a split.
§Safety
- Caller must hold the lock on
self. new_siblingmust be valid and not yet in the chain.
Trait Implementations§
Source§impl<P: LeafPolicy> Debug for LeafNode15<P>
impl<P: LeafPolicy> Debug for LeafNode15<P>
Source§impl<P: LeafPolicy> Drop for LeafNode15<P>
impl<P: LeafPolicy> Drop for LeafNode15<P>
Source§impl<P: LeafPolicy> TreeLeafNode<P> for LeafNode15<P>
impl<P: LeafPolicy> TreeLeafNode<P> for LeafNode15<P>
Source§const SPLIT_THRESHOLD: usize = WIDTH_15
const SPLIT_THRESHOLD: usize = WIDTH_15
Source§const INLINE_KSUF_CAPACITY: usize = 512
const INLINE_KSUF_CAPACITY: usize = 512
Source§type Internode = InternodeNode
type Internode = InternodeNode
Source§fn new_root_boxed() -> Box<Self>
fn new_root_boxed() -> Box<Self>
Source§fn new_layer_root_boxed() -> Box<Self>
fn new_layer_root_boxed() -> Box<Self>
Source§fn version(&self) -> &NodeVersion
fn version(&self) -> &NodeVersion
Source§fn permutation(&self) -> Permuter15
fn permutation(&self) -> Permuter15
Source§fn set_permutation(&self, perm: Permuter15)
fn set_permutation(&self, perm: Permuter15)
Source§fn set_permutation_relaxed(&self, perm: Permuter15)
fn set_permutation_relaxed(&self, perm: Permuter15)
Source§fn permutation_raw(&self) -> u64
fn permutation_raw(&self) -> u64
Source§fn ikey_relaxed(&self, slot: usize) -> u64
fn ikey_relaxed(&self, slot: usize) -> u64
Source§fn set_ikey_relaxed(&self, slot: usize, ikey: u64)
fn set_ikey_relaxed(&self, slot: usize, ikey: u64)
Source§fn ikey_bound(&self) -> u64
fn ikey_bound(&self) -> u64
Source§fn find_ikey_matches(&self, target_ikey: u64) -> u32
fn find_ikey_matches(&self, target_ikey: u64) -> u32
Source§fn keylenx_relaxed(&self, slot: usize) -> u8
fn keylenx_relaxed(&self, slot: usize) -> u8
Source§fn set_keylenx(&self, slot: usize, keylenx: u8)
fn set_keylenx(&self, slot: usize, keylenx: u8)
Source§fn set_keylenx_relaxed(&self, slot: usize, keylenx: u8)
fn set_keylenx_relaxed(&self, slot: usize, keylenx: u8)
Source§fn load_value(&self, slot: usize) -> Option<P::Output>
fn load_value(&self, slot: usize) -> Option<P::Output>
None if empty.