1use super::{
10 btree_index, Analyzer, Arc, BTreeMap, DocId, DocumentStore, InvertedIndex, KeyValueCatalog,
11 KeyValueDocumentStore, KeyValueHNSWIndex, KeyValueIVFIndex, KeyValueInvertedIndex,
12 KeyValueStore, KeyValueVectorIndex, PersistentStorageBackend, PersistentStorageIdentity,
13 StorageBackendResult, Value, VectorIndex, VectorIndexOpenMode, VectorIndexSpec,
14};
15use crate::{CatalogFacade, PersistentStorageSession};
16
17#[derive(Clone)]
19pub struct KeyValueStorageBackend {
20 store: Arc<dyn KeyValueStore>,
21}
22
23impl KeyValueStorageBackend {
24 pub fn new(store: Arc<dyn KeyValueStore>) -> Self {
25 Self { store }
26 }
27
28 pub fn store(&self) -> Arc<dyn KeyValueStore> {
29 Arc::clone(&self.store)
30 }
31}
32
33impl PersistentStorageBackend for KeyValueStorageBackend {
34 fn storage_identity(&self) -> StorageBackendResult<Option<PersistentStorageIdentity>> {
35 self.store.storage_identity()
36 }
37
38 fn open_session(&self) -> StorageBackendResult<PersistentStorageSession> {
39 let store = self.store.open_session()?;
40 let catalog: Arc<dyn CatalogFacade> = Arc::new(KeyValueCatalog::new(Arc::clone(&store)));
41 let backend: Arc<dyn PersistentStorageBackend> = Arc::new(Self::new(store));
42 Ok(PersistentStorageSession::new(catalog, backend))
43 }
44
45 fn document_store(&self, table: &str) -> Box<dyn DocumentStore> {
46 Box::new(KeyValueDocumentStore::new(Arc::clone(&self.store), table))
47 }
48
49 fn migrate_document_storage(&self) -> StorageBackendResult<()> {
50 KeyValueDocumentStore::migrate_legacy_storage(self.store.as_ref())
51 }
52
53 fn inverted_index(&self, table: &str, analyzer: Analyzer) -> Box<dyn InvertedIndex> {
54 Box::new(KeyValueInvertedIndex::new(
55 Arc::clone(&self.store),
56 table,
57 analyzer,
58 ))
59 }
60
61 fn migrate_inverted_index_storage(&self) -> StorageBackendResult<()> {
62 KeyValueInvertedIndex::migrate_legacy_storage(self.store.as_ref())
63 }
64
65 fn vector_index(
66 &self,
67 table: &str,
68 field: &str,
69 dimensions: u32,
70 spec: VectorIndexSpec,
71 mode: VectorIndexOpenMode,
72 ) -> StorageBackendResult<Box<dyn VectorIndex>> {
73 match spec {
74 VectorIndexSpec::BruteForce => Ok(Box::new(KeyValueVectorIndex::new(
75 Arc::clone(&self.store),
76 table,
77 field,
78 dimensions,
79 ))),
80 VectorIndexSpec::IVF(params) => match mode {
81 VectorIndexOpenMode::Create => Ok(Box::new(KeyValueIVFIndex::create(
82 Arc::clone(&self.store),
83 table,
84 field,
85 dimensions,
86 params,
87 )?)),
88 VectorIndexOpenMode::Restore => Ok(Box::new(KeyValueIVFIndex::restore(
89 Arc::clone(&self.store),
90 table,
91 field,
92 dimensions,
93 params,
94 )?)),
95 },
96 VectorIndexSpec::HNSW(params) => match mode {
97 VectorIndexOpenMode::Create => Ok(Box::new(KeyValueHNSWIndex::create(
98 Arc::clone(&self.store),
99 table,
100 field,
101 dimensions,
102 params,
103 )?)),
104 VectorIndexOpenMode::Restore => Ok(Box::new(KeyValueHNSWIndex::restore(
105 Arc::clone(&self.store),
106 table,
107 field,
108 dimensions,
109 params,
110 )?)),
111 },
112 }
113 }
114
115 fn drop_vector_index_metadata(&self, table: &str, field: &str) -> StorageBackendResult<()> {
116 KeyValueIVFIndex::drop_metadata(self.store.as_ref(), table, field)
117 }
118
119 fn persists_btree_indexes(&self) -> bool {
120 true
121 }
122
123 fn load_btree_index(
124 &self,
125 table: &str,
126 field: &crate::ValueIndexKey,
127 ) -> StorageBackendResult<Option<Vec<(DocId, Value)>>> {
128 btree_index::load(self.store.as_ref(), table, field)
129 }
130
131 fn btree_index_fields(&self, table: &str) -> StorageBackendResult<Vec<crate::ValueIndexKey>> {
132 btree_index::fields(self.store.as_ref(), table)
133 }
134
135 fn replace_btree_index(
136 &self,
137 table: &str,
138 field: &crate::ValueIndexKey,
139 values: &[(DocId, Value)],
140 ) -> StorageBackendResult<()> {
141 btree_index::replace(self.store.as_ref(), table, field, values)
142 }
143
144 fn replace_btree_indexes(
145 &self,
146 table: &str,
147 indexes: &[(&crate::ValueIndexKey, &[(DocId, Value)])],
148 ) -> StorageBackendResult<()> {
149 btree_index::replace_many(self.store.as_ref(), table, indexes)
150 }
151
152 fn apply_btree_index_write(
153 &self,
154 table: &str,
155 doc_id: DocId,
156 values: Option<&BTreeMap<crate::ValueIndexKey, Value>>,
157 ) -> StorageBackendResult<()> {
158 btree_index::apply_write(self.store.as_ref(), table, doc_id, values)
159 }
160
161 fn drop_btree_index(
162 &self,
163 table: &str,
164 field: &crate::ValueIndexKey,
165 ) -> StorageBackendResult<()> {
166 btree_index::drop_index(self.store.as_ref(), table, field)
167 }
168
169 fn clear_btree_indexes(&self, table: &str) -> StorageBackendResult<()> {
170 btree_index::clear_entries(self.store.as_ref(), table)
171 }
172
173 fn begin_transaction(&self) -> StorageBackendResult<()> {
174 self.store.begin_transaction()
175 }
176
177 fn begin_read_transaction(&self) -> StorageBackendResult<()> {
178 self.store.begin_read_transaction()
179 }
180
181 fn begin_upgradeable_transaction(&self) -> StorageBackendResult<()> {
182 self.store.begin_upgradeable_transaction()
183 }
184
185 fn in_transaction(&self) -> bool {
186 self.store.in_transaction()
187 }
188
189 fn transaction_has_written(&self) -> StorageBackendResult<bool> {
190 self.store.transaction_has_written()
191 }
192
193 fn change_version(&self) -> StorageBackendResult<Option<u64>> {
194 self.store.change_version()
195 }
196
197 fn change_version_monitor_is_nonblocking(&self) -> StorageBackendResult<bool> {
198 self.store.change_version_monitor_is_nonblocking()
199 }
200
201 fn pin_transaction_snapshot(&self) -> StorageBackendResult<()> {
202 self.store.pin_transaction_snapshot()
203 }
204
205 fn commit_transaction(&self) -> StorageBackendResult<()> {
206 self.store.commit_transaction()
207 }
208
209 fn rollback_transaction(&self) -> StorageBackendResult<()> {
210 self.store.rollback_transaction()
211 }
212
213 fn savepoint(&self, id: crate::StorageSavepointId) -> StorageBackendResult<()> {
214 self.store.savepoint(&id.backend_name())
215 }
216
217 fn release_savepoint(&self, id: crate::StorageSavepointId) -> StorageBackendResult<()> {
218 self.store.release_savepoint(&id.backend_name())
219 }
220
221 fn rollback_to_savepoint(&self, id: crate::StorageSavepointId) -> StorageBackendResult<()> {
222 self.store.rollback_to_savepoint(&id.backend_name())
223 }
224}