// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#![allow(missing_docs, unused_results, clippy::unwrap_used)]

use criterion::{black_box, criterion_group, criterion_main, Criterion};
use handle_map::*;
use std::sync::Arc;
use std::thread;
use std::time::{Duration, Instant};

// For the sake of these benchmarks, we just want
// to be able to allocate an almost-arbitrary number of handles
// if needed by the particular benchmark.
const MAX_ACTIVE_HANDLES: u32 = u32::MAX - 1;

// The default number of threads+shards to use
// in multi-threaded benchmarks, chosen
// to represent a typical multi-threaded use-case.
const DEFAULT_SHARDS_AND_THREADS: u8 = 8;

/// We're using u8's for the wrapped object type to deliberately ignore
/// costs related to accessing the underlying data - we just care about
/// benchmarking handle-map operations.
type BenchHandleMap = HandleMap<u8>;

fn build_handle_map(num_shards: u8) -> BenchHandleMap {
    let dimensions = HandleMapDimensions {
        num_shards,
        max_active_handles: MAX_ACTIVE_HANDLES,
    };
    HandleMap::with_dimensions(dimensions)
}

/// Benchmark for repeated reads on a single thread
fn single_threaded_read_benchmark(c: &mut Criterion) {
    // The number of shards should not matter much here.
    let handle_map = build_handle_map(8);
    // Pre-populate the map with a single handle.
    let handle = handle_map.allocate(|| 0xFF).unwrap();
    let handle_map_ref = &handle_map;
    // Perform repeated reads
    let _ = c.bench_function("single-threaded reads", |b| {
        b.iter(|| {
            let guard = handle_map_ref.get(black_box(handle)).unwrap();
            black_box(*guard)
        })
    });
}

/// Benchmark for repeated writes on a single thread
fn single_threaded_write_benchmark(c: &mut Criterion) {
    // The number of shards should not matter much here.
    let handle_map = build_handle_map(8);
    // Pre-populate the map with a single handle.
    let handle = handle_map.allocate(|| 0xFF).unwrap();
    let handle_map_ref = &handle_map;
    // Perform repeated writes
    c.bench_function("single-threaded writes", |b| {
        b.iter(|| {
            let mut guard = handle_map_ref.get_mut(black_box(handle)).unwrap();
            *guard *= black_box(0);
        })
    });
}

/// Benchmark for repeated allocations on a single thread
#[allow(unused_must_use)]
fn single_threaded_allocate_benchmark(c: &mut Criterion) {
    // The number of shards here is chosen to be quasi-reasonable.
    // Realistically, performance will fluctuate somewhat with this
    // due to the difference in the number of internal hash-map collisions,
    // but ultimately we only care about the asymptotic behavior.
    let handle_map = build_handle_map(8);
    let handle_map_ref = &handle_map;
    // Perform repeated allocations
    c.bench_function("single-threaded allocations", |b| {
        b.iter(|| {
            handle_map_ref.allocate(|| black_box(0xEE));
        })
    });
}

/// Benchmark for repeated allocation->deallocation on a single thread
/// starting from an empty map.
#[allow(unused_must_use)]
fn single_threaded_allocate_deallocate_near_empty_benchmark(c: &mut Criterion) {
    // The number of shards should not matter much here.
    let handle_map = build_handle_map(8);
    let handle_map_ref = &handle_map;
    // Perform repeated allocation/deallocation pairs
    c.bench_function(
        "single-threaded allocate/deallocate pairs (empty init state)",
        |b| {
            b.iter(|| {
                let handle = handle_map_ref.allocate(|| black_box(0xDD)).unwrap();
                handle_map_ref.deallocate(handle);
            })
        },
    );
}

/// Benchmark for repeated allocation->deallocation starting
/// from a map with a thousand elements per shard.
#[allow(unused_must_use)]
fn single_threaded_allocate_deallocate_one_thousand_benchmark(c: &mut Criterion) {
    let handle_map = build_handle_map(8);
    for _ in 0..(8 * 1000) {
        handle_map.allocate(|| black_box(0xFF)).unwrap();
    }
    let handle_map_ref = &handle_map;

    // Perform repeated allocation/deallocation pairs
    c.bench_function(
        "single-threaded allocate/deallocate pairs (init one thousand elements per shard)",
        |b| {
            b.iter(|| {
                let handle = handle_map_ref.allocate(|| black_box(0xDD)).unwrap();
                handle_map_ref.deallocate(handle);
            })
        },
    );
}

