use seerdb::{DBOptions, DB};
use std::sync::Arc;
use std::thread;
use tempfile::tempdir;
#[test]
fn test_snapshot_isolation_basic() {
let dir = tempdir().unwrap();
let db = DB::open(dir.path()).unwrap();
db.put(b"key1", b"value1").unwrap();
db.put(b"key2", b"value2").unwrap();
let snapshot = db.snapshot().unwrap();
db.put(b"key1", b"value1_updated").unwrap();
db.delete(b"key2").unwrap();
db.put(b"key3", b"value3_new").unwrap();
assert_eq!(
snapshot.get(b"key1").unwrap(),
Some(bytes::Bytes::from("value1"))
);
assert_eq!(
snapshot.get(b"key2").unwrap(),
Some(bytes::Bytes::from("value2"))
);
assert_eq!(snapshot.get(b"key3").unwrap(), None);
assert_eq!(
db.get(b"key1").unwrap(),
Some(bytes::Bytes::from("value1_updated"))
);
assert_eq!(db.get(b"key2").unwrap(), None);
assert_eq!(
db.get(b"key3").unwrap(),
Some(bytes::Bytes::from("value3_new"))
);
}
#[test]
fn test_snapshot_range_iteration() {
let dir = tempdir().unwrap();
let db = DB::open(dir.path()).unwrap();
db.put(b"key1", b"value1").unwrap();
db.put(b"key3", b"value3").unwrap();
let snapshot = db.snapshot().unwrap();
db.put(b"key2", b"value2").unwrap();
let items: Vec<_> = snapshot.range(b"", None).unwrap().collect();
assert_eq!(items.len(), 2);
assert_eq!(items[0].as_ref().unwrap().0, bytes::Bytes::from("key1"));
assert_eq!(items[1].as_ref().unwrap().0, bytes::Bytes::from("key3"));
let db_items: Vec<_> = db.range(b"", None).unwrap().collect();
assert_eq!(db_items.len(), 3);
}
#[test]
fn test_concurrent_snapshot() {
let dir = tempdir().unwrap();
let db = Arc::new(
DBOptions::default()
.background_flush(true) .open(dir.path())
.unwrap(),
);
let db_clone = db.clone();
let handle = thread::spawn(move || {
for i in 0..1000 {
db_clone
.put(format!("key{}", i).as_bytes(), b"value")
.unwrap();
if i % 100 == 0 {
let _snap = db_clone.snapshot().unwrap();
}
}
});
handle.join().unwrap();
assert!(true);
}