use std::{fs, hash::BuildHasherDefault, hint::black_box, io::Write, time::Instant};

use ahash::AHasher;
use fhash::FHasherBuilder;
use hashbrown::HashSet;
use rand::RngCore;

const ITERATIONS: usize = 8_000;

fn main() {
    let mut file = fs::File::create("benchmark.txt").unwrap();
    writeln!(file, "Size\tAHash\tFHash").unwrap();

    for size in 0..128 {
        write!(file, "{}", size).unwrap();

        println!("Size: {}", size);

        let mut hashing_values = Vec::with_capacity(1024);
        hashing_values.resize(size, vec![]);

        for bytes in hashing_values.iter_mut() {
            bytes.resize(size, 0);

            rand::thread_rng().fill_bytes(bytes);
        }

        let duration = (0..16)
            .into_iter()
            .map(|_| {
                let mut heshset: HashSet<&[u8], BuildHasherDefault<AHasher>> =
                    HashSet::with_capacity_and_hasher(
                        1024,
                        BuildHasherDefault::<AHasher>::default(),
                    );

                let start = Instant::now();
                for _ in 0..ITERATIONS {
                    for bytes in &hashing_values {
                        heshset.insert(black_box(bytes));
                    }
                }
                let duration = Instant::now() - start;

                black_box(heshset);

                duration
            })
            .min()
            .unwrap();

        write!(file, "\t{}", duration.as_micros()).unwrap();

        let duration = (0..16)
            .into_iter()
            .map(|_| {
                let mut heshset: HashSet<&[u8], FHasherBuilder> =
                    HashSet::with_capacity_and_hasher(1024, FHasherBuilder::default());

                let start = Instant::now();
                for _ in 0..ITERATIONS {
                    for bytes in &hashing_values {
                        heshset.insert(black_box(bytes));
                    }
                }
                let duration = Instant::now() - start;

                black_box(heshset);

                duration
            })
            .min()
            .unwrap();

        writeln!(file, "\t{}", duration.as_micros()).unwrap();
    }
}
