Skip to main content

reifydb_store_single/
tier.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2025 ReifyDB
3
4//! Common storage tier traits and types.
5//!
6//! This module defines the minimal interface that all storage tiers (hot, warm, cold)
7//! must implement for single-version storage.
8
9use std::ops::Bound;
10
11use reifydb_type::{Result, util::cowvec::CowVec};
12
13/// A raw storage entry.
14///
15/// Value is None for tombstones (deletions).
16#[derive(Debug, Clone)]
17pub struct RawEntry {
18	pub key: CowVec<u8>,
19	pub value: Option<CowVec<u8>>,
20}
21
22/// A batch of range results with continuation info for pagination.
23#[derive(Debug, Clone)]
24pub struct RangeBatch {
25	/// The entries in this batch.
26	pub entries: Vec<RawEntry>,
27	/// Whether there are more entries after this batch.
28	pub has_more: bool,
29}
30
31impl RangeBatch {
32	/// Creates an empty batch with no more results.
33	pub fn empty() -> Self {
34		Self {
35			entries: Vec::new(),
36			has_more: false,
37		}
38	}
39
40	/// Returns true if this batch contains no entries.
41	pub fn is_empty(&self) -> bool {
42		self.entries.is_empty()
43	}
44}
45
46/// Cursor state for streaming range queries.
47///
48/// Tracks position within a range scan, enabling efficient continuation
49/// across multiple batches without re-scanning from the beginning.
50#[derive(Debug, Clone)]
51pub struct RangeCursor {
52	/// Last key seen in the previous batch (for Bound::Excluded continuation)
53	pub last_key: Option<CowVec<u8>>,
54	/// Whether this stream is exhausted
55	pub exhausted: bool,
56}
57
58impl RangeCursor {
59	/// Create a new cursor at the start of a range.
60	pub fn new() -> Self {
61		Self {
62			last_key: None,
63			exhausted: false,
64		}
65	}
66
67	/// Check if the stream is exhausted.
68	pub fn is_exhausted(&self) -> bool {
69		self.exhausted
70	}
71}
72
73impl Default for RangeCursor {
74	fn default() -> Self {
75		Self::new()
76	}
77}
78
79/// The tier storage trait for single-version storage.
80///
81/// This is intentionally minimal - just raw bytes in/out with no version history.
82/// Single-version storage maintains only the current value for each key.
83///
84/// Implementations must be thread-safe and cloneable.
85
86pub trait TierStorage: Send + Sync + Clone + 'static {
87	/// Get the value for a key, or None if not found.
88	fn get(&self, key: &[u8]) -> Result<Option<CowVec<u8>>>;
89
90	/// Check if a key exists in storage.
91	fn contains(&self, key: &[u8]) -> Result<bool> {
92		Ok(self.get(key)?.is_some())
93	}
94
95	/// Write entries atomically.
96	///
97	/// All entries are written in a single transaction.
98	/// This ensures durability and atomicity for commits.
99	fn set(&self, entries: Vec<(CowVec<u8>, Option<CowVec<u8>>)>) -> Result<()>;
100
101	/// Fetch the next batch of entries in key order (descending).
102	///
103	/// Uses the cursor to track position. On first call, cursor should be new.
104	/// On subsequent calls, pass the same cursor to continue from where left off.
105	/// Returns up to `batch_size` entries. The cursor is updated with the last
106	/// key seen, and `exhausted` is set to true when no more entries remain.
107	fn range_next(
108		&self,
109		cursor: &mut RangeCursor,
110		start: Bound<&[u8]>,
111		end: Bound<&[u8]>,
112		batch_size: usize,
113	) -> Result<RangeBatch>;
114
115	/// Fetch the next batch of entries in reverse key order (ascending).
116	///
117	/// Uses the cursor to track position. On first call, cursor should be new.
118	/// On subsequent calls, pass the same cursor to continue from where left off.
119	/// Returns up to `batch_size` entries. The cursor is updated with the last
120	/// key seen, and `exhausted` is set to true when no more entries remain.
121	fn range_rev_next(
122		&self,
123		cursor: &mut RangeCursor,
124		start: Bound<&[u8]>,
125		end: Bound<&[u8]>,
126		batch_size: usize,
127	) -> Result<RangeBatch>;
128
129	/// Ensure storage is initialized.
130	///
131	/// This may create necessary storage structures if needed.
132	fn ensure_table(&self) -> Result<()>;
133
134	/// Delete all entries in storage.
135	fn clear_table(&self) -> Result<()>;
136}
137
138/// Marker trait for storage tiers that support the tier storage interface.
139pub trait TierBackend: TierStorage {}