use std::sync::atomic::{AtomicU64, Ordering};
static SNAPSHOT_COUNTER: AtomicU64 = AtomicU64::new(1);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct SnapshotId(pub u64);
impl SnapshotId {
pub fn current() -> Self {
SnapshotId(0)
}
pub fn new_incrementing() -> Self {
let lsn = SNAPSHOT_COUNTER.fetch_add(1, Ordering::SeqCst);
SnapshotId(lsn)
}
pub fn from_tx(tx_id: u64) -> Self {
SnapshotId(tx_id)
}
pub fn from_lsn(lsn: u64) -> Self {
SnapshotId(lsn)
}
pub fn invalid() -> Self {
SnapshotId(u64::MAX)
}
pub fn is_valid(&self) -> bool {
self.0 != u64::MAX
}
pub fn as_u64(&self) -> u64 {
self.0
}
pub fn as_lsn(&self) -> u64 {
self.0
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_snapshot_id_creation() {
let snapshot = SnapshotId(12345);
assert_eq!(snapshot.as_u64(), 12345);
}
#[test]
fn test_snapshot_id_from_tx() {
let snapshot = SnapshotId::from_tx(999);
assert_eq!(snapshot.as_u64(), 999);
}
#[test]
fn test_snapshot_id_from_lsn() {
let snapshot = SnapshotId::from_lsn(12345);
assert_eq!(snapshot.as_lsn(), 12345);
assert_eq!(snapshot.as_u64(), 12345);
}
#[test]
fn test_snapshot_id_invalid() {
let invalid = SnapshotId::invalid();
assert_eq!(invalid.as_u64(), u64::MAX);
assert!(!invalid.is_valid());
}
#[test]
fn test_snapshot_id_valid() {
let valid = SnapshotId::from_tx(100);
assert!(valid.is_valid());
}
#[test]
fn test_snapshot_id_current() {
let current = SnapshotId::current();
assert_eq!(current, SnapshotId(0));
assert!(current.is_valid());
}
#[test]
fn test_snapshot_id_new_incrementing() {
let snapshot1 = SnapshotId::new_incrementing();
let snapshot2 = SnapshotId::new_incrementing();
let snapshot3 = SnapshotId::new_incrementing();
assert!(snapshot2.as_u64() > snapshot1.as_u64());
assert!(snapshot3.as_u64() > snapshot2.as_u64());
assert!(snapshot1.is_valid());
assert!(snapshot2.is_valid());
assert!(snapshot3.is_valid());
}
#[test]
fn test_snapshot_id_equality() {
let s1 = SnapshotId(100);
let s2 = SnapshotId(100);
let s3 = SnapshotId(200);
assert_eq!(s1, s2);
assert_ne!(s1, s3);
}
#[test]
fn test_snapshot_id_hash() {
use std::collections::HashSet;
let mut set = HashSet::new();
set.insert(SnapshotId(100));
set.insert(SnapshotId(200));
set.insert(SnapshotId(100));
assert_eq!(set.len(), 2);
}
#[test]
fn test_snapshot_id_copy() {
let s1 = SnapshotId(100);
let s2 = s1;
assert_eq!(s1.as_u64(), 100);
assert_eq!(s2.as_u64(), 100);
}
}