reifydb_store_multi/tier/
mod.rs1pub mod commit;
5pub mod persistent;
6pub mod read;
7
8use std::{collections::HashMap, ops::Bound};
9
10use reifydb_core::{common::CommitVersion, encoded::key::EncodedKey, interface::store::EntryKind};
11use reifydb_value::{Result, util::cowvec::CowVec};
12
13use crate::MultiVersionScope;
14
15pub type TierBatch = HashMap<EntryKind, Vec<(EncodedKey, Option<CowVec<u8>>)>>;
16
17#[derive(Debug, Clone)]
18pub enum VersionedGetResult {
19 Value {
20 value: CowVec<u8>,
21 version: CommitVersion,
22 },
23
24 Tombstone,
25
26 NotFound,
27}
28
29impl VersionedGetResult {
30 pub fn value(self) -> Option<CowVec<u8>> {
31 match self {
32 VersionedGetResult::Value {
33 value,
34 ..
35 } => Some(value),
36 VersionedGetResult::Tombstone | VersionedGetResult::NotFound => None,
37 }
38 }
39}
40
41#[derive(Debug, Clone)]
42pub struct RawEntry {
43 pub key: EncodedKey,
44 pub version: CommitVersion,
45 pub value: Option<CowVec<u8>>,
46}
47
48#[derive(Debug, Clone)]
49pub struct RangeBatch {
50 pub entries: Vec<RawEntry>,
51
52 pub has_more: bool,
53}
54
55impl RangeBatch {
56 pub fn empty() -> Self {
57 Self {
58 entries: Vec::new(),
59 has_more: false,
60 }
61 }
62
63 pub fn is_empty(&self) -> bool {
64 self.entries.is_empty()
65 }
66}
67
68#[derive(Debug, Clone)]
69pub struct RangeCursor {
70 pub last_key: Option<EncodedKey>,
71
72 pub exhausted: bool,
73}
74
75#[derive(Debug, Clone, Default)]
76pub struct HistoricalCursor {
77 pub last_key: Option<EncodedKey>,
78 pub last_version: Option<CommitVersion>,
79 pub exhausted: bool,
80}
81
82impl HistoricalCursor {
83 pub fn new() -> Self {
84 Self::default()
85 }
86
87 pub fn is_exhausted(&self) -> bool {
88 self.exhausted
89 }
90}
91
92impl RangeCursor {
93 pub fn new() -> Self {
94 Self {
95 last_key: None,
96 exhausted: false,
97 }
98 }
99
100 pub fn is_exhausted(&self) -> bool {
101 self.exhausted
102 }
103}
104
105impl Default for RangeCursor {
106 fn default() -> Self {
107 Self::new()
108 }
109}
110
111pub trait TierStorage: Send + Sync + Clone + 'static {
112 fn get(&self, table: EntryKind, key: &[u8], version: CommitVersion) -> Result<VersionedGetResult>;
113
114 fn get_many(
115 &self,
116 table: EntryKind,
117 keys: &[&[u8]],
118 version: CommitVersion,
119 ) -> Result<Vec<VersionedGetResult>> {
120 let mut out = Vec::with_capacity(keys.len());
121 for &key in keys {
122 out.push(self.get(table, key, version)?);
123 }
124 Ok(out)
125 }
126
127 fn contains(&self, table: EntryKind, key: &[u8], version: CommitVersion) -> Result<bool> {
128 Ok(matches!(self.get(table, key, version)?, VersionedGetResult::Value { .. }))
129 }
130
131 fn set(&self, version: CommitVersion, batches: TierBatch) -> Result<()>;
132
133 fn range_next(
134 &self,
135 table: EntryKind,
136 cursor: &mut RangeCursor,
137 start: Bound<&[u8]>,
138 end: Bound<&[u8]>,
139 scope: MultiVersionScope,
140 batch_size: usize,
141 ) -> Result<RangeBatch>;
142
143 fn range_rev_next(
144 &self,
145 table: EntryKind,
146 cursor: &mut RangeCursor,
147 start: Bound<&[u8]>,
148 end: Bound<&[u8]>,
149 scope: MultiVersionScope,
150 batch_size: usize,
151 ) -> Result<RangeBatch>;
152
153 fn ensure_table(&self, table: EntryKind) -> Result<()>;
154
155 fn clear_table(&self, table: EntryKind) -> Result<()>;
156
157 fn drop(&self, batches: HashMap<EntryKind, Vec<(EncodedKey, CommitVersion)>>) -> Result<()>;
158
159 fn get_all_versions(&self, table: EntryKind, key: &[u8]) -> Result<Vec<(CommitVersion, Option<CowVec<u8>>)>>;
160
161 fn scan_historical_below(
162 &self,
163 table: EntryKind,
164 cutoff: CommitVersion,
165 cursor: &mut HistoricalCursor,
166 batch_size: usize,
167 ) -> Result<Vec<(EncodedKey, CommitVersion)>>;
168}
169
170pub trait TierBackend: TierStorage {}