manifold_vectors/
multi.rs

1//! Multi-vector storage for token-level embeddings.
2use manifold::{
3    ReadOnlyTable, ReadTransaction, ReadableTableMetadata, StorageError, Table, TableDefinition,
4    TableError, WriteTransaction,
5};
6use uuid::Uuid;
7
8/// Table for storing multi-vectors (sequences of vectors)
9pub struct MultiVectorTable<'txn, const DIM: usize> {
10    table: Table<'txn, Uuid, Vec<[f32; DIM]>>,
11}
12
13impl<'txn, const DIM: usize> MultiVectorTable<'txn, DIM> {
14    /// Opens a multi-vector table for writing
15    pub fn open(txn: &'txn WriteTransaction, name: &str) -> Result<Self, TableError> {
16        let def: TableDefinition<Uuid, Vec<[f32; DIM]>> = TableDefinition::new(name);
17        let table = txn.open_table(def)?;
18        Ok(Self { table })
19    }
20
21    /// Inserts a sequence of vectors
22    pub fn insert(&mut self, key: &Uuid, vectors: &[[f32; DIM]]) -> Result<(), TableError> {
23        self.table.insert(key, &vectors.to_vec())?;
24        Ok(())
25    }
26
27    /// Returns the number of entries stored
28    pub fn len(&self) -> Result<u64, StorageError> {
29        self.table.len()
30    }
31
32    /// Returns true if the table is empty
33    pub fn is_empty(&self) -> Result<bool, StorageError> {
34        Ok(self.len()? == 0)
35    }
36}
37
38/// Read-only multi-vector table
39pub struct MultiVectorTableRead<const DIM: usize> {
40    table: ReadOnlyTable<Uuid, Vec<[f32; DIM]>>,
41}
42
43impl<const DIM: usize> MultiVectorTableRead<DIM> {
44    /// Opens a multi-vector table for reading
45    pub fn open(txn: &ReadTransaction, name: &str) -> Result<Self, StorageError> {
46        let def: TableDefinition<Uuid, Vec<[f32; DIM]>> = TableDefinition::new(name);
47        let table = txn.open_table(def).map_err(|e| match e {
48            TableError::Storage(s) => s,
49            _ => StorageError::Io(std::io::Error::other(e)),
50        })?;
51        Ok(Self { table })
52    }
53
54    /// Retrieves a sequence of vectors by key
55    pub fn get(&self, key: &Uuid) -> Result<Option<Vec<[f32; DIM]>>, StorageError> {
56        Ok(self.table.get(key)?.map(|guard| guard.value().clone()))
57    }
58
59    /// Returns the number of entries stored
60    pub fn len(&self) -> Result<u64, StorageError> {
61        self.table.len()
62    }
63
64    /// Returns true if the table is empty
65    pub fn is_empty(&self) -> Result<bool, StorageError> {
66        Ok(self.len()? == 0)
67    }
68}