use std::{
sync::{Arc, Barrier},
thread,
};
use super::{assert_estimate_eq, ConcurrentDDSketch};
#[test]
fn concurrent_inserts_initialize_one_production_block() {
let expected = ConcurrentDDSketch::with_range(1.0, 1.0);
expected.insert(1.0);
expected.insert(1.0);
let sketch = Arc::new(ConcurrentDDSketch::with_range(1.0, 1.0));
let start = Arc::new(Barrier::new(3));
let mut threads = Vec::new();
for _ in 0..2 {
let sketch = Arc::clone(&sketch);
let start = Arc::clone(&start);
threads.push(thread::spawn(move || {
start.wait();
sketch.insert(1.0);
}));
}
start.wait();
for thread in threads {
thread.join().unwrap();
}
assert_estimate_eq(sketch.quantile(0.5), expected.quantile(0.5));
assert_eq!(sketch.percentile_rank(1.0), Some(1.0));
}
#[test]
fn production_queries_tolerate_a_concurrent_insert() {
let sketch = Arc::new(ConcurrentDDSketch::with_range(1.0, 2.0));
sketch.insert(1.0);
let inserter = Arc::clone(&sketch);
let insert = thread::spawn(move || inserter.insert(2.0));
let quantile = sketch.quantile(1.0).unwrap();
assert!((1.0..=2.0).contains(&quantile));
let rank = sketch.percentile_rank(1.0).unwrap();
assert!(rank == 0.5 || rank == 1.0);
insert.join().unwrap();
let maximum = sketch.quantile(1.0).unwrap();
assert!((maximum - 2.0).abs() / 2.0 <= 0.01 * 1.001);
assert_eq!(sketch.percentile_rank(1.0), Some(0.5));
}