const IN_FLIGHT: u64 = 1 << 63;
const ID_MASK: u64 = !IN_FLIGHT;
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub struct Timestamp(pub u64);
impl Timestamp {
pub const ZERO: Timestamp = Timestamp(0);
pub const MAX: Timestamp = Timestamp(ID_MASK);
#[inline]
pub const fn raw(self) -> u64 {
self.0
}
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub struct TxnId(pub u64);
impl TxnId {
pub const NONE: TxnId = TxnId(0);
#[inline]
pub const fn tagged(self) -> u64 {
self.0 | IN_FLIGHT
}
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub(crate) enum Visibility {
CommittedAt(Timestamp),
InFlight(TxnId),
}
impl Visibility {
#[inline]
pub(crate) const fn decode(raw: u64) -> Visibility {
if raw & IN_FLIGHT != 0 {
Visibility::InFlight(TxnId(raw & ID_MASK))
} else {
Visibility::CommittedAt(Timestamp(raw))
}
}
#[inline]
pub(crate) fn reached(self, snapshot: Timestamp, reader: TxnId) -> bool {
match self {
Visibility::CommittedAt(ts) => ts <= snapshot,
Visibility::InFlight(id) => id == reader,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn tagged_txn_ids_round_trip() {
let id = TxnId(12345);
assert_eq!(Visibility::decode(id.tagged()), Visibility::InFlight(id));
}
#[test]
fn commit_timestamps_round_trip() {
let ts = Timestamp(999);
assert_eq!(Visibility::decode(ts.raw()), Visibility::CommittedAt(ts));
}
#[test]
fn own_writes_are_visible_to_their_author() {
let me = TxnId(7);
let someone_else = TxnId(8);
let v = Visibility::decode(me.tagged());
assert!(v.reached(Timestamp::ZERO, me));
assert!(!v.reached(Timestamp::MAX, someone_else));
}
#[test]
fn max_timestamp_does_not_collide_with_in_flight_tag() {
assert!(matches!(
Visibility::decode(Timestamp::MAX.raw()),
Visibility::CommittedAt(_)
));
}
}