Skip to main content

linkrs_storage/client/
context.rs

1use linkrs_core::types::Timestamp;
2use linkrs_core::types::TransactionId;
3use linkrs_transaction::TransactionMutationRecorder;
4
5use std::sync::Arc;
6
7/// Immutable context bound to one storage operation scope.
8#[derive(Debug)]
9pub struct StorageOperationContext {
10    pub transaction_id: Option<TransactionId>,
11    pub read_timestamp: Timestamp,
12    pub write_timestamp: Option<Timestamp>,
13    pub read_only: bool,
14    pub auto_commit: bool,
15    pub mutation_recorder: Option<Arc<dyn TransactionMutationRecorder>>,
16    /// Undo log entry count at the start of this statement's segment (group
17    /// mode only). Used by `finalize_operation` to roll back only the failed
18    /// statement's segment when a shared undo log is in use.
19    pub auto_commit_group_start: Option<usize>,
20    /// Staging buffer journal and index lengths at the start of this
21    /// statement (group mode only). Used by `finalize_operation` to roll the
22    /// shared transaction buffer back to the statement start.
23    pub auto_commit_staging_start: Option<(usize, usize)>,
24    /// Shared staged-WAL length at the start of this statement (group mode
25    /// only). Used to truncate the group's WAL redo back to the statement.
26    pub auto_commit_wal_start: usize,
27}
28
29impl PartialEq for StorageOperationContext {
30    fn eq(&self, other: &Self) -> bool {
31        self.transaction_id == other.transaction_id
32            && self.read_timestamp == other.read_timestamp
33            && self.write_timestamp == other.write_timestamp
34            && self.read_only == other.read_only
35            && self.auto_commit == other.auto_commit
36    }
37}
38
39impl Eq for StorageOperationContext {}
40
41impl Clone for StorageOperationContext {
42    fn clone(&self) -> Self {
43        Self {
44            transaction_id: self.transaction_id,
45            read_timestamp: self.read_timestamp,
46            write_timestamp: self.write_timestamp,
47            read_only: self.read_only,
48            auto_commit: self.auto_commit,
49            mutation_recorder: self.mutation_recorder.clone(),
50            auto_commit_group_start: self.auto_commit_group_start,
51            auto_commit_staging_start: self.auto_commit_staging_start,
52            auto_commit_wal_start: self.auto_commit_wal_start,
53        }
54    }
55}
56
57impl StorageOperationContext {
58    pub fn transaction_with_timestamps(
59        transaction_id: TransactionId,
60        read_timestamp: Timestamp,
61        write_timestamp: Option<Timestamp>,
62        read_only: bool,
63        auto_commit: bool,
64    ) -> Self {
65        Self {
66            transaction_id: Some(transaction_id),
67            read_timestamp,
68            write_timestamp,
69            read_only,
70            auto_commit,
71            mutation_recorder: None,
72            auto_commit_group_start: None,
73            auto_commit_staging_start: None,
74            auto_commit_wal_start: 0,
75        }
76    }
77
78    pub fn with_mutation_recorder(
79        mut self,
80        recorder: Arc<dyn TransactionMutationRecorder>,
81    ) -> Self {
82        self.mutation_recorder = Some(recorder);
83        self
84    }
85
86    /// Timestamp at which MVCC snapshots are registered for this operation.
87    ///
88    /// Read-only operations pin their read snapshot; auto-commit writes pin
89    /// the write timestamp (the statement both reads and writes at it).
90    pub fn snapshot_timestamp(&self) -> Option<Timestamp> {
91        if self.read_only {
92            Some(self.read_timestamp)
93        } else {
94            self.write_timestamp
95        }
96    }
97}