1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
use std::thread::scope;
use std::time::Instant;

use concurrent_map::ConcurrentMap;

const PRODUCERS: usize = 128;
const CONSUMERS: usize = 128;
const N: usize = 1024 * 1024;
const PRODUCER_N: usize = N / PRODUCERS;
const CONSUMER_N: usize = N / CONSUMERS;

fn producer(cm: ConcurrentMap<usize, usize>, min: usize, max: usize) {
    for i in min..max {
        cm.insert(i, i);
    }
}

fn consumer(cm: ConcurrentMap<usize, usize>, n: usize) {
    let mut popped = 0;
    while popped < n {
        if let Some((k, v)) = cm.pop_first() {
            assert_eq!(k, v);
            popped += 1;
        }
    }
}

fn main() {
    let cm = ConcurrentMap::default();

    let before = Instant::now();
    scope(|s| {
        let mut handles = vec![];

        for i in 0..PRODUCERS {
            let min = i * PRODUCER_N;
            let max = (i + 1) * PRODUCER_N;
            let cm = cm.clone();
            let handle = s.spawn(move || producer(cm, min, max));
            handles.push(handle);
        }

        for _ in 0..CONSUMERS {
            let cm = cm.clone();
            let handle = s.spawn(move || consumer(cm, CONSUMER_N));
            handles.push(handle);
        }

        for handle in handles.into_iter() {
            handle.join().unwrap()
        }
    });

    let elapsed = before.elapsed();

    let per_second = N as u128 * 1000 / elapsed.as_millis();

    println!(
        "with {} producers and {} consumers, took {:?} to transfer {} items ({} per second)",
        PRODUCERS, CONSUMERS, elapsed, N, per_second
    );
}