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 inverted_index(&self, table: &str, analyzer: Analyzer) -> Box<dyn InvertedIndex> {
50 Box::new(KeyValueInvertedIndex::new(
51 Arc::clone(&self.store),
52 table,
53 analyzer,
54 ))
55 }
56
57 fn migrate_inverted_index_storage(&self) -> StorageBackendResult<()> {
58 KeyValueInvertedIndex::migrate_legacy_storage(self.store.as_ref())
59 }
60
61 fn vector_index(
62 &self,
63 table: &str,
64 field: &str,
65 dimensions: u32,
66 spec: VectorIndexSpec,
67 mode: VectorIndexOpenMode,
68 ) -> StorageBackendResult<Box<dyn VectorIndex>> {
69 match spec {
70 VectorIndexSpec::BruteForce => Ok(Box::new(KeyValueVectorIndex::new(
71 Arc::clone(&self.store),
72 table,
73 field,
74 dimensions,
75 ))),
76 VectorIndexSpec::IVF(params) => match mode {
77 VectorIndexOpenMode::Create => Ok(Box::new(KeyValueIVFIndex::create(
78 Arc::clone(&self.store),
79 table,
80 field,
81 dimensions,
82 params,
83 )?)),
84 VectorIndexOpenMode::Restore => Ok(Box::new(KeyValueIVFIndex::restore(
85 Arc::clone(&self.store),
86 table,
87 field,
88 dimensions,
89 params,
90 )?)),
91 },
92 VectorIndexSpec::HNSW(params) => match mode {
93 VectorIndexOpenMode::Create => Ok(Box::new(KeyValueHNSWIndex::create(
94 Arc::clone(&self.store),
95 table,
96 field,
97 dimensions,
98 params,
99 )?)),
100 VectorIndexOpenMode::Restore => Ok(Box::new(KeyValueHNSWIndex::restore(
101 Arc::clone(&self.store),
102 table,
103 field,
104 dimensions,
105 params,
106 )?)),
107 },
108 }
109 }
110
111 fn drop_vector_index_metadata(&self, table: &str, field: &str) -> StorageBackendResult<()> {
112 KeyValueIVFIndex::drop_metadata(self.store.as_ref(), table, field)
113 }
114
115 fn persists_btree_indexes(&self) -> bool {
116 true
117 }
118
119 fn load_btree_index(
120 &self,
121 table: &str,
122 field: &str,
123 ) -> StorageBackendResult<Option<Vec<(DocId, Value)>>> {
124 btree_index::load(self.store.as_ref(), table, field)
125 }
126
127 fn btree_index_fields(&self, table: &str) -> StorageBackendResult<Vec<String>> {
128 btree_index::fields(self.store.as_ref(), table)
129 }
130
131 fn replace_btree_index(
132 &self,
133 table: &str,
134 field: &str,
135 values: &[(DocId, Value)],
136 ) -> StorageBackendResult<()> {
137 btree_index::replace(self.store.as_ref(), table, field, values)
138 }
139
140 fn replace_btree_indexes(
141 &self,
142 table: &str,
143 indexes: &[(&str, &[(DocId, Value)])],
144 ) -> StorageBackendResult<()> {
145 btree_index::replace_many(self.store.as_ref(), table, indexes)
146 }
147
148 fn apply_btree_index_write(
149 &self,
150 table: &str,
151 doc_id: DocId,
152 values: Option<&BTreeMap<String, Value>>,
153 ) -> StorageBackendResult<()> {
154 btree_index::apply_write(self.store.as_ref(), table, doc_id, values)
155 }
156
157 fn drop_btree_index(&self, table: &str, field: &str) -> StorageBackendResult<()> {
158 btree_index::drop_index(self.store.as_ref(), table, field)
159 }
160
161 fn clear_btree_indexes(&self, table: &str) -> StorageBackendResult<()> {
162 btree_index::clear_entries(self.store.as_ref(), table)
163 }
164
165 fn begin_transaction(&self) -> StorageBackendResult<()> {
166 self.store.begin_transaction()
167 }
168
169 fn begin_read_transaction(&self) -> StorageBackendResult<()> {
170 self.store.begin_read_transaction()
171 }
172
173 fn in_transaction(&self) -> bool {
174 self.store.in_transaction()
175 }
176
177 fn transaction_has_written(&self) -> StorageBackendResult<bool> {
178 self.store.transaction_has_written()
179 }
180
181 fn change_version(&self) -> StorageBackendResult<Option<u64>> {
182 self.store.change_version()
183 }
184
185 fn change_version_monitor_is_nonblocking(&self) -> StorageBackendResult<bool> {
186 self.store.change_version_monitor_is_nonblocking()
187 }
188
189 fn pin_transaction_snapshot(&self) -> StorageBackendResult<()> {
190 self.store.pin_transaction_snapshot()
191 }
192
193 fn commit_transaction(&self) -> StorageBackendResult<()> {
194 self.store.commit_transaction()
195 }
196
197 fn rollback_transaction(&self) -> StorageBackendResult<()> {
198 self.store.rollback_transaction()
199 }
200
201 fn savepoint(&self, id: crate::StorageSavepointId) -> StorageBackendResult<()> {
202 self.store.savepoint(&id.backend_name())
203 }
204
205 fn release_savepoint(&self, id: crate::StorageSavepointId) -> StorageBackendResult<()> {
206 self.store.release_savepoint(&id.backend_name())
207 }
208
209 fn rollback_to_savepoint(&self, id: crate::StorageSavepointId) -> StorageBackendResult<()> {
210 self.store.rollback_to_savepoint(&id.backend_name())
211 }
212}