use atomic_cuckoo_filter::CuckooFilter;
use std::sync::Arc;
use std::thread;
#[test]
fn test_concurrent_reads() {
let filter = Arc::new(CuckooFilter::with_capacity(1024));
for i in 0..100 {
assert!(filter.insert(&i).is_ok());
}
let mut handles = vec![];
for _ in 0..5 {
let filter_clone = Arc::clone(&filter);
handles.push(thread::spawn(move || {
for i in 0..100 {
assert!(filter_clone.contains(&i));
}
}));
}
for handle in handles {
handle.join().unwrap();
}
}
#[test]
fn test_concurrent_insert() {
let filter = Arc::new(CuckooFilter::with_capacity(10000));
let mut handles = vec![];
for thread_id in 0..5 {
let filter_clone = Arc::clone(&filter);
handles.push(thread::spawn(move || {
for i in 0..100 {
let item = format!("thread_{thread_id}_item_{i}");
filter_clone.insert(&item).unwrap();
}
}));
}
for handle in handles {
handle.join().unwrap();
}
for thread_id in 0..5 {
for i in 0..100 {
let item = format!("thread_{thread_id}_item_{i}");
assert!(filter.contains(&item));
}
}
assert_eq!(filter.len(), 500);
}
#[test]
fn test_concurrent_insert_unique() {
let filter = Arc::new(CuckooFilter::with_capacity(131072));
let mut handles = vec![];
for _ in 0..5 {
let filter_clone = filter.clone();
handles.push(thread::spawn(move || {
(0..100000)
.filter(|i| filter_clone.insert_unique(i).unwrap())
.count()
}));
}
let inserted: usize = handles.into_iter().map(|h| h.join().unwrap()).sum();
for i in 0..100000 {
assert!(filter.contains(&i));
}
assert_eq!(inserted, filter.len());
assert!(inserted <= 100000);
}
#[test]
fn concurrent_remove() {
let filter = Arc::new(CuckooFilter::with_capacity(131072));
let mut handles = vec![];
for i in 0..100000 {
assert!(filter.insert(&i).is_ok());
}
for _ in 0..5 {
let f = filter.clone();
handles.push(thread::spawn(move || {
(0..100000).filter(|i| f.remove(i)).count()
}));
}
let removed: usize = handles.into_iter().map(|h| h.join().unwrap()).sum();
assert_eq!(removed, 100000)
}
#[test]
fn test_concurrent_insert_and_remove() {
let filter = Arc::new(CuckooFilter::with_capacity(10000));
let mut handles = vec![];
for thread_id in 0..5 {
let filter_clone = Arc::clone(&filter);
handles.push(thread::spawn(move || {
for i in 0..100 {
let item = format!("thread_{thread_id}_item_{i}");
filter_clone.insert(&item).unwrap();
}
}));
}
for thread_id in 0..5 {
let filter_clone = Arc::clone(&filter);
handles.push(thread::spawn(move || {
for i in 0..100 {
let item = format!("thread_{thread_id}_item_{i}");
while !filter_clone.remove(&item) {}
}
}));
}
for handle in handles {
handle.join().unwrap();
}
assert_eq!(filter.len(), 0);
}