Skip to main content

kvbm_logical/blocks/
mod.rs

1// SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2// SPDX-License-Identifier: Apache-2.0
3
4//! RAII guard types that enforce the block lifecycle state machine.
5//!
6//! Every logical block in KVBM progresses through a fixed sequence of
7//! states. The guard types in this module make those transitions explicit
8//! at the type level: each transition consumes one guard and produces the
9//! next. Dropping a guard at any point automatically returns the
10//! underlying slot to the appropriate pool, so blocks are never leaked.
11//!
12//! # State machine
13//!
14//! ```text
15//!                  stage / complete          register_block
16//!   Reset ──────────────────────► Staged ─────────────────► Registered
17//!     ▲                              │                          │
18//!     │          reset               │                          │
19//!     ├──────────────────────────────┘                          │
20//!     │                          drop (reset + return)          │
21//!     └─────────────────────────────────────────────────────────┘
22//! ```
23//!
24//! # Public guard types
25//!
26//! - [`MutableBlock`] — `Reset` state.
27//! - [`CompleteBlock`] — `Staged` state.
28//! - [`ImmutableBlock`] — `Registered` state (cheap-to-clone strong handle).
29//! - [`WeakBlock`] — non-owning reference to a registered block.
30//!
31//! Slot bookkeeping lives in [`BlockStore<T>`](crate::pools::BlockStore);
32//! `Primary` vs `Duplicate` is captured by an internal flag on
33//! [`ImmutableBlockInner`] and the corresponding slot state.
34
35mod complete;
36mod immutable;
37mod mutable;
38mod pin;
39
40pub use complete::CompleteBlock;
41pub use immutable::{ImmutableBlock, WeakBlock};
42pub use mutable::MutableBlock;
43pub use pin::{LifecyclePin, LifecyclePinRef};
44
45pub(crate) use immutable::ImmutableBlockInner;
46
47pub use crate::registry::BlockRegistrationHandle;
48pub use crate::registry::BlockRegistry;
49
50pub use crate::{BlockId, SequenceHash};
51
52/// Marker trait for types that can serve as block-level metadata.
53///
54/// A blanket implementation covers every type that is `Clone + Send + Sync
55/// + 'static`, so callers rarely need to think about this trait directly.
56pub trait BlockMetadata: Clone + Send + Sync + 'static {}
57impl<T: Clone + Send + Sync + 'static> BlockMetadata for T {}
58
59/// Error returned by block state transitions.
60///
61/// Every variant carries the originating block back to the caller so that
62/// the block is never silently leaked on failure. The caller can inspect
63/// the error, recover the block from the variant, and retry or drop it as
64/// needed.
65#[derive(Debug, thiserror::Error)]
66pub enum BlockError<B> {
67    /// The number of tokens in the provided data did not match the block's
68    /// fixed size. The block is returned in the `block` field.
69    #[error("Block size mismatch: expected {expected} tokens, got {actual}")]
70    BlockSizeMismatch {
71        expected: usize,
72        actual: usize,
73        block: B,
74    },
75}
76
77/// Controls whether the [`BlockRegistry`] accepts multiple physical blocks
78/// that share the same [`SequenceHash`].
79///
80/// The policy is set once when a [`BlockManager`](crate::manager::BlockManager)
81/// is built and applies to every subsequent registration.
82#[derive(Debug, Clone, Copy, PartialEq, Eq)]
83pub enum BlockDuplicationPolicy {
84    /// Multiple physical blocks may hold the same data for a single
85    /// logical block / sequence hash.
86    Allow,
87    /// Only one physical block is retained per sequence hash. Attempting
88    /// to register a duplicate returns the existing primary block instead.
89    Reject,
90}