Skip to main content

NodeVersion

Struct NodeVersion 

Source
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

Source

pub fn lock_bounded(&self) -> LockGuard<'_>

Acquire the lock with bounded spinning before yielding.

Source§

impl NodeVersion

Source

pub const fn new(is_leaf: bool) -> Self

Create a new node version.

Source

pub const fn from_value(value: u32) -> Self

Create from raw value. Testing only.

Source

pub fn is_leaf(&self) -> bool

Check if this is a leaf node.

Source

pub fn is_root(&self) -> bool

Check if this is a root node.

Source

pub fn is_deleted(&self) -> bool

Check if this node is logically deleted.

Source

pub const fn is_deleted_version(version: u32) -> bool

Static check on an already-loaded version value.

Source

pub fn is_locked(&self) -> bool

Check if this node is locked.

Source

pub fn is_unpublished(&self) -> bool

True if version counters are zero (freshly allocated, not yet linked into tree).

Source

pub fn is_inserting(&self) -> bool

Check if this node is being inserted into.

Source

pub fn is_splitting(&self) -> bool

Check if this node is being split.

Source

pub fn is_dirty(&self) -> bool

Check if any dirty bit set (inserting or splitting).

Source

pub fn value(&self) -> u32

Get the raw version value.

Source

pub const fn as_ptr(&self) -> *const Self

Raw pointer for APIs that lock nodes via pointers (e.g., PropagationContext).

Source

pub fn stable(&self) -> u32

Get a stable version for optimistic reading.

Source

pub fn acquire_raw(&self) -> u32

Load version without spinning on dirty bits.

Source

pub const fn is_dirty_value(v: u32) -> bool

Static check: does this version value have dirty bits set?

Source

pub fn try_stable(&self) -> Option<u32>

Non-spinning stable: returns Some(version) if clean, None if dirty.

Source

pub fn stable_yield(&self) -> u32

Variant of stable() that yields instead of exponential backoff.

Source

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.

Source

pub fn has_split(&self, old: u32) -> bool

Check if a split has occurred since old.

Includes Acquire ordering. See has_changed().

Source

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.

Source

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).

Source

pub fn lock(&self) -> LockGuard<'_>

Acquire the lock with exponential backoff. Returns a guard.

Source

pub fn try_lock(&self) -> Option<LockGuard<'_>>

Try to acquire the lock without blocking.

Source

pub fn try_lock_for(&self, timeout: Duration) -> Option<LockGuard<'_>>

Try to acquire the lock within timeout.

Source

pub fn lock_with_yield(&self) -> LockGuard<'_>

Acquire lock with yield-on-contention instead of exponential backoff.

Source

pub fn mark_root(&self)

Mark as root. Does not require lock.

Source

pub fn mark_nonroot(&self)

Clear root bit. Used when layer root is demoted.

Source

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.

Source

pub fn unlock_for_split(&self)

Unlock a node created with new_for_split. Increments split version counter.

Source

pub fn is_split_locked(&self) -> bool

True if LOCK_BIT and SPLITTING_BIT are both set. For debugging.

Trait Implementations§

Source§

impl Clone for NodeVersion

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for NodeVersion

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for NodeVersion

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.