[io_generator] Support mixed sequential and random io pattern
This commit is contained in:
parent
7ed013fcab
commit
061d966e7a
@ -44,25 +44,45 @@ namespace {
|
|||||||
: begin_(begin),
|
: begin_(begin),
|
||||||
end_(begin + (size / step) * step),
|
end_(begin + (size / step) * step),
|
||||||
step_(step),
|
step_(step),
|
||||||
current_(begin) {
|
current_(begin),
|
||||||
|
rounds_(0) {
|
||||||
if (size < step)
|
if (size < step)
|
||||||
throw std::runtime_error("size must be greater than the step");
|
throw std::runtime_error("size must be greater than the step");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
forward_sequence_generator()
|
||||||
|
: begin_(0), end_(1), step_(1),
|
||||||
|
current_(0), rounds_(0) {
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t next() {
|
uint64_t next() {
|
||||||
uint64_t r = current_;
|
uint64_t r = current_;
|
||||||
current_ += step_;
|
current_ += step_;
|
||||||
if (current_ >= end_) {
|
if (current_ >= end_) {
|
||||||
current_ = begin_;
|
current_ = begin_;
|
||||||
|
++rounds_;
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void reset(uint64_t begin, uint64_t size, uint64_t step = 1) {
|
||||||
|
begin_ = begin;
|
||||||
|
end_ = begin + (size / step) * step;
|
||||||
|
step_ = step;
|
||||||
|
current_ = begin;
|
||||||
|
rounds_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t get_rounds() {
|
||||||
|
return rounds_;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint64_t begin_;
|
uint64_t begin_;
|
||||||
uint64_t end_;
|
uint64_t end_;
|
||||||
uint64_t step_;
|
uint64_t step_;
|
||||||
uint64_t current_;
|
uint64_t current_;
|
||||||
|
uint64_t rounds_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// - The maximum generated value is not greater than (begin+size)
|
// - The maximum generated value is not greater than (begin+size)
|
||||||
@ -73,21 +93,25 @@ namespace {
|
|||||||
// TODO: load random seeds
|
// TODO: load random seeds
|
||||||
random_sequence_generator(uint64_t begin,
|
random_sequence_generator(uint64_t begin,
|
||||||
uint64_t size,
|
uint64_t size,
|
||||||
uint64_t step)
|
uint64_t step,
|
||||||
|
unsigned seq_nr = 1)
|
||||||
: begin_(begin),
|
: begin_(begin),
|
||||||
nr_steps_(size / step),
|
nr_steps_(size / step),
|
||||||
step_(step),
|
step_(step),
|
||||||
nr_generated_(0) {
|
max_forward_steps_(seq_nr),
|
||||||
|
nr_generated_(0)
|
||||||
|
{
|
||||||
|
if (!max_forward_steps_ || max_forward_steps_ > nr_steps_)
|
||||||
|
throw std::runtime_error("invalid number of forward steps");
|
||||||
|
|
||||||
|
if (max_forward_steps_ > 1)
|
||||||
|
reset_forward_generator();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t next() {
|
uint64_t next() {
|
||||||
uint64_t step_idx;
|
// FIXME: eliminate if-else
|
||||||
|
uint64_t step_idx = (max_forward_steps_ > 1) ?
|
||||||
bool found = true;
|
next_forward_step() : next_random_step();
|
||||||
while (found) {
|
|
||||||
step_idx = std::rand() % nr_steps_;
|
|
||||||
found = rand_map_.member(step_idx);
|
|
||||||
}
|
|
||||||
rand_map_.add(step_idx);
|
rand_map_.add(step_idx);
|
||||||
++nr_generated_;
|
++nr_generated_;
|
||||||
|
|
||||||
@ -101,12 +125,47 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void reset_forward_generator() {
|
||||||
|
uint64_t begin = next_random_step();
|
||||||
|
unsigned seq_nr = (std::rand() % max_forward_steps_) + 1;
|
||||||
|
forward_gen_.reset(begin, seq_nr);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t next_forward_step() {
|
||||||
|
uint64_t step_idx;
|
||||||
|
|
||||||
|
bool found = true;
|
||||||
|
while (found) {
|
||||||
|
step_idx = forward_gen_.next();
|
||||||
|
found = rand_map_.member(step_idx);
|
||||||
|
|
||||||
|
if (found || forward_gen_.get_rounds())
|
||||||
|
reset_forward_generator();
|
||||||
|
}
|
||||||
|
|
||||||
|
return step_idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t next_random_step() const {
|
||||||
|
uint64_t step_idx;
|
||||||
|
|
||||||
|
bool found = true;
|
||||||
|
while (found) {
|
||||||
|
step_idx = std::rand() % nr_steps_;
|
||||||
|
found = rand_map_.member(step_idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
return step_idx;
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t begin_;
|
uint64_t begin_;
|
||||||
uint64_t nr_steps_;
|
uint64_t nr_steps_;
|
||||||
uint64_t step_;
|
uint64_t step_;
|
||||||
|
unsigned max_forward_steps_;
|
||||||
|
|
||||||
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_;
|
||||||
};
|
};
|
||||||
|
|
||||||
//--------------------------------
|
//--------------------------------
|
||||||
@ -187,7 +246,8 @@ namespace {
|
|||||||
|
|
||||||
if (opts.pattern_.is_random())
|
if (opts.pattern_.is_random())
|
||||||
gen = new random_sequence_generator(opts.offset_,
|
gen = new random_sequence_generator(opts.offset_,
|
||||||
opts.size_, opts.block_size_);
|
opts.size_, opts.block_size_,
|
||||||
|
opts.nr_seq_blocks_);
|
||||||
else
|
else
|
||||||
gen = new forward_sequence_generator(opts.offset_,
|
gen = new forward_sequence_generator(opts.offset_,
|
||||||
opts.size_, opts.block_size_);
|
opts.size_, opts.block_size_);
|
||||||
|
@ -36,6 +36,7 @@ namespace base {
|
|||||||
sector_t block_size_;
|
sector_t block_size_;
|
||||||
sector_t size_;
|
sector_t size_;
|
||||||
sector_t io_size_;
|
sector_t io_size_;
|
||||||
|
unsigned nr_seq_blocks_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class io_generator {
|
class io_generator {
|
||||||
|
@ -47,6 +47,7 @@ namespace {
|
|||||||
base::sector_t offset;
|
base::sector_t offset;
|
||||||
boost::optional<base::sector_t> size;
|
boost::optional<base::sector_t> size;
|
||||||
boost::optional<base::sector_t> io_size;
|
boost::optional<base::sector_t> io_size;
|
||||||
|
boost::optional<unsigned> nr_seq_blocks;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool flags::check_conformance() {
|
bool flags::check_conformance() {
|
||||||
@ -65,6 +66,14 @@ namespace {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nr_seq_blocks) {
|
||||||
|
if (!pattern.is_random()) {
|
||||||
|
cerr << "Cannot specify the sequence size"
|
||||||
|
" while doing non-random IO" << endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
check_output_file_requirements(*output);
|
check_output_file_requirements(*output);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -90,6 +99,7 @@ namespace {
|
|||||||
opts.offset_ = fs.offset;
|
opts.offset_ = fs.offset;
|
||||||
opts.size_ = *fs.size;
|
opts.size_ = *fs.size;
|
||||||
opts.io_size_ = !fs.io_size ? *fs.size : *fs.io_size;
|
opts.io_size_ = !fs.io_size ? *fs.size : *fs.io_size;
|
||||||
|
opts.nr_seq_blocks_ = !fs.nr_seq_blocks ? 1 : *fs.nr_seq_blocks;
|
||||||
io_generator::ptr gen = create_io_generator(opts);
|
io_generator::ptr gen = create_io_generator(opts);
|
||||||
|
|
||||||
base::io io;
|
base::io io;
|
||||||
@ -133,6 +143,7 @@ thin_generate_mappings_cmd::usage(std::ostream &out) const
|
|||||||
<< " {--io-size} <io-size in sectors>\n"
|
<< " {--io-size} <io-size in sectors>\n"
|
||||||
<< " {--rw write|trim|randwrite|randtrim|randtw}\n"
|
<< " {--rw write|trim|randwrite|randtrim|randtw}\n"
|
||||||
<< " {--size} <size in sectors>\n"
|
<< " {--size} <size in sectors>\n"
|
||||||
|
<< " {--seq-nr} <max nr. of sequential ios>\n"
|
||||||
<< " {-V|--version}" << endl;
|
<< " {-V|--version}" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,6 +161,7 @@ thin_generate_mappings_cmd::run(int argc, char **argv)
|
|||||||
{ "offset", required_argument, NULL, 3 },
|
{ "offset", required_argument, NULL, 3 },
|
||||||
{ "size", required_argument, NULL, 4 },
|
{ "size", required_argument, NULL, 4 },
|
||||||
{ "io-size", required_argument, NULL, 5 },
|
{ "io-size", required_argument, NULL, 5 },
|
||||||
|
{ "seq-nr", required_argument, NULL, 6 },
|
||||||
{ "version", no_argument, NULL, 'V' },
|
{ "version", no_argument, NULL, 'V' },
|
||||||
{ NULL, no_argument, NULL, 0 }
|
{ NULL, no_argument, NULL, 0 }
|
||||||
};
|
};
|
||||||
@ -184,6 +196,10 @@ thin_generate_mappings_cmd::run(int argc, char **argv)
|
|||||||
fs.io_size = parse_uint64(optarg, "io_size");
|
fs.io_size = parse_uint64(optarg, "io_size");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 6:
|
||||||
|
fs.nr_seq_blocks = parse_uint64(optarg, "seq_nr");
|
||||||
|
break;
|
||||||
|
|
||||||
case 'V':
|
case 'V':
|
||||||
cout << THIN_PROVISIONING_TOOLS_VERSION << endl;
|
cout << THIN_PROVISIONING_TOOLS_VERSION << endl;
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user