package bench;

import org.openjdk.jmh.annotations.*;

import java.util.Arrays;
import java.util.Collections;
import java.util.Random;
import java.util.zip.CRC32C;

@State(Scope.Thread)
public class CrcBench {
    private static final int ARRAY_COUNT = 1000;

    @State(Scope.Benchmark)
    public static class Data {
        byte[][] arrays;
    }

    // All powers of two from 64 to 131072 plus the values in the middle
    @Param({"64", "91", "128", "181", "256", "362", "512", "724", "1024", "1448", "2048", "2896", "4096", "5793", "8192", "11585", "16384", "23170", "32768", "46341", "65536", "92682", "131072"})
    int length;

    int index;

    @Setup
    public void setup(Data data) {
        Random random = new Random(1);
        data.arrays = new byte[ARRAY_COUNT][length];
        for (byte[] array : data.arrays) {
            random.nextBytes(array);
        }
        Collections.shuffle(Arrays.asList(data.arrays));
    }

    @Benchmark
    public long crc32c(Data data) {
        if (++index >= data.arrays.length) index = 0;
        return calcChecksum(data.arrays[index]);
    }

    private static long calcChecksum(byte[] input) {
        CRC32C checksum = new CRC32C();
        checksum.update(input);
        return checksum.getValue();
    }
}