/// Benchmark for repeated allocation->deallocation starting
/// from a map with a million elements per shard.
#[allow(unused_must_use)]
fn single_threaded_allocate_deallocate_one_million_benchmark(c: &mut Criterion) {
    let handle_map = build_handle_map(8);
    for _ in 0..(8 * 1000000) {
        handle_map.allocate(|| black_box(0xFF)).unwrap();
    }
    let handle_map_ref = &handle_map;

    // Perform repeated allocation/deallocation pairs
    c.bench_function(
        "single-threaded allocate/deallocate pairs (init one million elements per shard)",
        |b| {
            b.iter(|| {
                let handle = handle_map_ref.allocate(|| black_box(0xDD)).unwrap();
                handle_map_ref.deallocate(handle);
            })
        },
    );
}

/// Helper function for creating a multi-threaded benchmark
/// with the set number of threads. Untimed Initialization of state
/// should occur prior to this call. This method will repeatedly
/// execute the benchmark code on all threads
fn bench_multithreaded<F>(name: &str, num_threads: u8, benchable_fn_ref: Arc<F>, c: &mut Criterion)
where
    F: Fn() + Send + Sync + 'static,
{
    c.bench_function(name, move |b| {
        b.iter_custom(|iters| {
            // The returned results from the threads will be their timings
            let mut join_handles = Vec::new();
            for _ in 0..num_threads {
                let benchable_fn_ref_clone = benchable_fn_ref.clone();
                let join_handle = thread::spawn(move || {
                    let start = Instant::now();
                    for _ in 0..iters {
                        benchable_fn_ref_clone();
                    }
                    start.elapsed()
                });
                join_handles.push(join_handle);
            }
            //Threads spawned, now collect the results
            let mut total_duration = Duration::from_nanos(0);
            for join_handle in join_handles {
                let thread_duration = join_handle.join().unwrap();
                total_duration += thread_duration;
            }
            total_duration /= num_threads as u32;
            total_duration
        })
    });
}

/// Defines a number of reads/writes to perform [relative
/// to other operations performed in a given test]
#[derive(Debug, Clone, Copy)]
struct ReadWriteCount {
    num_reads: usize,
    num_writes: usize,
}

const READS_ONLY: ReadWriteCount = ReadWriteCount {
    num_reads: 4,
    num_writes: 0,
};

const READ_LEANING: ReadWriteCount = ReadWriteCount {
    num_reads: 3,
    num_writes: 1,
};

const BALANCED: ReadWriteCount = ReadWriteCount {
    num_reads: 2,
    num_writes: 2,
};

const WRITE_LEANING: ReadWriteCount = ReadWriteCount {
    num_reads: 1,
    num_writes: 3,
};

const WRITES_ONLY: ReadWriteCount = ReadWriteCount {
    num_reads: 0,
    num_writes: 4,
};

const READ_WRITE_COUNTS: [ReadWriteCount; 5] = [
    READS_ONLY,
    READ_LEANING,
    BALANCED,
    WRITE_LEANING,
    WRITES_ONLY,
];

/// Benchmarks a repeated allocate/[X writes]/[Y reads]/deallocate workflow across
/// the default number of threads and shards.
fn lifecycle_read_and_write_multithreaded(per_object_rw_count: ReadWriteCount, c: &mut Criterion) {
    let name = format!(
        "lifecycle_read_and_write_multithreaded(reads/object: {}, writes/object:{})",
        per_object_rw_count.num_reads, per_object_rw_count.num_writes
    );
    // We need an Arc to be able to pass this off to `bench_multithreaded`.
    let handle_map = Arc::new(build_handle_map(DEFAULT_SHARDS_AND_THREADS));
    bench_multithreaded(
        &name,
        DEFAULT_SHARDS_AND_THREADS,
        Arc::new(move || {
            let handle = handle_map.allocate(|| black_box(0xFF)).unwrap();
            for _ in 0..per_object_rw_count.num_writes {
                let mut write_guard = handle_map.get_mut(handle).unwrap();
                *write_guard *= black_box(1);
            }
            for _ in 0..per_object_rw_count.num_reads {
                let read_guard = handle_map.get_mut(handle).unwrap();
                black_box(*read_guard);
            }
            handle_map.deallocate(handle).unwrap();
        }),
        c,
    );
}

