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