uqa_storage/mvcc/
receipts.rs1use super::{
10 CommitReceipt, CommitStatus, SerializableParticipant, SerializableTransactionId,
11 StorageTransactionId, VersionError, VersionResult,
12};
13
14pub const DEFAULT_RECEIPT_RETENTION_LIMIT: u64 = 65_536;
16
17pub fn receipt_lease_id(transaction: StorageTransactionId) -> SerializableTransactionId {
19 SerializableTransactionId::new(
20 transaction.database(),
21 *b"UQAReceiptLease1",
22 transaction.allocation(),
23 )
24 .expect("receipt allocation and namespace are nonzero")
25}
26
27pub struct RetainedTransactionAllocation {
29 transaction: StorageTransactionId,
30 _lease: Option<SerializableParticipant>,
31}
32
33impl RetainedTransactionAllocation {
34 pub fn untracked(transaction: StorageTransactionId) -> Self {
35 Self {
36 transaction,
37 _lease: None,
38 }
39 }
40
41 pub fn retain(
42 transaction: StorageTransactionId,
43 lease: SerializableParticipant,
44 ) -> VersionResult<Self> {
45 if lease.id() != receipt_lease_id(transaction) {
46 return Err(VersionError::InvalidEncoding(
47 "receipt owner lease identity mismatch",
48 ));
49 }
50 Ok(Self {
51 transaction,
52 _lease: Some(lease),
53 })
54 }
55
56 pub fn transaction(&self) -> StorageTransactionId {
57 self.transaction
58 }
59}
60
61#[derive(Debug, Clone, Copy, PartialEq, Eq)]
63pub enum ReceiptAcknowledgement {
64 Committed(CommitReceipt),
65 Aborted(StorageTransactionId),
66}
67
68impl ReceiptAcknowledgement {
69 pub fn transaction(self) -> StorageTransactionId {
70 match self {
71 Self::Committed(receipt) => receipt.transaction,
72 Self::Aborted(transaction) => transaction,
73 }
74 }
75
76 pub fn validate(self, status: CommitStatus) -> VersionResult<()> {
78 match (self, status) {
79 (_, CommitStatus::Unknown) | (Self::Aborted(_), CommitStatus::Aborted) => Ok(()),
80 (Self::Committed(expected), CommitStatus::Committed(actual)) if expected == actual => {
81 Ok(())
82 }
83 (_, CommitStatus::Pending) => Err(VersionError::TransactionSealed),
84 (_, CommitStatus::Committed(receipt)) => Err(VersionError::AlreadyCommitted(receipt)),
85 (_, CommitStatus::Aborted) => Err(VersionError::AlreadyAborted(self.transaction())),
86 }
87 }
88}