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