Documentation
use cache::{Cache, Cacheable};
use test::Bencher;
use rand::{Rand, StdRng};
use rand::distributions::{Range, IndependentSample};

struct Types;

impl Cacheable for Types {
    type UpperKey = u32;
    type LowerKey = u32;
    type Payload = bool;
}

#[bench]
fn has_empty(b: &mut Bencher) {
    let mut cache = Cache::<Types>::new(400, 400);
    b.iter(|| cache.has(0));
}

#[bench]
fn best_cache_hit(b: &mut Bencher) {
    let mut cache = Cache::<Types>::new(400, 400);
    cache.set(0, 0, true);
    b.iter(|| {
        let _ = cache.get(0, 0);
    });
}

#[bench]
fn random_u32_constrained_to_50(b: &mut Bencher) {
    let mut cache = Cache::<Types>::new(400, 400);
    let between = Range::new(0, 50);
    let mut rng = StdRng::new().unwrap();
    b.iter(|| {
        let cache_key = between.ind_sample(&mut rng);
        let register_key= between.ind_sample(&mut rng);
        cache.set(cache_key, register_key, true);
    });
}

#[bench]
fn random_u32_constrained_to_50_get(b: &mut Bencher) {
    let mut cache = Cache::<Types>::new(400, 400);
    let between = Range::new(0, 50);
    let mut rng = StdRng::new().unwrap();
    for _ in 0..160000 {
        let cache_key = between.ind_sample(&mut rng);
        let register_key= between.ind_sample(&mut rng);
        cache.set(cache_key, register_key, true);
    }
    b.iter(|| {
        let cache_key = between.ind_sample(&mut rng);
        let register_key= between.ind_sample(&mut rng);
        cache.get(cache_key, register_key);
    });
}

#[bench]
fn random_u32_constrained_to_400(b: &mut Bencher) {
    let mut cache = Cache::<Types>::new(400, 400);
    let between = Range::new(0, 400);
    let mut rng = StdRng::new().unwrap();
    b.iter(|| {
        let cache_key = between.ind_sample(&mut rng);
        let register_key= between.ind_sample(&mut rng);
        cache.set(cache_key, register_key, true);
    });
}

#[bench]
fn random_u32_constrained_to_400_get(b: &mut Bencher) {
    let mut cache = Cache::<Types>::new(400, 400);
    let between = Range::new(0, 400);
    let mut rng = StdRng::new().unwrap();
    for _ in 0..160000 {
        let cache_key = between.ind_sample(&mut rng);
        let register_key= between.ind_sample(&mut rng);
        cache.set(cache_key, register_key, true);
    }
    b.iter(|| {
        let cache_key = between.ind_sample(&mut rng);
        let register_key= between.ind_sample(&mut rng);
        cache.get(cache_key, register_key);
    });
}

#[bench]
fn random_u32_constrained_to_500(b: &mut Bencher) {
    let mut cache = Cache::<Types>::new(400, 400);
    let between = Range::new(0, 500);
    let mut rng = StdRng::new().unwrap();
    b.iter(|| {
        let cache_key = between.ind_sample(&mut rng);
        let register_key= between.ind_sample(&mut rng);
        cache.set(cache_key, register_key, true);
    });
}

#[bench]
fn random_u32_constrained_to_500_get(b: &mut Bencher) {
    let mut cache = Cache::<Types>::new(400, 400);
    let between = Range::new(0, 500);
    let mut rng = StdRng::new().unwrap();
    for _ in 0..160000 {
        let cache_key = between.ind_sample(&mut rng);
        let register_key= between.ind_sample(&mut rng);
        cache.set(cache_key, register_key, true);
    }
    b.iter(|| {
        let cache_key = between.ind_sample(&mut rng);
        let register_key= between.ind_sample(&mut rng);
        cache.get(cache_key, register_key);
    });
}

#[bench]
fn random_u32(b: &mut Bencher) {
    let mut cache = Cache::<Types>::new(400, 400);
    let mut rng = StdRng::new().unwrap();
    b.iter(|| {
        let cache_key = u32::rand(&mut rng);
        let register_key= u32::rand(&mut rng);
        cache.set(cache_key, register_key, true);
    });
}