chore: checkpoint before Python removal

This commit is contained in:
2026-03-26 22:33:59 +00:00
parent 683cec9307
commit e568ddf82a
29972 changed files with 11269302 additions and 2 deletions

621
vendor/flurry/tests/basic.rs vendored Normal file
View File

@@ -0,0 +1,621 @@
use flurry::*;
use std::sync::Arc;
#[test]
fn new() {
let _map = HashMap::<usize, usize>::new();
}
#[test]
fn clear() {
let map = HashMap::<usize, usize>::new();
let guard = map.guard();
{
map.insert(0, 1, &guard);
map.insert(1, 1, &guard);
map.insert(2, 1, &guard);
map.insert(3, 1, &guard);
map.insert(4, 1, &guard);
}
map.clear(&guard);
assert!(map.is_empty());
}
#[test]
fn insert() {
let map = HashMap::<usize, usize>::new();
let guard = map.guard();
let old = map.insert(42, 0, &guard);
assert!(old.is_none());
}
#[test]
fn get_empty() {
let map = HashMap::<usize, usize>::new();
{
let guard = map.guard();
let e = map.get(&42, &guard);
assert!(e.is_none());
}
}
#[test]
fn get_key_value_empty() {
let map = HashMap::<usize, usize>::new();
{
let guard = map.guard();
let e = map.get_key_value(&42, &guard);
assert!(e.is_none());
}
}
#[test]
fn remove_empty() {
let map = HashMap::<usize, usize>::new();
{
let guard = map.guard();
let old = map.remove(&42, &guard);
assert!(old.is_none());
}
}
#[test]
fn insert_and_remove() {
let map = HashMap::<usize, usize>::new();
{
let guard = map.guard();
map.insert(42, 0, &guard);
let old = map.remove(&42, &guard).unwrap();
assert_eq!(old, &0);
assert!(map.get(&42, &guard).is_none());
}
}
#[test]
fn insert_and_get() {
let map = HashMap::<usize, usize>::new();
map.insert(42, 0, &map.guard());
{
let guard = map.guard();
let e = map.get(&42, &guard).unwrap();
assert_eq!(e, &0);
}
}
#[test]
fn insert_and_get_key_value() {
let map = HashMap::<usize, usize>::new();
map.insert(42, 0, &map.guard());
{
let guard = map.guard();
let e = map.get_key_value(&42, &guard).unwrap();
assert_eq!(e, (&42, &0));
}
}
mod hasher;
use hasher::ZeroHashBuilder;
#[test]
fn one_bucket() {
let map = HashMap::<&'static str, usize, _>::with_hasher(ZeroHashBuilder);
let guard = map.guard();
// we want to check that all operations work regardless on whether
// we are operating on the head of a bucket, the tail of the bucket,
// or somewhere in the middle.
let v = map.insert("head", 0, &guard);
assert_eq!(v, None);
let v = map.insert("middle", 10, &guard);
assert_eq!(v, None);
let v = map.insert("tail", 100, &guard);
assert_eq!(v, None);
let e = map.get("head", &guard).unwrap();
assert_eq!(e, &0);
let e = map.get("middle", &guard).unwrap();
assert_eq!(e, &10);
let e = map.get("tail", &guard).unwrap();
assert_eq!(e, &100);
// check that replacing the keys returns the correct old value
let v = map.insert("head", 1, &guard);
assert_eq!(v, Some(&0));
let v = map.insert("middle", 11, &guard);
assert_eq!(v, Some(&10));
let v = map.insert("tail", 101, &guard);
assert_eq!(v, Some(&100));
// and updated the right value
let e = map.get("head", &guard).unwrap();
assert_eq!(e, &1);
let e = map.get("middle", &guard).unwrap();
assert_eq!(e, &11);
let e = map.get("tail", &guard).unwrap();
assert_eq!(e, &101);
// and that remove produces the right value
// note that we must remove them in a particular order
// so that we test all three node positions
let v = map.remove("middle", &guard);
assert_eq!(v, Some(&11));
let v = map.remove("tail", &guard);
assert_eq!(v, Some(&101));
let v = map.remove("head", &guard);
assert_eq!(v, Some(&1));
}
#[test]
fn update() {
let map = HashMap::<usize, usize>::new();
let guard = map.guard();
map.insert(42, 0, &guard);
let old = map.insert(42, 1, &guard);
assert_eq!(old, Some(&0));
{
let guard = map.guard();
let e = map.get(&42, &guard).unwrap();
assert_eq!(e, &1);
}
}
#[test]
fn compute_if_present() {
let map = HashMap::<usize, usize>::new();
let guard = map.guard();
map.insert(42, 0, &guard);
let new = map.compute_if_present(&42, |_, v| Some(v + 1), &guard);
assert_eq!(new, Some(&1));
{
let guard = map.guard();
let e = map.get(&42, &guard).unwrap();
assert_eq!(e, &1);
}
}
#[test]
fn compute_if_present_empty() {
let map = HashMap::<usize, usize>::new();
let guard = map.guard();
let new = map.compute_if_present(&42, |_, v| Some(v + 1), &guard);
assert!(new.is_none());
{
let guard = map.guard();
assert!(map.get(&42, &guard).is_none());
}
}
#[test]
fn compute_if_present_remove() {
let map = HashMap::<usize, usize>::new();
let guard = map.guard();
map.insert(42, 0, &guard);
let new = map.compute_if_present(&42, |_, _| None, &guard);
assert!(new.is_none());
{
let guard = map.guard();
assert!(map.get(&42, &guard).is_none());
}
}
#[test]
#[cfg_attr(miri, ignore)]
fn concurrent_insert() {
let map = Arc::new(HashMap::<usize, usize>::new());
let map1 = map.clone();
let t1 = std::thread::spawn(move || {
for i in 0..64 {
map1.insert(i, 0, &map1.guard());
}
});
let map2 = map.clone();
let t2 = std::thread::spawn(move || {
for i in 0..64 {
map2.insert(i, 1, &map2.guard());
}
});
t1.join().unwrap();
t2.join().unwrap();
let guard = map.guard();
for i in 0..64 {
let v = map.get(&i, &guard).unwrap();
assert!(v == &0 || v == &1);
let kv = map.get_key_value(&i, &guard).unwrap();
assert!(kv == (&i, &0) || kv == (&i, &1));
}
}
#[test]
#[cfg_attr(miri, ignore)]
fn concurrent_remove() {
let map = Arc::new(HashMap::<usize, usize>::new());
{
let guard = map.guard();
for i in 0..64 {
map.insert(i, i, &guard);
}
}
let map1 = map.clone();
let t1 = std::thread::spawn(move || {
let guard = map1.guard();
for i in 0..64 {
if let Some(v) = map1.remove(&i, &guard) {
assert_eq!(v, &i);
}
}
});
let map2 = map.clone();
let t2 = std::thread::spawn(move || {
let guard = map2.guard();
for i in 0..64 {
if let Some(v) = map2.remove(&i, &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 i in 0..64 {
assert!(map.get(&i, &guard).is_none());
}
}
#[test]
#[cfg_attr(miri, ignore)]
fn concurrent_compute_if_present() {
let map = Arc::new(HashMap::<usize, usize>::new());
{
let guard = map.guard();
for i in 0..64 {
map.insert(i, i, &guard);
}
}
let map1 = map.clone();
let t1 = std::thread::spawn(move || {
let guard = map1.guard();
for i in 0..64 {
let new = map1.compute_if_present(&i, |_, _| None, &guard);
assert!(new.is_none());
}
});
let map2 = map.clone();
let t2 = std::thread::spawn(move || {
let guard = map2.guard();
for i in 0..64 {
let new = map2.compute_if_present(&i, |_, _| None, &guard);
assert!(new.is_none());
}
});
t1.join().unwrap();
t2.join().unwrap();
// after joining the threads, the map should be empty
let guard = map.guard();
for i in 0..64 {
assert!(map.get(&i, &guard).is_none());
}
}
#[test]
#[cfg_attr(miri, ignore)]
fn concurrent_resize_and_get() {
let map = Arc::new(HashMap::<usize, usize>::new());
{
let guard = map.guard();
for i in 0..1024 {
map.insert(i, i, &guard);
}
}
let map1 = map.clone();
// t1 is using reserve to trigger a bunch of resizes
let t1 = std::thread::spawn(move || {
let guard = map1.guard();
// there should be 2 ** 10 capacity already, so trigger additional resizes
for power in 11..16 {
map1.reserve(1 << power, &guard);
}
});
let map2 = map.clone();
// t2 is retrieving existing keys a lot, attempting to encounter a BinEntry::Moved
let t2 = std::thread::spawn(move || {
let guard = map2.guard();
for _ in 0..32 {
for i in 0..1024 {
let v = map2.get(&i, &guard).unwrap();
assert_eq!(v, &i);
}
}
});
t1.join().unwrap();
t2.join().unwrap();
// make sure all the entries still exist after all the resizes
{
let guard = map.guard();
for i in 0..1024 {
let v = map.get(&i, &guard).unwrap();
assert_eq!(v, &i);
}
}
}
#[test]
fn current_kv_dropped() {
let dropped1 = Arc::new(0);
let dropped2 = Arc::new(0);
let map = HashMap::<Arc<usize>, Arc<usize>>::new();
map.insert(dropped1.clone(), dropped2.clone(), &map.guard());
assert_eq!(Arc::strong_count(&dropped1), 2);
assert_eq!(Arc::strong_count(&dropped2), 2);
drop(map);
// dropping the map should immediately drop (not deferred) all keys and values
assert_eq!(Arc::strong_count(&dropped1), 1);
assert_eq!(Arc::strong_count(&dropped2), 1);
}
#[test]
fn empty_maps_equal() {
let map1 = HashMap::<usize, usize>::new();
let map2 = HashMap::<usize, usize>::new();
assert_eq!(map1, map2);
assert_eq!(map2, map1);
}
#[test]
fn different_size_maps_not_equal() {
let map1 = HashMap::<usize, usize>::new();
let map2 = HashMap::<usize, usize>::new();
{
let guard1 = map1.guard();
let guard2 = map2.guard();
map1.insert(1, 0, &guard1);
map1.insert(2, 0, &guard1);
map1.insert(3, 0, &guard1);
map2.insert(1, 0, &guard2);
map2.insert(2, 0, &guard2);
}
assert_ne!(map1, map2);
assert_ne!(map2, map1);
}
#[test]
fn same_values_equal() {
let map1 = HashMap::<usize, usize>::new();
let map2 = HashMap::<usize, usize>::new();
{
map1.pin().insert(1, 0);
map2.pin().insert(1, 0);
}
assert_eq!(map1, map2);
assert_eq!(map2, map1);
}
#[test]
fn different_values_not_equal() {
let map1 = HashMap::<usize, usize>::new();
let map2 = HashMap::<usize, usize>::new();
{
map1.pin().insert(1, 0);
map2.pin().insert(1, 1);
}
assert_ne!(map1, map2);
assert_ne!(map2, map1);
}
#[test]
#[ignore]
// ignored because we cannot control when destructors run
fn drop_value() {
let dropped1 = Arc::new(0);
let dropped2 = Arc::new(1);
let map = HashMap::<usize, Arc<usize>>::new();
map.insert(42, dropped1.clone(), &map.guard());
assert_eq!(Arc::strong_count(&dropped1), 2);
assert_eq!(Arc::strong_count(&dropped2), 1);
map.insert(42, dropped2.clone(), &map.guard());
assert_eq!(Arc::strong_count(&dropped2), 2);
drop(map);
// First NotifyOnDrop was dropped when it was replaced by the second
assert_eq!(Arc::strong_count(&dropped1), 1);
// Second NotifyOnDrop was dropped when the map was dropped
assert_eq!(Arc::strong_count(&dropped2), 1);
}
#[test]
fn clone_map_empty() {
let map = HashMap::<&'static str, u32>::new();
let cloned_map = map.clone();
assert_eq!(map.len(), cloned_map.len());
assert_eq!(&map, &cloned_map);
assert_eq!(cloned_map.len(), 0);
}
#[test]
// Test that same values exists in both maps (original and cloned)
fn clone_map_filled() {
let map = HashMap::<&'static str, u32>::new();
map.insert("FooKey", 0, &map.guard());
map.insert("BarKey", 10, &map.guard());
let cloned_map = map.clone();
assert_eq!(map.len(), cloned_map.len());
assert_eq!(&map, &cloned_map);
// test that we are not mapping the same tables
map.insert("NewItem", 100, &map.guard());
assert_ne!(&map, &cloned_map);
}
#[test]
fn default() {
let map: HashMap<usize, usize> = Default::default();
let guard = map.guard();
map.insert(42, 0, &guard);
assert_eq!(map.get(&42, &guard), Some(&0));
}
#[test]
fn debug() {
let map: HashMap<usize, usize> = HashMap::new();
let guard = map.guard();
map.insert(42, 0, &guard);
map.insert(16, 8, &guard);
let formatted = format!("{:?}", map);
assert!(formatted == "{42: 0, 16: 8}" || formatted == "{16: 8, 42: 0}");
}
#[test]
fn extend() {
let map: HashMap<usize, usize> = HashMap::new();
let guard = map.guard();
let mut entries: Vec<(usize, usize)> = vec![(42, 0), (16, 6), (38, 42)];
entries.sort_unstable();
(&map).extend(entries.clone().into_iter());
let mut collected: Vec<(usize, usize)> = map
.iter(&guard)
.map(|(key, value)| (*key, *value))
.collect();
collected.sort_unstable();
assert_eq!(entries, collected);
}
#[test]
fn extend_ref() {
let map: HashMap<usize, usize> = HashMap::new();
let mut entries: Vec<(&usize, &usize)> = vec![(&42, &0), (&16, &6), (&38, &42)];
entries.sort();
(&map).extend(entries.clone().into_iter());
let guard = map.guard();
let mut collected: Vec<(&usize, &usize)> = map.iter(&guard).collect();
collected.sort();
assert_eq!(entries, collected);
}
#[test]
fn from_iter_ref() {
use std::iter::FromIterator;
let mut entries: Vec<(&usize, &usize)> = vec![(&42, &0), (&16, &6), (&38, &42)];
entries.sort();
let map: HashMap<usize, usize> = HashMap::from_iter(entries.clone().into_iter());
let guard = map.guard();
let mut collected: Vec<(&usize, &usize)> = map.iter(&guard).collect();
collected.sort();
assert_eq!(entries, entries)
}
#[test]
fn from_iter_empty() {
use std::iter::FromIterator;
let entries: Vec<(usize, usize)> = Vec::new();
let map: HashMap<usize, usize> = HashMap::from_iter(entries.into_iter());
assert_eq!(map.len(), 0)
}
#[test]
fn retain_empty() {
let map = HashMap::<&'static str, u32>::new();
let guard = map.guard();
map.retain(|_, _| false, &guard);
assert_eq!(map.len(), 0);
}
#[test]
fn retain_all_false() {
let map: HashMap<u32, u32> = (0..10_u32).map(|x| (x, x)).collect();
let guard = map.guard();
map.retain(|_, _| false, &guard);
assert_eq!(map.len(), 0);
}
#[test]
fn retain_all_true() {
let size = 10usize;
let map: HashMap<usize, usize> = (0..size).map(|x| (x, x)).collect();
let guard = map.guard();
map.retain(|_, _| true, &guard);
assert_eq!(map.len(), size);
}
#[test]
fn retain_some() {
let map: HashMap<u32, u32> = (0..10).map(|x| (x, x)).collect();
let guard = map.guard();
let expected_map: HashMap<u32, u32> = (5..10).map(|x| (x, x)).collect();
map.retain(|_, v| *v >= 5, &guard);
assert_eq!(map.len(), 5);
assert_eq!(map, expected_map);
}
#[test]
fn retain_force_empty() {
let map = HashMap::<&'static str, u32>::new();
let guard = map.guard();
map.retain_force(|_, _| false, &guard);
assert_eq!(map.len(), 0);
}
#[test]
fn retain_force_some() {
let map: HashMap<u32, u32> = (0..10).map(|x| (x, x)).collect();
let guard = map.guard();
let expected_map: HashMap<u32, u32> = (5..10).map(|x| (x, x)).collect();
map.retain_force(|_, v| *v >= 5, &guard);
assert_eq!(map.len(), 5);
assert_eq!(map, expected_map);
}

525
vendor/flurry/tests/basic_ref.rs vendored Normal file
View File

@@ -0,0 +1,525 @@
use flurry::*;
use std::sync::Arc;
#[test]
fn pin() {
let map = HashMap::<usize, usize>::new();
let _pinned = map.pin();
}
#[test]
fn with_guard() {
let map = HashMap::<usize, usize>::new();
let guard = map.guard();
let _pinned = map.with_guard(&guard);
}
#[test]
fn clear() {
let map = HashMap::<usize, usize>::new();
let map = map.pin();
{
map.insert(0, 1);
map.insert(1, 1);
map.insert(2, 1);
map.insert(3, 1);
map.insert(4, 1);
}
map.clear();
assert!(map.is_empty());
}
#[test]
fn insert() {
let map = HashMap::<usize, usize>::new();
let map = map.pin();
let old = map.insert(42, 0);
assert!(old.is_none());
}
#[test]
fn get_empty() {
let map = HashMap::<usize, usize>::new();
let map = map.pin();
let e = map.get(&42);
assert!(e.is_none());
}
#[test]
fn get_key_value_empty() {
let map = HashMap::<usize, usize>::new();
let map = map.pin();
let e = map.get_key_value(&42);
assert!(e.is_none());
}
#[test]
fn remove_empty() {
let map = HashMap::<usize, usize>::new();
let map = map.pin();
let old = map.remove(&42);
assert!(old.is_none());
}
#[test]
fn insert_and_remove() {
let map = HashMap::<usize, usize>::new();
let map = map.pin();
map.insert(42, 0);
let old = map.remove(&42).unwrap();
assert_eq!(old, &0);
assert!(map.get(&42).is_none());
}
#[test]
fn insert_and_get() {
let map = HashMap::<usize, usize>::new();
map.pin().insert(42, 0);
{
let map = map.pin();
let e = map.get(&42).unwrap();
assert_eq!(e, &0);
}
}
#[test]
fn insert_and_get_key_value() {
let map = HashMap::<usize, usize>::new();
map.pin().insert(42, 0);
{
let map = map.pin();
let e = map.get_key_value(&42).unwrap();
assert_eq!(e, (&42, &0));
}
}
mod hasher;
use hasher::ZeroHashBuilder;
#[test]
fn one_bucket() {
let map = HashMap::<&'static str, usize, _>::with_hasher(ZeroHashBuilder);
let map = map.pin();
// we want to check that all operations work regardless on whether
// we are operating on the head of a bucket, the tail of the bucket,
// or somewhere in the middle.
let v = map.insert("head", 0);
assert_eq!(v, None);
let v = map.insert("middle", 10);
assert_eq!(v, None);
let v = map.insert("tail", 100);
assert_eq!(v, None);
let e = map.get("head").unwrap();
assert_eq!(e, &0);
let e = map.get("middle").unwrap();
assert_eq!(e, &10);
let e = map.get("tail").unwrap();
assert_eq!(e, &100);
// check that replacing the keys returns the correct old value
let v = map.insert("head", 1);
assert_eq!(v, Some(&0));
let v = map.insert("middle", 11);
assert_eq!(v, Some(&10));
let v = map.insert("tail", 101);
assert_eq!(v, Some(&100));
// and updated the right value
let e = map.get("head").unwrap();
assert_eq!(e, &1);
let e = map.get("middle").unwrap();
assert_eq!(e, &11);
let e = map.get("tail").unwrap();
assert_eq!(e, &101);
// and that remove produces the right value
// note that we must remove them in a particular order
// so that we test all three node positions
let v = map.remove("middle");
assert_eq!(v, Some(&11));
let v = map.remove("tail");
assert_eq!(v, Some(&101));
let v = map.remove("head");
assert_eq!(v, Some(&1));
}
#[test]
fn update() {
let map = HashMap::<usize, usize>::new();
let map1 = map.pin();
map1.insert(42, 0);
let old = map1.insert(42, 1);
assert_eq!(old, Some(&0));
{
let map2 = map.pin();
let e = map2.get(&42).unwrap();
assert_eq!(e, &1);
}
}
#[test]
fn compute_if_present() {
let map = HashMap::<usize, usize>::new();
let map1 = map.pin();
map1.insert(42, 0);
let new = map1.compute_if_present(&42, |_, v| Some(v + 1));
assert_eq!(new, Some(&1));
{
let map2 = map.pin();
let e = map2.get(&42).unwrap();
assert_eq!(e, &1);
}
}
#[test]
fn compute_if_present_empty() {
let map = HashMap::<usize, usize>::new();
let map1 = map.pin();
let new = map1.compute_if_present(&42, |_, v| Some(v + 1));
assert!(new.is_none());
{
let map2 = map.pin();
assert!(map2.get(&42).is_none());
}
}
#[test]
fn compute_if_present_remove() {
let map = HashMap::<usize, usize>::new();
let map1 = map.pin();
map1.insert(42, 0);
let new = map1.compute_if_present(&42, |_, _| None);
assert!(new.is_none());
{
let map2 = map.pin();
assert!(map2.get(&42).is_none());
}
}
#[test]
fn empty_maps_equal() {
let map1 = HashMap::<usize, usize>::new();
let map2 = HashMap::<usize, usize>::new();
assert_eq!(map1, map2.pin());
assert_eq!(map1.pin(), map2);
assert_eq!(map1.pin(), map2.pin());
assert_eq!(map2.pin(), map1.pin());
}
#[test]
fn different_size_maps_not_equal() {
let map1 = HashMap::<usize, usize>::new();
let map2 = HashMap::<usize, usize>::new();
{
let map1 = map1.pin();
let map2 = map2.pin();
map1.insert(1, 0);
map1.insert(2, 0);
map2.insert(1, 0);
}
assert_ne!(map1, map2.pin());
assert_ne!(map1.pin(), map2);
assert_ne!(map1.pin(), map2.pin());
assert_ne!(map2.pin(), map1.pin());
}
#[test]
fn same_values_equal() {
let map1 = HashMap::<usize, usize>::new();
let map2 = HashMap::<usize, usize>::new();
{
let map1 = map1.pin();
let map2 = map2.pin();
map1.insert(1, 0);
map2.insert(1, 0);
}
assert_eq!(map1, map2.pin());
assert_eq!(map1.pin(), map2);
assert_eq!(map1.pin(), map2.pin());
assert_eq!(map2.pin(), map1.pin());
}
#[test]
fn different_values_not_equal() {
let map1 = HashMap::<usize, usize>::new();
let map2 = HashMap::<usize, usize>::new();
{
let map1 = map1.pin();
let map2 = map2.pin();
map1.insert(1, 0);
map2.insert(1, 1);
}
assert_ne!(map1, map2.pin());
assert_ne!(map1.pin(), map2);
assert_ne!(map1.pin(), map2.pin());
assert_ne!(map2.pin(), map1.pin());
}
#[test]
#[ignore]
// ignored because we cannot control when destructors run
fn drop_value() {
let dropped1 = Arc::new(0);
let dropped2 = Arc::new(1);
let map = HashMap::<usize, Arc<usize>>::new();
let map = map.pin();
map.insert(42, dropped1.clone());
assert_eq!(Arc::strong_count(&dropped1), 2);
assert_eq!(Arc::strong_count(&dropped2), 1);
map.insert(42, dropped2.clone());
assert_eq!(Arc::strong_count(&dropped2), 2);
drop(map);
// First NotifyOnDrop was dropped when it was replaced by the second
assert_eq!(Arc::strong_count(&dropped1), 1);
// Second NotifyOnDrop was dropped when the map was dropped
assert_eq!(Arc::strong_count(&dropped2), 1);
}
#[test]
fn clone_map_empty() {
let map = HashMap::<&'static str, u32>::new();
let map = map.pin();
let cloned_map = map.clone();
assert_eq!(map.len(), cloned_map.len());
assert_eq!(&map, &cloned_map);
assert_eq!(cloned_map.len(), 0);
}
#[test]
// Test that same values exists in both maps (original and cloned)
fn clone_map_filled() {
let map_ref = HashMap::<&'static str, u32>::new();
let map_ref = map_ref.pin();
map_ref.insert("FooKey", 0);
map_ref.insert("BarKey", 10);
let cloned_map_ref = map_ref.clone();
assert_eq!(map_ref.len(), cloned_map_ref.len());
assert_eq!(&map_ref, &cloned_map_ref);
// test that both maps are equal,
// because the ref and the cloned ref, point to the same map
map_ref.insert("NewItem", 100);
assert_eq!(&map_ref, &cloned_map_ref);
}
#[test]
fn default() {
let map: HashMap<usize, usize> = Default::default();
let map = map.pin();
map.insert(42, 0);
assert_eq!(map.get(&42), Some(&0));
}
#[test]
fn debug() {
let map: HashMap<usize, usize> = HashMap::new();
let map = map.pin();
map.insert(42, 0);
map.insert(16, 8);
let formatted = format!("{:?}", map);
assert!(formatted == "{42: 0, 16: 8}" || formatted == "{16: 8, 42: 0}");
}
#[test]
fn from_iter_ref() {
use std::iter::FromIterator;
let mut entries: Vec<(&usize, &usize)> = vec![(&42, &0), (&16, &6), (&38, &42)];
entries.sort();
let map: HashMap<usize, usize> = HashMap::from_iter(entries.clone().into_iter());
let map = map.pin();
let mut collected: Vec<(&usize, &usize)> = map.iter().collect();
collected.sort();
assert_eq!(entries, entries)
}
#[test]
fn from_iter_empty() {
use std::iter::FromIterator;
let entries: Vec<(usize, usize)> = Vec::new();
let map: HashMap<usize, usize> = HashMap::from_iter(entries.into_iter());
let map = map.pin();
assert_eq!(map.len(), 0)
}
#[test]
fn retain_empty() {
let map = HashMap::<&'static str, u32>::new();
let map = map.pin();
map.retain(|_, _| false);
assert_eq!(map.len(), 0);
}
#[test]
fn retain_all_false() {
let map: HashMap<u32, u32> = (0..10 as u32).map(|x| (x, x)).collect();
let map = map.pin();
map.retain(|_, _| false);
assert_eq!(map.len(), 0);
}
#[test]
fn retain_all_true() {
let size = 10usize;
let map: HashMap<usize, usize> = (0..size).map(|x| (x, x)).collect();
let map = map.pin();
map.retain(|_, _| true);
assert_eq!(map.len(), size);
}
#[test]
fn retain_some() {
let map: HashMap<u32, u32> = (0..10).map(|x| (x, x)).collect();
let map = map.pin();
let expected_map: HashMap<u32, u32> = (5..10).map(|x| (x, x)).collect();
let expected_map = expected_map.pin();
map.retain(|_, v| *v >= 5);
assert_eq!(map.len(), 5);
assert_eq!(map, expected_map);
}
#[test]
fn retain_force_empty() {
let map = HashMap::<&'static str, u32>::new();
let map = map.pin();
map.retain_force(|_, _| false);
assert_eq!(map.len(), 0);
}
#[test]
fn retain_force_some() {
let map: HashMap<u32, u32> = (0..10).map(|x| (x, x)).collect();
let map = map.pin();
let expected_map: HashMap<u32, u32> = (5..10).map(|x| (x, x)).collect();
map.retain_force(|_, v| *v >= 5);
assert_eq!(map.len(), 5);
assert_eq!(map, expected_map);
}
#[test]
#[cfg_attr(miri, ignore)]
fn concurrent_insert() {
let map = Arc::new(HashMap::<usize, usize>::new());
let map1 = map.clone();
let t1 = std::thread::spawn(move || {
for i in 0..64 {
map1.pin().insert(i, 0);
}
});
let map2 = map.clone();
let t2 = std::thread::spawn(move || {
for i in 0..64 {
map2.pin().insert(i, 0);
}
});
t1.join().unwrap();
t2.join().unwrap();
let map = map.pin();
for i in 0..64 {
let v = map.get(&i).unwrap();
assert!(v == &0 || v == &1);
let kv = map.get_key_value(&i).unwrap();
assert!(kv == (&i, &0) || kv == (&i, &1));
}
}
#[test]
#[cfg_attr(miri, ignore)]
fn concurrent_remove() {
let map = Arc::new(HashMap::<usize, usize>::new());
{
let map = map.pin();
for i in 0..64 {
map.insert(i, i);
}
}
let map1 = map.clone();
let t1 = std::thread::spawn(move || {
let map1 = map1.pin();
for i in 0..64 {
if let Some(v) = map1.remove(&i) {
assert_eq!(v, &i);
}
}
});
let map2 = map.clone();
let t2 = std::thread::spawn(move || {
let map2 = map2.pin();
for i in 0..64 {
if let Some(v) = map2.remove(&i) {
assert_eq!(v, &i);
}
}
});
t1.join().unwrap();
t2.join().unwrap();
// after joining the threads, the map should be empty
let map = map.pin();
for i in 0..64 {
assert!(map.get(&i).is_none());
}
}
#[test]
#[cfg_attr(miri, ignore)]
fn concurrent_compute_if_present() {
let map = Arc::new(HashMap::<usize, usize>::new());
{
let map = map.pin();
for i in 0..64 {
map.insert(i, i);
}
}
let map1 = map.clone();
let t1 = std::thread::spawn(move || {
let map1 = map1.pin();
for i in 0..64 {
let new = map1.compute_if_present(&i, |_, _| None);
assert!(new.is_none());
}
});
let map2 = map.clone();
let t2 = std::thread::spawn(move || {
let map2 = map2.pin();
for i in 0..64 {
let new = map2.compute_if_present(&i, |_, _| None);
assert!(new.is_none());
}
});
t1.join().unwrap();
t2.join().unwrap();
// after joining the threads, the map should be empty
let map = map.pin();
for i in 0..64 {
assert!(map.get(&i).is_none());
}
}

141
vendor/flurry/tests/borrow.rs vendored Normal file
View File

@@ -0,0 +1,141 @@
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());
}
}

1
vendor/flurry/tests/cuckoo/README.md vendored Normal file
View File

@@ -0,0 +1 @@
These tests are ported from https://github.com/efficient/libcuckoo/tree/master/tests

1
vendor/flurry/tests/cuckoo/main.rs vendored Normal file
View File

@@ -0,0 +1 @@
mod stress;

190
vendor/flurry/tests/cuckoo/stress.rs vendored Normal file
View File

@@ -0,0 +1,190 @@
// https://github.com/efficient/libcuckoo/tree/master/tests/stress-tests
use flurry::*;
use parking_lot::Mutex;
use rand::distributions::{Distribution, Uniform};
use std::sync::{
atomic::{AtomicBool, Ordering},
Arc,
};
use std::thread;
/// Number of keys and values to work with.
const NUM_KEYS: usize = 1 << 12;
/// Number of threads that should be started.
const NUM_THREADS: usize = 4;
/// How long the stress test will run (in milliseconds).
const TEST_LEN: u64 = 5000;
type Key = usize;
type Value = usize;
struct Environment {
table1: HashMap<Key, Value>,
table2: HashMap<Key, Value>,
keys: Vec<Key>,
vals1: Mutex<Vec<Value>>,
vals2: Mutex<Vec<Value>>,
ind_dist: Uniform<usize>,
val_dist1: Uniform<Value>,
val_dist2: Uniform<Value>,
in_table: Mutex<Vec<bool>>,
in_use: Mutex<Vec<AtomicBool>>,
finished: AtomicBool,
}
impl Environment {
pub fn new() -> Self {
let mut keys = Vec::with_capacity(NUM_KEYS);
let mut in_use = Vec::with_capacity(NUM_KEYS);
for i in 0..NUM_KEYS {
keys.push(i);
in_use.push(AtomicBool::new(false));
}
Self {
table1: HashMap::new(),
table2: HashMap::new(),
keys,
vals1: Mutex::new(vec![0usize; NUM_KEYS]),
vals2: Mutex::new(vec![0usize; NUM_KEYS]),
ind_dist: Uniform::from(0..NUM_KEYS - 1),
val_dist1: Uniform::from(Value::min_value()..Value::max_value()),
val_dist2: Uniform::from(Value::min_value()..Value::max_value()),
in_table: Mutex::new(vec![false; NUM_KEYS]),
in_use: Mutex::new(in_use),
finished: AtomicBool::new(false),
}
}
}
fn stress_insert_thread(env: Arc<Environment>) {
let mut rng = rand::thread_rng();
let guard1 = env.table1.guard();
let guard2 = env.table2.guard();
while !env.finished.load(Ordering::SeqCst) {
let idx = env.ind_dist.sample(&mut rng);
let in_use = env.in_use.lock();
if (*in_use)[idx]
.compare_exchange(false, true, Ordering::SeqCst, Ordering::Relaxed)
.is_ok()
{
let key = env.keys[idx];
let val1 = env.val_dist1.sample(&mut rng);
let val2 = env.val_dist2.sample(&mut rng);
let res1 = if !env.table1.contains_key(&key, &guard1) {
env.table1
.insert(key, val1, &guard1)
.map_or(true, |_| false)
} else {
false
};
let res2 = if !env.table2.contains_key(&key, &guard2) {
env.table2
.insert(key, val2, &guard2)
.map_or(true, |_| false)
} else {
false
};
let mut in_table = env.in_table.lock();
assert_ne!(res1, (*in_table)[idx]);
assert_ne!(res2, (*in_table)[idx]);
if res1 {
assert_eq!(Some(&val1), env.table1.get(&key, &guard1));
assert_eq!(Some(&val2), env.table2.get(&key, &guard2));
let mut vals1 = env.vals1.lock();
let mut vals2 = env.vals2.lock();
(*vals1)[idx] = val1;
(*vals2)[idx] = val2;
(*in_table)[idx] = true;
}
(*in_use)[idx].swap(false, Ordering::SeqCst);
}
}
}
fn stress_delete_thread(env: Arc<Environment>) {
let mut rng = rand::thread_rng();
let guard1 = env.table1.guard();
let guard2 = env.table2.guard();
while !env.finished.load(Ordering::SeqCst) {
let idx = env.ind_dist.sample(&mut rng);
let in_use = env.in_use.lock();
if (*in_use)[idx]
.compare_exchange(false, true, Ordering::SeqCst, Ordering::Relaxed)
.is_ok()
{
let key = env.keys[idx];
let res1 = env.table1.remove(&key, &guard1).map_or(false, |_| true);
let res2 = env.table2.remove(&key, &guard2).map_or(false, |_| true);
let mut in_table = env.in_table.lock();
assert_eq!(res1, (*in_table)[idx]);
assert_eq!(res2, (*in_table)[idx]);
if res1 {
assert!(env.table1.get(&key, &guard1).is_none());
assert!(env.table2.get(&key, &guard2).is_none());
(*in_table)[idx] = false;
}
(*in_use)[idx].swap(false, Ordering::SeqCst);
}
}
}
fn stress_find_thread(env: Arc<Environment>) {
let mut rng = rand::thread_rng();
let guard1 = env.table1.guard();
let guard2 = env.table2.guard();
while !env.finished.load(Ordering::SeqCst) {
let idx = env.ind_dist.sample(&mut rng);
let in_use = env.in_use.lock();
if (*in_use)[idx]
.compare_exchange(false, true, Ordering::SeqCst, Ordering::Relaxed)
.is_ok()
{
let key = env.keys[idx];
let in_table = env.in_table.lock();
let val1 = (*env.vals1.lock())[idx];
let val2 = (*env.vals2.lock())[idx];
let value = env.table1.get(&key, &guard1);
if value.is_some() {
assert_eq!(&val1, value.unwrap());
assert!((*in_table)[idx]);
}
let value = env.table2.get(&key, &guard2);
if value.is_some() {
assert_eq!(&val2, value.unwrap());
assert!((*in_table)[idx]);
}
(*in_use)[idx].swap(false, Ordering::SeqCst);
}
}
}
#[test]
#[cfg_attr(miri, ignore)]
fn stress_test() {
let root = Arc::new(Environment::new());
let mut threads = Vec::new();
for _ in 0..NUM_THREADS {
let env = Arc::clone(&root);
threads.push(thread::spawn(move || stress_insert_thread(env)));
let env = Arc::clone(&root);
threads.push(thread::spawn(move || stress_delete_thread(env)));
let env = Arc::clone(&root);
threads.push(thread::spawn(move || stress_find_thread(env)));
}
thread::sleep(std::time::Duration::from_millis(TEST_LEN));
root.finished.swap(true, Ordering::SeqCst);
for t in threads {
t.join().expect("failed to join thread");
}
let in_table = &*root.in_table.lock();
let num_filled = in_table.iter().filter(|b| **b).count();
assert_eq!(num_filled, root.table1.len());
assert_eq!(num_filled, root.table2.len());
}

64
vendor/flurry/tests/hasher.rs vendored Normal file
View File

@@ -0,0 +1,64 @@
use flurry::{DefaultHashBuilder, HashMap};
use std::hash::{BuildHasher, BuildHasherDefault, Hasher};
#[derive(Default)]
pub struct ZeroHasher;
pub struct ZeroHashBuilder;
impl Hasher for ZeroHasher {
fn finish(&self) -> u64 {
0
}
fn write(&mut self, _: &[u8]) {}
}
impl BuildHasher for ZeroHashBuilder {
type Hasher = ZeroHasher;
fn build_hasher(&self) -> ZeroHasher {
ZeroHasher
}
}
fn check<S: BuildHasher + Default>() {
let range = if cfg!(miri) { 0..16 } else { 0..1000 };
let map = HashMap::<i32, i32, S>::default();
let guard = map.guard();
for i in range.clone() {
map.insert(i, i, &guard);
}
assert!(!map.contains_key(&i32::min_value(), &guard));
assert!(!map.contains_key(&(range.start - 1), &guard));
for i in range.clone() {
assert!(map.contains_key(&i, &guard));
}
assert!(!map.contains_key(&range.end, &guard));
assert!(!map.contains_key(&i32::max_value(), &guard));
}
#[test]
fn test_default_hasher() {
check::<DefaultHashBuilder>();
}
#[test]
fn test_zero_hasher() {
check::<BuildHasherDefault<ZeroHasher>>();
}
#[test]
fn test_max_hasher() {
#[derive(Default)]
struct MaxHasher;
impl Hasher for MaxHasher {
fn finish(&self) -> u64 {
u64::max_value()
}
fn write(&mut self, _: &[u8]) {}
}
check::<BuildHasherDefault<MaxHasher>>();
}

1
vendor/flurry/tests/jdk/README.md vendored Normal file
View File

@@ -0,0 +1 @@
These tests are ported from https://hg.openjdk.java.net/jdk/jdk13/file/tip/test/jdk/java/util/concurrent/ConcurrentHashMap

View File

@@ -0,0 +1,62 @@
use flurry::HashMap;
use rand::Rng;
use std::sync::Arc;
/// Number of entries for each thread to place in the map.
const NUM_ENTRIES: usize = 128;
/// Number of iterations for each test
const ITERATIONS: usize = 64;
#[derive(Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
struct KeyVal {
_data: usize,
}
impl KeyVal {
pub fn new() -> Self {
let mut rng = rand::thread_rng();
Self { _data: rng.gen() }
}
}
fn insert(map: Arc<HashMap<KeyVal, KeyVal>>, k: KeyVal) {
map.insert(k, k, &map.guard());
}
#[test]
#[cfg_attr(miri, ignore)]
fn test_concurrent_insert<'g>() {
test(insert);
}
fn test<F>(associator: F)
where
F: Fn(Arc<HashMap<KeyVal, KeyVal>>, KeyVal) + Send + Copy + 'static,
{
for _ in 0..ITERATIONS {
test_once(associator);
}
}
fn test_once<F>(associator: F)
where
F: Fn(Arc<HashMap<KeyVal, KeyVal>>, KeyVal) + Send + Copy + 'static,
{
let map = Arc::new(HashMap::new());
let mut threads = Vec::new();
for _ in 0..num_cpus::get().min(8) {
let map = map.clone();
let handle = std::thread::spawn(move || {
for _ in 0..NUM_ENTRIES {
let key = KeyVal::new();
associator(map.clone(), key);
assert!(map.contains_key(&key, &map.guard()));
}
});
threads.push(handle);
}
for t in threads {
t.join().expect("failed to join thread");
}
}

