1#![cfg_attr(not(debug_assertions), deny(clippy::disallowed_methods))]
18#![cfg_attr(debug_assertions, warn(clippy::disallowed_methods))]
19#![cfg_attr(not(debug_assertions), deny(warnings))]
20#![allow(clippy::tabs_in_doc_comments)]
21
22use reifydb_core::{
23 event::EventBus,
24 interface::version::{ComponentType, HasVersion, SystemVersion},
25};
26use reifydb_value::Result;
27
28pub mod flush;
29pub mod gc;
30pub mod tier;
31
32pub mod config;
33pub mod store;
34
35use std::collections::HashMap;
36
37use config::{CommitBufferConfig, MultiStoreConfig};
38use reifydb_core::{
39 common::CommitVersion,
40 delta::Delta,
41 encoded::key::{EncodedKey, EncodedKeyRange},
42 interface::store::{
43 MultiVersionCommit, MultiVersionContains, MultiVersionGet, MultiVersionGetPrevious, MultiVersionRow,
44 MultiVersionStore,
45 },
46};
47use reifydb_runtime::shutdown::Shutdown;
48#[cfg(all(feature = "sqlite", not(target_arch = "wasm32")))]
49use reifydb_sqlite::SqliteTempPathGuard;
50use reifydb_value::util::cowvec::CowVec;
51use store::StandardMultiStore;
52
53pub mod memory {}
54pub mod sqlite {}
55
56pub struct MultiStoreVersion;
57
58impl HasVersion for MultiStoreVersion {
59 fn version(&self) -> SystemVersion {
60 SystemVersion {
61 name: env!("CARGO_PKG_NAME")
62 .strip_prefix("reifydb-")
63 .unwrap_or(env!("CARGO_PKG_NAME"))
64 .to_string(),
65 version: env!("CARGO_PKG_VERSION").to_string(),
66 description: "Multi-version storage for OLTP operations with MVCC support".to_string(),
67 r#type: ComponentType::Module,
68 }
69 }
70}
71
72#[repr(u8)]
73#[derive(Clone)]
74pub enum MultiStore {
75 Standard(StandardMultiStore) = 0,
76}
77
78impl MultiStore {
79 pub fn standard(config: MultiStoreConfig) -> Self {
80 Self::Standard(StandardMultiStore::new(config).unwrap())
81 }
82}
83
84impl MultiStore {
85 pub fn testing_memory() -> Self {
86 MultiStore::Standard(StandardMultiStore::testing_memory())
87 }
88
89 pub fn testing_memory_with_eventbus(event_bus: EventBus) -> Self {
90 MultiStore::Standard(StandardMultiStore::testing_memory_with_eventbus(event_bus))
91 }
92
93 #[cfg(all(feature = "sqlite", not(target_arch = "wasm32")))]
94 pub fn testing_memory_with_persistent_sqlite() -> (Self, SqliteTempPathGuard) {
95 let (store, guard) = StandardMultiStore::testing_memory_with_persistent_sqlite();
96 (MultiStore::Standard(store), guard)
97 }
98
99 #[cfg(all(feature = "sqlite", not(target_arch = "wasm32")))]
100 pub fn testing_memory_with_persistent_sqlite_with_eventbus(event_bus: EventBus) -> (Self, SqliteTempPathGuard) {
101 let (store, guard) = StandardMultiStore::testing_memory_with_persistent_sqlite_with_eventbus(event_bus);
102 (MultiStore::Standard(store), guard)
103 }
104
105 pub fn flush_pending_blocking(&self) {
106 match self {
107 MultiStore::Standard(store) => store.flush_pending_blocking(),
108 }
109 }
110
111 pub fn flush_all_blocking(&self) {
112 match self {
113 MultiStore::Standard(store) => store.flush_all_blocking(),
114 }
115 }
116
117 pub fn commit(&self) -> Option<&tier::commit::buffer::MultiCommitBufferTier> {
118 match self {
119 MultiStore::Standard(store) => store.commit(),
120 }
121 }
122
123 pub fn persistent(&self) -> Option<&tier::persistent::MultiPersistentTier> {
124 match self {
125 MultiStore::Standard(store) => store.persistent(),
126 }
127 }
128
129 pub fn clear_eviction_watermark(&self) {
130 match self {
131 MultiStore::Standard(store) => store.clear_eviction_watermark(),
132 }
133 }
134}
135
136impl Shutdown for MultiStore {
137 fn shutdown(&self) {
138 match self {
139 MultiStore::Standard(store) => store.shutdown(),
140 }
141 }
142}
143
144impl MultiVersionGet for MultiStore {
145 #[inline]
146 fn get(&self, key: &EncodedKey, version: CommitVersion) -> Result<Option<MultiVersionRow>> {
147 match self {
148 MultiStore::Standard(store) => MultiVersionGet::get(store, key, version),
149 }
150 }
151}
152
153impl MultiVersionContains for MultiStore {
154 #[inline]
155 fn contains(&self, key: &EncodedKey, version: CommitVersion) -> Result<bool> {
156 match self {
157 MultiStore::Standard(store) => MultiVersionContains::contains(store, key, version),
158 }
159 }
160}
161
162impl MultiVersionCommit for MultiStore {
163 #[inline]
164 fn commit(&self, deltas: CowVec<Delta>, version: CommitVersion) -> Result<()> {
165 match self {
166 MultiStore::Standard(store) => MultiVersionCommit::commit(store, deltas, version),
167 }
168 }
169}
170
171impl MultiVersionGetPrevious for MultiStore {
172 #[inline]
173 fn get_previous_version(
174 &self,
175 key: &EncodedKey,
176 before_version: CommitVersion,
177 ) -> Result<Option<MultiVersionRow>> {
178 match self {
179 MultiStore::Standard(store) => store.get_previous_version(key, before_version),
180 }
181 }
182}
183
184pub type MultiVersionRangeIterator<'a> = Box<dyn Iterator<Item = Result<MultiVersionRow>> + Send + 'a>;
185
186#[derive(Debug, Copy, Clone, PartialEq, Eq)]
190pub enum MultiVersionScope {
191 AsOf {
193 read: CommitVersion,
194 },
195 Between {
198 after: CommitVersion,
199 read: CommitVersion,
200 },
201}
202
203impl MultiVersionScope {
204 #[inline]
205 pub fn read(&self) -> CommitVersion {
206 match self {
207 Self::AsOf {
208 read,
209 }
210 | Self::Between {
211 read,
212 ..
213 } => *read,
214 }
215 }
216
217 #[inline]
218 pub fn contains(&self, v: CommitVersion) -> bool {
219 match self {
220 Self::AsOf {
221 read,
222 } => v <= *read,
223 Self::Between {
224 after,
225 read,
226 } => v > *after && v <= *read,
227 }
228 }
229}
230
231impl MultiStore {
232 pub fn range(
233 &self,
234 range: EncodedKeyRange,
235 scope: MultiVersionScope,
236 batch_size: usize,
237 ) -> MultiVersionRangeIterator<'_> {
238 match self {
239 MultiStore::Standard(store) => Box::new(store.range(range, scope, batch_size)),
240 }
241 }
242
243 pub fn range_rev(
244 &self,
245 range: EncodedKeyRange,
246 scope: MultiVersionScope,
247 batch_size: usize,
248 ) -> MultiVersionRangeIterator<'_> {
249 match self {
250 MultiStore::Standard(store) => Box::new(store.range_rev(range, scope, batch_size)),
251 }
252 }
253
254 pub fn get_many(
255 &self,
256 keys: &[EncodedKey],
257 version: CommitVersion,
258 ) -> Result<HashMap<EncodedKey, MultiVersionRow>> {
259 match self {
260 MultiStore::Standard(store) => store.get_many(keys, version),
261 }
262 }
263}
264
265impl MultiVersionStore for MultiStore {}