Skip to main content

reifydb_core/interface/
store.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2025 ReifyDB
3
4use reifydb_type::{Result, util::cowvec::CowVec};
5
6use crate::{
7	common::CommitVersion,
8	delta::Delta,
9	encoded::{
10		key::{EncodedKey, EncodedKeyRange},
11		row::EncodedRow,
12	},
13	interface::catalog::{flow::FlowNodeId, shape::ShapeId},
14};
15
16/// Identifies which storage tier data resides in.
17#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18pub enum Tier {
19	Hot,
20	Warm,
21	Cold,
22}
23
24/// Identifies a logical table/namespace in storage.
25///
26/// The store layer routes keys to the appropriate storage based on key type.
27#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
28pub enum EntryKind {
29	/// Multi-version storage for general data
30	Multi,
31	/// Per-source table for row data
32	Source(ShapeId),
33	/// Per-operator table for flow node state
34	Operator(FlowNodeId),
35}
36
37#[derive(Debug, Clone)]
38pub struct MultiVersionRow {
39	pub key: EncodedKey,
40	pub row: EncodedRow,
41	pub version: CommitVersion,
42}
43
44#[derive(Debug, Clone)]
45pub struct SingleVersionRow {
46	pub key: EncodedKey,
47	pub row: EncodedRow,
48}
49
50/// A batch of multi-version range results with continuation info.
51#[derive(Debug, Clone)]
52pub struct MultiVersionBatch {
53	/// The values in this batch.
54	pub items: Vec<MultiVersionRow>,
55	/// Whether there are more items after this batch.
56	pub has_more: bool,
57}
58
59impl MultiVersionBatch {
60	/// Creates an empty batch with no more results.
61	pub fn empty() -> Self {
62		Self {
63			items: Vec::new(),
64			has_more: false,
65		}
66	}
67
68	/// Returns true if this batch contains no items.
69	pub fn is_empty(&self) -> bool {
70		self.items.is_empty()
71	}
72}
73
74/// Trait for committing deltas to multi-version storage.
75pub trait MultiVersionCommit: Send + Sync {
76	/// Commit a batch of deltas at the given version.
77	fn commit(&self, deltas: CowVec<Delta>, version: CommitVersion) -> Result<()>;
78}
79
80/// Trait for getting values from multi-version storage.
81pub trait MultiVersionGet: Send + Sync {
82	/// Get the value for a key at a specific version.
83	fn get(&self, key: &EncodedKey, version: CommitVersion) -> Result<Option<MultiVersionRow>>;
84}
85
86/// Trait for checking key existence in multi-version storage.
87pub trait MultiVersionContains: Send + Sync {
88	/// Check if a key exists at a specific version.
89	fn contains(&self, key: &EncodedKey, version: CommitVersion) -> Result<bool>;
90}
91
92/// Trait for getting the previous version of a key before a given version.
93///
94/// This trait allows looking up what value existed for a key before a specific version,
95/// which is essential for CDC (Change Data Capture) to determine if a change is an
96/// Insert, Update, or Delete.
97pub trait MultiVersionGetPrevious: Send + Sync {
98	/// Get the previous version of a key before the given version.
99	///
100	/// # Arguments
101	/// * `key` - The encoded key to look up
102	/// * `before_version` - Look for versions strictly before this version
103	///
104	/// # Returns
105	/// * `Ok(Some(values))` - Found a previous version with its value
106	/// * `Ok(None)` - No previous version exists (this is the first version)
107	/// * `Err(_)` - Lookup failed
108	fn get_previous_version(
109		&self,
110		key: &EncodedKey,
111		before_version: CommitVersion,
112	) -> Result<Option<MultiVersionRow>>;
113}
114
115/// Composite trait for multi-version storage capabilities.
116pub trait MultiVersionStore:
117	Send + Sync + Clone + MultiVersionCommit + MultiVersionGet + MultiVersionGetPrevious + MultiVersionContains + 'static
118{
119}
120
121/// A batch of single-version range results with continuation info.
122#[derive(Debug, Clone)]
123pub struct SingleVersionBatch {
124	/// The values in this batch.
125	pub items: Vec<SingleVersionRow>,
126	/// Whether there are more items after this batch.
127	pub has_more: bool,
128}
129
130impl SingleVersionBatch {
131	/// Creates an empty batch with no more results.
132	pub fn empty() -> Self {
133		Self {
134			items: Vec::new(),
135			has_more: false,
136		}
137	}
138
139	/// Returns true if this batch contains no items.
140	pub fn is_empty(&self) -> bool {
141		self.items.is_empty()
142	}
143}
144
145/// Trait for committing deltas to single-version storage.
146pub trait SingleVersionCommit: Send + Sync {
147	/// Commit a batch of deltas.
148	fn commit(&mut self, deltas: CowVec<Delta>) -> Result<()>;
149}
150
151/// Trait for getting values from single-version storage.
152pub trait SingleVersionGet: Send + Sync {
153	/// Get the value for a key.
154	fn get(&self, key: &EncodedKey) -> Result<Option<SingleVersionRow>>;
155}
156
157/// Trait for checking key existence in single-version storage.
158pub trait SingleVersionContains: Send + Sync {
159	/// Check if a key exists.
160	fn contains(&self, key: &EncodedKey) -> Result<bool>;
161}
162
163/// Trait for setting values in single-version storage.
164pub trait SingleVersionSet: SingleVersionCommit {
165	/// Set a value for a key.
166	fn set(&mut self, key: &EncodedKey, row: EncodedRow) -> Result<()> {
167		Self::commit(
168			self,
169			CowVec::new(vec![Delta::Set {
170				key: key.clone(),
171				row: row.clone(),
172			}]),
173		)
174	}
175}
176
177/// Trait for removing values from single-version storage.
178pub trait SingleVersionRemove: SingleVersionCommit {
179	/// Unset a key, preserving the deleted values for CDC and metrics.
180	fn unset(&mut self, key: &EncodedKey, row: EncodedRow) -> Result<()> {
181		Self::commit(
182			self,
183			CowVec::new(vec![Delta::Unset {
184				key: key.clone(),
185				row,
186			}]),
187		)
188	}
189
190	/// Remove a key without preserving the deleted values.
191	fn remove(&mut self, key: &EncodedKey) -> Result<()> {
192		Self::commit(
193			self,
194			CowVec::new(vec![Delta::Remove {
195				key: key.clone(),
196			}]),
197		)
198	}
199}
200
201/// Trait for forward range queries with batch-fetch pattern.
202pub trait SingleVersionRange: Send + Sync {
203	/// Fetch a batch of values in key order (ascending).
204	fn range_batch(&self, range: EncodedKeyRange, batch_size: u64) -> Result<SingleVersionBatch>;
205
206	/// Convenience method with default batch size.
207	fn range(&self, range: EncodedKeyRange) -> Result<SingleVersionBatch> {
208		self.range_batch(range, 1024)
209	}
210
211	/// Range query with prefix.
212	fn prefix(&self, prefix: &EncodedKey) -> Result<SingleVersionBatch> {
213		self.range(EncodedKeyRange::prefix(prefix))
214	}
215}
216
217/// Trait for reverse range queries with batch-fetch pattern.
218pub trait SingleVersionRangeRev: Send + Sync {
219	/// Fetch a batch of values in reverse key order (descending).
220	fn range_rev_batch(&self, range: EncodedKeyRange, batch_size: u64) -> Result<SingleVersionBatch>;
221
222	/// Convenience method with default batch size.
223	fn range_rev(&self, range: EncodedKeyRange) -> Result<SingleVersionBatch> {
224		self.range_rev_batch(range, 1024)
225	}
226
227	/// Reverse range query with prefix.
228	fn prefix_rev(&self, prefix: &EncodedKey) -> Result<SingleVersionBatch> {
229		self.range_rev(EncodedKeyRange::prefix(prefix))
230	}
231}
232
233/// Composite trait for single-version storage capabilities.
234pub trait SingleVersionStore:
235	Send
236	+ Sync
237	+ Clone
238	+ SingleVersionCommit
239	+ SingleVersionGet
240	+ SingleVersionContains
241	+ SingleVersionSet
242	+ SingleVersionRemove
243	+ SingleVersionRange
244	+ SingleVersionRangeRev
245	+ 'static
246{
247}