manifold_vectors/
dense.rs1use manifold::{
4 AccessGuard, ReadOnlyTable, ReadTransaction, ReadableTable, ReadableTableMetadata,
5 StorageError, Table, TableDefinition, TableError, WriteTransaction,
6};
7use std::ops::Deref;
8use uuid::Uuid;
9
10pub struct VectorTable<'txn, const DIM: usize> {
12 table: Table<'txn, Uuid, [f32; DIM]>,
13}
14
15impl<'txn, const DIM: usize> VectorTable<'txn, DIM> {
16 pub fn open(txn: &'txn WriteTransaction, name: &str) -> Result<Self, TableError> {
18 let def: TableDefinition<Uuid, [f32; DIM]> = TableDefinition::new(name);
19 let table = txn.open_table(def)?;
20 Ok(Self { table })
21 }
22
23 pub fn insert(&mut self, key: &Uuid, vector: &[f32; DIM]) -> Result<(), TableError> {
25 self.table.insert(key, vector)?;
26 Ok(())
27 }
28
29 pub fn insert_batch(
31 &mut self,
32 items: &[(Uuid, [f32; DIM])],
33 sorted: bool,
34 ) -> Result<(), StorageError> {
35 self.table.insert_bulk(items.to_vec(), sorted)?;
36 Ok(())
37 }
38
39 pub fn remove(&mut self, key: &Uuid) -> Result<Option<VectorGuard<'_, DIM>>, StorageError> {
43 match self.table.remove(key) {
44 Ok(Some(guard)) => {
45 let value_cached = guard.value();
46 Ok(Some(VectorGuard {
47 value_cached,
48 _guard: guard,
49 }))
50 }
51 Ok(None) => Ok(None),
52 Err(e) => Err(e),
53 }
54 }
55
56 pub fn remove_bulk(&mut self, keys: &[Uuid]) -> Result<usize, StorageError> {
60 self.table.remove_bulk(keys.iter().copied())
61 }
62
63 pub fn len(&self) -> Result<u64, StorageError> {
65 self.table.len()
66 }
67
68 pub fn is_empty(&self) -> Result<bool, StorageError> {
70 Ok(self.len()? == 0)
71 }
72}
73
74pub struct VectorTableRead<const DIM: usize> {
79 table: ReadOnlyTable<Uuid, [f32; DIM]>,
80}
81
82impl<const DIM: usize> VectorTableRead<DIM> {
83 pub fn open(txn: &ReadTransaction, name: &str) -> Result<Self, StorageError> {
85 let def: TableDefinition<Uuid, [f32; DIM]> = TableDefinition::new(name);
86 let table = txn.open_table(def).map_err(|e| match e {
87 TableError::Storage(s) => s,
88 _ => StorageError::Io(std::io::Error::other(e)),
89 })?;
90 Ok(Self { table })
91 }
92
93 pub fn get(&self, key: &Uuid) -> Result<Option<VectorGuard<'_, DIM>>, StorageError> {
98 Ok(self.table.get(key)?.map(VectorGuard::new))
99 }
100
101 pub fn len(&self) -> Result<u64, StorageError> {
103 self.table.len()
104 }
105
106 pub fn is_empty(&self) -> Result<bool, StorageError> {
108 Ok(self.len()? == 0)
109 }
110
111 pub fn all_vectors(&self) -> Result<VectorIter<'_, DIM>, StorageError> {
113 Ok(VectorIter {
114 inner: self.table.iter()?,
115 })
116 }
117}
118
119pub struct VectorGuard<'a, const DIM: usize> {
124 value_cached: [f32; DIM],
125 _guard: AccessGuard<'a, [f32; DIM]>,
126}
127
128impl<'a, const DIM: usize> VectorGuard<'a, DIM> {
129 fn new(guard: AccessGuard<'a, [f32; DIM]>) -> Self {
130 let value_cached = guard.value();
131 Self {
132 value_cached,
133 _guard: guard,
134 }
135 }
136
137 pub fn value(&self) -> &[f32; DIM] {
139 &self.value_cached
140 }
141
142 pub fn as_slice(&self) -> &[f32] {
144 &self.value_cached
145 }
146}
147
148impl<const DIM: usize> Deref for VectorGuard<'_, DIM> {
149 type Target = [f32; DIM];
150
151 fn deref(&self) -> &Self::Target {
152 &self.value_cached
153 }
154}
155
156pub struct VectorIter<'a, const DIM: usize> {
158 inner: manifold::Range<'a, Uuid, [f32; DIM]>,
159}
160
161impl<'a, const DIM: usize> Iterator for VectorIter<'a, DIM> {
162 type Item = Result<(Uuid, VectorGuard<'a, DIM>), StorageError>;
163
164 fn next(&mut self) -> Option<Self::Item> {
165 self.inner.next().map(|result| {
166 result
167 .map(|(key_guard, value_guard)| (key_guard.value(), VectorGuard::new(value_guard)))
168 })
169 }
170}