rushdb_storage/
overlay_view.rs1use std::collections::{BTreeMap, BTreeSet};
11use std::ops::Bound;
12use std::sync::Arc;
13
14use crate::{Op, ReadCancellation, ReadView, ScanBounds, ScanProjection, StorageError};
15
16#[derive(Clone)]
21pub struct OverlayView {
22 base: Arc<ReadView>,
23 buffer: BTreeMap<Vec<u8>, Option<Vec<u8>>>,
24 derived: std::sync::OnceLock<Result<Arc<BTreeMap<Vec<u8>, Option<Vec<u8>>>>, StorageError>>,
28}
29
30impl std::fmt::Debug for OverlayView {
31 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
32 f.debug_struct("OverlayView")
33 .field("commit_index", &self.base.commit_index())
34 .field("overlay_keys", &self.buffer.len())
35 .finish_non_exhaustive()
36 }
37}
38
39impl OverlayView {
40 #[must_use]
42 pub fn new(base: Arc<ReadView>) -> Self {
43 Self {
44 base,
45 buffer: BTreeMap::new(),
46 derived: std::sync::OnceLock::new(),
47 }
48 }
49
50 #[must_use]
52 pub fn with_buffer(base: Arc<ReadView>, buffer: BTreeMap<Vec<u8>, Option<Vec<u8>>>) -> Self {
53 Self {
54 base,
55 buffer,
56 derived: std::sync::OnceLock::new(),
57 }
58 }
59
60 fn derived_rows(&self) -> Result<Arc<BTreeMap<Vec<u8>, Option<Vec<u8>>>>, StorageError> {
63 self.derived
64 .get_or_init(|| {
65 let mut rows = BTreeMap::new();
66 if let Some(deriver) = self.base.deriver() {
67 if !self.buffer.is_empty() {
68 let ops: Vec<Op> = self
69 .buffer
70 .iter()
71 .map(|(key, value)| match value {
72 Some(value) => Op::Put(key.clone(), value.clone()),
73 None => Op::Del(key.clone()),
74 })
75 .collect();
76 crate::derive::fold(&mut rows, &deriver.derive(0, &ops, &*self.base)?);
77 }
78 }
79 Ok(Arc::new(rows))
80 })
81 .clone()
82 }
83
84 fn reaches_derived(&self, prefix: &[u8]) -> bool {
85 !self.buffer.is_empty()
86 && self
87 .base
88 .deriver()
89 .is_some_and(|deriver| deriver.prefix_reaches_derived(prefix))
90 }
91
92 #[must_use]
94 pub fn base(&self) -> &Arc<ReadView> {
95 &self.base
96 }
97
98 #[must_use]
100 pub fn buffer(&self) -> &BTreeMap<Vec<u8>, Option<Vec<u8>>> {
101 &self.buffer
102 }
103
104 #[must_use]
106 pub fn commit_index(&self) -> u64 {
107 self.base.commit_index()
108 }
109
110 #[must_use]
112 pub fn cancellation(&self) -> ReadCancellation {
113 self.base.cancellation()
114 }
115
116 pub fn put(&mut self, key: Vec<u8>, value: Vec<u8>) {
118 self.derived = std::sync::OnceLock::new();
119 self.buffer.insert(key, Some(value));
120 }
121
122 pub fn delete(&mut self, key: Vec<u8>) {
124 self.derived = std::sync::OnceLock::new();
125 self.buffer.insert(key, None);
126 }
127
128 pub fn apply_ops(&mut self, ops: &[Op]) {
131 for op in ops {
132 match op {
133 Op::Put(k, v) | Op::Set(k, v) => {
134 self.buffer.insert(k.clone(), Some(v.clone()));
135 }
136 Op::Del(k) | Op::Purge(k) => {
137 self.buffer.insert(k.clone(), None);
138 }
139 }
140 }
141 self.derived = std::sync::OnceLock::new();
142 }
143
144 pub fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>, StorageError> {
149 if let Some(value) = self.buffer.get(key) {
150 return Ok(value.clone());
151 }
152 if self.reaches_derived(key)
153 && self
154 .base
155 .deriver()
156 .is_some_and(|deriver| deriver.is_derived_key(key))
157 {
158 if let Some(value) = self.derived_rows()?.get(key) {
159 return Ok(value.clone());
160 }
161 }
162 self.base.get(key)
163 }
164
165 pub fn range_prefix(&self, prefix: &[u8]) -> Result<Vec<(Vec<u8>, Vec<u8>)>, StorageError> {
171 let mut merged: BTreeMap<Vec<u8>, Vec<u8>> =
172 self.base.range_prefix(prefix)?.into_iter().collect();
173 let derived = if self.reaches_derived(prefix) {
174 Some(self.derived_rows()?)
175 } else {
176 None
177 };
178 for (key, value) in self
179 .buffer
180 .range::<[u8], _>((Bound::Included(prefix), Bound::Unbounded))
181 .chain(derived.iter().flat_map(|rows| {
182 rows.range::<[u8], _>((Bound::Included(prefix), Bound::Unbounded))
183 }))
184 {
185 if !key.starts_with(prefix) {
186 continue;
187 }
188 match value {
189 Some(value) => {
190 merged.insert(key.clone(), value.clone());
191 }
192 None => {
193 merged.remove(key);
194 }
195 }
196 }
197 Ok(merged.into_iter().collect())
198 }
199
200 pub fn range_keys(&self, start: &[u8], end: &[u8]) -> Result<Vec<Vec<u8>>, StorageError> {
207 let bounds = ScanBounds {
208 start: Bound::Included(start.to_vec()),
209 end: if end.is_empty() {
210 Bound::Unbounded
211 } else {
212 Bound::Excluded(end.to_vec())
213 },
214 };
215 let mut keys: BTreeSet<Vec<u8>> = BTreeSet::new();
216 let mut cursor = self.base.scan(bounds, ScanProjection::Keys)?;
217 loop {
218 let batch = cursor.next_batch(1024, 8 * 1024 * 1024)?;
219 for row in batch.rows {
220 keys.insert(row.key);
221 }
222 if batch.done {
223 break;
224 }
225 }
226 let end_bound = if end.is_empty() {
227 Bound::Unbounded
228 } else {
229 Bound::Excluded(end)
230 };
231 for (key, value) in self
232 .buffer
233 .range::<[u8], _>((Bound::Included(start), end_bound))
234 {
235 match value {
236 Some(_) => {
237 keys.insert(key.clone());
238 }
239 None => {
240 keys.remove(key);
241 }
242 }
243 }
244 Ok(keys.into_iter().collect())
245 }
246
247 pub fn range(&self, start: &[u8], end: &[u8]) -> Result<Vec<(Vec<u8>, Vec<u8>)>, StorageError> {
253 let mut merged: BTreeMap<Vec<u8>, Vec<u8>> =
254 self.base.range(start, end)?.into_iter().collect();
255 let end_bound = if end.is_empty() {
256 Bound::Unbounded
257 } else {
258 Bound::Excluded(end)
259 };
260 let common = start
261 .iter()
262 .zip(end.iter())
263 .take_while(|(a, b)| a == b)
264 .count();
265 let derived = if self.reaches_derived(&start[..common]) {
266 Some(self.derived_rows()?)
267 } else {
268 None
269 };
270 for (key, value) in self
271 .buffer
272 .range::<[u8], _>((Bound::Included(start), end_bound))
273 .chain(
274 derived
275 .iter()
276 .flat_map(|rows| rows.range::<[u8], _>((Bound::Included(start), end_bound))),
277 )
278 {
279 match value {
280 Some(value) => {
281 merged.insert(key.clone(), value.clone());
282 }
283 None => {
284 merged.remove(key);
285 }
286 }
287 }
288 Ok(merged.into_iter().collect())
289 }
290}