1use std::{collections::HashMap, ops::Bound};
9
10use reifydb_codec::key::encoded::EncodedKey;
11use reifydb_core::{common::CommitVersion, interface::store::EntryKind};
12use reifydb_runtime::shutdown::Shutdown;
13#[cfg(all(feature = "sqlite", not(target_arch = "wasm32")))]
14use reifydb_sqlite::{SqliteConfig, SqliteTempPathGuard};
15use reifydb_value::{Result, util::cowvec::CowVec};
16
17use crate::{
18 MultiVersionScope,
19 tier::{
20 HistoricalCursor, RangeBatch, RangeCursor, RawEntry, TierBackend, TierBatch, TierStorage,
21 VersionedGetResult,
22 },
23};
24
25#[cfg(all(feature = "sqlite", not(target_arch = "wasm32")))]
26pub mod sqlite;
27
28#[cfg(all(feature = "sqlite", not(target_arch = "wasm32")))]
29use sqlite::storage::SqlitePersistentStorage;
30
31#[derive(Debug, Clone, Copy, PartialEq, Eq)]
32pub struct CheckpointOutcome {
33 pub log_frames: u32,
34 pub restarted: bool,
35}
36
37#[derive(Clone)]
38#[cfg_attr(all(feature = "sqlite", not(target_arch = "wasm32")), repr(u8))]
39pub enum MultiPersistentTier {
40 #[cfg(all(feature = "sqlite", not(target_arch = "wasm32")))]
41 Sqlite(SqlitePersistentStorage) = 0,
42}
43
44impl Shutdown for MultiPersistentTier {
45 fn shutdown(&self) {
46 match self {
47 #[cfg(all(feature = "sqlite", not(target_arch = "wasm32")))]
48 Self::Sqlite(s) => s.shutdown(),
49 #[cfg(not(all(feature = "sqlite", not(target_arch = "wasm32"))))]
50 _ => {}
51 }
52 }
53}
54
55#[cfg(all(feature = "sqlite", not(target_arch = "wasm32")))]
56impl MultiPersistentTier {
57 pub fn sqlite(config: SqliteConfig) -> Self {
58 Self::Sqlite(SqlitePersistentStorage::new(config))
59 }
60
61 pub fn sqlite_in_memory() -> (Self, SqliteTempPathGuard) {
62 let (storage, guard) = SqlitePersistentStorage::in_memory();
63 (Self::Sqlite(storage), guard)
64 }
65
66 pub fn maybe_checkpoint(&self) -> Result<CheckpointOutcome> {
67 match self {
68 Self::Sqlite(s) => s.maybe_checkpoint(),
69 }
70 }
71
72 pub fn set_checkpoint_threshold(&self, frames: u32) {
73 match self {
74 Self::Sqlite(s) => s.set_checkpoint_threshold(frames),
75 }
76 }
77
78 pub fn delete_below_version(
79 &self,
80 table: EntryKind,
81 cutoff_version: CommitVersion,
82 prefix: Option<&[u8]>,
83 ) -> Result<Vec<EncodedKey>> {
84 match self {
85 Self::Sqlite(s) => s.delete_below_version(table, cutoff_version, prefix),
86 }
87 }
88
89 pub fn delete_keys(&self, table: EntryKind, keys: &[EncodedKey]) -> Result<u64> {
90 match self {
91 Self::Sqlite(s) => s.delete_keys(table, keys),
92 }
93 }
94
95 pub fn set_collecting_accepted(&self, version: CommitVersion, batches: TierBatch) -> Result<Vec<EncodedKey>> {
96 match self {
97 Self::Sqlite(s) => s.set_collecting_accepted(version, batches),
98 }
99 }
100
101 pub fn persist_sweep(&self, batches: Vec<(CommitVersion, TierBatch)>) -> Result<Vec<EncodedKey>> {
102 match self {
103 Self::Sqlite(s) => s.persist_sweep(batches),
104 }
105 }
106
107 pub fn load_range_consistent(
108 &self,
109 table: EntryKind,
110 start: Bound<&[u8]>,
111 end: Bound<&[u8]>,
112 read: CommitVersion,
113 limit: Option<usize>,
114 ) -> Result<Vec<RawEntry>> {
115 match self {
116 Self::Sqlite(s) => s.load_range_consistent(table, start, end, read, limit),
117 }
118 }
119
120 pub fn delete_keys_through(&self, table: EntryKind, keys: &[(EncodedKey, CommitVersion)]) -> Result<u64> {
121 match self {
122 Self::Sqlite(s) => s.delete_keys_through(table, keys),
123 }
124 }
125}
126
127#[cfg(not(all(feature = "sqlite", not(target_arch = "wasm32"))))]
128impl MultiPersistentTier {
129 pub fn maybe_checkpoint(&self) -> Result<CheckpointOutcome> {
130 match *self {}
131 }
132
133 pub fn set_checkpoint_threshold(&self, _frames: u32) {
134 match *self {}
135 }
136
137 pub fn delete_below_version(
138 &self,
139 _table: EntryKind,
140 _cutoff_version: CommitVersion,
141 _prefix: Option<&[u8]>,
142 ) -> Result<Vec<EncodedKey>> {
143 match *self {}
144 }
145
146 pub fn delete_keys(&self, _table: EntryKind, _keys: &[EncodedKey]) -> Result<u64> {
147 match *self {}
148 }
149
150 pub fn persist_sweep(&self, _batches: Vec<(CommitVersion, TierBatch)>) -> Result<Vec<EncodedKey>> {
151 match *self {}
152 }
153
154 pub fn load_range_consistent(
155 &self,
156 _table: EntryKind,
157 _start: Bound<&[u8]>,
158 _end: Bound<&[u8]>,
159 _read: CommitVersion,
160 _limit: Option<usize>,
161 ) -> Result<Vec<RawEntry>> {
162 match *self {}
163 }
164
165 pub fn delete_keys_through(&self, _table: EntryKind, _keys: &[(EncodedKey, CommitVersion)]) -> Result<u64> {
166 match *self {}
167 }
168}
169
170#[cfg(all(feature = "sqlite", not(target_arch = "wasm32")))]
171impl TierStorage for MultiPersistentTier {
172 fn get(&self, table: EntryKind, key: &[u8], version: CommitVersion) -> Result<VersionedGetResult> {
173 match self {
174 Self::Sqlite(s) => s.get(table, key, version),
175 }
176 }
177
178 fn get_many(
179 &self,
180 table: EntryKind,
181 keys: &[&[u8]],
182 version: CommitVersion,
183 ) -> Result<Vec<VersionedGetResult>> {
184 match self {
185 Self::Sqlite(s) => s.get_many(table, keys, version),
186 }
187 }
188
189 fn set(&self, version: CommitVersion, batches: TierBatch) -> Result<()> {
190 match self {
191 Self::Sqlite(s) => s.set(version, batches),
192 }
193 }
194
195 fn range_next(
196 &self,
197 table: EntryKind,
198 cursor: &mut RangeCursor,
199 start: Bound<&[u8]>,
200 end: Bound<&[u8]>,
201 scope: MultiVersionScope,
202 batch_size: usize,
203 ) -> Result<RangeBatch> {
204 match self {
205 Self::Sqlite(s) => s.range_next(table, cursor, start, end, scope, batch_size),
206 }
207 }
208
209 fn range_rev_next(
210 &self,
211 table: EntryKind,
212 cursor: &mut RangeCursor,
213 start: Bound<&[u8]>,
214 end: Bound<&[u8]>,
215 scope: MultiVersionScope,
216 batch_size: usize,
217 ) -> Result<RangeBatch> {
218 match self {
219 Self::Sqlite(s) => s.range_rev_next(table, cursor, start, end, scope, batch_size),
220 }
221 }
222
223 fn ensure_table(&self, table: EntryKind) -> Result<()> {
224 match self {
225 Self::Sqlite(s) => s.ensure_table(table),
226 }
227 }
228
229 fn clear_table(&self, table: EntryKind) -> Result<()> {
230 match self {
231 Self::Sqlite(s) => s.clear_table(table),
232 }
233 }
234
235 fn drop(&self, batches: HashMap<EntryKind, Vec<(EncodedKey, CommitVersion)>>) -> Result<()> {
236 match self {
237 Self::Sqlite(s) => s.drop(batches),
238 }
239 }
240
241 fn get_all_versions(&self, table: EntryKind, key: &[u8]) -> Result<Vec<(CommitVersion, Option<CowVec<u8>>)>> {
242 match self {
243 Self::Sqlite(s) => s.get_all_versions(table, key),
244 }
245 }
246
247 fn scan_historical_below(
248 &self,
249 table: EntryKind,
250 cutoff: CommitVersion,
251 cursor: &mut HistoricalCursor,
252 batch_size: usize,
253 ) -> Result<Vec<(EncodedKey, CommitVersion)>> {
254 match self {
255 Self::Sqlite(s) => s.scan_historical_below(table, cutoff, cursor, batch_size),
256 }
257 }
258}
259
260#[cfg(not(all(feature = "sqlite", not(target_arch = "wasm32"))))]
261impl TierStorage for MultiPersistentTier {
262 fn get(&self, _table: EntryKind, _key: &[u8], _version: CommitVersion) -> Result<VersionedGetResult> {
263 match *self {}
264 }
265
266 fn set(&self, _version: CommitVersion, _batches: TierBatch) -> Result<()> {
267 match *self {}
268 }
269
270 fn range_next(
271 &self,
272 _table: EntryKind,
273 _cursor: &mut RangeCursor,
274 _start: Bound<&[u8]>,
275 _end: Bound<&[u8]>,
276 _scope: MultiVersionScope,
277 _batch_size: usize,
278 ) -> Result<RangeBatch> {
279 match *self {}
280 }
281
282 fn range_rev_next(
283 &self,
284 _table: EntryKind,
285 _cursor: &mut RangeCursor,
286 _start: Bound<&[u8]>,
287 _end: Bound<&[u8]>,
288 _scope: MultiVersionScope,
289 _batch_size: usize,
290 ) -> Result<RangeBatch> {
291 match *self {}
292 }
293
294 fn ensure_table(&self, _table: EntryKind) -> Result<()> {
295 match *self {}
296 }
297
298 fn clear_table(&self, _table: EntryKind) -> Result<()> {
299 match *self {}
300 }
301
302 fn drop(&self, _batches: HashMap<EntryKind, Vec<(EncodedKey, CommitVersion)>>) -> Result<()> {
303 match *self {}
304 }
305
306 fn get_all_versions(&self, _table: EntryKind, _key: &[u8]) -> Result<Vec<(CommitVersion, Option<CowVec<u8>>)>> {
307 match *self {}
308 }
309
310 fn scan_historical_below(
311 &self,
312 _table: EntryKind,
313 _cutoff: CommitVersion,
314 _cursor: &mut HistoricalCursor,
315 _batch_size: usize,
316 ) -> Result<Vec<(EncodedKey, CommitVersion)>> {
317 match *self {}
318 }
319}
320
321impl TierBackend for MultiPersistentTier {}