kvbm_logical/blocks/complete.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 for a block in the **Staged** state.
5//!
6//! A [`CompleteBlock`] represents a block that has been assigned a
7//! [`SequenceHash`](super::SequenceHash) but has not yet been registered in
8//! the [`BlockRegistry`](crate::registry::BlockRegistry). It is produced by
9//! [`MutableBlock::stage`](super::MutableBlock::stage) or
10//! [`MutableBlock::complete`](super::MutableBlock::complete) and can be
11//! either registered via
12//! [`BlockManager::register_block`](crate::manager::BlockManager::register_block)
13//! or rolled back to a [`MutableBlock`](super::MutableBlock) with
14//! [`reset`](CompleteBlock::reset).
15
16use super::{
17 Block, BlockId, BlockMetadata, MutableBlock, ResetReturnFn, SequenceHash, state::Staged,
18};
19
20/// RAII guard for a block in the **Staged** state.
21///
22/// Wraps an internal `Block<T, Staged>` -- a block that carries a
23/// [`SequenceHash`](super::SequenceHash) and is ready for registration.
24///
25/// # Obtaining a `CompleteBlock`
26///
27/// - [`MutableBlock::stage`](super::MutableBlock::stage) -- from a
28/// pre-computed [`SequenceHash`](super::SequenceHash).
29/// - [`MutableBlock::complete`](super::MutableBlock::complete) -- by
30/// extracting the hash from a [`TokenBlock`](dynamo_tokens::TokenBlock).
31///
32/// # State transitions
33///
34/// - Pass to [`BlockManager::register_block`](crate::manager::BlockManager::register_block)
35/// to move the block into the **Registered** state and receive an
36/// [`ImmutableBlock`](super::ImmutableBlock).
37/// - Call [`reset`](Self::reset) to undo the staging and get a
38/// [`MutableBlock`](super::MutableBlock) back (metrics are `None` on this
39/// path).
40///
41/// # Drop behaviour
42///
43/// If the `CompleteBlock` is dropped without being consumed, the underlying
44/// block is reset to the **Reset** state and returned to the reset pool.
45pub struct CompleteBlock<T: BlockMetadata> {
46 pub(crate) block: Option<Block<T, Staged>>,
47 pub(crate) return_fn: ResetReturnFn<T>,
48}
49
50impl<T: BlockMetadata> CompleteBlock<T> {
51 /// Create a new CompleteBlock
52 pub(crate) fn new(block: Block<T, Staged>, return_fn: ResetReturnFn<T>) -> Self {
53 Self {
54 block: Some(block),
55 return_fn,
56 }
57 }
58
59 /// Returns the [`BlockId`] assigned to this block.
60 pub fn block_id(&self) -> BlockId {
61 self.block.as_ref().unwrap().block_id()
62 }
63
64 /// Returns the [`SequenceHash`](super::SequenceHash) that was assigned
65 /// during staging.
66 pub fn sequence_hash(&self) -> SequenceHash {
67 self.block.as_ref().unwrap().sequence_hash()
68 }
69
70 /// Undoes the staging transition, returning a [`MutableBlock`] in the
71 /// **Reset** state.
72 ///
73 /// The returned `MutableBlock` does **not** carry metrics (they are set
74 /// to `None`) because this is an undo/rollback path rather than a fresh
75 /// allocation.
76 pub fn reset(mut self) -> MutableBlock<T> {
77 let block = self.block.take().unwrap().reset();
78
79 MutableBlock::new(block, self.return_fn.clone(), None)
80 }
81}
82
83impl<T: BlockMetadata> Drop for CompleteBlock<T> {
84 #[inline]
85 fn drop(&mut self) {
86 if let Some(block) = self.block.take() {
87 (self.return_fn)(block.reset());
88 }
89 }
90}