// Copyright 2022 The Abseil Authors
//
// 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
//
//     https://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.

#include <string>

#include "absl/crc/crc32c.h"
#include "absl/crc/internal/crc32c.h"
#include "absl/memory/memory.h"
#include "benchmark/benchmark.h"

namespace {

std::string TestString(size_t len) {
  std::string result;
  result.reserve(len);
  for (size_t i = 0; i < len; ++i) {
    result.push_back(static_cast<char>(i % 256));
  }
  return result;
}

void BM_Calculate(benchmark::State& state) {
  int len = state.range(0);
  std::string data = TestString(len);
  for (auto s : state) {
    benchmark::DoNotOptimize(data);
    absl::crc32c_t crc = absl::ComputeCrc32c(data);
    benchmark::DoNotOptimize(crc);
  }
}
BENCHMARK(BM_Calculate)->Arg(0)->Arg(1)->Arg(100)->Arg(10000)->Arg(500000);

void BM_Extend(benchmark::State& state) {
  int len = state.range(0);
  std::string extension = TestString(len);
  absl::crc32c_t base = absl::crc32c_t{0xC99465AA};  // CRC32C of "Hello World"
  for (auto s : state) {
    benchmark::DoNotOptimize(base);
    benchmark::DoNotOptimize(extension);
    absl::crc32c_t crc = absl::ExtendCrc32c(base, extension);
    benchmark::DoNotOptimize(crc);
  }
}
BENCHMARK(BM_Extend)->Arg(0)->Arg(1)->Arg(100)->Arg(10000)->Arg(500000);

void BM_ExtendByZeroes(benchmark::State& state) {
  absl::crc32c_t base = absl::crc32c_t{0xC99465AA};  // CRC32C of "Hello World"
  int num_zeroes = state.range(0);
  for (auto s : state) {
    benchmark::DoNotOptimize(base);
    absl::crc32c_t crc = absl::ExtendCrc32cByZeroes(base, num_zeroes);
    benchmark::DoNotOptimize(crc);
  }
}
BENCHMARK(BM_ExtendByZeroes)
    ->RangeMultiplier(10)
    ->Range(1, 1000000)
    ->RangeMultiplier(32)
    ->Range(1, 1 << 20);

void BM_UnextendByZeroes(benchmark::State& state) {
  absl::crc32c_t base = absl::crc32c_t{0xdeadbeef};
  int num_zeroes = state.range(0);
  for (auto s : state) {
    benchmark::DoNotOptimize(base);
    absl::crc32c_t crc =
        absl::crc_internal::UnextendCrc32cByZeroes(base, num_zeroes);
    benchmark::DoNotOptimize(crc);
  }
}
BENCHMARK(BM_UnextendByZeroes)
    ->RangeMultiplier(10)
    ->Range(1, 1000000)
    ->RangeMultiplier(32)
    ->Range(1, 1 << 20);

void BM_Concat(benchmark::State& state) {
  int string_b_len = state.range(0);
  std::string string_b = TestString(string_b_len);

  // CRC32C of "Hello World"
  absl::crc32c_t crc_a = absl::crc32c_t{0xC99465AA};
  absl::crc32c_t crc_b = absl::ComputeCrc32c(string_b);

  for (auto s : state) {
    benchmark::DoNotOptimize(crc_a);
    benchmark::DoNotOptimize(crc_b);
    benchmark::DoNotOptimize(string_b_len);
    absl::crc32c_t crc_ab = absl::ConcatCrc32c(crc_a, crc_b, string_b_len);
    benchmark::DoNotOptimize(crc_ab);
  }
}
BENCHMARK(BM_Concat)
    ->RangeMultiplier(10)
    ->Range(1, 1000000)
    ->RangeMultiplier(32)
    ->Range(1, 1 << 20);

void BM_Memcpy(benchmark::State& state) {
  int string_len = state.range(0);

  std::string source = TestString(string_len);
  auto dest = absl::make_unique<char[]>(string_len);

  for (auto s : state) {
    benchmark::DoNotOptimize(source);
    absl::crc32c_t crc =
        absl::MemcpyCrc32c(dest.get(), source.data(), source.size());
    benchmark::DoNotOptimize(crc);
    benchmark::DoNotOptimize(dest);
    benchmark::DoNotOptimize(dest.get());
    benchmark::DoNotOptimize(dest[0]);
  }

  state.SetBytesProcessed(static_cast<int64_t>(state.iterations()) *
                          state.range(0));
}
BENCHMARK(BM_Memcpy)->Arg(0)->Arg(1)->Arg(100)->Arg(10000)->Arg(500000);

void BM_RemoveSuffix(benchmark::State& state) {
  int full_string_len = state.range(0);
  int suffix_len = state.range(1);

  std::string full_string = TestString(full_string_len);
  std::string suffix = full_string.substr(
    full_string_len - suffix_len, full_string_len);

  absl::crc32c_t full_string_crc = absl::ComputeCrc32c(full_string);
  absl::crc32c_t suffix_crc = absl::ComputeCrc32c(suffix);

  for (auto s : state) {
    benchmark::DoNotOptimize(full_string_crc);
    benchmark::DoNotOptimize(suffix_crc);
    benchmark::DoNotOptimize(suffix_len);
    absl::crc32c_t crc = absl::RemoveCrc32cSuffix(full_string_crc, suffix_crc,
      suffix_len);
    benchmark::DoNotOptimize(crc);
  }
}
BENCHMARK(BM_RemoveSuffix)
    ->ArgPair(1, 1)
    ->ArgPair(100, 10)
    ->ArgPair(100, 100)
    ->ArgPair(10000, 1)
    ->ArgPair(10000, 100)
    ->ArgPair(10000, 10000)
    ->ArgPair(500000, 1)
    ->ArgPair(500000, 100)
    ->ArgPair(500000, 10000)
    ->ArgPair(500000, 500000);
}  // namespace
