1use crate::key_value::{
8 KeyPresenceVisitor, KeyValuePointVisitor, KeyValueRead, KeyValueReadKeyIterator,
9 KeyValueReadRevision,
10};
11use crate::mvcc::{DatabaseId, VersionError};
12use crate::mvcc::{MergedRecordSnapshot, VersionResult};
13use crate::read_control::{KeyReadVisitor, KeyValueReadVisitor, StorageReadControl};
14use crate::{read_control::ValueReadVisitor, StorageBackendResult};
15use uqa_core::memory::BudgetedVec;
16
17pub struct RecordRead<'a> {
19 pub(super) view: &'a MergedRecordSnapshot,
20 pub(super) database: DatabaseId,
21 pub(super) control: &'a StorageReadControl,
22}
23
24impl<'a> RecordRead<'a> {
25 pub fn new(
26 view: &'a MergedRecordSnapshot,
27 database: DatabaseId,
28 control: &'a StorageReadControl,
29 ) -> Self {
30 Self {
31 view,
32 database,
33 control,
34 }
35 }
36}
37
38impl KeyValueRead for RecordRead<'_> {
39 fn control(&self) -> &StorageReadControl {
40 self.control
41 }
42
43 fn marker_fingerprint(&self, key: &[u8]) -> StorageBackendResult<Option<[u8; 32]>> {
44 self.view
45 .marker_fingerprint(self.database, key, self.control)
46 .map(Some)
47 }
48
49 fn revision(&self, prefixes: &[&[u8]]) -> StorageBackendResult<KeyValueReadRevision> {
50 self.control.check()?;
51 let mut private = None;
52 for prefix in prefixes {
53 let mut after = BudgetedVec::new(self.control.memory());
54 loop {
55 let page = self
56 .view
57 .private_keys(
58 prefix,
59 (!after.is_empty()).then_some(&*after),
60 64,
61 self.control,
62 )
63 .map_err(VersionError::into_storage_error)?;
64 let Some(last) = page.last() else { break };
65 after.clear();
66 after.extend_from_slice(last.key())?;
67 for record in page.iter() {
68 private = private.max(Some(record.revision()));
69 }
70 }
71 }
72 Ok(KeyValueReadRevision::records(
73 self.database,
74 self.view.sequence(),
75 private,
76 ))
77 }
78
79 fn record_revision(&self, key: &[u8]) -> StorageBackendResult<Option<KeyValueReadRevision>> {
80 self.view
81 .record_revision(self.database, key, self.control)
82 .map(|revision| revision.map(KeyValueReadRevision::record))
83 .map_err(VersionError::into_storage_error)
84 }
85
86 fn retained_source(
87 &self,
88 key: &[u8],
89 ) -> StorageBackendResult<Option<std::sync::Arc<dyn KeyValueRead + Send + Sync>>> {
90 self.view
91 .retained_source(key, self.control)
92 .map_err(VersionError::into_storage_error)
93 }
94
95 fn retain(
96 &self,
97 _prefixes: &[&[u8]],
98 ) -> StorageBackendResult<std::sync::Arc<dyn KeyValueRead + Send + Sync>> {
99 self.control.check()?;
100 let memory = self
101 .control
102 .memory()
103 .reserve(std::mem::size_of::<RetainedRecordRead>())?;
104 Ok(std::sync::Arc::new(RetainedRecordRead {
105 view: self
106 .view
107 .try_clone()
108 .map_err(VersionError::into_storage_error)?,
109 database: self.database,
110 control: self.control.clone(),
111 _memory: memory,
112 }))
113 }
114
115 fn visit_value(
116 &self,
117 key: &[u8],
118 visit: &mut ValueReadVisitor<'_>,
119 ) -> StorageBackendResult<()> {
120 self.visit_value_budgeted(key, self.control, visit)
121 }
122
123 fn visit_prefix(
124 &self,
125 prefix: &[u8],
126 visit: &mut KeyValueReadVisitor<'_>,
127 ) -> StorageBackendResult<()> {
128 self.visit_prefix_after(prefix, None, usize::MAX, self.control, visit)
129 }
130
131 fn visit_value_budgeted(
132 &self,
133 key: &[u8],
134 control: &StorageReadControl,
135 visit: &mut ValueReadVisitor<'_>,
136 ) -> StorageBackendResult<()> {
137 self.view
138 .visit_value(key, control, &mut |record| {
139 visit(record.and_then(|record| record.value)).map_err(Into::into)
140 })
141 .map_err(VersionError::into_storage_error)
142 }
143
144 fn visit_values(
145 &self,
146 keys: &mut KeyValueReadKeyIterator<'_>,
147 visit: &mut KeyValuePointVisitor<'_>,
148 ) -> StorageBackendResult<()> {
149 let mut keys = keys.map(|key| key.map_err(VersionError::from));
150 self.view
151 .visit_values(&mut keys, self.control, &mut |key, record| {
152 visit(key, record.and_then(|record| record.value)).map_err(Into::into)
153 })
154 .map_err(VersionError::into_storage_error)
155 }
156
157 fn visit_key_presence(
158 &self,
159 keys: &mut KeyValueReadKeyIterator<'_>,
160 visit: &mut KeyPresenceVisitor<'_>,
161 ) -> StorageBackendResult<()> {
162 let mut selected = self.view.selected(self.control);
163 loop {
164 self.control.check()?;
165 let Some(key) = keys.next() else {
166 return Ok(());
167 };
168 let key = key?;
169 let present = selected
170 .metadata(&key, self.control)
171 .map_err(VersionError::into_storage_error)?
172 .is_some_and(|record| record.live);
173 let more = visit(&key, present)?;
174 self.control.check()?;
175 if !more {
176 return Ok(());
177 }
178 }
179 }
180
181 fn visit_value_bounded(
182 &self,
183 key: &[u8],
184 max_bytes: usize,
185 control: &StorageReadControl,
186 visit: &mut ValueReadVisitor<'_>,
187 ) -> StorageBackendResult<()> {
188 self.view
189 .visit_value_bounded(key, max_bytes, control, &mut |record| {
190 visit(record.and_then(|record| record.value)).map_err(Into::into)
191 })
192 .map_err(VersionError::into_storage_error)
193 }
194
195 fn visit_prefix_after(
196 &self,
197 prefix: &[u8],
198 after: Option<&[u8]>,
199 limit: usize,
200 control: &StorageReadControl,
201 visit: &mut KeyValueReadVisitor<'_>,
202 ) -> StorageBackendResult<()> {
203 visit_live(self.view, prefix, after, limit, control, visit)
204 .map_err(VersionError::into_storage_error)
205 }
206
207 fn visit_keys_after(
208 &self,
209 prefix: &[u8],
210 after: Option<&[u8]>,
211 limit: usize,
212 control: &StorageReadControl,
213 visit: &mut KeyReadVisitor<'_>,
214 ) -> StorageBackendResult<()> {
215 control.check()?;
216 if limit == 0 {
217 return Ok(());
218 }
219 let mut count = 0;
220 self.view
221 .visit_keys(prefix, after, usize::MAX, control, &mut |key, record| {
222 if record.live {
223 visit(key)?;
224 count += 1;
225 }
226 Ok(count < limit)
227 })
228 .map_err(VersionError::into_storage_error)
229 }
230
231 fn contains_prefix_budgeted(
232 &self,
233 prefix: &[u8],
234 control: &StorageReadControl,
235 ) -> StorageBackendResult<bool> {
236 control.check()?;
237 let mut found = false;
238 self.view
239 .visit_keys(prefix, None, usize::MAX, control, &mut |_, record| {
240 found = record.live;
241 Ok(!found)
242 })
243 .map_err(VersionError::into_storage_error)?;
244 Ok(found)
245 }
246}
247
248pub(super) fn visit_live(
249 view: &MergedRecordSnapshot,
250 prefix: &[u8],
251 after: Option<&[u8]>,
252 limit: usize,
253 control: &StorageReadControl,
254 visit: &mut KeyValueReadVisitor<'_>,
255) -> VersionResult<()> {
256 control.cancellation().check()?;
257 if limit == 0 {
258 return Ok(());
259 }
260 let mut count = 0;
261 view.visit_prefix(prefix, after, usize::MAX, control, &mut |key, record| {
262 if let Some(value) = record.value {
263 visit(key, value)?;
264 count += 1;
265 }
266 Ok(count < limit)
267 })
268}
269
270struct RetainedRecordRead {
271 view: MergedRecordSnapshot,
272 database: DatabaseId,
273 control: StorageReadControl,
274 _memory: uqa_core::memory::MemoryReservation,
275}
276impl RetainedRecordRead {
277 fn read(&self) -> RecordRead<'_> {
278 RecordRead {
279 view: &self.view,
280 database: self.database,
281 control: &self.control,
282 }
283 }
284}
285impl KeyValueRead for RetainedRecordRead {
286 fn control(&self) -> &StorageReadControl {
287 &self.control
288 }
289 fn marker_fingerprint(&self, key: &[u8]) -> StorageBackendResult<Option<[u8; 32]>> {
290 self.read().marker_fingerprint(key)
291 }
292 fn revision(&self, prefixes: &[&[u8]]) -> StorageBackendResult<KeyValueReadRevision> {
293 self.read().revision(prefixes)
294 }
295 fn record_revision(&self, key: &[u8]) -> StorageBackendResult<Option<KeyValueReadRevision>> {
296 self.read().record_revision(key)
297 }
298 fn retained_source(
299 &self,
300 key: &[u8],
301 ) -> StorageBackendResult<Option<std::sync::Arc<dyn KeyValueRead + Send + Sync>>> {
302 self.read().retained_source(key)
303 }
304 fn retain(
305 &self,
306 prefixes: &[&[u8]],
307 ) -> StorageBackendResult<std::sync::Arc<dyn KeyValueRead + Send + Sync>> {
308 self.read().retain(prefixes)
309 }
310 fn visit_value(
311 &self,
312 key: &[u8],
313 visit: &mut ValueReadVisitor<'_>,
314 ) -> StorageBackendResult<()> {
315 self.read().visit_value(key, visit)
316 }
317 fn visit_prefix(
318 &self,
319 prefix: &[u8],
320 visit: &mut KeyValueReadVisitor<'_>,
321 ) -> StorageBackendResult<()> {
322 self.read().visit_prefix(prefix, visit)
323 }
324 fn visit_values(
325 &self,
326 keys: &mut KeyValueReadKeyIterator<'_>,
327 visit: &mut KeyValuePointVisitor<'_>,
328 ) -> StorageBackendResult<()> {
329 self.read().visit_values(keys, visit)
330 }
331 fn visit_key_presence(
332 &self,
333 keys: &mut KeyValueReadKeyIterator<'_>,
334 visit: &mut KeyPresenceVisitor<'_>,
335 ) -> StorageBackendResult<()> {
336 self.read().visit_key_presence(keys, visit)
337 }
338 fn visit_value_budgeted(
339 &self,
340 key: &[u8],
341 control: &StorageReadControl,
342 visit: &mut ValueReadVisitor<'_>,
343 ) -> StorageBackendResult<()> {
344 self.read().visit_value_budgeted(key, control, visit)
345 }
346 fn visit_value_bounded(
347 &self,
348 key: &[u8],
349 max_bytes: usize,
350 control: &StorageReadControl,
351 visit: &mut ValueReadVisitor<'_>,
352 ) -> StorageBackendResult<()> {
353 self.read()
354 .visit_value_bounded(key, max_bytes, control, visit)
355 }
356 fn visit_prefix_after(
357 &self,
358 prefix: &[u8],
359 after: Option<&[u8]>,
360 limit: usize,
361 control: &StorageReadControl,
362 visit: &mut KeyValueReadVisitor<'_>,
363 ) -> StorageBackendResult<()> {
364 self.read()
365 .visit_prefix_after(prefix, after, limit, control, visit)
366 }
367 fn contains_prefix_budgeted(
368 &self,
369 prefix: &[u8],
370 control: &StorageReadControl,
371 ) -> StorageBackendResult<bool> {
372 self.read().contains_prefix_budgeted(prefix, control)
373 }
374
375 fn visit_keys_after(
376 &self,
377 prefix: &[u8],
378 after: Option<&[u8]>,
379 limit: usize,
380 control: &StorageReadControl,
381 visit: &mut KeyReadVisitor<'_>,
382 ) -> StorageBackendResult<()> {
383 self.read()
384 .visit_keys_after(prefix, after, limit, control, visit)
385 }
386}