Skip to main content

velesdb_core/
lock_rank.rs

1//! Compiled lock-rank invariant for the global lock-acquisition order.
2//!
3//! Lock ordering was historically documented as convention in
4//! [`docs/CONCURRENCY_MODEL.md`]. This module promotes that convention to a
5//! typed [`LockRank`] newtype so the global acquisition order is expressed in
6//! code, with a debug-only [`assert_lock_order`] check that compiles to
7//! nothing in release builds (zero release overhead).
8//!
9//! Locks MUST be acquired in strictly ascending rank. Core ranks occupy the
10//! low ordinals (`gpu < vectors < columnar < layers < neighbors`); the
11//! inclusive range `[40, 59]` is reserved for premium-owned lock classes so
12//! premium can order its locks relative to core without collision.
13
14#[cfg(test)]
15#[path = "lock_rank_tests.rs"]
16mod lock_rank_tests;
17
18/// Ordinal encoding the global lock-acquisition order.
19///
20/// Locks MUST be acquired in strictly ascending rank; the debug-only
21/// [`assert_lock_order`] enforces this in debug builds. The type is a thin
22/// newtype over `u8` and derives a total ordering.
23#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
24pub struct LockRank(u8);
25
26impl LockRank {
27    /// GPU vector snapshot lock — lowest core rank.
28    pub const GPU_VECTORS_SNAPSHOT: LockRank = LockRank(5);
29    /// Dense-vector storage lock.
30    pub const VECTORS: LockRank = LockRank(10);
31    /// Columnar (`ColumnStore`) lock.
32    pub const COLUMNAR: LockRank = LockRank(15);
33    /// HNSW layer-structure lock.
34    pub const LAYERS: LockRank = LockRank(20);
35    /// HNSW neighbor-list lock — highest core rank.
36    pub const NEIGHBORS: LockRank = LockRank(30);
37
38    /// Inclusive lower bound of the reserved premium rank range.
39    ///
40    /// Core never assigns ranks at or above this value; premium declares
41    /// cluster-state / tenant-store / server-level ranks within `[40, 59]`
42    /// without colliding with core.
43    pub const PREMIUM_MIN: u8 = 40;
44    /// Inclusive upper bound of the reserved premium rank range.
45    pub const PREMIUM_MAX: u8 = 59;
46
47    /// Returns the underlying ordinal value.
48    #[must_use]
49    pub const fn ordinal(self) -> u8 {
50        self.0
51    }
52
53    /// Constructs a premium-owned rank, clamped to the reserved range.
54    ///
55    /// Returns `None` if `value` is outside the inclusive range
56    /// `[PREMIUM_MIN, PREMIUM_MAX]` (i.e. `[40, 59]`).
57    #[must_use]
58    pub const fn premium(value: u8) -> Option<LockRank> {
59        if value >= Self::PREMIUM_MIN && value <= Self::PREMIUM_MAX {
60            Some(LockRank(value))
61        } else {
62            None
63        }
64    }
65}
66
67/// Debug-only acquisition-order assertion.
68///
69/// Asserts that `about_to_acquire` has a strictly greater rank than
70/// `previously_held`. Compiles to nothing in release builds, so it carries
71/// zero release overhead.
72///
73/// # Panics
74/// In debug builds, panics if `about_to_acquire <= previously_held`, signaling
75/// a lock-order violation.
76#[inline]
77pub fn assert_lock_order(previously_held: LockRank, about_to_acquire: LockRank) {
78    debug_assert!(
79        about_to_acquire > previously_held,
80        "lock-order violation: acquiring rank {} while holding rank {}",
81        about_to_acquire.ordinal(),
82        previously_held.ordinal()
83    );
84}