// Copyright 2018 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 <stdint.h>

#include <algorithm>
#include <array>
#include <cstddef>
#include <functional>
#include <map>
#include <memory>
#include <numeric>
#include <random>
#include <set>
#include <string>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

#include "absl/algorithm/container.h"
#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/container/btree_map.h"
#include "absl/container/btree_set.h"
#include "absl/container/btree_test.h"
#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/container/internal/hashtable_debug.h"
#include "absl/hash/hash.h"
#include "absl/log/log.h"
#include "absl/memory/memory.h"
#include "absl/random/random.h"
#include "absl/strings/cord.h"
#include "absl/strings/str_format.h"
#include "absl/time/time.h"
#include "benchmark/benchmark.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace container_internal {
namespace {

constexpr size_t kBenchmarkValues = 1 << 20;

// How many times we add and remove sub-batches in one batch of *AddRem
// benchmarks.
constexpr size_t kAddRemBatchSize = 1 << 2;

// Generates n values in the range [0, 4 * n].
template <typename V>
std::vector<V> GenerateValues(int n) {
  constexpr int kSeed = 23;
  return GenerateValuesWithSeed<V>(n, 4 * n, kSeed);
}

// Benchmark insertion of values into a container.
template <typename T>
void BM_InsertImpl(benchmark::State& state, bool sorted) {
  using V = typename remove_pair_const<typename T::value_type>::type;
  typename KeyOfValue<typename T::key_type, V>::type key_of_value;

  std::vector<V> values = GenerateValues<V>(kBenchmarkValues);
  if (sorted) {
    std::sort(values.begin(), values.end());
  }
  T container(values.begin(), values.end());

  // Remove and re-insert 10% of the keys per batch.
  const int batch_size = (kBenchmarkValues + 9) / 10;
  while (state.KeepRunningBatch(batch_size)) {
    state.PauseTiming();
    const auto i = static_cast<int>(state.iterations());

    for (int j = i; j < i + batch_size; j++) {
      int x = j % kBenchmarkValues;
      container.erase(key_of_value(values[x]));
    }

    state.ResumeTiming();

    for (int j = i; j < i + batch_size; j++) {
      int x = j % kBenchmarkValues;
      container.insert(values[x]);
    }
  }
}

template <typename T>
void BM_Insert(benchmark::State& state) {
  BM_InsertImpl<T>(state, false);
}

template <typename T>
void BM_InsertSorted(benchmark::State& state) {
  BM_InsertImpl<T>(state, true);
}

// Benchmark inserting the first few elements in a container. In b-tree, this is
// when the root node grows.
template <typename T>
void BM_InsertSmall(benchmark::State& state) {
  using V = typename remove_pair_const<typename T::value_type>::type;

  const int kSize = 8;
  std::vector<V> values = GenerateValues<V>(kSize);
  T container;

  while (state.KeepRunningBatch(kSize)) {
    for (int i = 0; i < kSize; ++i) {
      benchmark::DoNotOptimize(container.insert(values[i]));
    }
    state.PauseTiming();
    // Do not measure the time it takes to clear the container.
    container.clear();
    state.ResumeTiming();
  }
}

template <typename T>
void BM_LookupImpl(benchmark::State& state, bool sorted) {
  using V = typename remove_pair_const<typename T::value_type>::type;
  typename KeyOfValue<typename T::key_type, V>::type key_of_value;

  std::vector<V> values = GenerateValues<V>(kBenchmarkValues);
  if (sorted) {
    std::sort(values.begin(), values.end());
  }
  T container(values.begin(), values.end());

  while (state.KeepRunning()) {
    int idx = state.iterations() % kBenchmarkValues;
    benchmark::DoNotOptimize(container.find(key_of_value(values[idx])));
  }
}

// Benchmark lookup of values in a container.
template <typename T>
void BM_Lookup(benchmark::State& state) {
  BM_LookupImpl<T>(state, false);
}

// Benchmark lookup of values in a full container, meaning that values
// are inserted in-order to take advantage of biased insertion, which
// yields a full tree.
template <typename T>
void BM_FullLookup(benchmark::State& state) {
  BM_LookupImpl<T>(state, true);
}

// Benchmark erasing values from a container.
template <typename T>
void BM_Erase(benchmark::State& state) {
  using V = typename remove_pair_const<typename T::value_type>::type;
  typename KeyOfValue<typename T::key_type, V>::type key_of_value;
  std::vector<V> values = GenerateValues<V>(kBenchmarkValues);
  T container(values.begin(), values.end());

  // Remove and re-insert 10% of the keys per batch.
  const int batch_size = (kBenchmarkValues + 9) / 10;
  while (state.KeepRunningBatch(batch_size)) {
    const int i = state.iterations();

    for (int j = i; j < i + batch_size; j++) {
      int x = j % kBenchmarkValues;
      container.erase(key_of_value(values[x]));
    }

    state.PauseTiming();
    for (int j = i; j < i + batch_size; j++) {
      int x = j % kBenchmarkValues;
      container.insert(values[x]);
    }
    state.ResumeTiming();
  }
}

// Benchmark erasing multiple values from a container.
template <typename T>
void BM_EraseRange(benchmark::State& state) {
  using V = typename remove_pair_const<typename T::value_type>::type;
  typename KeyOfValue<typename T::key_type, V>::type key_of_value;
  std::vector<V> values = GenerateValues<V>(kBenchmarkValues);
  T container(values.begin(), values.end());

  // Remove and re-insert 10% of the keys per batch.
  const int batch_size = (kBenchmarkValues + 9) / 10;
  while (state.KeepRunningBatch(batch_size)) {
    const int i = state.iterations();

    const int start_index = i % kBenchmarkValues;

    state.PauseTiming();
    {
      std::vector<V> removed;
      removed.reserve(batch_size);
      auto itr = container.find(key_of_value(values[start_index]));
      auto start = itr;
      for (int j = 0; j < batch_size; j++) {
        if (itr == container.end()) {
          state.ResumeTiming();
          container.erase(start, itr);
          state.PauseTiming();
          itr = container.begin();
          start = itr;
        }
        removed.push_back(*itr++);
      }

      state.ResumeTiming();
      container.erase(start, itr);
      state.PauseTiming();

      container.insert(removed.begin(), removed.end());
    }
    state.ResumeTiming();
  }
}

// Predicate that erases every other element. We can't use a lambda because
// C++11 doesn't support generic lambdas.
// TODO(b/207389011): consider adding benchmarks that remove different fractions
// of keys (e.g. 10%, 90%).
struct EraseIfPred {
  uint64_t i = 0;
  template <typename T>
  bool operator()(const T&) {
    return ++i % 2;
  }
};

// Benchmark erasing multiple values from a container with a predicate.
template <typename T>
void BM_EraseIf(benchmark::State& state) {
  using V = typename remove_pair_const<typename T::value_type>::type;
  std::vector<V> values = GenerateValues<V>(kBenchmarkValues);

  // Removes half of the keys per batch.
  const int batch_size = (kBenchmarkValues + 1) / 2;
  EraseIfPred pred;
  while (state.KeepRunningBatch(batch_size)) {
    state.PauseTiming();
    {
      T container(values.begin(), values.end());
      state.ResumeTiming();
      erase_if(container, pred);
      benchmark::DoNotOptimize(container);
      state.PauseTiming();
    }
    state.ResumeTiming();
  }
}

// Benchmark steady-state insert (into first half of range) and remove (from
// second half of range), treating the container approximately like a queue with
// log-time access for all elements. This benchmark does not test the case where
// insertion and removal happen in the same region of the tree.  This benchmark
// counts two value constructors.
template <typename T>
void BM_QueueAddRem(benchmark::State& state) {
  using V = typename remove_pair_const<typename T::value_type>::type;
  typename KeyOfValue<typename T::key_type, V>::type key_of_value;

  ABSL_RAW_CHECK(kBenchmarkValues % 2 == 0, "for performance");

  T container;

  const size_t half = kBenchmarkValues / 2;
  std::vector<int> remove_keys(half);
  std::vector<int> add_keys(half);

  // We want to do the exact same work repeatedly, and the benchmark can end
  // after a different number of iterations depending on the speed of the
  // individual run so we use a large batch size here and ensure that we do
  // deterministic work every batch.
  while (state.KeepRunningBatch(half * kAddRemBatchSize)) {
    state.PauseTiming();

    container.clear();

    for (size_t i = 0; i < half; ++i) {
      remove_keys[i] = i;
      add_keys[i] = i;
    }
    constexpr int kSeed = 5;
    std::mt19937_64 rand(kSeed);
    std::shuffle(remove_keys.begin(), remove_keys.end(), rand);
    std::shuffle(add_keys.begin(), add_keys.end(), rand);

    // Note needs lazy generation of values.
    Generator<V> g(kBenchmarkValues * kAddRemBatchSize);

    for (size_t i = 0; i < half; ++i) {
      container.insert(g(add_keys[i]));
      container.insert(g(half + remove_keys[i]));
    }

    // There are three parts each of size "half":
    // 1 is being deleted from  [offset - half, offset)
    // 2 is standing            [offset, offset + half)
    // 3 is being inserted into [offset + half, offset + 2 * half)
    size_t offset = 0;

    for (size_t i = 0; i < kAddRemBatchSize; ++i) {
      std::shuffle(remove_keys.begin(), remove_keys.end(), rand);
      std::shuffle(add_keys.begin(), add_keys.end(), rand);
      offset += half;

      state.ResumeTiming();
      for (size_t idx = 0; idx < half; ++idx) {
        container.erase(key_of_value(g(offset - half + remove_keys[idx])));
        container.insert(g(offset + half + add_keys[idx]));
      }
      state.PauseTiming();
    }
    state.ResumeTiming();
  }
}

// Mixed insertion and deletion in the same range using pre-constructed values.
template <typename T>
void BM_MixedAddRem(benchmark::State& state) {
  using V = typename remove_pair_const<typename T::value_type>::type;
  typename KeyOfValue<typename T::key_type, V>::type key_of_value;

  ABSL_RAW_CHECK(kBenchmarkValues % 2 == 0, "for performance");

  T container;

  // Create two random shuffles
  std::vector<int> remove_keys(kBenchmarkValues);
  std::vector<int> add_keys(kBenchmarkValues);

  // We want to do the exact same work repeatedly, and the benchmark can end
  // after a different number of iterations depending on the speed of the
  // individual run so we use a large batch size here and ensure that we do
  // deterministic work every batch.
  while (state.KeepRunningBatch(kBenchmarkValues * kAddRemBatchSize)) {
    state.PauseTiming();

    container.clear();

    constexpr int kSeed = 7;
    std::mt19937_64 rand(kSeed);

    std::vector<V> values = GenerateValues<V>(kBenchmarkValues * 2);

    // Insert the first half of the values (already in random order)
    container.insert(values.begin(), values.begin() + kBenchmarkValues);

    // Insert the first half of the values (already in random order)
    for (size_t i = 0; i < kBenchmarkValues; ++i) {
      // remove_keys and add_keys will be swapped before each round,
      // therefore fill add_keys here w/ the keys being inserted, so
      // they'll be the first to be removed.
      remove_keys[i] = i + kBenchmarkValues;
      add_keys[i] = i;
    }

    for (size_t i = 0; i < kAddRemBatchSize; ++i) {
      remove_keys.swap(add_keys);
      std::shuffle(remove_keys.begin(), remove_keys.end(), rand);
      std::shuffle(add_keys.begin(), add_keys.end(), rand);

      state.ResumeTiming();
      for (size_t idx = 0; idx < kBenchmarkValues; ++idx) {
        container.erase(key_of_value(values[remove_keys[idx]]));
        container.insert(values[add_keys[idx]]);
      }
      state.PauseTiming();
    }
    state.ResumeTiming();
  }
}

// Insertion at end, removal from the beginning.  This benchmark
// counts two value constructors.
// TODO(ezb): we could add a GenerateNext version of generator that could reduce
// noise for string-like types.
template <typename T>
void BM_Fifo(benchmark::State& state) {
  using V = typename remove_pair_const<typename T::value_type>::type;

  T container;
  // Need lazy generation of values as state.max_iterations is large.
  Generator<V> g(kBenchmarkValues + state.max_iterations);

  for (int i = 0; i < kBenchmarkValues; i++) {
    container.insert(g(i));
  }

  while (state.KeepRunning()) {
    container.erase(container.begin());
    container.insert(container.end(), g(state.iterations() + kBenchmarkValues));
  }
}

// Iteration (forward) through the tree
template <typename T>
void BM_FwdIter(benchmark::State& state) {
  using V = typename remove_pair_const<typename T::value_type>::type;

  std::vector<V> values = GenerateValues<V>(kBenchmarkValues);
  T container(values.begin(), values.end());

  auto iter = container.end();

  while (state.KeepRunning()) {
    if (iter == container.end()) iter = container.begin();
    auto *v = &(*iter);
    benchmark::DoNotOptimize(v);
    benchmark::DoNotOptimize(++iter);
  }
}

// Benchmark random range-construction of a container.
template <typename T>
void BM_RangeConstructionImpl(benchmark::State& state, bool sorted) {
  using V = typename remove_pair_const<typename T::value_type>::type;

  std::vector<V> values = GenerateValues<V>(kBenchmarkValues);
  if (sorted) {
    std::sort(values.begin(), values.end());
  }
  {
    T container(values.begin(), values.end());
  }

  while (state.KeepRunning()) {
    T container(values.begin(), values.end());
    benchmark::DoNotOptimize(container);
  }
}

template <typename T>
void BM_InsertRangeRandom(benchmark::State& state) {
  BM_RangeConstructionImpl<T>(state, false);
}

template <typename T>
void BM_InsertRangeSorted(benchmark::State& state) {
  BM_RangeConstructionImpl<T>(state, true);
}

#define STL_ORDERED_TYPES(value)                     \
  using stl_set_##value = std::set<value>;           \
  using stl_map_##value = std::map<value, intptr_t>; \
  using stl_multiset_##value = std::multiset<value>; \
  using stl_multimap_##value = std::multimap<value, intptr_t>

using StdString = std::string;
STL_ORDERED_TYPES(int32_t);
STL_ORDERED_TYPES(int64_t);
STL_ORDERED_TYPES(StdString);
STL_ORDERED_TYPES(Cord);
STL_ORDERED_TYPES(Time);

#define STL_UNORDERED_TYPES(value)                                       \
  using stl_unordered_set_##value = std::unordered_set<value>;           \
  using stl_unordered_map_##value = std::unordered_map<value, intptr_t>; \
  using flat_hash_set_##value = flat_hash_set<value>;                    \
  using flat_hash_map_##value = flat_hash_map<value, intptr_t>;          \
  using stl_unordered_multiset_##value = std::unordered_multiset<value>; \
  using stl_unordered_multimap_##value =                                 \
      std::unordered_multimap<value, intptr_t>

#define STL_UNORDERED_TYPES_CUSTOM_HASH(value, hash)                           \
  using stl_unordered_set_##value = std::unordered_set<value, hash>;           \
  using stl_unordered_map_##value = std::unordered_map<value, intptr_t, hash>; \
  using flat_hash_set_##value = flat_hash_set<value, hash>;                    \
  using flat_hash_map_##value = flat_hash_map<value, intptr_t, hash>;          \
  using stl_unordered_multiset_##value = std::unordered_multiset<value, hash>; \
  using stl_unordered_multimap_##value =                                       \
      std::unordered_multimap<value, intptr_t, hash>

STL_UNORDERED_TYPES_CUSTOM_HASH(Cord, absl::Hash<absl::Cord>);

STL_UNORDERED_TYPES(int32_t);
STL_UNORDERED_TYPES(int64_t);
STL_UNORDERED_TYPES(StdString);
STL_UNORDERED_TYPES_CUSTOM_HASH(Time, absl::Hash<absl::Time>);

#define BTREE_TYPES(value)                                            \
  using btree_256_set_##value =                                       \
      btree_set<value, std::less<value>, std::allocator<value>>;      \
  using btree_256_map_##value =                                       \
      btree_map<value, intptr_t, std::less<value>,                    \
                std::allocator<std::pair<const value, intptr_t>>>;    \
  using btree_256_multiset_##value =                                  \
      btree_multiset<value, std::less<value>, std::allocator<value>>; \
  using btree_256_multimap_##value =                                  \
      btree_multimap<value, intptr_t, std::less<value>,               \
                     std::allocator<std::pair<const value, intptr_t>>>

BTREE_TYPES(int32_t);
BTREE_TYPES(int64_t);
BTREE_TYPES(StdString);
BTREE_TYPES(Cord);
BTREE_TYPES(Time);

#define MY_BENCHMARK4(type, func)                                              \
  void BM_##type##_##func(benchmark::State& state) { BM_##func<type>(state); } \
  BENCHMARK(BM_##type##_##func)

#define MY_BENCHMARK3_STL(type)           \
  MY_BENCHMARK4(type, Insert);            \
  MY_BENCHMARK4(type, InsertSorted);      \
  MY_BENCHMARK4(type, InsertSmall);       \
  MY_BENCHMARK4(type, Lookup);            \
  MY_BENCHMARK4(type, FullLookup);        \
  MY_BENCHMARK4(type, Erase);             \
  MY_BENCHMARK4(type, EraseRange);        \
  MY_BENCHMARK4(type, QueueAddRem);       \
  MY_BENCHMARK4(type, MixedAddRem);       \
  MY_BENCHMARK4(type, Fifo);              \
  MY_BENCHMARK4(type, FwdIter);           \
  MY_BENCHMARK4(type, InsertRangeRandom); \
  MY_BENCHMARK4(type, InsertRangeSorted)

#define MY_BENCHMARK3(type)     \
  MY_BENCHMARK4(type, EraseIf); \
  MY_BENCHMARK3_STL(type)

#define MY_BENCHMARK2_SUPPORTS_MULTI_ONLY(type) \
  MY_BENCHMARK3_STL(stl_##type);                \
  MY_BENCHMARK3_STL(stl_unordered_##type);      \
  MY_BENCHMARK3(btree_256_##type)

#define MY_BENCHMARK2(type)                \
  MY_BENCHMARK2_SUPPORTS_MULTI_ONLY(type); \
  MY_BENCHMARK3(flat_hash_##type)

// Define MULTI_TESTING to see benchmarks for multi-containers also.
//
// You can use --copt=-DMULTI_TESTING.
#ifdef MULTI_TESTING
#define MY_BENCHMARK(type)                            \
  MY_BENCHMARK2(set_##type);                          \
  MY_BENCHMARK2(map_##type);                          \
  MY_BENCHMARK2_SUPPORTS_MULTI_ONLY(multiset_##type); \
  MY_BENCHMARK2_SUPPORTS_MULTI_ONLY(multimap_##type)
#else
#define MY_BENCHMARK(type)   \
  MY_BENCHMARK2(set_##type); \
  MY_BENCHMARK2(map_##type)
#endif

MY_BENCHMARK(int32_t);
MY_BENCHMARK(int64_t);
MY_BENCHMARK(StdString);
MY_BENCHMARK(Cord);
MY_BENCHMARK(Time);

// Define a type whose size and cost of moving are independently customizable.
// When sizeof(value_type) increases, we expect btree to no longer have as much
// cache-locality advantage over STL. When cost of moving increases, we expect
// btree to actually do more work than STL because it has to move values around
// and STL doesn't have to.
template <int Size, int Copies>
struct BigType {
  BigType() : BigType(0) {}
  explicit BigType(int x) { std::iota(values.begin(), values.end(), x); }

  void Copy(const BigType& other) {
    for (int i = 0; i < Size && i < Copies; ++i) values[i] = other.values[i];
    // If Copies > Size, do extra copies.
    for (int i = Size, idx = 0; i < Copies; ++i) {
      int64_t tmp = other.values[idx];
      benchmark::DoNotOptimize(tmp);
      idx = idx + 1 == Size ? 0 : idx + 1;
    }
  }

  BigType(const BigType& other) { Copy(other); }
  BigType& operator=(const BigType& other) {
    Copy(other);
    return *this;
  }

  // Compare only the first Copies elements if Copies is less than Size.
  bool operator<(const BigType& other) const {
    return std::lexicographical_compare(
        values.begin(), values.begin() + std::min(Size, Copies),
        other.values.begin(), other.values.begin() + std::min(Size, Copies));
  }
  bool operator==(const BigType& other) const {
    return std::equal(values.begin(), values.begin() + std::min(Size, Copies),
                      other.values.begin());
  }

  // Support absl::Hash.
  template <typename State>
  friend State AbslHashValue(State h, const BigType& b) {
    for (int i = 0; i < Size && i < Copies; ++i)
      h = State::combine(std::move(h), b.values[i]);
    return h;
  }

  std::array<int64_t, Size> values;
};

#define BIG_TYPE_BENCHMARKS(SIZE, COPIES)                                     \
  using stl_set_size##SIZE##copies##COPIES = std::set<BigType<SIZE, COPIES>>; \
  using stl_map_size##SIZE##copies##COPIES =                                  \
      std::map<BigType<SIZE, COPIES>, intptr_t>;                              \
  using stl_multiset_size##SIZE##copies##COPIES =                             \
      std::multiset<BigType<SIZE, COPIES>>;                                   \
  using stl_multimap_size##SIZE##copies##COPIES =                             \
      std::multimap<BigType<SIZE, COPIES>, intptr_t>;                         \
  using stl_unordered_set_size##SIZE##copies##COPIES =                        \
      std::unordered_set<BigType<SIZE, COPIES>,                               \
                         absl::Hash<BigType<SIZE, COPIES>>>;                  \
  using stl_unordered_map_size##SIZE##copies##COPIES =                        \
      std::unordered_map<BigType<SIZE, COPIES>, intptr_t,                     \
                         absl::Hash<BigType<SIZE, COPIES>>>;                  \
  using flat_hash_set_size##SIZE##copies##COPIES =                            \
      flat_hash_set<BigType<SIZE, COPIES>>;                                   \
  using flat_hash_map_size##SIZE##copies##COPIES =                            \
      flat_hash_map<BigType<SIZE, COPIES>, intptr_t>;                         \
  using stl_unordered_multiset_size##SIZE##copies##COPIES =                   \
      std::unordered_multiset<BigType<SIZE, COPIES>,                          \
                              absl::Hash<BigType<SIZE, COPIES>>>;             \
  using stl_unordered_multimap_size##SIZE##copies##COPIES =                   \
      std::unordered_multimap<BigType<SIZE, COPIES>, intptr_t,                \
                              absl::Hash<BigType<SIZE, COPIES>>>;             \
  using btree_256_set_size##SIZE##copies##COPIES =                            \
      btree_set<BigType<SIZE, COPIES>>;                                       \
  using btree_256_map_size##SIZE##copies##COPIES =                            \
      btree_map<BigType<SIZE, COPIES>, intptr_t>;                             \
  using btree_256_multiset_size##SIZE##copies##COPIES =                       \
      btree_multiset<BigType<SIZE, COPIES>>;                                  \
  using btree_256_multimap_size##SIZE##copies##COPIES =                       \
      btree_multimap<BigType<SIZE, COPIES>, intptr_t>;                        \
  MY_BENCHMARK(size##SIZE##copies##COPIES)

// Define BIG_TYPE_TESTING to see benchmarks for more big types.
//
// You can use --copt=-DBIG_TYPE_TESTING.
#ifndef NODESIZE_TESTING
#ifdef BIG_TYPE_TESTING
BIG_TYPE_BENCHMARKS(1, 4);
BIG_TYPE_BENCHMARKS(4, 1);
BIG_TYPE_BENCHMARKS(4, 4);
BIG_TYPE_BENCHMARKS(1, 8);
BIG_TYPE_BENCHMARKS(8, 1);
BIG_TYPE_BENCHMARKS(8, 8);
BIG_TYPE_BENCHMARKS(1, 16);
BIG_TYPE_BENCHMARKS(16, 1);
BIG_TYPE_BENCHMARKS(16, 16);
BIG_TYPE_BENCHMARKS(1, 32);
BIG_TYPE_BENCHMARKS(32, 1);
BIG_TYPE_BENCHMARKS(32, 32);
#else
BIG_TYPE_BENCHMARKS(32, 32);
#endif
#endif

// Benchmark using unique_ptrs to large value types. In order to be able to use
// the same benchmark code as the other types, use a type that holds a
// unique_ptr and has a copy constructor.
template <int Size>
struct BigTypePtr {
  BigTypePtr() : BigTypePtr(0) {}
  explicit BigTypePtr(int x) { ptr = std::make_unique<BigType<Size, Size>>(x); }
  BigTypePtr(const BigTypePtr& other) {
    ptr = std::make_unique<BigType<Size, Size>>(*other.ptr);
  }
  BigTypePtr(BigTypePtr&& other) noexcept = default;
  BigTypePtr& operator=(const BigTypePtr& other) {
    ptr = std::make_unique<BigType<Size, Size>>(*other.ptr);
  }
  BigTypePtr& operator=(BigTypePtr&& other) noexcept = default;

  bool operator<(const BigTypePtr& other) const { return *ptr < *other.ptr; }
  bool operator==(const BigTypePtr& other) const { return *ptr == *other.ptr; }

  std::unique_ptr<BigType<Size, Size>> ptr;
};

template <int Size>
double ContainerInfo(const btree_set<BigTypePtr<Size>>& b) {
  const double bytes_used =
      b.bytes_used() + b.size() * sizeof(BigType<Size, Size>);
  const double bytes_per_value = bytes_used / b.size();
  BtreeContainerInfoLog(b, bytes_used, bytes_per_value);
  return bytes_per_value;
}
template <int Size>
double ContainerInfo(const btree_map<int, BigTypePtr<Size>>& b) {
  const double bytes_used =
      b.bytes_used() + b.size() * sizeof(BigType<Size, Size>);
  const double bytes_per_value = bytes_used / b.size();
  BtreeContainerInfoLog(b, bytes_used, bytes_per_value);
  return bytes_per_value;
}

#define BIG_TYPE_PTR_BENCHMARKS(SIZE)                                          \
  using stl_set_size##SIZE##copies##SIZE##ptr = std::set<BigType<SIZE, SIZE>>; \
  using stl_map_size##SIZE##copies##SIZE##ptr =                                \
      std::map<int, BigType<SIZE, SIZE>>;                                      \
  using stl_unordered_set_size##SIZE##copies##SIZE##ptr =                      \
      std::unordered_set<BigType<SIZE, SIZE>,                                  \
                         absl::Hash<BigType<SIZE, SIZE>>>;                     \
  using stl_unordered_map_size##SIZE##copies##SIZE##ptr =                      \
      std::unordered_map<int, BigType<SIZE, SIZE>>;                            \
  using flat_hash_set_size##SIZE##copies##SIZE##ptr =                          \
      flat_hash_set<BigType<SIZE, SIZE>>;                                      \
  using flat_hash_map_size##SIZE##copies##SIZE##ptr =                          \
      flat_hash_map<int, BigTypePtr<SIZE>>;                                    \
  using btree_256_set_size##SIZE##copies##SIZE##ptr =                          \
      btree_set<BigTypePtr<SIZE>>;                                             \
  using btree_256_map_size##SIZE##copies##SIZE##ptr =                          \
      btree_map<int, BigTypePtr<SIZE>>;                                        \
  MY_BENCHMARK3_STL(stl_set_size##SIZE##copies##SIZE##ptr);                    \
  MY_BENCHMARK3_STL(stl_unordered_set_size##SIZE##copies##SIZE##ptr);          \
  MY_BENCHMARK3(flat_hash_set_size##SIZE##copies##SIZE##ptr);                  \
  MY_BENCHMARK3(btree_256_set_size##SIZE##copies##SIZE##ptr);                  \
  MY_BENCHMARK3_STL(stl_map_size##SIZE##copies##SIZE##ptr);                    \
  MY_BENCHMARK3_STL(stl_unordered_map_size##SIZE##copies##SIZE##ptr);          \
  MY_BENCHMARK3(flat_hash_map_size##SIZE##copies##SIZE##ptr);                  \
  MY_BENCHMARK3(btree_256_map_size##SIZE##copies##SIZE##ptr)

BIG_TYPE_PTR_BENCHMARKS(32);

void BM_BtreeSet_IteratorDifference(benchmark::State& state) {
  absl::InsecureBitGen bitgen;
  std::vector<int> vec;
  // Randomize the set's insertion order so the nodes aren't all full.
  vec.reserve(state.range(0));
  for (int i = 0; i < state.range(0); ++i) vec.push_back(i);
  absl::c_shuffle(vec, bitgen);

  absl::btree_set<int> set;
  for (int i : vec) set.insert(i);

  size_t distance = absl::Uniform(bitgen, 0u, set.size());
  while (state.KeepRunningBatch(distance)) {
    size_t end = absl::Uniform(bitgen, distance, set.size());
    size_t begin = end - distance;
    benchmark::DoNotOptimize(set.find(static_cast<int>(end)) -
                             set.find(static_cast<int>(begin)));
    distance = absl::Uniform(bitgen, 0u, set.size());
  }
}

BENCHMARK(BM_BtreeSet_IteratorDifference)->Range(1 << 10, 1 << 20);

void BM_BtreeSet_IteratorAddition(benchmark::State& state) {
  absl::InsecureBitGen bitgen;
  std::vector<int> vec;
  // Randomize the set's insertion order so the nodes aren't all full.
  vec.reserve(static_cast<size_t>(state.range(0)));
  for (int i = 0; i < state.range(0); ++i) vec.push_back(i);
  absl::c_shuffle(vec, bitgen);

  absl::btree_set<int> set;
  for (int i : vec) set.insert(i);

  size_t distance = absl::Uniform(bitgen, 0u, set.size());
  while (state.KeepRunningBatch(distance)) {
    // Let the increment go all the way to the `end` iterator.
    const size_t begin =
        absl::Uniform(absl::IntervalClosed, bitgen, 0u, set.size() - distance);
    auto it = set.find(static_cast<int>(begin));
    benchmark::DoNotOptimize(it += static_cast<int>(distance));
    distance = absl::Uniform(bitgen, 0u, set.size());
  }
}

BENCHMARK(BM_BtreeSet_IteratorAddition)->Range(1 << 10, 1 << 20);

void BM_BtreeSet_IteratorSubtraction(benchmark::State& state) {
  absl::InsecureBitGen bitgen;
  std::vector<int> vec;
  // Randomize the set's insertion order so the nodes aren't all full.
  vec.reserve(static_cast<size_t>(state.range(0)));
  for (int i = 0; i < state.range(0); ++i) vec.push_back(i);
  absl::c_shuffle(vec, bitgen);

  absl::btree_set<int> set;
  for (int i : vec) set.insert(i);

  size_t distance = absl::Uniform(bitgen, 0u, set.size());
  while (state.KeepRunningBatch(distance)) {
    size_t end = absl::Uniform(bitgen, distance, set.size());
    auto it = set.find(static_cast<int>(end));
    benchmark::DoNotOptimize(it -= static_cast<int>(distance));
    distance = absl::Uniform(bitgen, 0u, set.size());
  }
}

BENCHMARK(BM_BtreeSet_IteratorSubtraction)->Range(1 << 10, 1 << 20);

}  // namespace
}  // namespace container_internal
ABSL_NAMESPACE_END
}  // namespace absl