View File

@@ -0,0 +1,52 @@
use flurry::HashMap;
use std::{sync::Arc, thread};
/// Number of entries for each thread to place in the map.
const NUM_ENTRIES: usize = 16;
/// Number of iterations for each test
const ITERATIONS: usize = 256;
/// Number of rounds every thread perfoms per entry.
const ROUNDS: usize = 32;
#[test]
#[cfg_attr(miri, ignore)]
fn test_concurrent_contains_key() {
let map = HashMap::new();
let mut content = [0; NUM_ENTRIES];
{
let guard = map.guard();
for k in 0..NUM_ENTRIES {
map.insert(k, k, &guard);
content[k] = k;
}
}
test(content, Arc::new(map));
}
fn test(content: [usize; NUM_ENTRIES], map: Arc<HashMap<usize, usize>>) {
for _ in 0..ITERATIONS {
test_once(content, map.clone());
}
}
fn test_once(content: [usize; NUM_ENTRIES], map: Arc<HashMap<usize, usize>>) {
let mut threads = Vec::new();
for _ in 0..num_cpus::get().min(8) {
let map = map.clone();
let content = content;
let handle = thread::spawn(move || {
let guard = map.guard();
let map = map.clone();
for i in 0..NUM_ENTRIES * ROUNDS {
let key = content[i % content.len()];
assert!(map.contains_key(&key, &guard));
}
});
threads.push(handle);
}
for t in threads {
t.join().expect("failed to join thread");
}
}

