mod util;
use flashmap::Evicted;
use std::{ops::Deref, thread};
#[test]
pub fn nested_readers() {
let (mut write, read) = flashmap::new::<Box<u32>, Box<u32>>();
let t1 = thread::spawn(move || {
write.guard().insert(Box::new(10), Box::new(20));
write.guard().insert(Box::new(20), Box::new(40));
});
let t2 = thread::spawn(move || {
let outer = read.guard();
let forty = outer.get(&20);
let middle = read.guard();
assert!(matches!(forty.map(Deref::deref), Some(40) | None));
let inner = read.guard();
let twenty = middle.get(&10);
assert!(matches!(forty.map(Deref::deref), Some(40) | None));
drop(outer);
assert!(matches!(twenty.map(Deref::deref), Some(20) | None));
assert_eq!(inner.get(&10), twenty);
drop(inner);
assert!(matches!(twenty.map(Deref::deref), Some(20) | None));
drop(middle);
});
t1.join().unwrap();
t2.join().unwrap();
}
#[test]
pub fn reclamation() {
let (mut write, read) = flashmap::new::<Box<u32>, Box<u32>>();
let mut guard = write.guard();
guard.insert(Box::new(10), Box::new(20));
guard.insert(Box::new(20), Box::new(40));
guard.insert(Box::new(40), Box::new(80));
drop(guard);
let mut guard = write.guard();
let twenty = guard.remove(Box::new(10)).unwrap();
let forty = guard.replace(Box::new(20), |_| Box::new(50)).unwrap();
let leaked_twenty = Evicted::leak(twenty);
let leaked_forty = Evicted::leak(forty);
let eighty = guard.insert(Box::new(40), Box::new(90)).unwrap();
let leaked_eighty = Evicted::leak(eighty);
drop(guard);
let reclaimer = write.reclaimer();
let twenty = reclaimer(leaked_twenty);
let forty = reclaimer(leaked_forty);
drop(reclaimer);
assert_eq!(*twenty * 2, *forty);
assert_eq!(**leaked_eighty, 80);
write.guard().drop_lazily(leaked_eighty);
drop(write);
let guard = read.guard();
assert!(guard.get(&10).is_none());
assert_eq!(**guard.get(&20).unwrap(), 50);
assert_eq!(**guard.get(&40).unwrap(), 90);
drop(guard);
drop(read);
}