mod helpers; use helpers::create_and_drop; use persy::ValueMode; #[test] fn test_snapshot_after_drop() { create_and_drop("after_drop", |persy| { let mut tx = persy.begin().unwrap(); tx.create_segment("test").unwrap(); tx.create_index::("index", ValueMode::Replace).unwrap(); let bytes = String::from("something").into_bytes(); let id = tx.insert("test", &bytes).unwrap(); tx.put::("index", 10, 20).unwrap(); let finalizer = tx.prepare().unwrap(); finalizer.commit().unwrap(); let snapshot = persy.snapshot().unwrap(); let mut tx = persy.begin().unwrap(); tx.drop_segment("test").unwrap(); tx.drop_index("index").unwrap(); let finalizer = tx.prepare().unwrap(); finalizer.commit().unwrap(); let bytes = String::from("something").into_bytes(); let read_after = snapshot.read("test", &id).unwrap(); assert_eq!(read_after, Some(bytes)); assert_eq!(snapshot.get::("index", &10).unwrap().next(), Some(20)); }); } #[test] fn test_double_snapshot_after_drop() { create_and_drop("double_after_drop", |persy| { let mut tx = persy.begin().unwrap(); tx.create_segment("test").unwrap(); tx.create_index::("index", ValueMode::Replace).unwrap(); let bytes = String::from("something").into_bytes(); let id = tx.insert("test", &bytes).unwrap(); tx.put::("index", 10, 20).unwrap(); let finalizer = tx.prepare().unwrap(); finalizer.commit().unwrap(); let snapshot = persy.snapshot().unwrap(); let snapshot1 = persy.snapshot().unwrap(); let mut tx = persy.begin().unwrap(); tx.drop_segment("test").unwrap(); tx.drop_index("index").unwrap(); let finalizer = tx.prepare().unwrap(); finalizer.commit().unwrap(); let bytes = String::from("something").into_bytes(); let read_after = snapshot.read("test", &id).unwrap(); assert_eq!(read_after, Some(bytes)); assert_eq!(snapshot.get::("index", &10).unwrap().next(), Some(20)); let bytes = String::from("something").into_bytes(); let read_after = snapshot1.read("test", &id).unwrap(); assert_eq!(read_after, Some(bytes)); assert_eq!(snapshot1.get::("index", &10).unwrap().next(), Some(20)); drop(snapshot1); let bytes = String::from("something").into_bytes(); let read_after = snapshot.read("test", &id).unwrap(); assert_eq!(read_after, Some(bytes)); assert_eq!(snapshot.get::("index", &10).unwrap().next(), Some(20)); }); } #[test] fn test_snapshot_ignore_newers() { create_and_drop("ignore_newers", |persy| { let mut tx = persy.begin().unwrap(); tx.create_segment("test").unwrap(); tx.create_index::("index", ValueMode::Replace).unwrap(); let bytes = String::from("something").into_bytes(); tx.insert("test", &bytes).unwrap(); tx.put::("index", 10, 20).unwrap(); let finalizer = tx.prepare().unwrap(); finalizer.commit().unwrap(); let snapshot = persy.snapshot().unwrap(); let mut tx = persy.begin().unwrap(); let bytes = String::from("other").into_bytes(); let id2 = tx.insert("test", &bytes).unwrap(); tx.put::("index", 11, 20).unwrap(); let finalizer = tx.prepare().unwrap(); finalizer.commit().unwrap(); let read_after = snapshot.read("test", &id2).unwrap(); assert_eq!(read_after, None); assert_eq!(snapshot.get::("index", &11).unwrap().len(), 0); }); } #[test] fn test_snapshot_list_after_drop() { create_and_drop("after_drop_list", |persy| { let mut tx = persy.begin().unwrap(); tx.create_segment("test").unwrap(); tx.create_index::("index", ValueMode::Replace).unwrap(); let bytes = String::from("something").into_bytes(); tx.insert("test", &bytes).unwrap(); tx.put::("index", 10, 20).unwrap(); let finalizer = tx.prepare().unwrap(); finalizer.commit().unwrap(); let snapshot = persy.snapshot().unwrap(); let mut tx = persy.begin().unwrap(); tx.drop_segment("test").unwrap(); tx.drop_index("index").unwrap(); let finalizer = tx.prepare().unwrap(); finalizer.commit().unwrap(); let read_after = snapshot.list_segments().unwrap(); assert_eq!(read_after.len(), 1); assert_eq!( read_after.into_iter().next().map(|(name, _)| (name)), Some("test".to_string()) ); let read_after = snapshot.list_indexes().unwrap(); assert_eq!(read_after.len(), 1); assert_eq!( read_after.into_iter().next().map(|(name, _)| (name)), Some("index".to_string()) ); }); } #[test] fn test_snapshot_scan_after_drop() { create_and_drop("after_drop_scan", |persy| { let mut tx = persy.begin().unwrap(); tx.create_segment("test").unwrap(); tx.create_index::("index", ValueMode::Replace).unwrap(); let bytes = String::from("something").into_bytes(); tx.insert("test", &bytes).unwrap(); tx.put::("index", 10, 20).unwrap(); let finalizer = tx.prepare().unwrap(); finalizer.commit().unwrap(); let snapshot = persy.snapshot().unwrap(); let mut tx = persy.begin().unwrap(); tx.drop_segment("test").unwrap(); tx.drop_index("index").unwrap(); let finalizer = tx.prepare().unwrap(); finalizer.commit().unwrap(); let read_after = snapshot.scan("test").unwrap(); assert_eq!(read_after.into_iter().next().map(|(_, content)| (content)), Some(bytes)); let mut read_after = snapshot.range::("index", ..).unwrap(); assert_eq!( read_after.next().map(|(_, value)| (value.into_iter().next().unwrap())), Some(20) ); }); } #[test] fn test_snapshot_after_remove_scan() { create_and_drop("after_remove_scan", |persy| { let mut tx = persy.begin().unwrap(); tx.create_segment("test").unwrap(); tx.create_index::("index", ValueMode::Replace).unwrap(); let bytes = String::from("something").into_bytes(); let id = tx.insert("test", &bytes).unwrap(); tx.put::("index", 10, 20).unwrap(); let finalizer = tx.prepare().unwrap(); finalizer.commit().unwrap(); let snapshot = persy.snapshot().unwrap(); let mut tx = persy.begin().unwrap(); tx.delete("test", &id).unwrap(); tx.remove::("index", 10, None).unwrap(); let finalizer = tx.prepare().unwrap(); finalizer.commit().unwrap(); let read_after = snapshot.read("test", &id).unwrap(); assert_eq!(read_after, Some(bytes.clone())); assert_eq!(snapshot.get::("index", &10).unwrap().next(), Some(20)); let mut read_after = snapshot.scan("test").unwrap(); assert_eq!(read_after.next().map(|(_, v)| v), Some(bytes)); assert_eq!( snapshot .range::("index", ..) .unwrap() .into_iter() .next() .map(|(_, v)| v.into_iter().next().unwrap()), Some(20) ); }); } #[test] fn test_snapshot_after_scan_after_delete_many() { create_and_drop("after_remove_scan", |persy| { let mut tx = persy.begin().unwrap(); tx.create_segment("test").unwrap(); let bytes = String::from("something").into_bytes(); for _ in 0..5000 { tx.insert("test", &bytes).unwrap(); } let finalizer = tx.prepare().unwrap(); finalizer.commit().unwrap(); let snapshot = persy.snapshot().unwrap(); let read_after = snapshot.scan("test").unwrap(); let mut tx = persy.begin().unwrap(); let recs = persy.scan("test").unwrap().map(|(id, ..)| id).collect::>(); //Reverse delete for some internal tweak forward delete works everytime for id in recs.iter().rev() { tx.delete("test", &id).unwrap(); } let finalizer = tx.prepare().unwrap(); finalizer.commit().unwrap(); assert_eq!(read_after.count(), 5000); }); }