Skip to main content

reifydb_store_multi/
lib.rs

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