#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct SnapshotId(pub u64);
#[cfg(feature = "native-v2")]
use std::sync::Arc;
#[cfg(feature = "native-v2")]
use std::sync::OnceLock;
#[cfg(feature = "native-v2")]
use crate::backend::native::v2::wal::manager::V2WALManager;
#[cfg(feature = "native-v2")]
static CURRENT_WAL_MANAGER: OnceLock<Arc<V2WALManager>> = OnceLock::new();
#[cfg(feature = "native-v2")]
pub(crate) fn register_wal_manager(manager: Arc<V2WALManager>) -> Result<(), Arc<V2WALManager>> {
CURRENT_WAL_MANAGER.set(manager)
}
#[cfg(feature = "native-v2")]
pub(crate) fn unregister_wal_manager() {
}
#[cfg(feature = "native-v2")]
fn with_wal_manager<F, R>(f: F) -> R
where
F: FnOnce(Option<&V2WALManager>) -> R,
{
let manager = CURRENT_WAL_MANAGER.get();
f(manager.map(|m| m.as_ref()))
}
impl SnapshotId {
#[cfg(not(feature = "native-v2"))]
pub fn current() -> Self {
SnapshotId(0)
}
#[cfg(feature = "native-v2")]
pub fn current() -> Self {
let lsn = with_wal_manager(|manager| {
manager
.map(|m| m.max_committed_lsn())
.unwrap_or(0)
});
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!(current.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);
}
}