// 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 "absl/strings/string_view.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(2048)
    ->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(2048)
    ->Arg(10000)
    ->Arg(500000)
    ->Arg(100 * 1000 * 1000);

// Make working set >> CPU cache size to benchmark prefetches better
void BM_ExtendCacheMiss(benchmark::State& state) {
  int len = state.range(0);
  constexpr int total = 300 * 1000 * 1000;
  std::string extension = TestString(total);
  absl::crc32c_t base = absl::crc32c_t{0xC99465AA};  // CRC32C of "Hello World"
  for (auto s : state) {
    for (int i = 0; i < total; i += len * 2) {
      benchmark::DoNotOptimize(base);
      benchmark::DoNotOptimize(extension);
      absl::crc32c_t crc =
          absl::ExtendCrc32c(base, absl::string_view(&extension[i], len));
      benchmark::DoNotOptimize(crc);
    }
  }
  state.SetBytesProcessed(static_cast<int64_t>(state.iterations()) * total / 2);
}
BENCHMARK(BM_ExtendCacheMiss)->Arg(10)->Arg(100)->Arg(1000)->Arg(100000);

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(2048)->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
