Skip to main content

nodedb_physical/
surrogate.rs

1// SPDX-License-Identifier: Apache-2.0
2
3//! Surrogate-allocation contract used by the shared SqlPlan → PhysicalPlan
4//! converter. Origin's WAL-durable, Raft-replicated allocator implements this
5//! trait; Lite supplies its own local-monotonic implementation.
6//!
7//! Synchronous-only: the converter runs on the Control Plane in `Send + Sync`
8//! code paths. Origin's async surrogate-fetch work stays internal to its impl
9//! and is hidden behind this sync facade.
10
11use nodedb_types::Surrogate;
12
13/// Errors a [`SurrogateAssigner`] may return.
14///
15/// The error surface is deliberately narrow — the converter does not need to
16/// distinguish more cases. Origin's rich allocator errors collapse to one of
17/// these at the trait boundary; the original error is preserved in
18/// [`SurrogateAssignError::Backend`]'s message.
19#[derive(Debug, thiserror::Error)]
20pub enum SurrogateAssignError {
21    #[error("surrogate registry lock poisoned")]
22    LockPoisoned,
23    #[error("surrogate backend: {0}")]
24    Backend(String),
25}
26
27/// Allocate stable, cross-engine surrogates for `(collection, pk_bytes)`.
28///
29/// Implementations must be:
30/// - **idempotent**: repeated calls for the same `(collection, pk_bytes)`
31///   return the same `Surrogate`;
32/// - **monotonic**: every allocated value is greater than every previously
33///   allocated value within the same allocator;
34/// - **`Send + Sync`**: the converter holds a reference across `await`
35///   points on the Control Plane.
36pub trait SurrogateAssigner: Send + Sync {
37    /// Highest surrogate ever issued by this assigner. `0` on a fresh
38    /// allocator. Used by CLONE DATABASE to capture an AS-OF cutoff.
39    fn current_hwm(&self) -> u32;
40
41    /// Resolve `(collection, pk_bytes)` to a stable surrogate. Allocate
42    /// on the first call; return the persisted value on every subsequent
43    /// call (UPSERT preserves the surrogate).
44    fn assign(&self, collection: &str, pk_bytes: &[u8]) -> Result<Surrogate, SurrogateAssignError>;
45}