// 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 "absl/container/internal/hashtablez_sampler.h"

#include <atomic>
#include <cassert>
#include <cmath>
#include <functional>
#include <limits>

#include "absl/base/attributes.h"
#include "absl/container/internal/have_sse.h"
#include "absl/debugging/stacktrace.h"
#include "absl/memory/memory.h"
#include "absl/synchronization/mutex.h"

namespace absl {
inline namespace lts_2019_08_08 {
namespace container_internal {
constexpr int HashtablezInfo::kMaxStackDepth;

namespace {
ABSL_CONST_INIT std::atomic<bool> g_hashtablez_enabled{
    false
};
ABSL_CONST_INIT std::atomic<int32_t> g_hashtablez_sample_parameter{1 << 10};
ABSL_CONST_INIT std::atomic<int32_t> g_hashtablez_max_samples{1 << 20};

// Returns the next pseudo-random value.
// pRNG is: aX+b mod c with a = 0x5DEECE66D, b =  0xB, c = 1<<48
// This is the lrand64 generator.
uint64_t NextRandom(uint64_t rnd) {
  const uint64_t prng_mult = uint64_t{0x5DEECE66D};
  const uint64_t prng_add = 0xB;
  const uint64_t prng_mod_power = 48;
  const uint64_t prng_mod_mask = ~(~uint64_t{0} << prng_mod_power);
  return (prng_mult * rnd + prng_add) & prng_mod_mask;
}

// Generates a geometric variable with the specified mean.
// This is done by generating a random number between 0 and 1 and applying
// the inverse cumulative distribution function for an exponential.
// Specifically: Let m be the inverse of the sample period, then
// the probability distribution function is m*exp(-mx) so the CDF is
// p = 1 - exp(-mx), so
// q = 1 - p = exp(-mx)
// log_e(q) = -mx
// -log_e(q)/m = x
// log_2(q) * (-log_e(2) * 1/m) = x
// In the code, q is actually in the range 1 to 2**26, hence the -26 below
//
int64_t GetGeometricVariable(int64_t mean) {
#if ABSL_HAVE_THREAD_LOCAL
  thread_local
#else   // ABSL_HAVE_THREAD_LOCAL
  // SampleSlow and hence GetGeometricVariable is guarded by a single mutex when
  // there are not thread locals.  Thus, a single global rng is acceptable for
  // that case.
  static
#endif  // ABSL_HAVE_THREAD_LOCAL
      uint64_t rng = []() {
        // We don't get well distributed numbers from this so we call
        // NextRandom() a bunch to mush the bits around.  We use a global_rand
        // to handle the case where the same thread (by memory address) gets
        // created and destroyed repeatedly.
        ABSL_CONST_INIT static std::atomic<uint32_t> global_rand(0);
        uint64_t r = reinterpret_cast<uint64_t>(&rng) +
                   global_rand.fetch_add(1, std::memory_order_relaxed);
        for (int i = 0; i < 20; ++i) {
          r = NextRandom(r);
        }
        return r;
      }();

  rng = NextRandom(rng);

  // Take the top 26 bits as the random number
  // (This plus the 1<<58 sampling bound give a max possible step of
  // 5194297183973780480 bytes.)
  const uint64_t prng_mod_power = 48;  // Number of bits in prng
  // The uint32_t cast is to prevent a (hard-to-reproduce) NAN
  // under piii debug for some binaries.
  double q = static_cast<uint32_t>(rng >> (prng_mod_power - 26)) + 1.0;
  // Put the computed p-value through the CDF of a geometric.
  double interval = (log2(q) - 26) * (-std::log(2.0) * mean);

  // Very large values of interval overflow int64_t. If we happen to
  // hit such improbable condition, we simply cheat and clamp interval
  // to largest supported value.
  if (interval > static_cast<double>(std::numeric_limits<int64_t>::max() / 2)) {
    return std::numeric_limits<int64_t>::max() / 2;
  }

  // Small values of interval are equivalent to just sampling next time.
  if (interval < 1) {
    return 1;
  }
  return static_cast<int64_t>(interval);
}

}  // namespace

HashtablezSampler& HashtablezSampler::Global() {
  static auto* sampler = new HashtablezSampler();
  return *sampler;
}

HashtablezSampler::DisposeCallback HashtablezSampler::SetDisposeCallback(
    DisposeCallback f) {
  return dispose_.exchange(f, std::memory_order_relaxed);
}

HashtablezInfo::HashtablezInfo() { PrepareForSampling(); }
HashtablezInfo::~HashtablezInfo() = default;

void HashtablezInfo::PrepareForSampling() {
  capacity.store(0, std::memory_order_relaxed);
  size.store(0, std::memory_order_relaxed);
  num_erases.store(0, std::memory_order_relaxed);
  max_probe_length.store(0, std::memory_order_relaxed);
  total_probe_length.store(0, std::memory_order_relaxed);
  hashes_bitwise_or.store(0, std::memory_order_relaxed);
  hashes_bitwise_and.store(~size_t{}, std::memory_order_relaxed);

  create_time = absl::Now();
  // The inliner makes hardcoded skip_count difficult (especially when combined
  // with LTO).  We use the ability to exclude stacks by regex when encoding
  // instead.
  depth = absl::GetStackTrace(stack, HashtablezInfo::kMaxStackDepth,
                              /* skip_count= */ 0);
  dead = nullptr;
}

HashtablezSampler::HashtablezSampler()
    : dropped_samples_(0), size_estimate_(0), all_(nullptr), dispose_(nullptr) {
  absl::MutexLock l(&graveyard_.init_mu);
  graveyard_.dead = &graveyard_;
}

HashtablezSampler::~HashtablezSampler() {
  HashtablezInfo* s = all_.load(std::memory_order_acquire);
  while (s != nullptr) {
    HashtablezInfo* next = s->next;
    delete s;
    s = next;
  }
}

void HashtablezSampler::PushNew(HashtablezInfo* sample) {
  sample->next = all_.load(std::memory_order_relaxed);
  while (!all_.compare_exchange_weak(sample->next, sample,
                                     std::memory_order_release,
                                     std::memory_order_relaxed)) {
  }
}

void HashtablezSampler::PushDead(HashtablezInfo* sample) {
  if (auto* dispose = dispose_.load(std::memory_order_relaxed)) {
    dispose(*sample);
  }

  absl::MutexLock graveyard_lock(&graveyard_.init_mu);
  absl::MutexLock sample_lock(&sample->init_mu);
  sample->dead = graveyard_.dead;
  graveyard_.dead = sample;
}

HashtablezInfo* HashtablezSampler::PopDead() {
  absl::MutexLock graveyard_lock(&graveyard_.init_mu);

  // The list is circular, so eventually it collapses down to
  //   graveyard_.dead == &graveyard_
  // when it is empty.
  HashtablezInfo* sample = graveyard_.dead;
  if (sample == &graveyard_) return nullptr;

  absl::MutexLock sample_lock(&sample->init_mu);
  graveyard_.dead = sample->dead;
  sample->PrepareForSampling();
  return sample;
}

HashtablezInfo* HashtablezSampler::Register() {
  int64_t size = size_estimate_.fetch_add(1, std::memory_order_relaxed);
  if (size > g_hashtablez_max_samples.load(std::memory_order_relaxed)) {
    size_estimate_.fetch_sub(1, std::memory_order_relaxed);
    dropped_samples_.fetch_add(1, std::memory_order_relaxed);
    return nullptr;
  }

  HashtablezInfo* sample = PopDead();
  if (sample == nullptr) {
    // Resurrection failed.  Hire a new warlock.
    sample = new HashtablezInfo();
    PushNew(sample);
  }

  return sample;
}

void HashtablezSampler::Unregister(HashtablezInfo* sample) {
  PushDead(sample);
  size_estimate_.fetch_sub(1, std::memory_order_relaxed);
}

int64_t HashtablezSampler::Iterate(
    const std::function<void(const HashtablezInfo& stack)>& f) {
  HashtablezInfo* s = all_.load(std::memory_order_acquire);
  while (s != nullptr) {
    absl::MutexLock l(&s->init_mu);
    if (s->dead == nullptr) {
      f(*s);
    }
    s = s->next;
  }

  return dropped_samples_.load(std::memory_order_relaxed);
}

HashtablezInfo* SampleSlow(int64_t* next_sample) {
  if (kAbslContainerInternalSampleEverything) {
    *next_sample = 1;
    return HashtablezSampler::Global().Register();
  }

  bool first = *next_sample < 0;
  *next_sample = GetGeometricVariable(
      g_hashtablez_sample_parameter.load(std::memory_order_relaxed));

  // g_hashtablez_enabled can be dynamically flipped, we need to set a threshold
  // low enough that we will start sampling in a reasonable time, so we just use
  // the default sampling rate.
  if (!g_hashtablez_enabled.load(std::memory_order_relaxed)) return nullptr;

  // We will only be negative on our first count, so we should just retry in
  // that case.
  if (first) {
    if (ABSL_PREDICT_TRUE(--*next_sample > 0)) return nullptr;
    return SampleSlow(next_sample);
  }

  return HashtablezSampler::Global().Register();
}

#if ABSL_PER_THREAD_TLS == 1
ABSL_PER_THREAD_TLS_KEYWORD int64_t global_next_sample = 0;
#endif  // ABSL_PER_THREAD_TLS == 1

void UnsampleSlow(HashtablezInfo* info) {
  HashtablezSampler::Global().Unregister(info);
}

void RecordInsertSlow(HashtablezInfo* info, size_t hash,
                      size_t distance_from_desired) {
  // SwissTables probe in groups of 16, so scale this to count items probes and
  // not offset from desired.
  size_t probe_length = distance_from_desired;
#if SWISSTABLE_HAVE_SSE2
  probe_length /= 16;
#else
  probe_length /= 8;
#endif

  info->hashes_bitwise_and.fetch_and(hash, std::memory_order_relaxed);
  info->hashes_bitwise_or.fetch_or(hash, std::memory_order_relaxed);
  info->max_probe_length.store(
      std::max(info->max_probe_length.load(std::memory_order_relaxed),
               probe_length),
      std::memory_order_relaxed);
  info->total_probe_length.fetch_add(probe_length, std::memory_order_relaxed);
  info->size.fetch_add(1, std::memory_order_relaxed);
}

void SetHashtablezEnabled(bool enabled) {
  g_hashtablez_enabled.store(enabled, std::memory_order_release);
}

void SetHashtablezSampleParameter(int32_t rate) {
  if (rate > 0) {
    g_hashtablez_sample_parameter.store(rate, std::memory_order_release);
  } else {
    ABSL_RAW_LOG(ERROR, "Invalid hashtablez sample rate: %lld",
                 static_cast<long long>(rate));  // NOLINT(runtime/int)
  }
}

void SetHashtablezMaxSamples(int32_t max) {
  if (max > 0) {
    g_hashtablez_max_samples.store(max, std::memory_order_release);
  } else {
    ABSL_RAW_LOG(ERROR, "Invalid hashtablez max samples: %lld",
                 static_cast<long long>(max));  // NOLINT(runtime/int)
  }
}

}  // namespace container_internal
}  // inline namespace lts_2019_08_08
}  // namespace absl
