142 lines
3.4 KiB
Rust
142 lines
3.4 KiB
Rust
|
|
use flurry::*;
|
||
|
|
use std::sync::Arc;
|
||
|
|
|
||
|
|
// These tests all use `K = String` and `Q = str` for `Borrow`-based lookups
|
||
|
|
|
||
|
|
#[test]
|
||
|
|
fn get_empty() {
|
||
|
|
let map = HashMap::<String, usize>::new();
|
||
|
|
|
||
|
|
{
|
||
|
|
let guard = map.guard();
|
||
|
|
let e = map.get("foo", &guard);
|
||
|
|
assert!(e.is_none());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#[test]
|
||
|
|
fn remove_empty() {
|
||
|
|
let map = HashMap::<String, usize>::new();
|
||
|
|
|
||
|
|
{
|
||
|
|
let guard = map.guard();
|
||
|
|
let old = map.remove("foo", &guard);
|
||
|
|
assert!(old.is_none());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#[test]
|
||
|
|
fn insert_and_remove() {
|
||
|
|
let map = HashMap::<String, usize>::new();
|
||
|
|
|
||
|
|
{
|
||
|
|
let guard = map.guard();
|
||
|
|
map.insert("foo".to_string(), 0, &guard);
|
||
|
|
let old = map.remove("foo", &guard).unwrap();
|
||
|
|
assert_eq!(old, &0);
|
||
|
|
assert!(map.get("foo", &guard).is_none());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#[test]
|
||
|
|
fn insert_and_get() {
|
||
|
|
let map = HashMap::<String, usize>::new();
|
||
|
|
|
||
|
|
map.insert("foo".to_string(), 0, &map.guard());
|
||
|
|
{
|
||
|
|
let guard = map.guard();
|
||
|
|
let e = map.get("foo", &guard).unwrap();
|
||
|
|
assert_eq!(e, &0);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#[test]
|
||
|
|
fn update() {
|
||
|
|
let map = HashMap::<String, usize>::new();
|
||
|
|
|
||
|
|
let guard = map.guard();
|
||
|
|
map.insert("foo".to_string(), 0, &guard);
|
||
|
|
let old = map.insert("foo".to_string(), 1, &guard);
|
||
|
|
assert_eq!(old, Some(&0));
|
||
|
|
{
|
||
|
|
let guard = map.guard();
|
||
|
|
let e = map.get("foo", &guard).unwrap();
|
||
|
|
assert_eq!(e, &1);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#[test]
|
||
|
|
#[cfg_attr(miri, ignore)]
|
||
|
|
fn concurrent_insert() {
|
||
|
|
let map = Arc::new(HashMap::<String, usize>::new());
|
||
|
|
let keys = Arc::new((0..64).map(|i| i.to_string()).collect::<Vec<_>>());
|
||
|
|
|
||
|
|
let map1 = map.clone();
|
||
|
|
let keys1 = keys.clone();
|
||
|
|
let t1 = std::thread::spawn(move || {
|
||
|
|
for key in keys1.iter() {
|
||
|
|
map1.insert(key.clone(), 0, &map1.guard());
|
||
|
|
}
|
||
|
|
});
|
||
|
|
let map2 = map.clone();
|
||
|
|
let keys2 = keys.clone();
|
||
|
|
let t2 = std::thread::spawn(move || {
|
||
|
|
for key in keys2.iter() {
|
||
|
|
map2.insert(key.clone(), 1, &map2.guard());
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
t1.join().unwrap();
|
||
|
|
t2.join().unwrap();
|
||
|
|
|
||
|
|
let guard = map.guard();
|
||
|
|
for key in keys.iter() {
|
||
|
|
let v = map.get(key.as_str(), &guard).unwrap();
|
||
|
|
assert!(v == &0 || v == &1);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#[test]
|
||
|
|
#[cfg_attr(miri, ignore)]
|
||
|
|
fn concurrent_remove() {
|
||
|
|
let map = Arc::new(HashMap::<String, usize>::new());
|
||
|
|
let keys = Arc::new((0..64).map(|i| i.to_string()).collect::<Vec<_>>());
|
||
|
|
|
||
|
|
{
|
||
|
|
let guard = map.guard();
|
||
|
|
for (i, key) in keys.iter().enumerate() {
|
||
|
|
map.insert(key.clone(), i, &guard);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
let map1 = map.clone();
|
||
|
|
let keys1 = keys.clone();
|
||
|
|
let t1 = std::thread::spawn(move || {
|
||
|
|
let guard = map1.guard();
|
||
|
|
for (i, key) in keys1.iter().enumerate() {
|
||
|
|
if let Some(v) = map1.remove(key.as_str(), &guard) {
|
||
|
|
assert_eq!(v, &i);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
});
|
||
|
|
let map2 = map.clone();
|
||
|
|
let keys2 = keys.clone();
|
||
|
|
let t2 = std::thread::spawn(move || {
|
||
|
|
let guard = map2.guard();
|
||
|
|
for (i, key) in keys2.iter().enumerate() {
|
||
|
|
if let Some(v) = map2.remove(key.as_str(), &guard) {
|
||
|
|
assert_eq!(v, &i);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
t1.join().unwrap();
|
||
|
|
t2.join().unwrap();
|
||
|
|
|
||
|
|
// after joining the threads, the map should be empty
|
||
|
|
let guard = map.guard();
|
||
|
|
for key in keys.iter() {
|
||
|
|
assert!(map.get(key.as_str(), &guard).is_none());
|
||
|
|
}
|
||
|
|
}
|