3
vendor/flurry/tests/jdk/main.rs vendored Normal file
View File

@@ -0,0 +1,3 @@
mod concurrent_associate;
mod concurrent_contains;
mod map_check;

201
vendor/flurry/tests/jdk/map_check.rs vendored Normal file
View File

@@ -0,0 +1,201 @@
use flurry::*;
use rand::prelude::*;
use std::hash::Hash;
#[cfg(not(miri))]
const SIZE: usize = 50_000;
#[cfg(miri)]
const SIZE: usize = 12;
// there must be more things absent than present!
#[cfg(not(miri))]
const ABSENT_SIZE: usize = 1 << 17;
#[cfg(miri)]
const ABSENT_SIZE: usize = 1 << 5;
const ABSENT_MASK: usize = ABSENT_SIZE - 1;
fn t1<K, V>(map: &HashMap<K, V>, keys: &[K], expect: usize)
where
K: Sync + Send + Clone + Hash + Ord,
V: Sync + Send,
{
let mut sum = 0;
let iters = 4;
let guard = map.guard();
for _ in 0..iters {
for key in keys {
if map.get(key, &guard).is_some() {
sum += 1;
}
}
}
assert_eq!(sum, expect * iters);
}
fn t2<K>(map: &HashMap<K, usize>, keys: &[K], expect: usize)
where
K: Sync + Send + Copy + Hash + Ord + std::fmt::Display,
{
let mut sum = 0;
let guard = map.guard();
for key in keys {
if map.remove(key, &guard).is_some() {
sum += 1;
}
}
assert_eq!(sum, expect);
}
fn t3<K>(map: &HashMap<K, usize>, keys: &[K], expect: usize)
where
K: Sync + Send + Copy + Hash + Ord,
{
let mut sum = 0;
let guard = map.guard();
for i in 0..keys.len() {
if map.insert(keys[i], 0, &guard).is_none() {
sum += 1;
}
}
assert_eq!(sum, expect);
}
fn t4<K>(map: &HashMap<K, usize>, keys: &[K], expect: usize)
where
K: Sync + Send + Copy + Hash + Ord,
{
let mut sum = 0;
let guard = map.guard();
for i in 0..keys.len() {
if map.contains_key(&keys[i], &guard) {
sum += 1;
}
}
assert_eq!(sum, expect);
}
fn t5<K>(map: &HashMap<K, usize>, keys: &[K], expect: usize)
where
K: Sync + Send + Copy + Hash + Ord,
{
let mut sum = 0;
let guard = map.guard();
let mut i = keys.len() as isize - 2;
while i >= 0 {
if map.remove(&keys[i as usize], &guard).is_some() {
sum += 1;
}
i -= 2;
}
assert_eq!(sum, expect);
}
fn t6<K, V>(map: &HashMap<K, V>, keys1: &[K], keys2: &[K], expect: usize)
where
K: Sync + Send + Clone + Hash + Ord,
V: Sync + Send,
{
let mut sum = 0;
let guard = map.guard();
for i in 0..expect {
if map.get(&keys1[i], &guard).is_some() {
sum += 1;
}
if map.get(&keys2[i & ABSENT_MASK], &guard).is_some() {
sum += 1;
}
}
assert_eq!(sum, expect);
}
fn t7<K>(map: &HashMap<K, usize>, k1: &[K], k2: &[K])
where
K: Sync + Send + Copy + Hash + Ord,
{
let mut sum = 0;
let guard = map.guard();
for i in 0..k1.len() {
if map.contains_key(&k1[i], &guard) {
sum += 1;
}
if map.contains_key(&k2[i], &guard) {
sum += 1;
}
}
assert_eq!(sum, k1.len());
}
fn ittest1<K>(map: &HashMap<K, usize>, expect: usize)
where
K: Sync + Send + Copy + Hash + Eq,
{
let mut sum = 0;
let guard = map.guard();
for _ in map.keys(&guard) {
sum += 1;
}
assert_eq!(sum, expect);
}
fn ittest2<K>(map: &HashMap<K, usize>, expect: usize)
where
K: Sync + Send + Copy + Hash + Eq,
{
let mut sum = 0;
let guard = map.guard();
for _ in map.values(&guard) {
sum += 1;
}
assert_eq!(sum, expect);
}
fn ittest3<K>(map: &HashMap<K, usize>, expect: usize)
where
K: Sync + Send + Copy + Hash + Eq,
{
let mut sum = 0;
let guard = map.guard();
for _ in map.iter(&guard) {
sum += 1;
}
assert_eq!(sum, expect);
}
#[test]
fn everything() {
let mut rng = rand::thread_rng();
let map = HashMap::new();
let mut keys: Vec<_> = (0..ABSENT_SIZE + SIZE).collect();
keys.shuffle(&mut rng);
let absent_keys = &keys[0..ABSENT_SIZE];
let keys = &keys[ABSENT_SIZE..];
// put (absent)
t3(&map, keys, SIZE);
// put (present)
t3(&map, keys, 0);
// contains_key (present & absent)
t7(&map, keys, absent_keys);
// contains_key (present)
t4(&map, keys, SIZE);
// contains_key (absent)
t4(&map, absent_keys, 0);
// get
t6(&map, keys, absent_keys, SIZE);
// get (present)
t1(&map, keys, SIZE);
// get (absent)
t1(&map, absent_keys, 0);
// remove (absent)
t2(&map, absent_keys, 0);
// remove (present)
t5(&map, keys, SIZE / 2);
// put (half present)
t3(&map, keys, SIZE / 2);
// iter, keys, values (present)
ittest1(&map, SIZE);
ittest2(&map, SIZE);
ittest3(&map, SIZE);
}

