extern crate evmap;
#[test]
fn it_works() {
let x = ('x', 42);
let (r, mut w) = evmap::new();
assert_eq!(r.get_and(&x.0, |rs| rs.len()), None);
w.refresh();
assert_eq!(r.get_and(&x.0, |rs| rs.len()), None);
assert_eq!(r.meta_get_and(&x.0, |rs| rs.len()), Some((None, ())));
w.insert(x.0, x);
assert_eq!(r.get_and(&x.0, |rs| rs.len()), None);
assert_eq!(r.meta_get_and(&x.0, |rs| rs.len()), Some((None, ())));
w.refresh();
assert_eq!(r.get_and(&x.0, |rs| rs.len()), Some(1));
assert_eq!(r.meta_get_and(&x.0, |rs| rs.len()), Some((Some(1), ())));
assert_eq!(
r.get_and(&x.0, |rs| rs.iter().any(|v| v.0 == x.0 && v.1 == x.1)),
Some(true)
);
assert_eq!(r.get_and(&'y', |rs| rs.len()), None);
assert_eq!(r.meta_get_and(&'y', |rs| rs.len()), Some((None, ())));
w.purge();
assert_eq!(
r.get_and(&x.0, |rs| rs.iter().any(|v| v.0 == x.0 && v.1 == x.1)),
Some(true)
);
w.refresh();
assert_eq!(r.get_and(&x.0, |rs| rs.len()), None);
assert_eq!(r.meta_get_and(&x.0, |rs| rs.len()), Some((None, ())));
}
#[test]
fn read_after_drop() {
let x = ('x', 42);
let (r, mut w) = evmap::new();
w.insert(x.0, x);
w.refresh();
assert_eq!(r.get_and(&x.0, |rs| rs.len()), Some(1));
drop(w);
assert_eq!(r.get_and(&x.0, |rs| rs.len()), None);
assert_eq!(r.meta_get_and(&x.0, |rs| rs.len()), None);
}
#[test]
fn clone_types() {
let x = evmap::shallow_copy::CopyValue::from(b"xyz");
let (r, mut w) = evmap::new();
w.insert(&*x, x);
w.refresh();
assert_eq!(r.get_and(&*x, |rs| rs.len()), Some(1));
assert_eq!(r.meta_get_and(&*x, |rs| rs.len()), Some((Some(1), ())));
assert_eq!(r.get_and(&*x, |rs| rs.iter().any(|v| *v == x)), Some(true));
}
#[test]
fn busybusybusy_fast() {
busybusybusy_inner(false);
}
#[test]
fn busybusybusy_slow() {
busybusybusy_inner(true);
}
fn busybusybusy_inner(slow: bool) {
use std::thread;
use std::time;
let threads = 4;
let mut n = 1000;
if !slow {
n *= 100;
}
let (r, mut w) = evmap::new();
let rs: Vec<_> = (0..threads)
.map(|_| {
let r = r.clone();
thread::spawn(move || {
for i in 0..n {
let i = i.into();
loop {
match r.get_and(&i, |rs| {
if slow {
thread::sleep(time::Duration::from_millis(2));
}
Vec::from(rs)
}) {
Some(rs) => {
assert_eq!(rs.len(), 1);
assert_eq!(rs[0], i);
break;
}
None => {
thread::yield_now();
}
}
}
}
})
})
.collect();
for i in 0..n {
w.insert(i, i);
w.refresh();
}
for r in rs {
r.join().unwrap();
}
}
#[test]
fn busybusybusy_heap() {
use std::thread;
let threads = 2;
let n = 1000;
let (r, mut w) = evmap::new::<_, Vec<_>>();
let rs: Vec<_> = (0..threads)
.map(|_| {
let r = r.clone();
thread::spawn(move || {
for i in 0..n {
let i = i.into();
loop {
match r.get_and(&i, |rs| Vec::from(rs)) {
Some(rs) => {
assert_eq!(rs.len(), 1);
assert_eq!(rs[0].len(), i);
break;
}
None => {
thread::yield_now();
}
}
}
}
})
})
.collect();
for i in 0..n {
w.insert(i, (0..i).collect());
w.refresh();
}
for r in rs {
r.join().unwrap();
}
}
#[test]
fn minimal_query() {
let (r, mut w) = evmap::new();
w.insert(1, "a");
w.refresh();
w.insert(1, "b");
assert_eq!(r.get_and(&1, |rs| rs.len()), Some(1));
assert!(r.get_and(&1, |rs| rs.iter().any(|r| r == &"a")).unwrap());
}
#[test]
fn clear_vs_empty() {
let (r, mut w) = evmap::new::<_, ()>();
w.refresh();
assert_eq!(r.get_and(&1, |rs| rs.len()), None);
w.clear(1);
w.refresh();
assert_eq!(r.get_and(&1, |rs| rs.len()), Some(0));
w.empty(1);
w.refresh();
assert_eq!(r.get_and(&1, |rs| rs.len()), None);
w.clear(1);
w.refresh();
assert_eq!(r.get_and(&1, |rs| rs.len()), Some(0));
w.empty(1);
w.refresh();
assert_eq!(r.get_and(&1, |rs| rs.len()), None);
}
#[test]
fn non_copy_values() {
let (r, mut w) = evmap::new();
w.insert(1, "a".to_string());
w.refresh();
w.insert(1, "b".to_string());
assert_eq!(r.get_and(&1, |rs| rs.len()), Some(1));
assert!(r.get_and(&1, |rs| rs.iter().any(|r| r == "a")).unwrap());
}
#[test]
fn non_minimal_query() {
let (r, mut w) = evmap::new();
w.insert(1, "a");
w.insert(1, "b");
w.refresh();
w.insert(1, "c");
assert_eq!(r.get_and(&1, |rs| rs.len()), Some(2));
assert!(r.get_and(&1, |rs| rs.iter().any(|r| r == &"a")).unwrap());
assert!(r.get_and(&1, |rs| rs.iter().any(|r| r == &"b")).unwrap());
}
#[test]
fn absorb_negative_immediate() {
let (r, mut w) = evmap::new();
w.insert(1, "a");
w.insert(1, "b");
w.remove(1, "a");
w.refresh();
assert_eq!(r.get_and(&1, |rs| rs.len()), Some(1));
assert!(r.get_and(&1, |rs| rs.iter().any(|r| r == &"b")).unwrap());
}
#[test]
fn absorb_negative_later() {
let (r, mut w) = evmap::new();
w.insert(1, "a");
w.insert(1, "b");
w.refresh();
w.remove(1, "a");
w.refresh();
assert_eq!(r.get_and(&1, |rs| rs.len()), Some(1));
assert!(r.get_and(&1, |rs| rs.iter().any(|r| r == &"b")).unwrap());
}
#[test]
fn absorb_multi() {
let (r, mut w) = evmap::new();
w.extend(vec![(1, "a"), (1, "b")]);
w.refresh();
assert_eq!(r.get_and(&1, |rs| rs.len()), Some(2));
assert!(r.get_and(&1, |rs| rs.iter().any(|r| r == &"a")).unwrap());
assert!(r.get_and(&1, |rs| rs.iter().any(|r| r == &"b")).unwrap());
w.remove(1, "a");
w.insert(1, "c");
w.remove(1, "c");
w.refresh();
assert_eq!(r.get_and(&1, |rs| rs.len()), Some(1));
assert!(r.get_and(&1, |rs| rs.iter().any(|r| r == &"b")).unwrap());
}
#[test]
fn empty() {
let (r, mut w) = evmap::new();
w.insert(1, "a");
w.insert(1, "b");
w.insert(2, "c");
w.empty(1);
w.refresh();
assert_eq!(r.get_and(&1, |rs| rs.len()), None);
assert_eq!(r.get_and(&2, |rs| rs.len()), Some(1));
assert!(r.get_and(&2, |rs| rs.iter().any(|r| r == &"c")).unwrap());
}
#[test]
fn empty_post_refresh() {
let (r, mut w) = evmap::new();
w.insert(1, "a");
w.insert(1, "b");
w.insert(2, "c");
w.refresh();
w.empty(1);
w.refresh();
assert_eq!(r.get_and(&1, |rs| rs.len()), None);
assert_eq!(r.get_and(&2, |rs| rs.len()), Some(1));
assert!(r.get_and(&2, |rs| rs.iter().any(|r| r == &"c")).unwrap());
}
#[test]
fn clear() {
let (r, mut w) = evmap::new();
w.insert(1, "a");
w.insert(1, "b");
w.insert(2, "c");
w.clear(1);
w.refresh();
assert_eq!(r.get_and(&1, |rs| rs.len()), Some(0));
assert_eq!(r.get_and(&2, |rs| rs.len()), Some(1));
w.clear(2);
w.refresh();
assert_eq!(r.get_and(&1, |rs| rs.len()), Some(0));
assert_eq!(r.get_and(&2, |rs| rs.len()), Some(0));
w.empty(1);
w.refresh();
assert_eq!(r.get_and(&1, |rs| rs.len()), None);
assert_eq!(r.get_and(&2, |rs| rs.len()), Some(0));
}
#[test]
fn replace() {
let (r, mut w) = evmap::new();
w.insert(1, "a");
w.insert(1, "b");
w.insert(2, "c");
w.update(1, "x");
w.refresh();
assert_eq!(r.get_and(&1, |rs| rs.len()), Some(1));
assert!(r.get_and(&1, |rs| rs.iter().any(|r| r == &"x")).unwrap());
assert_eq!(r.get_and(&2, |rs| rs.len()), Some(1));
assert!(r.get_and(&2, |rs| rs.iter().any(|r| r == &"c")).unwrap());
}
#[test]
fn replace_post_refresh() {
let (r, mut w) = evmap::new();
w.insert(1, "a");
w.insert(1, "b");
w.insert(2, "c");
w.refresh();
w.update(1, "x");
w.refresh();
assert_eq!(r.get_and(&1, |rs| rs.len()), Some(1));
assert!(r.get_and(&1, |rs| rs.iter().any(|r| r == &"x")).unwrap());
assert_eq!(r.get_and(&2, |rs| rs.len()), Some(1));
assert!(r.get_and(&2, |rs| rs.iter().any(|r| r == &"c")).unwrap());
}
#[test]
fn with_meta() {
let (r, mut w) = evmap::with_meta::<usize, usize, _>(42);
assert_eq!(r.meta_get_and(&1, |rs| rs.len()), None);
w.refresh();
assert_eq!(r.meta_get_and(&1, |rs| rs.len()), Some((None, 42)));
w.set_meta(43);
assert_eq!(r.meta_get_and(&1, |rs| rs.len()), Some((None, 42)));
w.refresh();
assert_eq!(r.meta_get_and(&1, |rs| rs.len()), Some((None, 43)));
}
#[test]
fn map_into() {
let (r, mut w) = evmap::new();
w.insert(1, "a");
w.insert(1, "b");
w.insert(2, "c");
w.refresh();
w.insert(1, "x");
use std::collections::HashMap;
let copy: HashMap<_, Vec<_>> = r.map_into(|&k, vs| (k, vs.to_vec()));
assert_eq!(copy.len(), 2);
assert!(copy.contains_key(&1));
assert!(copy.contains_key(&2));
assert_eq!(copy[&1].len(), 2);
assert_eq!(copy[&2].len(), 1);
assert_eq!(copy[&1], vec!["a", "b"]);
assert_eq!(copy[&2], vec!["c"]);
}
#[test]
fn clone_churn() {
use std::thread;
let (r, mut w) = evmap::new();
thread::spawn(move || loop {
let r = r.clone();
if let Some(_) = r.get_and(&1, |rs| rs.len()) {
thread::yield_now();
}
});
for i in 0..1000 {
w.insert(1, i);
w.refresh();
}
}
#[test]
fn foreach() {
let (r, mut w) = evmap::new();
w.insert(1, "a");
w.insert(1, "b");
w.insert(2, "c");
w.refresh();
w.insert(1, "x");
r.for_each(|&k, vs| match k {
1 => assert_eq!(vs, &*vec!["a", "b"]),
2 => assert_eq!(vs, &*vec!["c"]),
_ => unreachable!(),
});
}
#[test]
fn retain() {
let mut v = Vec::new();
let (r, mut w) = evmap::new();
for i in 0..50 {
w.insert(0, i);
v.push(i);
}
fn is_even(num: &i32) -> bool {
num % 2 == 0
}
w.retain(0, is_even).refresh();
v.retain(is_even);
r.get_and(&0, |nums| assert_eq!(v, nums)).unwrap();
}