fn lifecycle_benchmarks(c: &mut Criterion) {
    for read_write_count in READ_WRITE_COUNTS {
        // Using 8 separate shards to roughly match the number of active threads.
        lifecycle_read_and_write_multithreaded(read_write_count, c);
    }
}

/// Benchmarks repeated cycles of accessing the given number of distinct objects, each
/// with the given number of reads and writes across the given number of threads.
fn read_and_write_contention_multithreaded(
    num_threads: u8,
    num_distinct_objects: u32,
    per_object_rw_count: ReadWriteCount,
    c: &mut Criterion,
) {
    let name = format!("read_and_write_contention_multithreaded(threads: {}, objects: {}, reads/object: {}, writes/object:{})",
                       num_threads, num_distinct_objects, per_object_rw_count.num_reads, per_object_rw_count.num_writes);
    // Default to 8 shards, ultimately doesn't matter much since we only ever access a few shards.
    // This needs to be `'static` in order to pass a ref off to `bench_multithreaded`.
    let handle_map = Arc::new(build_handle_map(8));
    let mut handles = Vec::new();
    for i in 0..num_distinct_objects {
        let handle = handle_map.allocate(|| i as u8).unwrap();
        handles.push(handle);
    }

    bench_multithreaded(
        &name,
        num_threads,
        Arc::new(move || {
            // Deliberately performing all writes first, with
            // the goal of getting staggered timings from
            // all of the threads for subsequent iterations.
            // We also perform reads and writes across all objects
            // in batches to get something resembling uniform access.
            for _ in 0..per_object_rw_count.num_writes {
                for handle in handles.iter() {
                    let mut write_guard = handle_map.get_mut(*handle).unwrap();
                    *write_guard *= black_box(1);
                }
            }
            for _ in 0..per_object_rw_count.num_reads {
                for handle in handles.iter() {
                    let read_guard = handle_map.get(*handle).unwrap();
                    black_box(*read_guard);
                }
            }
        }),
        c,
    );
}

fn read_write_contention_benchmarks(c: &mut Criterion) {
    for num_threads in [2, 4, 8].iter() {
        for num_distinct_objects in [1u32, 2u32, 4u32].iter() {
            if num_distinct_objects >= &(*num_threads as u32) {
                continue;
            }
            for read_write_count in READ_WRITE_COUNTS {
                read_and_write_contention_multithreaded(
                    *num_threads,
                    *num_distinct_objects,
                    read_write_count,
                    c,
                );
            }
        }
    }
}

/// Benchmarks allocation (starting from empty) for the default number of shards and threads
fn allocator_contention_benchmark(c: &mut Criterion) {
    let name = "allocator_contention_multithreaded";
    // We need an Arc to pass this off to `bench_multithreaded`
    let handle_map = Arc::new(build_handle_map(DEFAULT_SHARDS_AND_THREADS));
    bench_multithreaded(
        name,
        DEFAULT_SHARDS_AND_THREADS,
        Arc::new(move || {
            handle_map.allocate(|| black_box(0xFF)).unwrap();
        }),
        c,
    );
}

criterion_group!(
    benches,
    single_threaded_read_benchmark,
    single_threaded_write_benchmark,
    single_threaded_allocate_benchmark,
    single_threaded_allocate_deallocate_near_empty_benchmark,
    single_threaded_allocate_deallocate_one_thousand_benchmark,
    single_threaded_allocate_deallocate_one_million_benchmark,
    lifecycle_benchmarks,
    read_write_contention_benchmarks,
    allocator_contention_benchmark,
);
criterion_main!(benches);