1
vendor/flurry/tests/jsr166/README.md vendored Normal file
View File

@@ -0,0 +1 @@
These tests are ported from http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/test/tck/

61
vendor/flurry/tests/jsr166/main.rs vendored Normal file
View File

@@ -0,0 +1,61 @@
use flurry::*;
use std::iter::FromIterator;
const ITER: [(usize, &'static str); 5] = [(1, "A"), (2, "B"), (3, "C"), (4, "D"), (5, "E")];
#[test]
fn test_from_iter() {
let guard = unsafe { seize::Guard::unprotected() };
let map1 = from_iter_contron();
let map2: HashMap<_, _> = HashMap::from_iter(ITER.iter());
// TODO: improve when `Map: Eq`
let mut fst: Vec<_> = map1.iter(&guard).collect();
let mut snd: Vec<_> = map2.iter(&guard).collect();
fst.sort();
snd.sort();
assert_eq!(fst, snd);
}
fn from_iter_contron() -> HashMap<usize, &'static str> {
let guard = unsafe { seize::Guard::unprotected() };
let map = HashMap::with_capacity(5);
assert!(map.is_empty());
for (key, value) in &ITER {
map.insert(*key, *value, &guard);
}
assert!(!map.is_empty());
assert_eq!(ITER.len(), map.len());
map
}
fn map5() -> HashMap<isize, String> {
let map = HashMap::new();
// TODO: add is_empty check once method exists
// assert!(map.is_empty());
let guard = map.guard();
map.insert(1, "A".to_owned(), &guard);
map.insert(2, "B".to_owned(), &guard);
map.insert(3, "C".to_owned(), &guard);
map.insert(4, "D".to_owned(), &guard);
map.insert(5, "E".to_owned(), &guard);
// TODO: add is_empty and len check once methods exist
// assert!(!map.is_empty());
// assert_eq!(map.len(), 5);
drop(guard);
map
}
// remove removes the correct key-value pair from the map
#[test]
fn test_remove() {
let map = map5();
let guard = map.guard();
map.remove(&5, &guard);
// TODO: add len check once method exists
// assert_eq!(map.len(), 4);
assert!(!map.contains_key(&5, &guard));
}

18
vendor/flurry/tests/regressions.rs vendored Normal file
View File

@@ -0,0 +1,18 @@
use flurry::*;
use rand::{thread_rng, Rng};
#[test]
fn issue90() {
#[cfg(not(miri))]
const ITERATIONS: usize = 100_000;
#[cfg(miri)]
const ITERATIONS: usize = 100;
let mut rng = thread_rng();
let map = HashMap::new();
let g = map.guard();
for _ in 0..ITERATIONS {
let el = rng.gen_range(0..1000);
let _ = map.try_insert(el, el, &g);
}
}

319
vendor/flurry/tests/set.rs vendored Normal file
View File

@@ -0,0 +1,319 @@
use flurry::HashSet;
use std::sync::Arc;
#[test]
fn new() {
let _set = HashSet::<usize>::new();
}
#[test]
fn insert() {
let set = HashSet::new();
let guard = set.guard();
let did_set = set.insert(42, &guard);
assert!(did_set);
let did_set = set.insert(42, &guard);
assert!(!did_set);
}
#[test]
fn no_contains() {
let set = HashSet::<usize>::new();
{
let guard = set.guard();
let contained = set.contains(&42, &guard);
assert!(!contained);
}
}
#[test]
fn get_no_contains() {
let set = HashSet::<usize>::new();
{
let guard = set.guard();
let e = set.get(&42, &guard);
assert!(e.is_none());
}
}
#[test]
fn remove_empty() {
let set = HashSet::<usize>::new();
{
let guard = set.guard();
let removed = set.remove(&42, &guard);
assert!(!removed);
}
}
#[test]
fn insert_and_remove() {
let set = HashSet::new();
{
let guard = set.guard();
set.insert(42, &guard);
let removed = set.remove(&42, &guard);
assert!(removed);
assert!(!set.contains(&42, &guard));
}
}
#[test]
fn insert_and_contains() {
let set = HashSet::new();
set.insert(42, &set.guard());
{
let guard = set.guard();
let got = set.contains(&42, &guard);
assert!(got);
}
}
#[test]
fn insert_and_get() {
let set = HashSet::new();
set.insert(42, &set.guard());
{
let guard = set.guard();
let e = set.get(&42, &guard).unwrap();
assert_eq!(e, &42);
}
}
#[test]
fn update() {
let set = HashSet::new();
let guard = set.guard();
set.insert(42, &guard);
let was_new = set.insert(42, &guard);
assert!(!was_new);
assert!(set.contains(&42, &guard));
}
#[test]
#[cfg_attr(miri, ignore)]
fn concurrent_insert() {
let set = Arc::new(HashSet::<usize>::new());
let set1 = set.clone();
let t1 = std::thread::spawn(move || {
for i in 0..64 {
set1.insert(i, &set1.guard());
}
});
let set2 = set.clone();
let t2 = std::thread::spawn(move || {
for i in 0..64 {
set2.insert(i, &set2.guard());
}
});
t1.join().unwrap();
t2.join().unwrap();
let guard = set.guard();
for i in 0..64 {
assert!(set.contains(&i, &guard));
let key = set.get(&i, &guard).unwrap();
assert_eq!(key, &i);
}
}
#[test]
#[cfg_attr(miri, ignore)]
fn concurrent_remove() {
let set = Arc::new(HashSet::<usize>::new());
{
let guard = set.guard();
for i in 0..64 {
set.insert(i, &guard);
}
}
let set1 = set.clone();
let t1 = std::thread::spawn(move || {
let guard = set1.guard();
for i in 0..64 {
set1.remove(&i, &guard);
}
});
let set2 = set.clone();
let t2 = std::thread::spawn(move || {
let guard = set2.guard();
for i in 0..64 {
set2.remove(&i, &guard);
}
});
t1.join().unwrap();
t2.join().unwrap();
// after joining the threads, the map should be empty
let guard = set.guard();
for i in 0..64 {
assert!(!set.contains(&i, &guard));
}
}
#[test]
fn empty_sets_equal() {
let set1 = HashSet::<usize>::new();
let set2 = HashSet::<usize>::new();
assert_eq!(set1, set2);
assert_eq!(set2, set1);
}
#[test]
fn different_size_maps_not_equal() {
let set1 = HashSet::<usize>::new();
let set2 = HashSet::<usize>::new();
{
set1.pin().insert(1);
set1.pin().insert(2);
set2.pin().insert(1);
}
assert_ne!(set1, set2);
assert_ne!(set2, set1);
}
#[test]
fn same_values_equal() {
let set1 = HashSet::<usize>::new();
let set2 = HashSet::<usize>::new();
{
set1.pin().insert(1);
set2.pin().insert(1);
}
assert_eq!(set1, set2);
assert_eq!(set2, set1);
}
#[test]
fn different_values_not_equal() {
let set1 = HashSet::<usize>::new();
let set2 = HashSet::<usize>::new();
{
set1.pin().insert(1);
set2.pin().insert(2);
}
assert_ne!(set1, set2);
assert_ne!(set2, set1);
}
#[test]
fn clone_set_empty() {
let set = HashSet::<&'static str>::new();
let cloned_set = set.clone();
assert_eq!(set.len(), cloned_set.len());
assert_eq!(&set, &cloned_set);
assert_eq!(cloned_set.len(), 0);
}
#[test]
// Test that same values exists in both maps (original and cloned)
fn clone_set_filled() {
let set = HashSet::<&'static str>::new();
set.insert("FooKey", &set.guard());
set.insert("BarKey", &set.guard());
let cloned_set = set.clone();
assert_eq!(set.len(), cloned_set.len());
assert_eq!(&set, &cloned_set);
// test that we are not mapping the same tables
set.insert("NewItem", &set.guard());
assert_ne!(&set, &cloned_set);
}
#[test]
fn default() {
let set: HashSet<usize> = Default::default();
let guard = set.guard();
set.insert(42, &guard);
assert!(set.contains(&42, &guard));
}
#[test]
fn debug() {
let set: HashSet<usize> = HashSet::new();
let guard = set.guard();
set.insert(42, &guard);
set.insert(16, &guard);
let formatted = format!("{:?}", set);
assert!(formatted == "{42, 16}" || formatted == "{16, 42}");
}
#[test]
fn extend() {
let set: HashSet<usize> = HashSet::new();
let guard = set.guard();
let mut entries = vec![42, 16, 38];
entries.sort_unstable();
(&set).extend(entries.clone().into_iter());
let mut collected: Vec<_> = set.iter(&guard).copied().collect();
collected.sort_unstable();
assert_eq!(entries, collected);
}
#[test]
fn extend_ref() {
let set: HashSet<usize> = HashSet::new();
let mut entries = vec![&42, &16, &38];
entries.sort();
(&set).extend(entries.clone().into_iter());
let guard = set.guard();
let mut collected: Vec<_> = set.iter(&guard).collect();
collected.sort();
assert_eq!(entries, collected);
}
#[test]
fn from_iter_ref() {
use std::iter::FromIterator;
let mut entries: Vec<_> = vec![&42, &16, &38];
entries.sort();
let set: HashSet<usize> = HashSet::from_iter(entries.clone().into_iter());
let guard = set.guard();
let mut collected: Vec<_> = set.iter(&guard).collect();
collected.sort();
assert_eq!(entries, entries)
}
#[test]
fn from_iter_empty() {
use std::iter::FromIterator;
let set: HashSet<_> = HashSet::from_iter(std::iter::empty::<usize>());
assert_eq!(set.len(), 0)
}