1use core::fmt;
2use std::sync::atomic::{AtomicU64, Ordering};
3
4use crate::{
5 btree::page_cache::PageCache, types::SmallResult, Unique,
6};
7
8static TRANSACTION_ID: AtomicU64 = AtomicU64::new(1);
9
10#[derive(Eq, Hash, PartialEq, Clone, Copy)]
11pub struct Transaction {
12 uuid: u64,
14}
15
16impl Transaction {
17 pub fn new() -> Self {
18 Self {
19 uuid: TRANSACTION_ID.fetch_add(1, Ordering::Relaxed),
20 }
21 }
22
23 pub fn start(&self) -> SmallResult {
24 Unique::mut_log_manager().log_start(self)
25 }
26
27 pub fn commit(&self) -> SmallResult {
28 self.complete(true, &Unique::mut_page_cache())
29 }
30
31 pub fn manual_commit(
32 &self,
33 page_cache: &PageCache,
34 ) -> SmallResult {
35 self.complete(true, page_cache)
36 }
37
38 pub fn abort(&self) -> SmallResult {
39 self.complete(false, &Unique::mut_page_cache())
40 }
41
42 pub fn manual_abort(
43 &self,
44 page_cache: &PageCache,
45 ) -> SmallResult {
46 self.complete(false, page_cache)
47 }
48
49 fn complete(
50 &self,
51 commit: bool,
52 page_cache: &PageCache,
53 ) -> SmallResult {
54 if !commit {
56 Unique::mut_log_manager().log_abort(self, page_cache)?;
58 }
59
60 page_cache.tx_complete(self, commit);
64
65 if commit {
67 Unique::mut_log_manager().log_commit(self)?;
68 }
69
70 Unique::concurrent_status().release_lock_by_tx(self)?;
71
72 Ok(())
73 }
74
75 pub fn get_id(&self) -> u64 {
76 self.uuid
77 }
78}
79
80impl fmt::Display for Transaction {
90 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
91 write!(f, "tx_{}", self.uuid)
92 }
93}
94
95impl fmt::Debug for Transaction {
96 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
97 return write!(f, "{}", self);
98 }
99}