Skip to main content

reifydb_store_multi/
lib.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2025 ReifyDB
3
4#![cfg_attr(not(debug_assertions), deny(warnings))]
5
6use reifydb_core::{
7	event::EventBus,
8	interface::version::{ComponentType, HasVersion, SystemVersion},
9};
10use reifydb_type::Result;
11
12pub mod cold;
13pub mod hot;
14pub mod tier;
15pub mod warm;
16
17pub mod config;
18pub mod multi;
19pub mod store;
20
21use config::{HotConfig, MultiStoreConfig};
22use reifydb_core::{
23	common::CommitVersion,
24	delta::Delta,
25	encoded::key::{EncodedKey, EncodedKeyRange},
26	interface::store::{
27		MultiVersionCommit, MultiVersionContains, MultiVersionGet, MultiVersionGetPrevious, MultiVersionStore,
28		MultiVersionValues,
29	},
30};
31use reifydb_type::util::cowvec::CowVec;
32use store::StandardMultiStore;
33
34pub mod memory {}
35pub mod sqlite {}
36
37pub struct MultiStoreVersion;
38
39impl HasVersion for MultiStoreVersion {
40	fn version(&self) -> SystemVersion {
41		SystemVersion {
42			name: env!("CARGO_PKG_NAME")
43				.strip_prefix("reifydb-")
44				.unwrap_or(env!("CARGO_PKG_NAME"))
45				.to_string(),
46			version: env!("CARGO_PKG_VERSION").to_string(),
47			description: "Multi-version storage for OLTP operations with MVCC support".to_string(),
48			r#type: ComponentType::Module,
49		}
50	}
51}
52
53#[repr(u8)]
54#[derive(Clone)]
55pub enum MultiStore {
56	Standard(StandardMultiStore) = 0,
57	// Other(Box<dyn MultiVersionStore>) = 254,
58}
59
60impl MultiStore {
61	pub fn standard(config: MultiStoreConfig) -> Self {
62		Self::Standard(StandardMultiStore::new(config).unwrap())
63	}
64}
65
66impl MultiStore {
67	pub fn testing_memory() -> Self {
68		MultiStore::Standard(StandardMultiStore::testing_memory())
69	}
70
71	pub fn testing_memory_with_eventbus(event_bus: EventBus) -> Self {
72		MultiStore::Standard(StandardMultiStore::testing_memory_with_eventbus(event_bus))
73	}
74
75	/// Get access to the hot storage tier.
76	///
77	/// Returns `None` if the hot tier is not configured.
78	pub fn hot(&self) -> Option<&hot::storage::HotStorage> {
79		match self {
80			MultiStore::Standard(store) => store.hot(),
81		}
82	}
83}
84
85// MultiVersion trait implementations
86
87impl MultiVersionGet for MultiStore {
88	#[inline]
89	fn get(&self, key: &EncodedKey, version: CommitVersion) -> Result<Option<MultiVersionValues>> {
90		match self {
91			MultiStore::Standard(store) => MultiVersionGet::get(store, key, version),
92		}
93	}
94}
95
96impl MultiVersionContains for MultiStore {
97	#[inline]
98	fn contains(&self, key: &EncodedKey, version: CommitVersion) -> Result<bool> {
99		match self {
100			MultiStore::Standard(store) => MultiVersionContains::contains(store, key, version),
101		}
102	}
103}
104
105impl MultiVersionCommit for MultiStore {
106	#[inline]
107	fn commit(&self, deltas: CowVec<Delta>, version: CommitVersion) -> Result<()> {
108		match self {
109			MultiStore::Standard(store) => store.commit(deltas, version),
110		}
111	}
112}
113
114impl MultiVersionGetPrevious for MultiStore {
115	#[inline]
116	fn get_previous_version(
117		&self,
118		key: &EncodedKey,
119		before_version: CommitVersion,
120	) -> Result<Option<MultiVersionValues>> {
121		match self {
122			MultiStore::Standard(store) => store.get_previous_version(key, before_version),
123		}
124	}
125}
126
127/// Iterator type for multi-version range results.
128pub type MultiVersionRangeIterator<'a> = Box<dyn Iterator<Item = Result<MultiVersionValues>> + Send + 'a>;
129
130impl MultiStore {
131	/// Create an iterator for forward range queries.
132	///
133	/// This properly handles high version density by scanning until batch_size
134	/// unique logical keys are collected. The iterator yields individual entries
135	/// and maintains cursor state internally.
136	pub fn range(
137		&self,
138		range: EncodedKeyRange,
139		version: CommitVersion,
140		batch_size: usize,
141	) -> MultiVersionRangeIterator<'_> {
142		match self {
143			MultiStore::Standard(store) => Box::new(store.range(range, version, batch_size)),
144		}
145	}
146
147	/// Create an iterator for reverse range queries.
148	///
149	/// This properly handles high version density by scanning until batch_size
150	/// unique logical keys are collected. The iterator yields individual entries
151	/// in reverse key order and maintains cursor state internally.
152	pub fn range_rev(
153		&self,
154		range: EncodedKeyRange,
155		version: CommitVersion,
156		batch_size: usize,
157	) -> MultiVersionRangeIterator<'_> {
158		match self {
159			MultiStore::Standard(store) => Box::new(store.range_rev(range, version, batch_size)),
160		}
161	}
162}
163
164// High-level trait implementations
165impl MultiVersionStore for MultiStore {}