[thin] Adopt stateful random number generators
This commit is contained in:
parent
06dfb976c2
commit
3f19818c56
@ -1,5 +1,7 @@
|
|||||||
#include "base/io_generator.h"
|
#include "base/io_generator.h"
|
||||||
#include "base/sequence_generator.h"
|
#include "base/sequence_generator.h"
|
||||||
|
#include <chrono>
|
||||||
|
#include <random>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
@ -31,19 +33,23 @@ namespace {
|
|||||||
typedef std::shared_ptr<op_generator> ptr;
|
typedef std::shared_ptr<op_generator> ptr;
|
||||||
|
|
||||||
op_generator(base::req_op op1)
|
op_generator(base::req_op op1)
|
||||||
: op1_(op1), op2_(op1), op1_pct_(100) {
|
: op1_(op1), op2_(op1), op1_pct_(100),
|
||||||
|
rand_seed_(std::chrono::high_resolution_clock::now().time_since_epoch().count()),
|
||||||
|
op_engine_(rand_seed_) {
|
||||||
}
|
}
|
||||||
|
|
||||||
op_generator(base::req_op op1,
|
op_generator(base::req_op op1,
|
||||||
base::req_op op2,
|
base::req_op op2,
|
||||||
unsigned op1_pct)
|
unsigned op1_pct)
|
||||||
: op1_(op1), op2_(op2), op1_pct_(op1_pct) {
|
: op1_(op1), op2_(op2), op1_pct_(op1_pct),
|
||||||
|
rand_seed_(std::chrono::high_resolution_clock::now().time_since_epoch().count()),
|
||||||
|
op_engine_(rand_seed_) {
|
||||||
if (op1_pct > 100)
|
if (op1_pct > 100)
|
||||||
throw std::runtime_error("invalid percentage");
|
throw std::runtime_error("invalid percentage");
|
||||||
}
|
}
|
||||||
|
|
||||||
base::req_op next_op() {
|
base::req_op next_op() {
|
||||||
if (static_cast<unsigned>(std::rand()) % 100 > op1_pct_)
|
if (op_engine_() % 100 > op1_pct_)
|
||||||
return op2_;
|
return op2_;
|
||||||
return op1_;
|
return op1_;
|
||||||
}
|
}
|
||||||
@ -52,6 +58,9 @@ namespace {
|
|||||||
base::req_op op1_;
|
base::req_op op1_;
|
||||||
base::req_op op2_;
|
base::req_op op2_;
|
||||||
unsigned op1_pct_;
|
unsigned op1_pct_;
|
||||||
|
uint64_t rand_seed_;
|
||||||
|
|
||||||
|
std::mt19937 op_engine_;
|
||||||
};
|
};
|
||||||
|
|
||||||
//--------------------------------
|
//--------------------------------
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#include "base/run_set.h"
|
#include "base/run_set.h"
|
||||||
#include "base/sequence_generator.h"
|
#include "base/sequence_generator.h"
|
||||||
|
#include <chrono>
|
||||||
|
#include <random>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
@ -80,6 +82,9 @@ namespace {
|
|||||||
: begin_(begin),
|
: begin_(begin),
|
||||||
step_(step),
|
step_(step),
|
||||||
max_forward_steps_(seq_nr),
|
max_forward_steps_(seq_nr),
|
||||||
|
rand_seed_(std::chrono::high_resolution_clock::now().time_since_epoch().count()),
|
||||||
|
results_engine_(rand_seed_),
|
||||||
|
steps_engine_(rand_seed_),
|
||||||
nr_generated_(0)
|
nr_generated_(0)
|
||||||
{
|
{
|
||||||
if (!size || !step || !seq_nr)
|
if (!size || !step || !seq_nr)
|
||||||
@ -93,8 +98,14 @@ namespace {
|
|||||||
if (!max_forward_steps_ || max_forward_steps_ > nr_steps_)
|
if (!max_forward_steps_ || max_forward_steps_ > nr_steps_)
|
||||||
throw std::runtime_error("invalid number of forward steps");
|
throw std::runtime_error("invalid number of forward steps");
|
||||||
|
|
||||||
if (max_forward_steps_ > 1)
|
results_distr_ = std::uniform_int_distribution<uint64_t>(0,
|
||||||
|
nr_steps_ - 1);
|
||||||
|
|
||||||
|
if (max_forward_steps_ > 1) {
|
||||||
|
steps_distr_ = std::uniform_int_distribution<uint64_t>(1,
|
||||||
|
max_forward_steps_);
|
||||||
reset_forward_generator();
|
reset_forward_generator();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t next() {
|
uint64_t next() {
|
||||||
@ -109,7 +120,7 @@ namespace {
|
|||||||
void reset_forward_generator() {
|
void reset_forward_generator() {
|
||||||
uint64_t begin = peek_random_step();
|
uint64_t begin = peek_random_step();
|
||||||
|
|
||||||
unsigned seq_nr = (std::rand() % max_forward_steps_) + 1;
|
unsigned seq_nr = steps_distr_(steps_engine_);
|
||||||
base::run_set<uint64_t>::const_iterator it = rand_map_.upper_bound(begin);
|
base::run_set<uint64_t>::const_iterator it = rand_map_.upper_bound(begin);
|
||||||
if (it != rand_map_.end())
|
if (it != rand_map_.end())
|
||||||
seq_nr = std::min<uint64_t>(seq_nr, *it->begin_ - begin);
|
seq_nr = std::min<uint64_t>(seq_nr, *it->begin_ - begin);
|
||||||
@ -148,12 +159,13 @@ namespace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t peek_random_step() const {
|
// TODO: improve the complexity of generating unique sequence
|
||||||
|
uint64_t peek_random_step() {
|
||||||
uint64_t step_idx;
|
uint64_t step_idx;
|
||||||
|
|
||||||
bool found = true;
|
bool found = true;
|
||||||
while (found) {
|
while (found) {
|
||||||
step_idx = std::rand() % nr_steps_;
|
step_idx = results_distr_(results_engine_);
|
||||||
found = rand_map_.member(step_idx);
|
found = rand_map_.member(step_idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,7 +176,12 @@ namespace {
|
|||||||
uint64_t nr_steps_;
|
uint64_t nr_steps_;
|
||||||
uint64_t step_;
|
uint64_t step_;
|
||||||
unsigned max_forward_steps_;
|
unsigned max_forward_steps_;
|
||||||
|
uint64_t rand_seed_;
|
||||||
|
|
||||||
|
std::mt19937_64 results_engine_;
|
||||||
|
std::mt19937_64 steps_engine_;
|
||||||
|
std::uniform_int_distribution<uint64_t> results_distr_;
|
||||||
|
std::uniform_int_distribution<uint64_t> steps_distr_;
|
||||||
base::run_set<uint64_t> rand_map_;
|
base::run_set<uint64_t> rand_map_;
|
||||||
uint64_t nr_generated_;
|
uint64_t nr_generated_;
|
||||||
forward_sequence_generator forward_gen_;
|
forward_sequence_generator forward_gen_;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#include <chrono>
|
||||||
|
#include <random>
|
||||||
#include "damage_generator.h"
|
#include "damage_generator.h"
|
||||||
|
|
||||||
using namespace thin_provisioning;
|
using namespace thin_provisioning;
|
||||||
@ -13,12 +15,14 @@ namespace {
|
|||||||
base::run_set<block_address> visited;
|
base::run_set<block_address> visited;
|
||||||
block_address nr_visited = 0;
|
block_address nr_visited = 0;
|
||||||
|
|
||||||
srand(time(NULL));
|
uint64_t rand_seed(std::chrono::high_resolution_clock::now().time_since_epoch().count());
|
||||||
|
std::mt19937 rand_engine(rand_seed);
|
||||||
|
|
||||||
while (nr_blocks) {
|
while (nr_blocks) {
|
||||||
if (nr_visited == sm_size)
|
if (nr_visited == sm_size)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
block_address b = rand() % sm_size;
|
block_address b = rand_engine() % sm_size;
|
||||||
if (visited.member(b))
|
if (visited.member(b))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user