pub use grafeo_common::mvcc::{VersionChain, VersionInfo};
#[cfg(test)]
mod tests {
use super::*;
use grafeo_common::types::{EpochId, TransactionId};
#[test]
fn test_version_visibility() {
let v = VersionInfo::new(EpochId::new(5), TransactionId::new(1));
assert!(!v.is_visible_at(EpochId::new(4)));
assert!(v.is_visible_at(EpochId::new(5)));
assert!(v.is_visible_at(EpochId::new(10)));
}
#[test]
fn test_deleted_version_visibility() {
let mut v = VersionInfo::new(EpochId::new(5), TransactionId::new(1));
v.mark_deleted(EpochId::new(10), TransactionId::new(99));
assert!(v.is_visible_at(EpochId::new(5)));
assert!(v.is_visible_at(EpochId::new(9)));
assert!(!v.is_visible_at(EpochId::new(10)));
assert!(!v.is_visible_at(EpochId::new(15)));
}
#[test]
fn test_version_visibility_to_transaction() {
let v = VersionInfo::new(EpochId::new(5), TransactionId::new(1));
assert!(v.is_visible_to(EpochId::new(3), TransactionId::new(1)));
assert!(!v.is_visible_to(EpochId::new(3), TransactionId::new(2)));
assert!(v.is_visible_to(EpochId::new(5), TransactionId::new(2)));
}
#[test]
fn test_version_chain_basic() {
let mut chain = VersionChain::with_initial("v1", EpochId::new(1), TransactionId::new(1));
assert_eq!(chain.visible_at(EpochId::new(1)), Some(&"v1"));
assert_eq!(chain.visible_at(EpochId::new(0)), None);
chain.add_version("v2", EpochId::new(5), TransactionId::new(2));
assert_eq!(chain.visible_at(EpochId::new(1)), Some(&"v1"));
assert_eq!(chain.visible_at(EpochId::new(4)), Some(&"v1"));
assert_eq!(chain.visible_at(EpochId::new(5)), Some(&"v2"));
assert_eq!(chain.visible_at(EpochId::new(10)), Some(&"v2"));
}
#[test]
fn test_version_chain_transaction_visibility() {
let mut chain = VersionChain::with_initial("v1", EpochId::new(1), TransactionId::new(1));
chain.add_version("v2", EpochId::new(5), TransactionId::new(2));
assert_eq!(
chain.visible_to(EpochId::new(3), TransactionId::new(2)),
Some(&"v2")
);
assert_eq!(
chain.visible_to(EpochId::new(3), TransactionId::new(3)),
Some(&"v1")
);
}
#[test]
fn test_version_chain_deletion() {
let mut chain = VersionChain::with_initial("v1", EpochId::new(1), TransactionId::new(1));
assert!(chain.mark_deleted(EpochId::new(5), TransactionId::new(99)));
assert_eq!(chain.visible_at(EpochId::new(4)), Some(&"v1"));
assert_eq!(chain.visible_at(EpochId::new(5)), None);
assert_eq!(chain.visible_at(EpochId::new(10)), None);
}
#[test]
fn test_version_chain_rollback() {
let mut chain = VersionChain::with_initial("v1", EpochId::new(1), TransactionId::new(1));
chain.add_version("v2", EpochId::new(5), TransactionId::new(2));
chain.add_version("v3", EpochId::new(6), TransactionId::new(2));
assert_eq!(chain.version_count(), 3);
chain.remove_versions_by(TransactionId::new(2));
assert_eq!(chain.version_count(), 1);
assert_eq!(chain.visible_at(EpochId::new(10)), Some(&"v1"));
}
#[test]
fn test_version_chain_conflict_detection() {
let mut chain = VersionChain::with_initial("v1", EpochId::new(1), TransactionId::new(1));
assert!(!chain.has_conflict(EpochId::new(1), TransactionId::new(2)));
assert!(chain.has_conflict(EpochId::new(0), TransactionId::new(2)));
chain.add_version("v2", EpochId::new(5), TransactionId::new(2));
assert!(chain.has_conflict(EpochId::new(0), TransactionId::new(3)));
assert!(!chain.has_conflict(EpochId::new(5), TransactionId::new(3)));
assert!(!chain.has_conflict(EpochId::new(4), TransactionId::new(2)));
}
#[test]
fn test_version_chain_gc() {
let mut chain = VersionChain::new();
chain.add_version("v1", EpochId::new(1), TransactionId::new(1));
chain.add_version("v2", EpochId::new(3), TransactionId::new(2));
chain.add_version("v3", EpochId::new(5), TransactionId::new(3));
chain.add_version("v4", EpochId::new(7), TransactionId::new(4));
assert_eq!(chain.version_count(), 4);
chain.gc(EpochId::new(6));
assert_eq!(chain.visible_at(EpochId::new(7)), Some(&"v4"));
assert!(chain.version_count() <= 4);
}
#[test]
fn test_version_chain_get_mut() {
let mut chain =
VersionChain::with_initial(String::from("v1"), EpochId::new(1), TransactionId::new(1));
{
let data = chain
.get_mut(EpochId::new(1), TransactionId::new(1), EpochId::new(2))
.unwrap();
data.push_str("_modified");
}
assert_eq!(chain.version_count(), 1); assert_eq!(chain.visible_at(EpochId::new(1)).unwrap(), "v1_modified");
{
let data = chain
.get_mut(EpochId::new(3), TransactionId::new(2), EpochId::new(3))
.unwrap();
data.push_str("_by_tx2");
}
assert_eq!(chain.version_count(), 2); assert_eq!(
chain.visible_at(EpochId::new(3)).unwrap(),
"v1_modified_by_tx2"
);
assert_eq!(chain.visible_at(EpochId::new(2)).unwrap(), "v1_modified");
}
}