lever/txn/
conflicts.rs

1use super::transact::TransactionIsolation;
2use crate::txn::readset::ReadSet;
3use crate::txn::writeset::WriteSet;
4use std::cmp::Ordering;
5
6#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
7pub(in crate::txn) enum CompareSet {
8    ReadLocal,
9    WriteLocal,
10}
11
12#[derive(Clone, Debug, PartialEq, Eq, Ord)]
13pub(in crate::txn) struct Compare {
14    rev: u64,
15    current: bool,
16    set: CompareSet,
17}
18
19impl Compare {
20    pub(in crate::txn) fn new(rev: u64, current: bool, set: CompareSet) -> Self {
21        Self { rev, current, set }
22    }
23
24    pub(in crate::txn) fn check(&self, other: &Compare, ordering: Ordering) -> bool {
25        self.cmp(&other) == ordering
26    }
27}
28
29impl PartialOrd for Compare {
30    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
31        Some(self.rev.cmp(&other.rev))
32    }
33}
34
35pub(crate) struct ConflictManager;
36
37impl ConflictManager {
38    pub(crate) fn check<T: 'static + Clone + Sync + Send>(iso: &TransactionIsolation) -> bool {
39        match iso {
40            // Serializable is also a checking for write conflicts, seprated from serializable reads only mode.
41            // Serializable will do check for write conflicts too. Even that would never happen.
42            TransactionIsolation::Serializable => {
43                let rs = ReadSet::local();
44                let ws = WriteSet::local();
45
46                let mut linear = rs.cmps::<T>();
47                let _writes_before_rev: Vec<Compare>;
48
49                let pinned_rev = rs.first::<T>().checked_add(1).unwrap_or(u64::MAX);
50                let writes_before_rev = ws.writes_before::<T>(pinned_rev);
51                linear.extend(writes_before_rev);
52
53                // dbg!(&linear);
54
55                linear.iter().all(|x| x.current)
56            }
57            TransactionIsolation::RepeatableRead => {
58                let rs = ReadSet::local();
59                let cmps = rs.cmps::<T>();
60                cmps.iter().all(|x| x.current)
61            }
62            TransactionIsolation::ReadCommitted => true,
63        }
64    }
65}