Skip to main content

bb_runtime/contracts/
index.rs

1//! `bb::Index` — Contract trait for vector indexes.
2//!
3//! Each method takes the engine's `&mut RuntimeResourceRef<'_>` ctx
4//! plus a [`CompletionHandle`] AND returns [`ContractResponse`]. The
5//! impl declares per call:
6//!
7//! - [`ContractResponse::Now(Ok(value))`] — result is ready inline.
8//!   The handle is ignored; the framework returns
9//!   `DispatchResult::Immediate(vec![(port, Box::new(value) as Box<dyn SlotValue>)])`
10//!   — `value` lands in the slot table as `Box<dyn SlotValue>` with no
11//!   serialization at this boundary — and skips the park /
12//!   ingress-drain cycle.
13//! - [`ContractResponse::Later`] — the impl retained the handle (sent
14//!   it to a worker thread, spawned a tokio task, queued a remote
15//!   RPC). The framework returns `DispatchResult::Async(cmd_id)` and
16//!   parks the dispatched op until the user calls
17//!   `handle.complete(result)` from off-thread.
18//!
19//! `ctx` is the per-dispatch runtime surface: impls reach their
20//! declared `#[depends(...)]` siblings through
21//! [`RuntimeResourceRef::dependency`] (e.g. an index that delegates
22//! distance math to a bound `Backend`).
23
24use crate::completion::{CompletionHandle, ContractResponse};
25use crate::runtime::RuntimeResourceRef;
26
27/// User-facing Contract trait for a vector index.
28pub trait Index: Send + Sync {
29    /// Vector storage. Library makers pick the tree position by
30    /// picking the type: `[f32]` for an f32-native index,
31    /// `bb_ir::types::AnyTensor` for a generic algorithm-class index
32    /// that outsources distance math to a bound `Backend`, a custom
33    /// packed type for specialized dtypes.
34    type Vector: ?Sized + bb_ir::types::Storage;
35
36    /// Library-maker-defined error type. The handle serializes the
37    /// error's `Display` rendering on completion failure.
38    type Error: std::error::Error + std::fmt::Display + Send + Sync + 'static;
39
40    /// Insert a vector. Return `Now(Ok(id))` if the assignment is
41    /// inline, or retain `completion` and return `Later` to deliver
42    /// the id off-thread. `ctx` exposes the per-dispatch runtime
43    /// surface, including the
44    /// [`RuntimeResourceRef::dependency`] lookup for declared
45    /// `#[depends(...)]` siblings.
46    fn add(
47        &mut self,
48        ctx: &mut RuntimeResourceRef<'_>,
49        vec: &Self::Vector,
50        completion: CompletionHandle<u64, Self::Error>,
51    ) -> ContractResponse<u64, Self::Error>;
52
53    /// Top-`k` nearest-neighbor search. Return inline results via
54    /// `Now(Ok(pairs))` or retain `completion` for off-thread delivery.
55    /// `ctx` carries the runtime surface so the search can resolve
56    /// `#[depends(...)]` siblings (e.g. a bound `Backend` supplying
57    /// distance kernels).
58    fn search(
59        &self,
60        ctx: &mut RuntimeResourceRef<'_>,
61        query: &Self::Vector,
62        k: u32,
63        completion: CompletionHandle<Vec<(u64, f32)>, Self::Error>,
64    ) -> ContractResponse<Vec<(u64, f32)>, Self::Error>;
65
66    /// Remove a vector by id. Return `Now(Ok(()))` if the removal is
67    /// synchronous, or retain `completion` and return `Later`.
68    fn remove(
69        &mut self,
70        ctx: &mut RuntimeResourceRef<'_>,
71        id: u64,
72        completion: CompletionHandle<(), Self::Error>,
73    ) -> ContractResponse<(), Self::Error>;
74
75    /// Optional training pass — IVF needs centroid k-means, PQ needs
76    /// sub-vector codebook learning, flat / hand-tuned indexes skip
77    /// this. Default returns `Now(Ok(()))` so impls that do not train
78    /// pay zero cost.
79    fn train(
80        &mut self,
81        _ctx: &mut RuntimeResourceRef<'_>,
82        _samples: &[&Self::Vector],
83        _completion: CompletionHandle<(), Self::Error>,
84    ) -> ContractResponse<(), Self::Error> {
85        ContractResponse::Now(Ok(()))
86    }
87}
88