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