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