pub struct NodeVersion { /* private fields */ }Expand description
A versioned lock for tree nodes.
§Layout
Bit 31: is_leaf | Bit 30: root | Bit 29: deleted | BITS 9-27: split_version
Bits 3-8: insert_version | Bit 2: splitting | Bit 1: inserting | Bit 0: locked
Implementations§
Source§impl NodeVersion
impl NodeVersion
Sourcepub fn lock_bounded(&self) -> LockGuard<'_>
pub fn lock_bounded(&self) -> LockGuard<'_>
Acquire the lock with bounded spinning before yielding.
Source§impl NodeVersion
impl NodeVersion
Sourcepub const fn from_value(value: u32) -> Self
pub const fn from_value(value: u32) -> Self
Create from raw value. Testing only.
Sourcepub fn is_deleted(&self) -> bool
pub fn is_deleted(&self) -> bool
Check if this node is logically deleted.
Sourcepub const fn is_deleted_version(version: u32) -> bool
pub const fn is_deleted_version(version: u32) -> bool
Static check on an already-loaded version value.
Sourcepub fn is_unpublished(&self) -> bool
pub fn is_unpublished(&self) -> bool
True if version counters are zero (freshly allocated, not yet linked into tree).
Sourcepub fn is_inserting(&self) -> bool
pub fn is_inserting(&self) -> bool
Check if this node is being inserted into.
Sourcepub fn is_splitting(&self) -> bool
pub fn is_splitting(&self) -> bool
Check if this node is being split.
Sourcepub const fn as_ptr(&self) -> *const Self
pub const fn as_ptr(&self) -> *const Self
Raw pointer for APIs that lock nodes via pointers (e.g., PropagationContext).
Sourcepub fn acquire_raw(&self) -> u32
pub fn acquire_raw(&self) -> u32
Load version without spinning on dirty bits.
Sourcepub const fn is_dirty_value(v: u32) -> bool
pub const fn is_dirty_value(v: u32) -> bool
Static check: does this version value have dirty bits set?
Sourcepub fn try_stable(&self) -> Option<u32>
pub fn try_stable(&self) -> Option<u32>
Non-spinning stable: returns Some(version) if clean, None if dirty.
Sourcepub fn stable_yield(&self) -> u32
pub fn stable_yield(&self) -> u32
Variant of stable() that yields instead of exponential backoff.
Sourcepub fn has_changed(&self, old: u32) -> bool
pub fn has_changed(&self, old: u32) -> bool
Check if the version has changed since old.
Returns true if any version counter bits changed (ignoring lock/inserting bits).
§C++ Divergence (INTENTIONAL)
C++ uses (x.v_ ^ v_) > lock_bit (ignores bit 0).
We use > (LOCK_BIT | INSERTING_BIT) (ignores bits 0-1).
This is safe because version COUNTERS (VINSERT/VSPLIT) are the source of truth.
INSERTING_BIT is only a progress indicator set while modifications are in-flight
(not yet visible). If writer acquires lock after stable() but before this check,
no data has been modified yet so returning false is correct. If writer has released,
the version counter increment is detected.
§Ordering
The Acquire load ensures all prior field reads are ordered before the version check on all architectures, not just x86/TSO.
Sourcepub fn has_split(&self, old: u32) -> bool
pub fn has_split(&self, old: u32) -> bool
Check if a split has occurred since old.
Includes Acquire ordering. See has_changed().
Sourcepub fn has_split_no_compiler_fence(&self, old: u32) -> bool
pub fn has_split_no_compiler_fence(&self, old: u32) -> bool
Identical to has_split(). Both now use Acquire loads.
Kept as a separate entry point for callers that document their ordering assumptions.
Sourcepub fn has_changed_or_locked(&self, old: u32) -> bool
pub fn has_changed_or_locked(&self, old: u32) -> bool
Stronger than has_changed(): also returns true if
dirty bits are set (modification in progress).
Sourcepub fn lock(&self) -> LockGuard<'_>
pub fn lock(&self) -> LockGuard<'_>
Acquire the lock with exponential backoff. Returns a guard.
Sourcepub fn try_lock_for(&self, timeout: Duration) -> Option<LockGuard<'_>>
pub fn try_lock_for(&self, timeout: Duration) -> Option<LockGuard<'_>>
Try to acquire the lock within timeout.
Sourcepub fn lock_with_yield(&self) -> LockGuard<'_>
pub fn lock_with_yield(&self) -> LockGuard<'_>
Acquire lock with yield-on-contention instead of exponential backoff.
Sourcepub fn mark_nonroot(&self)
pub fn mark_nonroot(&self)
Clear root bit. Used when layer root is demoted.
Sourcepub fn new_for_split(source: &Self) -> Self
pub fn new_for_split(source: &Self) -> Self
Create a version for a split sibling: locked + SPLITTING_BIT + same ISLEAF,
zero version counters.
Caller must ensure source is locked and unlock_for_split() is called
exactly once after the parent pointer is set.
Sourcepub fn unlock_for_split(&self)
pub fn unlock_for_split(&self)
Unlock a node created with new_for_split. Increments split version counter.
Sourcepub fn is_split_locked(&self) -> bool
pub fn is_split_locked(&self) -> bool
True if LOCK_BIT and SPLITTING_BIT are both set. For debugging.