//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include <algorithm>
#include <cstdint>
#include <memory>
#include <random>
#include <set>
#include <string>
#include <vector>

#include "CartesianBenchmarks.h"
#include "benchmark/benchmark.h"
#include "test_macros.h"

namespace {

enum class HitType { Hit, Miss };

struct AllHitTypes : EnumValuesAsTuple<AllHitTypes, HitType, 2> {
  static constexpr const char* Names[] = {"Hit", "Miss"};
};

enum class AccessPattern { Ordered, Random };

struct AllAccessPattern
    : EnumValuesAsTuple<AllAccessPattern, AccessPattern, 2> {
  static constexpr const char* Names[] = {"Ordered", "Random"};
};

void sortKeysBy(std::vector<uint64_t>& Keys, AccessPattern AP) {
  if (AP == AccessPattern::Random) {
    std::random_device R;
    std::mt19937 M(R());
    std::shuffle(std::begin(Keys), std::end(Keys), M);
  }
}

struct TestSets {
  std::vector<std::set<uint64_t> > Sets;
  std::vector<uint64_t> Keys;
};

TestSets makeTestingSets(size_t TableSize, size_t NumTables, HitType Hit,
                         AccessPattern Access) {
  TestSets R;
  R.Sets.resize(1);

  for (uint64_t I = 0; I < TableSize; ++I) {
    R.Sets[0].insert(2 * I);
    R.Keys.push_back(Hit == HitType::Hit ? 2 * I : 2 * I + 1);
  }
  R.Sets.resize(NumTables, R.Sets[0]);
  sortKeysBy(R.Keys, Access);

  return R;
}

struct Base {
  size_t TableSize;
  size_t NumTables;
  Base(size_t T, size_t N) : TableSize(T), NumTables(N) {}

  bool skip() const {
    size_t Total = TableSize * NumTables;
    return Total < 100 || Total > 1000000;
  }

  std::string baseName() const {
    return "_TableSize" + std::to_string(TableSize) + "_NumTables" +
           std::to_string(NumTables);
  }
};

template <class Access>
struct Create : Base {
  using Base::Base;

  void run(benchmark::State& State) const {
    std::vector<uint64_t> Keys(TableSize);
    std::iota(Keys.begin(), Keys.end(), uint64_t{0});
    sortKeysBy(Keys, Access());

    while (State.KeepRunningBatch(TableSize * NumTables)) {
      std::vector<std::set<uint64_t>> Sets(NumTables);
      for (auto K : Keys) {
        for (auto& Set : Sets) {
          benchmark::DoNotOptimize(Set.insert(K));
        }
      }
    }
  }

  std::string name() const {
    return "BM_Create" + Access::name() + baseName();
  }
};

template <class Hit, class Access>
struct Find : Base {
  using Base::Base;

  void run(benchmark::State& State) const {
    auto Data = makeTestingSets(TableSize, NumTables, Hit(), Access());

    while (State.KeepRunningBatch(TableSize * NumTables)) {
      for (auto K : Data.Keys) {
        for (auto& Set : Data.Sets) {
          benchmark::DoNotOptimize(Set.find(K));
        }
      }
    }
  }

  std::string name() const {
    return "BM_Find" + Hit::name() + Access::name() + baseName();
  }
};

template <class Hit, class Access>
struct FindNeEnd : Base {
  using Base::Base;

  void run(benchmark::State& State) const {
    auto Data = makeTestingSets(TableSize, NumTables, Hit(), Access());

    while (State.KeepRunningBatch(TableSize * NumTables)) {
      for (auto K : Data.Keys) {
        for (auto& Set : Data.Sets) {
          benchmark::DoNotOptimize(Set.find(K) != Set.end());
        }
      }
    }
  }

  std::string name() const {
    return "BM_FindNeEnd" + Hit::name() + Access::name() + baseName();
  }
};

template <class Access>
struct InsertHit : Base {
  using Base::Base;

  void run(benchmark::State& State) const {
    auto Data = makeTestingSets(TableSize, NumTables, HitType::Hit, Access());

    while (State.KeepRunningBatch(TableSize * NumTables)) {
      for (auto K : Data.Keys) {
        for (auto& Set : Data.Sets) {
          benchmark::DoNotOptimize(Set.insert(K));
        }
      }
    }
  }

  std::string name() const {
    return "BM_InsertHit" + Access::name() + baseName();
  }
};

template <class Access>
struct InsertMissAndErase : Base {
  using Base::Base;

  void run(benchmark::State& State) const {
    auto Data = makeTestingSets(TableSize, NumTables, HitType::Miss, Access());

    while (State.KeepRunningBatch(TableSize * NumTables)) {
      for (auto K : Data.Keys) {
        for (auto& Set : Data.Sets) {
          benchmark::DoNotOptimize(Set.erase(Set.insert(K).first));
        }
      }
    }
  }

  std::string name() const {
    return "BM_InsertMissAndErase" + Access::name() + baseName();
  }
};

struct IterateRangeFor : Base {
  using Base::Base;

  void run(benchmark::State& State) const {
    auto Data = makeTestingSets(TableSize, NumTables, HitType::Miss,
                                AccessPattern::Ordered);

    while (State.KeepRunningBatch(TableSize * NumTables)) {
      for (auto& Set : Data.Sets) {
        for (auto& V : Set) {
          benchmark::DoNotOptimize(V);
        }
      }
    }
  }

  std::string name() const { return "BM_IterateRangeFor" + baseName(); }
};

struct IterateBeginEnd : Base {
  using Base::Base;

  void run(benchmark::State& State) const {
    auto Data = makeTestingSets(TableSize, NumTables, HitType::Miss,
                                AccessPattern::Ordered);

    while (State.KeepRunningBatch(TableSize * NumTables)) {
      for (auto& Set : Data.Sets) {
        for (auto it = Set.begin(); it != Set.end(); ++it) {
          benchmark::DoNotOptimize(*it);
        }
      }
    }
  }

  std::string name() const { return "BM_IterateBeginEnd" + baseName(); }
};

}  // namespace

int main(int argc, char** argv) {
  benchmark::Initialize(&argc, argv);
  if (benchmark::ReportUnrecognizedArguments(argc, argv))
    return 1;

  const std::vector<size_t> TableSize{1, 10, 100, 1000, 10000, 100000, 1000000};
  const std::vector<size_t> NumTables{1, 10, 100, 1000, 10000, 100000, 1000000};

  makeCartesianProductBenchmark<Create, AllAccessPattern>(TableSize, NumTables);
  makeCartesianProductBenchmark<Find, AllHitTypes, AllAccessPattern>(
      TableSize, NumTables);
  makeCartesianProductBenchmark<FindNeEnd, AllHitTypes, AllAccessPattern>(
      TableSize, NumTables);
  makeCartesianProductBenchmark<InsertHit, AllAccessPattern>(
      TableSize, NumTables);
  makeCartesianProductBenchmark<InsertMissAndErase, AllAccessPattern>(
      TableSize, NumTables);
  makeCartesianProductBenchmark<IterateRangeFor>(TableSize, NumTables);
  makeCartesianProductBenchmark<IterateBeginEnd>(TableSize, NumTables);
  benchmark::RunSpecifiedBenchmarks();
}
