use core::fmt;
use std::sync::atomic::{AtomicU64, Ordering};
use crate::{
btree::page_cache::PageCache, types::SmallResult, Unique,
};
static TRANSACTION_ID: AtomicU64 = AtomicU64::new(1);
#[derive(Eq, Hash, PartialEq, Clone, Copy)]
pub struct Transaction {
uuid: u64,
}
impl Transaction {
pub fn new() -> Self {
Self {
uuid: TRANSACTION_ID.fetch_add(1, Ordering::Relaxed),
}
}
pub fn start(&self) -> SmallResult {
Unique::mut_log_manager().log_start(self)
}
pub fn commit(&self) -> SmallResult {
self.complete(true, &Unique::mut_page_cache())
}
pub fn manual_commit(
&self,
page_cache: &PageCache,
) -> SmallResult {
self.complete(true, page_cache)
}
pub fn abort(&self) -> SmallResult {
self.complete(false, &Unique::mut_page_cache())
}
pub fn manual_abort(
&self,
page_cache: &PageCache,
) -> SmallResult {
self.complete(false, page_cache)
}
fn complete(
&self,
commit: bool,
page_cache: &PageCache,
) -> SmallResult {
if !commit {
Unique::mut_log_manager().log_abort(self, page_cache)?;
}
page_cache.tx_complete(self, commit);
if commit {
Unique::mut_log_manager().log_commit(self)?;
}
Unique::concurrent_status().release_lock_by_tx(self)?;
Ok(())
}
pub fn get_id(&self) -> u64 {
self.uuid
}
}
impl fmt::Display for Transaction {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "tx_{}", self.uuid)
}
}
impl fmt::Debug for Transaction {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
return write!(f, "{}", self);
}
}