1mod batch;
10mod evaluation;
11mod notifications;
12mod observed;
13mod read;
14pub use read::RecordRead;
15mod sequence_values;
16pub use sequence_values::SequencePublicationLease;
17mod serializable;
18pub use serializable::{
19 SerializableReadContext, SerializableSession, SerializableSnapshotCapture,
20 SerializableSnapshotOptions,
21};
22mod transaction;
23mod vector_fields;
24pub use vector_fields::VectorFieldGuardMaintenance;
25
26use std::sync::Arc;
27
28use parking_lot::{Mutex, MutexGuard};
29
30use crate::read_control::{KeyValueReadVisitor, StorageReadControl, ValueReadVisitor};
31use crate::{
32 KeyValueBatch, KeyValueStore, PersistentStorageIdentity, StorageBackendError,
33 StorageBackendResult, StorageSessionAffinity,
34};
35
36use super::{
37 CommitFailure, MergedRecordSnapshot, StorageTransactionId, VersionError, VersionResult,
38 VersionedPersistence,
39};
40use transaction::Transaction;
41
42#[derive(Debug, Clone, Copy)]
44pub struct VersionedSessionOptions {
45 pub retained_bytes: usize,
46}
47
48impl Default for VersionedSessionOptions {
49 fn default() -> Self {
50 Self {
51 retained_bytes: 64 * 1024 * 1024,
52 }
53 }
54}
55
56pub struct VersionedKeyValueStore {
58 affinity: StorageSessionAffinity,
59 persistence: Arc<dyn VersionedPersistence>,
60 identity: Option<PersistentStorageIdentity>,
61 options: VersionedSessionOptions,
62 control: StorageReadControl,
63 write_cancellation: uqa_core::CancellationToken,
64 retained: Option<MergedRecordSnapshot>,
65 active: Mutex<Option<Transaction>>,
66 observed: Mutex<observed::ObservedWatermarks>,
67 latest: Mutex<Option<(u64, super::CommitSequence)>>,
69 completed: Mutex<Option<super::CommitReceipt>>,
70 sequence_durability: Arc<sequence_values::SequenceDurability>,
72 sequence_generation: Option<u64>,
73}
74
75impl VersionedKeyValueStore {
76 fn evaluate_mutation(
77 &self,
78 operation: &mut crate::key_value::KeyValueMutation<'_>,
79 prefixes: Option<&[&[u8]]>,
80 ) -> StorageBackendResult<Option<crate::key_value::KeyValueReadRevision>> {
81 self.control.check()?;
82 let ((identity, sequence), receipt) = self.write_with_receipt(|transaction| {
83 let view = transaction.view()?;
84 let read = read::RecordRead {
85 view: &view,
86 database: self.persistence.database_id(),
87 control: &self.control,
88 };
89 let mut batch = batch::Batch::new(
90 self,
91 transaction
92 .serializable_context()
93 .map(SerializableReadContext::id),
94 );
95 operation(&read, &mut batch)?;
96 self.control.check()?;
97 batch.apply(transaction)?;
98 let identity = prefixes.and_then(|prefixes| {
100 let staged = transaction.view().ok()?;
101 crate::key_value::KeyValueRead::revision(
102 &read::RecordRead {
103 view: &staged,
104 database: self.persistence.database_id(),
105 control: &self.control,
106 },
107 prefixes,
108 )
109 .ok()
110 });
111 Ok((identity, view.sequence()))
112 })?;
113 Ok(match (identity, receipt) {
114 (Some(_), Some(receipt)) if sequence.successor().ok() == Some(receipt.sequence) => {
116 Some(crate::key_value::KeyValueReadRevision::records(
117 self.persistence.database_id(),
118 receipt.sequence,
119 None,
120 ))
121 }
122 (identity, _) => identity,
123 })
124 }
125 pub fn with_versioned_record_mutation<T>(
127 &self,
128 operation: impl FnOnce(
129 super::StorageMutationOrigin,
130 MergedRecordSnapshot,
131 &mut dyn KeyValueBatch,
132 ) -> StorageBackendResult<T>,
133 ) -> StorageBackendResult<T> {
134 self.control.check()?;
135 self.write(|transaction| {
136 let origin = transaction.mutation_origin(&*self.persistence, &self.write_control())?;
137 let view = transaction.view()?;
138 let mut batch = batch::Batch::new(
139 self,
140 transaction
141 .serializable_context()
142 .map(SerializableReadContext::id),
143 );
144 let result = operation(origin, view, &mut batch)?;
145 self.control.check()?;
146 batch.apply(transaction)?;
147 Ok(result)
148 })
149 }
150
151 pub fn reclaim_versions(&self) -> StorageBackendResult<u64> {
153 let control = self.write_control();
154 VectorFieldGuardMaintenance::run(self, &control)?;
155 let removed = self
156 .persistence
157 .reclaim_versions(&control)
158 .map_err(VersionError::into_storage_error)?;
159 self.persistence
160 .reclaim_diskann_tombstones(&control)
161 .map_err(VersionError::into_storage_error)?;
162 Ok(removed)
163 }
164
165 pub fn identifier_watermark(&self, namespace: &[u8]) -> StorageBackendResult<Option<u64>> {
167 self.persistence
168 .identifier_watermark(namespace, &self.control)
169 .map_err(VersionError::into_storage_error)
170 }
171
172 pub fn allocate_identifiers(
174 &self,
175 namespace: &[u8],
176 request: super::IdentifierRequest,
177 ) -> StorageBackendResult<super::IdentifierAllocation> {
178 let _active = self.admit_identifier_allocation()?;
179 self.allocate_admitted_identifiers(namespace, request)
180 }
181
182 pub fn observe_identifier(
184 &self,
185 namespace: &[u8],
186 value: u64,
187 ) -> StorageBackendResult<super::ObservedIdentifier> {
188 let _active = self.admit_identifier_allocation()?;
189 if self.observed.lock().covers(namespace, value) {
190 return Ok(super::ObservedIdentifier::Covered);
191 }
192 self.allocate_admitted_identifiers(namespace, super::IdentifierRequest::Observe(value))
193 .map(|allocation| super::ObservedIdentifier::Observed {
194 previous: allocation.previous(),
195 })
196 }
197
198 fn admit_identifier_allocation(
200 &self,
201 ) -> StorageBackendResult<MutexGuard<'_, Option<Transaction>>> {
202 self.require_mutable_session()?;
203 let active = self.active.lock();
204 if let Some(transaction) = active.as_ref() {
205 transaction
206 .writable()
207 .map_err(VersionError::into_storage_error)?;
208 }
209 Ok(active)
210 }
211
212 fn allocate_admitted_identifiers(
213 &self,
214 namespace: &[u8],
215 request: super::IdentifierRequest,
216 ) -> StorageBackendResult<super::IdentifierAllocation> {
217 let allocation = self
218 .persistence
219 .allocate_identifiers(namespace, request, &self.write_control())
220 .map_err(VersionError::into_storage_error)?;
221 self.observed
223 .lock()
224 .record(namespace, allocation.watermark());
225 Ok(allocation)
226 }
227
228 pub fn new(
229 persistence: Arc<dyn VersionedPersistence>,
230 identity: Option<PersistentStorageIdentity>,
231 options: VersionedSessionOptions,
232 ) -> Self {
233 Self::new_with_cancellation(
234 persistence,
235 identity,
236 options,
237 uqa_core::CancellationToken::new(),
238 )
239 }
240
241 pub fn new_with_cancellation(
243 persistence: Arc<dyn VersionedPersistence>,
244 identity: Option<PersistentStorageIdentity>,
245 options: VersionedSessionOptions,
246 write_cancellation: uqa_core::CancellationToken,
247 ) -> Self {
248 Self {
249 affinity: StorageSessionAffinity::new(),
250 persistence,
251 identity,
252 options,
253 control: StorageReadControl::with_limit(options.retained_bytes),
254 write_cancellation,
255 retained: None,
256 active: Mutex::new(None),
257 observed: Mutex::default(),
258 latest: Mutex::new(None),
259 completed: Mutex::new(None),
260 sequence_durability: Arc::default(),
261 sequence_generation: None,
262 }
263 }
264
265 pub fn new_session(&self) -> Self {
267 Self::new(
268 Arc::clone(&self.persistence),
269 self.identity.clone(),
270 self.options,
271 )
272 }
273
274 pub fn new_session_with_cancellation(
276 &self,
277 cancellation: &uqa_core::CancellationToken,
278 ) -> Self {
279 Self::new_with_cancellation(
280 Arc::clone(&self.persistence),
281 self.identity.clone(),
282 self.options,
283 cancellation.clone(),
284 )
285 }
286
287 pub fn new_controlled_session(&self, control: &StorageReadControl) -> Self {
289 let mut session = self.new_session_with_cancellation(control.cancellation());
290 session.control = StorageReadControl::new(control.memory(), session.control.cancellation());
291 session
292 }
293
294 pub fn new_retained_read_session(
296 &self,
297 cancellation: &uqa_core::CancellationToken,
298 ) -> StorageBackendResult<Self> {
299 cancellation.check()?;
300 let active = self.active.lock();
301 let retained = self
302 .view_locked(active.as_ref())
303 .map_err(VersionError::into_storage_error)?;
304 let mut session = self.new_session_with_cancellation(cancellation);
305 session.control =
306 StorageReadControl::new(self.control.memory(), session.control.cancellation());
307 session.retained = Some(retained);
308 session.sequence_durability = Arc::clone(&self.sequence_durability);
309 session.sequence_generation = Some(
310 self.sequence_generation
311 .unwrap_or_else(|| self.sequence_durability.generation()),
312 );
313 Ok(session)
314 }
315
316 fn require_mutable_session(&self) -> StorageBackendResult<()> {
317 if self.retained.is_some() {
318 return Err(StorageBackendError::Other(
319 "cannot write through a retained read-only session".into(),
320 ));
321 }
322 Ok(())
323 }
324
325 fn write_control(&self) -> StorageReadControl {
326 StorageReadControl::new(self.control.memory(), &self.write_cancellation)
327 }
328
329 pub fn committed_data_revision(&self) -> Option<crate::CommittedDataRevision> {
331 let receipt = self.completed_commit()?;
332 self.persistence
333 .commit_preserves_catalog_definitions(receipt)
334 .then(|| crate::CommittedDataRevision::from_receipt(receipt))
335 }
336
337 pub fn options(&self) -> VersionedSessionOptions {
338 self.options
339 }
340
341 pub fn record_snapshot(&self) -> VersionResult<MergedRecordSnapshot> {
343 self.view()
344 }
345
346 pub fn refresh_transaction_snapshot(
348 &self,
349 cancellation: &uqa_core::CancellationToken,
350 ) -> StorageBackendResult<()> {
351 cancellation.check()?;
352 let control = StorageReadControl::new(self.control.memory(), cancellation);
353 let mut active = self.active.lock();
354 if self.retained.is_some() {
355 active.as_ref().ok_or_else(no_transaction)?;
356 return Ok(());
357 }
358 active
359 .as_mut()
360 .ok_or_else(no_transaction)?
361 .refresh(&*self.persistence, &control)
362 .map_err(VersionError::into_storage_error)
363 }
364
365 pub fn retention_control(&self) -> StorageReadControl {
367 self.control.clone()
368 }
369
370 pub fn session_affinity(&self) -> StorageSessionAffinity {
371 self.affinity.clone()
372 }
373
374 pub fn pending_commit(&self) -> Option<StorageTransactionId> {
376 self.active
377 .lock()
378 .as_ref()
379 .and_then(Transaction::pending_commit)
380 }
381
382 pub fn pending_transaction_completion(&self) -> Option<super::TransactionOutcomeId> {
384 self.active
385 .lock()
386 .as_ref()
387 .and_then(Transaction::pending_completion)
388 }
389
390 pub fn establish_serializable_snapshot(&self) -> StorageBackendResult<SerializableReadContext> {
392 self.require_mutable_session()?;
393 self.active
394 .lock()
395 .as_mut()
396 .ok_or_else(no_transaction)?
397 .establish_serializable(&self.persistence, &self.write_control())
398 .map_err(VersionError::into_storage_error)
399 }
400
401 pub fn observe_serializable_write(
403 &self,
404 predicate: super::SerializablePredicate<'_>,
405 ) -> StorageBackendResult<()> {
406 let mut active = self.active.lock();
407 let transaction = active.as_mut().ok_or_else(no_transaction)?;
408 transaction
409 .writable()
410 .map_err(VersionError::into_storage_error)?;
411 let context = transaction.serializable_context().ok_or_else(|| {
412 StorageBackendError::Other("no serializable participant in this session".into())
413 })?;
414 let control = self.write_control();
415 context
416 .with_graph(&control, |graph| {
417 graph.observe_write(context.id(), predicate, &control)
418 })
419 .map_err(VersionError::into_storage_error)
420 }
421
422 fn begin(&self, read_only: bool) -> StorageBackendResult<()> {
423 if !read_only {
424 self.require_mutable_session()?;
425 }
426 let mut active = self.active.lock();
427 if active.is_some() {
428 return Err(StorageBackendError::Other(
429 "a KeyValue transaction is already active".into(),
430 ));
431 }
432 *self.completed.lock() = None;
433 let transaction = match self.retained.as_ref() {
434 Some(view) => Transaction::at_snapshot(view.retain_committed(), true, &self.control),
435 None => self
436 .capture(read_only)
437 .map_err(VersionError::into_storage_error)?,
438 };
439 if self.retained.is_none() {
440 self.sequence_durability.begin()?;
441 }
442 *active = Some(transaction);
443 Ok(())
444 }
445
446 fn capture(&self, read_only: bool) -> VersionResult<Transaction> {
448 let transaction = Transaction::new(&*self.persistence, read_only, &self.control)?;
449 *self.latest.lock() = transaction.captured();
450 Ok(transaction)
451 }
452
453 fn latest_sequence(&self) -> VersionResult<super::CommitSequence> {
455 if let Some(monitor) = self.persistence.commit_monitor_version()? {
456 if let Some((_, sequence)) = self
457 .latest
458 .lock()
459 .filter(|(captured_at, _)| *captured_at == monitor)
460 {
461 return Ok(sequence);
462 }
463 }
464 Ok(self.capture(true)?.view()?.sequence())
465 }
466
467 fn view(&self) -> VersionResult<MergedRecordSnapshot> {
468 self.view_locked(self.active.lock().as_ref())
469 }
470
471 fn view_locked(&self, active: Option<&Transaction>) -> VersionResult<MergedRecordSnapshot> {
472 if let Some(view) = self.retained.as_ref() {
473 return view.try_clone();
474 }
475 if let Some(transaction) = active {
476 transaction.view()
477 } else {
478 self.capture(true)?.view()
479 }
480 }
481
482 fn write<T>(
483 &self,
484 operation: impl FnOnce(&mut Transaction) -> VersionResult<T>,
485 ) -> StorageBackendResult<T> {
486 self.write_with_receipt(operation).map(|(value, _)| value)
487 }
488
489 fn write_with_receipt<T>(
490 &self,
491 operation: impl FnOnce(&mut Transaction) -> VersionResult<T>,
492 ) -> StorageBackendResult<(T, Option<super::CommitReceipt>)> {
493 self.require_mutable_session()?;
494 let mut active = self.active.lock();
495 if let Some(transaction) = active.as_mut() {
496 return transaction
497 .atomic(operation)
498 .map(|value| (value, None))
499 .map_err(VersionError::into_storage_error);
500 }
501 *self.completed.lock() = None;
502 let transaction = Transaction::new(&*self.persistence, false, &self.control)
503 .map_err(VersionError::into_storage_error)?;
504 let result = self.evaluate_autocommit(&mut active, transaction, operation)?;
505 active
506 .as_mut()
507 .expect("retained attempt")
508 .commit(&*self.persistence, &self.write_control())?;
509 active
510 .as_ref()
511 .expect("retained attempt")
512 .acknowledge_completion(&*self.persistence, &self.control)?;
513 let receipt = active.as_ref().and_then(Transaction::committed_receipt);
514 *self.completed.lock() = receipt;
515 *active = None;
516 Ok((result, receipt))
517 }
518
519 fn savepoint_action(
520 &self,
521 operation: impl FnOnce(&mut Transaction) -> VersionResult<()>,
522 ) -> StorageBackendResult<()> {
523 let mut active = self.active.lock();
524 let transaction = active.as_mut().ok_or_else(no_transaction)?;
525 transaction
526 .unsealed()
527 .map_err(VersionError::into_storage_error)?;
528 operation(transaction).map_err(VersionError::into_storage_error)
529 }
530}
531
532impl super::IdentifierAllocator for VersionedKeyValueStore {
533 fn identifier_watermark(&self, namespace: &[u8]) -> StorageBackendResult<Option<u64>> {
534 Self::identifier_watermark(self, namespace)
535 }
536
537 fn allocate_identifiers(
538 &self,
539 namespace: &[u8],
540 request: super::IdentifierRequest,
541 ) -> StorageBackendResult<super::IdentifierAllocation> {
542 Self::allocate_identifiers(self, namespace, request)
543 }
544
545 fn observe_identifier(
546 &self,
547 namespace: &[u8],
548 value: u64,
549 ) -> StorageBackendResult<super::ObservedIdentifier> {
550 Self::observe_identifier(self, namespace, value)
551 }
552}
553
554impl KeyValueStore for VersionedKeyValueStore {
555 fn resource_leases(&self) -> Option<&dyn super::ResourceLeaseProvider> {
556 self.persistence.resource_leases()
557 }
558
559 fn retention_control(&self) -> Option<StorageReadControl> {
560 Some(Self::retention_control(self))
561 }
562
563 fn notification_publications(
564 &self,
565 ) -> Option<&dyn crate::notifications::NotificationPublicationStore> {
566 Some(self)
567 }
568
569 fn serializable_session(&self) -> Option<&dyn SerializableSession> {
570 self.persistence
571 .serializable_coordinator()
572 .map(|_| self as &dyn SerializableSession)
573 }
574
575 fn reclaim_obsolete(&self) -> StorageBackendResult<()> {
576 let active = self.active.lock();
577 if active.is_some() {
578 return Err(StorageBackendError::Other(
579 "vacuum requires an inactive logical session".into(),
580 ));
581 }
582 let control = self.write_control();
583 let source: Arc<dyn KeyValueStore> =
584 Arc::new(self.new_session_with_cancellation(control.cancellation()));
585 crate::key_value::KeyValueDiskANNMaintenance::run(&source, &control)?;
586 self.reclaim_versions().map(|_| ())
587 }
588
589 fn write_cancellation(&self) -> Option<uqa_core::CancellationToken> {
590 Some(self.write_cancellation.clone())
591 }
592
593 fn open_controlled_session(
594 &self,
595 control: &StorageReadControl,
596 ) -> StorageBackendResult<Arc<dyn KeyValueStore>> {
597 control.check()?;
598 Ok(Arc::new(self.new_controlled_session(control)))
599 }
600
601 fn open_session_with_cancellation(
602 &self,
603 cancellation: &uqa_core::CancellationToken,
604 ) -> StorageBackendResult<Arc<dyn KeyValueStore>> {
605 cancellation.check()?;
606 Ok(Arc::new(self.new_session_with_cancellation(cancellation)))
607 }
608
609 fn open_retained_read_session(
610 &self,
611 cancellation: &uqa_core::CancellationToken,
612 ) -> StorageBackendResult<Arc<dyn KeyValueStore>> {
613 Ok(Arc::new(self.new_retained_read_session(cancellation)?))
614 }
615
616 fn transaction_model(&self) -> crate::StorageTransactionModel {
617 crate::StorageTransactionModel::VersionedConcurrent {
618 database: self.persistence.database_id(),
619 }
620 }
621
622 fn refresh_transaction_snapshot(
623 &self,
624 cancellation: &uqa_core::CancellationToken,
625 ) -> StorageBackendResult<()> {
626 Self::refresh_transaction_snapshot(self, cancellation)
627 }
628
629 fn identifier_allocator(&self) -> Option<&dyn super::IdentifierAllocator> {
630 Some(self)
631 }
632
633 fn with_read_view(
634 &self,
635 operation: &mut crate::key_value::KeyValueReadScope<'_>,
636 ) -> StorageBackendResult<()> {
637 self.control.check()?;
638 let view = self.view().map_err(VersionError::into_storage_error)?;
639 operation(&read::RecordRead {
640 view: &view,
641 database: self.persistence.database_id(),
642 control: &self.control,
643 })?;
644 self.control.check()
645 }
646
647 fn with_mutation(
648 &self,
649 operation: &mut crate::key_value::KeyValueMutation<'_>,
650 ) -> StorageBackendResult<()> {
651 self.evaluate_mutation(operation, None).map(|_| ())
652 }
653
654 fn with_mutation_revision(
655 &self,
656 prefixes: &[&[u8]],
657 operation: &mut crate::key_value::KeyValueMutation<'_>,
658 ) -> StorageBackendResult<Option<crate::key_value::KeyValueReadRevision>> {
659 self.evaluate_mutation(operation, Some(prefixes))
660 }
661
662 fn with_versioned_mutation(
663 &self,
664 operation: &mut crate::key_value::KeyValueVersionedMutation<'_>,
665 ) -> StorageBackendResult<()> {
666 self.with_versioned_record_mutation(|origin, view, batch| {
667 operation(
668 origin,
669 &read::RecordRead {
670 view: &view,
671 database: self.persistence.database_id(),
672 control: &self.control,
673 },
674 batch,
675 )
676 })
677 }
678
679 fn transaction_affinity(&self) -> Option<StorageSessionAffinity> {
680 Some(self.session_affinity())
681 }
682
683 fn storage_identity(&self) -> StorageBackendResult<Option<PersistentStorageIdentity>> {
684 Ok(self.identity.clone())
685 }
686
687 fn open_session(&self) -> StorageBackendResult<Arc<dyn KeyValueStore>> {
688 Ok(Arc::new(self.new_session()))
689 }
690
691 fn get(&self, key: &[u8]) -> StorageBackendResult<Option<Vec<u8>>> {
692 let mut value = None;
693 self.visit_value(key, &self.control, &mut |bytes| {
694 value = bytes.map(<[u8]>::to_vec);
695 Ok(())
696 })?;
697 Ok(value)
698 }
699
700 fn contains_key(&self, key: &[u8]) -> StorageBackendResult<bool> {
701 Ok(self
702 .view()
703 .and_then(|view| view.metadata(key, &self.control))
704 .map_err(VersionError::into_storage_error)?
705 .is_some_and(|record| record.live))
706 }
707
708 fn contains_prefix_budgeted(
709 &self,
710 prefix: &[u8],
711 control: &StorageReadControl,
712 ) -> StorageBackendResult<bool> {
713 control.check()?;
714 let mut found = false;
715 self.view()
716 .map_err(VersionError::into_storage_error)?
717 .visit_keys(prefix, None, usize::MAX, control, &mut |_, record| {
718 found = record.live;
719 Ok(!found)
720 })
721 .map_err(VersionError::into_storage_error)?;
722 Ok(found)
723 }
724
725 fn visit_value(
726 &self,
727 key: &[u8],
728 control: &StorageReadControl,
729 visit: &mut ValueReadVisitor<'_>,
730 ) -> StorageBackendResult<()> {
731 control.check()?;
732 self.view()
733 .map_err(VersionError::into_storage_error)?
734 .visit_value(key, control, &mut |record| {
735 visit(record.and_then(|record| record.value)).map_err(VersionError::from)
736 })
737 .map_err(VersionError::into_storage_error)
738 }
739
740 fn visit_value_bounded(
741 &self,
742 key: &[u8],
743 max_bytes: usize,
744 control: &StorageReadControl,
745 visit: &mut ValueReadVisitor<'_>,
746 ) -> StorageBackendResult<()> {
747 control.check()?;
748 self.view()
749 .map_err(VersionError::into_storage_error)?
750 .visit_value_bounded(key, max_bytes, control, &mut |record| {
751 visit(record.and_then(|record| record.value)).map_err(VersionError::from)
752 })
753 .map_err(VersionError::into_storage_error)
754 }
755
756 fn visit_prefix_after(
757 &self,
758 prefix: &[u8],
759 after: Option<&[u8]>,
760 limit: usize,
761 control: &StorageReadControl,
762 visit: &mut KeyValueReadVisitor<'_>,
763 ) -> StorageBackendResult<()> {
764 control.check()?;
765 if limit == 0 {
766 return Ok(());
767 }
768 let view = self.view().map_err(VersionError::into_storage_error)?;
769 read::visit_live(&view, prefix, after, limit, control, visit)
770 .map_err(VersionError::into_storage_error)
771 }
772
773 fn put(&self, key: &[u8], value: &[u8]) -> StorageBackendResult<()> {
774 self.write(|transaction| transaction.replace(key, Some(value), &self.control))
775 }
776 fn delete(&self, key: &[u8]) -> StorageBackendResult<()> {
777 self.write(|transaction| transaction.replace(key, None, &self.control))
778 }
779
780 fn scan_prefix(&self, prefix: &[u8]) -> StorageBackendResult<Vec<(Vec<u8>, Vec<u8>)>> {
781 self.scan_prefix_after(prefix, None, usize::MAX)
782 }
783
784 fn scan_prefix_after(
785 &self,
786 prefix: &[u8],
787 after: Option<&[u8]>,
788 limit: usize,
789 ) -> StorageBackendResult<Vec<(Vec<u8>, Vec<u8>)>> {
790 let mut rows = Vec::new();
791 self.visit_prefix_after(prefix, after, limit, &self.control, &mut |key, value| {
792 rows.push((key.to_vec(), value.to_vec()));
793 Ok(())
794 })?;
795 Ok(rows)
796 }
797
798 fn scan_prefix_keys_after(
799 &self,
800 prefix: &[u8],
801 after: Option<&[u8]>,
802 limit: usize,
803 ) -> StorageBackendResult<Vec<Vec<u8>>> {
804 let mut keys = Vec::new();
805 if limit != 0 {
806 self.view()
807 .map_err(VersionError::into_storage_error)?
808 .visit_keys(
809 prefix,
810 after,
811 usize::MAX,
812 &self.control,
813 &mut |key, record| {
814 if record.live {
815 keys.push(key.to_vec());
816 }
817 Ok(keys.len() < limit)
818 },
819 )
820 .map_err(VersionError::into_storage_error)?;
821 }
822 Ok(keys)
823 }
824
825 fn first_prefix_after(
826 &self,
827 prefix: &[u8],
828 after: Option<&[u8]>,
829 ) -> StorageBackendResult<Option<(Vec<u8>, Vec<u8>)>> {
830 Ok(self.scan_prefix_after(prefix, after, 1)?.pop())
831 }
832 fn delete_prefix(&self, prefix: &[u8]) -> StorageBackendResult<usize> {
833 self.write(|transaction| transaction.delete_prefix(prefix, &self.control))
834 }
835 fn batch(&self) -> Box<dyn KeyValueBatch + '_> {
836 let participant = self
837 .active
838 .lock()
839 .as_ref()
840 .and_then(Transaction::serializable_context)
841 .map(SerializableReadContext::id);
842 Box::new(batch::Batch::new(self, participant))
843 }
844 fn begin_transaction(&self) -> StorageBackendResult<()> {
845 self.begin(false)
846 }
847 fn begin_read_transaction(&self) -> StorageBackendResult<()> {
848 self.begin(true)
849 }
850 fn begin_upgradeable_transaction(&self) -> StorageBackendResult<()> {
851 self.begin(self.retained.is_some())
852 }
853 fn in_transaction(&self) -> bool {
854 self.active.lock().is_some()
855 }
856 fn transaction_has_written(&self) -> StorageBackendResult<bool> {
857 Ok(self.active.lock().as_ref().is_some_and(|transaction| {
858 transaction.changes.has_written() || transaction.has_derived_changes()
859 }))
860 }
861 fn change_version(&self) -> StorageBackendResult<Option<u64>> {
862 let pinned = match self.retained.as_ref() {
863 Some(view) => Some(view.sequence()),
864 None => self
865 .active
866 .lock()
867 .as_ref()
868 .map(Transaction::view)
869 .transpose()
870 .map_err(VersionError::into_storage_error)?
871 .map(|view| view.sequence()),
872 };
873 let sequence = match pinned {
874 Some(sequence) => sequence,
875 None => self
876 .latest_sequence()
877 .map_err(VersionError::into_storage_error)?,
878 };
879 Ok(Some(sequence.as_u64()))
880 }
881
882 fn read_view_revision(
883 &self,
884 ) -> StorageBackendResult<Option<crate::key_value::KeyValueReadRevision>> {
885 let view = self.view().map_err(VersionError::into_storage_error)?;
886 Ok(Some(crate::key_value::KeyValueReadRevision::records(
887 self.persistence.database_id(),
888 view.sequence(),
889 view.private_revision(),
890 )))
891 }
892
893 fn completed_commit(&self) -> Option<super::CommitReceipt> {
894 let active = self.active.lock();
895 if active.is_some() {
896 None
897 } else {
898 *self.completed.lock()
899 }
900 }
901
902 fn commit_transaction(&self) -> StorageBackendResult<()> {
903 let mut active = self.active.lock();
904 let sequence_completion = self
905 .retained
906 .is_none()
907 .then(|| self.sequence_durability.close());
908 let transaction = active.as_mut().ok_or_else(no_transaction)?;
909 let synchronized_first = !transaction.has_record_publication();
911 if synchronized_first {
912 self.synchronize_sequence_values(&self.write_control())
913 .map_err(|error| transaction.completion_error(error))?;
914 }
915 transaction.commit(&*self.persistence, &self.write_control())?;
916 if !synchronized_first {
917 self.synchronize_sequence_values(&self.control)
918 .map_err(|error| transaction.completion_error(error))?;
919 }
920 active
921 .as_ref()
922 .expect("completed attempt")
923 .acknowledge_completion(&*self.persistence, &self.control)?;
924 *self.completed.lock() = active.as_ref().and_then(Transaction::committed_receipt);
925 *active = None;
926 if sequence_completion.is_some() {
927 self.sequence_durability.clear();
928 }
929 Ok(())
930 }
931
932 fn rollback_transaction(&self) -> StorageBackendResult<()> {
933 let mut active = self.active.lock();
934 let sequence_completion = self
935 .retained
936 .is_none()
937 .then(|| self.sequence_durability.close());
938 active
939 .as_mut()
940 .ok_or_else(no_transaction)?
941 .abort(&*self.persistence, &self.control)?;
942 self.synchronize_sequence_values(&self.control)
943 .map_err(|error| {
944 active
945 .as_ref()
946 .expect("completed attempt")
947 .completion_error(error)
948 })?;
949 active
950 .as_ref()
951 .expect("completed attempt")
952 .acknowledge_completion(&*self.persistence, &self.control)?;
953 *self.completed.lock() = None;
954 *active = None;
955 if sequence_completion.is_some() {
956 self.sequence_durability.clear();
957 }
958 Ok(())
959 }
960
961 fn savepoint(&self, name: &str) -> StorageBackendResult<()> {
962 self.savepoint_action(|transaction| transaction.savepoint(name, &self.control))
963 }
964 fn release_savepoint(&self, name: &str) -> StorageBackendResult<()> {
965 self.savepoint_action(|transaction| transaction.release(name))
966 }
967 fn rollback_to_savepoint(&self, name: &str) -> StorageBackendResult<()> {
968 self.savepoint_action(|transaction| transaction.rollback_to(name, &self.control))
969 }
970}
971
972fn no_transaction() -> StorageBackendError {
973 StorageBackendError::Other("no active KeyValue transaction".into())
974}
975
976fn commit_error(error: CommitFailure) -> StorageBackendError {
977 match error {
978 CommitFailure::Rejected(error) => error.into_storage_error(),
979 error @ CommitFailure::Indeterminate { .. } => StorageBackendError::backend("MVCC", error),
980 }
981}