#pragma once
#include <stdint.h>
#include <algorithm>
#include <random>
#include "rocksdb_namespace.h"
namespace ROCKSDB_NAMESPACE {
class Random {
private:
enum : uint32_t {
M = 2147483647L };
enum : uint64_t {
A = 16807 };
uint32_t seed_;
static uint32_t GoodSeed(uint32_t s) { return (s & M) != 0 ? (s & M) : 1; }
public:
enum : uint32_t { kMaxNext = M };
explicit Random(uint32_t s) : seed_(GoodSeed(s)) {}
void Reset(uint32_t s) { seed_ = GoodSeed(s); }
uint32_t Next() {
uint64_t product = seed_ * A;
seed_ = static_cast<uint32_t>((product >> 31) + (product & M));
if (seed_ > M) {
seed_ -= M;
}
return seed_;
}
uint64_t Next64() { return (uint64_t{Next()} << 32) | Next(); }
uint32_t Uniform(int n) { return Next() % n; }
bool OneIn(int n) { return Uniform(n) == 0; }
bool OneInOpt(int n) { return n > 0 && OneIn(n); }
bool PercentTrue(int percentage) {
return static_cast<int>(Uniform(100)) < percentage;
}
uint32_t Skewed(int max_log) { return Uniform(1 << Uniform(max_log + 1)); }
std::string RandomString(int len);
std::string HumanReadableString(int len);
std::string RandomBinaryString(int len);
static Random* GetTLSInstance();
};
class Random32 {
private:
std::mt19937 generator_;
public:
explicit Random32(uint32_t s) : generator_(s) {}
uint32_t Next() { return static_cast<uint32_t>(generator_()); }
uint32_t Uniform(uint32_t n) {
return static_cast<uint32_t>(
std::uniform_int_distribution<std::mt19937::result_type>(
0, n - 1)(generator_));
}
uint32_t Uniformish(uint32_t n) {
return static_cast<uint32_t>((uint64_t(generator_()) * uint64_t(n)) >> 32);
}
bool OneIn(uint32_t n) { return Uniform(n) == 0; }
uint32_t Skewed(int max_log) {
return Uniform(uint32_t{1} << Uniform(max_log + 1));
}
void Seed(uint32_t new_seed) { generator_.seed(new_seed); }
};
class Random64 {
private:
std::mt19937_64 generator_;
public:
explicit Random64(uint64_t s) : generator_(s) {}
uint64_t Next() { return generator_(); }
uint64_t Uniform(uint64_t n) {
return std::uniform_int_distribution<uint64_t>(0, n - 1)(generator_);
}
bool OneIn(uint64_t n) { return Uniform(n) == 0; }
uint64_t Skewed(int max_log) {
return Uniform(uint64_t(1) << Uniform(max_log + 1));
}
};
template <class RandomIt>
void RandomShuffle(RandomIt first, RandomIt last, uint32_t seed) {
std::mt19937 rng(seed);
std::shuffle(first, last, rng);
}
template <class RandomIt>
void RandomShuffle(RandomIt first, RandomIt last) {
RandomShuffle(first, last, std::random_device{}());
}
}