|
|
|
@ -24,8 +24,6 @@ |
|
|
|
|
#include <random> |
|
|
|
|
#include <vector> |
|
|
|
|
|
|
|
|
|
#include "absl/types/variant.h" |
|
|
|
|
|
|
|
|
|
namespace grpc_core { |
|
|
|
|
|
|
|
|
|
// Set of random numbers from a proto file (or other container) forming a bit
|
|
|
|
@ -34,35 +32,27 @@ class ProtoBitGen : public std::numeric_limits<uint64_t> { |
|
|
|
|
public: |
|
|
|
|
template <typename SourceContainer> |
|
|
|
|
explicit ProtoBitGen(const SourceContainer& c) { |
|
|
|
|
auto& initial_round = absl::get<InitialRound>(generator_); |
|
|
|
|
for (auto r : c) { |
|
|
|
|
initial_round.results.push_back(r); |
|
|
|
|
results_.push_back(r); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
using result_type = uint64_t; |
|
|
|
|
|
|
|
|
|
uint64_t operator()() { |
|
|
|
|
if (auto* initial_round = absl::get_if<InitialRound>(&generator_)) { |
|
|
|
|
if (initial_round->current >= initial_round->results.size()) { |
|
|
|
|
auto seed = std::move(initial_round->results); |
|
|
|
|
std::seed_seq seq(seed.begin(), seed.end()); |
|
|
|
|
generator_.emplace<std::mt19937_64>(seq); |
|
|
|
|
} else { |
|
|
|
|
return initial_round->results[initial_round->current++]; |
|
|
|
|
} |
|
|
|
|
if (current_ < results_.size()) { |
|
|
|
|
return results_[current_++]; |
|
|
|
|
} |
|
|
|
|
return absl::get<std::mt19937_64>(generator_)(); |
|
|
|
|
return generator_(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
struct InitialRound { |
|
|
|
|
InitialRound() = default; |
|
|
|
|
std::vector<uint64_t> results; |
|
|
|
|
size_t current = 0; |
|
|
|
|
}; |
|
|
|
|
absl::variant<InitialRound, std::mt19937_64> generator_{ |
|
|
|
|
absl::in_place_type_t<InitialRound>{}}; |
|
|
|
|
std::vector<uint64_t> results_; |
|
|
|
|
size_t current_ = 0; |
|
|
|
|
std::mt19937_64 generator_ = [this]() { |
|
|
|
|
std::seed_seq seq(results_.begin(), results_.end()); |
|
|
|
|
return std::mt19937_64(seq); |
|
|
|
|
}(); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
} // namespace grpc_core
|
|
|
|
|