Skip to main content

reifydb_store_multi/persistent/
mod.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2025 ReifyDB
3
4//! Cold tier of the multi-version store. Holds the durable, version-history-bearing record of every key the
5//! buffer has flushed. The default backend is SQLite; the trait surface is generic so other backends can be
6//! plugged in without touching the buffer or transaction layer.
7
8use std::{collections::HashMap, ops::Bound};
9
10use reifydb_core::{common::CommitVersion, encoded::key::EncodedKey, interface::store::EntryKind};
11#[cfg(all(feature = "sqlite", not(target_arch = "wasm32")))]
12use reifydb_sqlite::SqliteConfig;
13use reifydb_type::{Result, util::cowvec::CowVec};
14
15use crate::tier::{HistoricalCursor, RangeBatch, RangeCursor, TierBackend, TierBatch, TierStorage};
16
17#[cfg(all(feature = "sqlite", not(target_arch = "wasm32")))]
18pub mod sqlite;
19
20#[cfg(all(feature = "sqlite", not(target_arch = "wasm32")))]
21use sqlite::storage::SqlitePersistentStorage;
22
23#[derive(Clone)]
24#[cfg_attr(all(feature = "sqlite", not(target_arch = "wasm32")), repr(u8))]
25pub enum MultiPersistentTier {
26	#[cfg(all(feature = "sqlite", not(target_arch = "wasm32")))]
27	Sqlite(SqlitePersistentStorage) = 0,
28}
29
30#[cfg(all(feature = "sqlite", not(target_arch = "wasm32")))]
31impl MultiPersistentTier {
32	pub fn sqlite(config: SqliteConfig) -> Self {
33		Self::Sqlite(SqlitePersistentStorage::new(config))
34	}
35
36	pub fn sqlite_in_memory() -> Self {
37		Self::Sqlite(SqlitePersistentStorage::in_memory())
38	}
39}
40
41#[cfg(all(feature = "sqlite", not(target_arch = "wasm32")))]
42impl TierStorage for MultiPersistentTier {
43	fn get(&self, table: EntryKind, key: &[u8], version: CommitVersion) -> Result<Option<CowVec<u8>>> {
44		match self {
45			Self::Sqlite(s) => s.get(table, key, version),
46		}
47	}
48
49	fn set(&self, version: CommitVersion, batches: TierBatch) -> Result<()> {
50		match self {
51			Self::Sqlite(s) => s.set(version, batches),
52		}
53	}
54
55	fn range_next(
56		&self,
57		table: EntryKind,
58		cursor: &mut RangeCursor,
59		start: Bound<&[u8]>,
60		end: Bound<&[u8]>,
61		version: CommitVersion,
62		batch_size: usize,
63	) -> Result<RangeBatch> {
64		match self {
65			Self::Sqlite(s) => s.range_next(table, cursor, start, end, version, batch_size),
66		}
67	}
68
69	fn range_rev_next(
70		&self,
71		table: EntryKind,
72		cursor: &mut RangeCursor,
73		start: Bound<&[u8]>,
74		end: Bound<&[u8]>,
75		version: CommitVersion,
76		batch_size: usize,
77	) -> Result<RangeBatch> {
78		match self {
79			Self::Sqlite(s) => s.range_rev_next(table, cursor, start, end, version, batch_size),
80		}
81	}
82
83	fn ensure_table(&self, table: EntryKind) -> Result<()> {
84		match self {
85			Self::Sqlite(s) => s.ensure_table(table),
86		}
87	}
88
89	fn clear_table(&self, table: EntryKind) -> Result<()> {
90		match self {
91			Self::Sqlite(s) => s.clear_table(table),
92		}
93	}
94
95	fn drop(&self, batches: HashMap<EntryKind, Vec<(EncodedKey, CommitVersion)>>) -> Result<()> {
96		match self {
97			Self::Sqlite(s) => s.drop(batches),
98		}
99	}
100
101	fn get_all_versions(&self, table: EntryKind, key: &[u8]) -> Result<Vec<(CommitVersion, Option<CowVec<u8>>)>> {
102		match self {
103			Self::Sqlite(s) => s.get_all_versions(table, key),
104		}
105	}
106
107	fn scan_historical_below(
108		&self,
109		table: EntryKind,
110		cutoff: CommitVersion,
111		cursor: &mut HistoricalCursor,
112		batch_size: usize,
113	) -> Result<Vec<(EncodedKey, CommitVersion)>> {
114		match self {
115			Self::Sqlite(s) => s.scan_historical_below(table, cutoff, cursor, batch_size),
116		}
117	}
118}
119
120#[cfg(not(all(feature = "sqlite", not(target_arch = "wasm32"))))]
121impl TierStorage for MultiPersistentTier {
122	fn get(&self, _table: EntryKind, _key: &[u8], _version: CommitVersion) -> Result<Option<CowVec<u8>>> {
123		match *self {}
124	}
125
126	fn set(&self, _version: CommitVersion, _batches: TierBatch) -> Result<()> {
127		match *self {}
128	}
129
130	fn range_next(
131		&self,
132		_table: EntryKind,
133		_cursor: &mut RangeCursor,
134		_start: Bound<&[u8]>,
135		_end: Bound<&[u8]>,
136		_version: CommitVersion,
137		_batch_size: usize,
138	) -> Result<RangeBatch> {
139		match *self {}
140	}
141
142	fn range_rev_next(
143		&self,
144		_table: EntryKind,
145		_cursor: &mut RangeCursor,
146		_start: Bound<&[u8]>,
147		_end: Bound<&[u8]>,
148		_version: CommitVersion,
149		_batch_size: usize,
150	) -> Result<RangeBatch> {
151		match *self {}
152	}
153
154	fn ensure_table(&self, _table: EntryKind) -> Result<()> {
155		match *self {}
156	}
157
158	fn clear_table(&self, _table: EntryKind) -> Result<()> {
159		match *self {}
160	}
161
162	fn drop(&self, _batches: HashMap<EntryKind, Vec<(EncodedKey, CommitVersion)>>) -> Result<()> {
163		match *self {}
164	}
165
166	fn get_all_versions(&self, _table: EntryKind, _key: &[u8]) -> Result<Vec<(CommitVersion, Option<CowVec<u8>>)>> {
167		match *self {}
168	}
169
170	fn scan_historical_below(
171		&self,
172		_table: EntryKind,
173		_cutoff: CommitVersion,
174		_cursor: &mut HistoricalCursor,
175		_batch_size: usize,
176	) -> Result<Vec<(EncodedKey, CommitVersion)>> {
177		match *self {}
178	}
179}
180
181impl TierBackend for MultiPersistentTier {}