reifydb_store_multi/tier/commit/
buffer.rs1use std::{collections::HashMap, ops::Bound};
5
6use reifydb_core::{common::CommitVersion, encoded::key::EncodedKey, interface::store::EntryKind};
7use reifydb_value::{Result, util::cowvec::CowVec};
8
9use crate::{
10 MultiVersionScope,
11 tier::{
12 HistoricalCursor, RangeBatch, RangeCursor, TierBackend, TierBatch, TierStorage, VersionedGetResult,
13 commit::memory::storage::MemoryPrimitiveStorage,
14 },
15};
16
17#[derive(Clone)]
18#[repr(u8)]
19pub enum MultiCommitBufferTier {
20 Memory(MemoryPrimitiveStorage) = 0,
21}
22
23impl MultiCommitBufferTier {
24 pub fn memory() -> Self {
25 Self::Memory(MemoryPrimitiveStorage::new())
26 }
27}
28
29impl MultiCommitBufferTier {
30 pub fn maintenance(&self) {
31 match self {
32 Self::Memory(_) => {}
33 }
34 }
35
36 pub fn count_current(&self, table: EntryKind) -> Result<u64> {
37 match self {
38 Self::Memory(s) => s.count_current(table),
39 }
40 }
41
42 pub fn count_historical(&self, table: EntryKind) -> Result<u64> {
43 match self {
44 Self::Memory(s) => s.count_historical(table),
45 }
46 }
47
48 pub fn list_all_entry_kinds(&self) -> Result<Vec<EntryKind>> {
49 match self {
50 Self::Memory(s) => s.list_all_entry_kinds(),
51 }
52 }
53}
54
55impl TierStorage for MultiCommitBufferTier {
56 #[inline]
57 fn get(&self, table: EntryKind, key: &[u8], version: CommitVersion) -> Result<VersionedGetResult> {
58 match self {
59 Self::Memory(s) => s.get(table, key, version),
60 }
61 }
62
63 #[inline]
64 fn contains(&self, table: EntryKind, key: &[u8], version: CommitVersion) -> Result<bool> {
65 match self {
66 Self::Memory(s) => s.contains(table, key, version),
67 }
68 }
69
70 #[inline]
71 fn set(&self, version: CommitVersion, batches: TierBatch) -> Result<()> {
72 match self {
73 Self::Memory(s) => s.set(version, batches),
74 }
75 }
76
77 #[inline]
78 fn range_next(
79 &self,
80 table: EntryKind,
81 cursor: &mut RangeCursor,
82 start: Bound<&[u8]>,
83 end: Bound<&[u8]>,
84 scope: MultiVersionScope,
85 batch_size: usize,
86 ) -> Result<RangeBatch> {
87 match self {
88 Self::Memory(s) => s.range_next(table, cursor, start, end, scope, batch_size),
89 }
90 }
91
92 #[inline]
93 fn range_rev_next(
94 &self,
95 table: EntryKind,
96 cursor: &mut RangeCursor,
97 start: Bound<&[u8]>,
98 end: Bound<&[u8]>,
99 scope: MultiVersionScope,
100 batch_size: usize,
101 ) -> Result<RangeBatch> {
102 match self {
103 Self::Memory(s) => s.range_rev_next(table, cursor, start, end, scope, batch_size),
104 }
105 }
106
107 #[inline]
108 fn ensure_table(&self, table: EntryKind) -> Result<()> {
109 match self {
110 Self::Memory(s) => s.ensure_table(table),
111 }
112 }
113
114 #[inline]
115 fn clear_table(&self, table: EntryKind) -> Result<()> {
116 match self {
117 Self::Memory(s) => s.clear_table(table),
118 }
119 }
120
121 #[inline]
122 fn drop(&self, batches: HashMap<EntryKind, Vec<(EncodedKey, CommitVersion)>>) -> Result<()> {
123 match self {
124 Self::Memory(s) => s.drop(batches),
125 }
126 }
127
128 #[inline]
129 fn get_all_versions(&self, table: EntryKind, key: &[u8]) -> Result<Vec<(CommitVersion, Option<CowVec<u8>>)>> {
130 match self {
131 Self::Memory(s) => s.get_all_versions(table, key),
132 }
133 }
134
135 #[inline]
136 fn scan_historical_below(
137 &self,
138 table: EntryKind,
139 cutoff: CommitVersion,
140 cursor: &mut HistoricalCursor,
141 batch_size: usize,
142 ) -> Result<Vec<(EncodedKey, CommitVersion)>> {
143 match self {
144 Self::Memory(s) => s.scan_historical_below(table, cutoff, cursor, batch_size),
145 }
146 }
147}
148
149impl TierBackend for MultiCommitBufferTier {}
150
151#[cfg(test)]
152pub mod tests {
153 use super::*;
154
155 #[test]
156 fn test_memory_backend() {
157 let storage = MultiCommitBufferTier::memory();
158
159 let key = EncodedKey::new(b"key".to_vec());
160 let version = CommitVersion(1);
161
162 storage.set(
163 version,
164 HashMap::from([(EntryKind::Multi, vec![(key.clone(), Some(CowVec::new(b"value".to_vec())))])]),
165 )
166 .unwrap();
167 assert_eq!(
168 storage.get(EntryKind::Multi, &key, version).unwrap().value().as_deref(),
169 Some(b"value".as_slice())
170 );
171 }
172
173 #[test]
174 fn test_range_next_memory() {
175 let storage = MultiCommitBufferTier::memory();
176
177 let version = CommitVersion(1);
178 storage.set(
179 version,
180 HashMap::from([(
181 EntryKind::Multi,
182 vec![
183 (EncodedKey::new(b"a".to_vec()), Some(CowVec::new(b"1".to_vec()))),
184 (EncodedKey::new(b"b".to_vec()), Some(CowVec::new(b"2".to_vec()))),
185 (EncodedKey::new(b"c".to_vec()), Some(CowVec::new(b"3".to_vec()))),
186 ],
187 )]),
188 )
189 .unwrap();
190
191 let mut cursor = RangeCursor::new();
192 let batch = storage
193 .range_next(
194 EntryKind::Multi,
195 &mut cursor,
196 Bound::Unbounded,
197 Bound::Unbounded,
198 MultiVersionScope::AsOf {
199 read: version,
200 },
201 100,
202 )
203 .unwrap();
204
205 assert_eq!(batch.entries.len(), 3);
206 assert!(!batch.has_more);
207 assert!(cursor.exhausted);
208 }
209}