Add --seed, --read_range to db_bench

Summary:
Adds the option --seed to db_bench to specify the base for the per-thread RNG.
When not set each thread uses the same value across runs of db_bench which defeats
IO stress testing.

Adds the option --read_range. When set to a value > 1 an iterator is created and
each query done for the randomread benchmark will do a range scan for that many
rows. When not set or set to 1 the existing behavior (a point lookup) is done.

Fixes a bug where a printf format string was missing.

Test Plan: run db_bench

Reviewers: dhruba

Reviewed By: dhruba

CC: leveldb

Differential Revision: https://reviews.facebook.net/D7749
This commit is contained in:
Mark Callaghan 2013-01-03 12:11:50 -08:00
parent 8cd86a7be5
commit 4069f66cc7

View file

@ -70,6 +70,12 @@ static long FLAGS_num = 1000000;
// Number of read operations to do. If negative, do FLAGS_num reads. // Number of read operations to do. If negative, do FLAGS_num reads.
static long FLAGS_reads = -1; static long FLAGS_reads = -1;
// When ==1 reads use ::Get, when >1 reads use an iterator
static long FLAGS_read_range = 1;
// Seed base for random number generators. When 0 it is deterministic.
static long FLAGS_seed = 0;
// Number of concurrent threads to run. // Number of concurrent threads to run.
static int FLAGS_threads = 1; static int FLAGS_threads = 1;
@ -382,7 +388,7 @@ class Stats {
if (FLAGS_stats_per_interval) { if (FLAGS_stats_per_interval) {
std::string stats; std::string stats;
if (db && db->GetProperty("leveldb.stats", &stats)) if (db && db->GetProperty("leveldb.stats", &stats))
fprintf(stderr, stats.c_str()); fprintf(stderr, "%s\n", stats.c_str());
} }
fflush(stderr); fflush(stderr);
@ -457,7 +463,7 @@ struct ThreadState {
/* implicit */ ThreadState(int index) /* implicit */ ThreadState(int index)
: tid(index), : tid(index),
rand(1000 + index) { rand((FLAGS_seed ? FLAGS_seed : 1000) + index) {
} }
}; };
@ -1068,17 +1074,32 @@ class Benchmark {
void ReadRandom(ThreadState* thread) { void ReadRandom(ThreadState* thread) {
ReadOptions options(FLAGS_verify_checksum, true); ReadOptions options(FLAGS_verify_checksum, true);
Iterator* iter = db_->NewIterator(options);
std::string value; std::string value;
long found = 0; long found = 0;
for (long i = 0; i < reads_; i++) { for (long i = 0; i < reads_; i++) {
char key[100]; char key[100];
const int k = thread->rand.Next() % FLAGS_num; const int k = thread->rand.Next() % FLAGS_num;
snprintf(key, sizeof(key), "%016d", k); snprintf(key, sizeof(key), "%016d", k);
if (db_->Get(options, key, &value).ok()) {
found++; if (FLAGS_read_range < 2) {
if (db_->Get(options, key, &value).ok()) {
found++;
}
} else {
Slice skey(key);
int count = 1;
for (iter->Seek(skey);
iter->Valid() && count <= FLAGS_read_range;
++count, iter->Next()) {
found++;
}
} }
thread->stats.FinishedSingleOp(db_); thread->stats.FinishedSingleOp(db_);
} }
delete iter;
char msg[100]; char msg[100];
snprintf(msg, sizeof(msg), "(%ld of %ld found)", found, num_); snprintf(msg, sizeof(msg), "(%ld of %ld found)", found, num_);
thread->stats.AddMessage(msg); thread->stats.AddMessage(msg);
@ -1302,6 +1323,10 @@ int main(int argc, char** argv) {
FLAGS_num = l; FLAGS_num = l;
} else if (sscanf(argv[i], "--reads=%d%c", &n, &junk) == 1) { } else if (sscanf(argv[i], "--reads=%d%c", &n, &junk) == 1) {
FLAGS_reads = n; FLAGS_reads = n;
} else if (sscanf(argv[i], "--read_range=%d%c", &n, &junk) == 1) {
FLAGS_read_range = n;
} else if (sscanf(argv[i], "--seed=%ld%c", &l, &junk) == 1) {
FLAGS_seed = l;
} else if (sscanf(argv[i], "--threads=%d%c", &n, &junk) == 1) { } else if (sscanf(argv[i], "--threads=%d%c", &n, &junk) == 1) {
FLAGS_threads = n; FLAGS_threads = n;
} else if (sscanf(argv[i], "--value_size=%d%c", &n, &junk) == 1) { } else if (sscanf(argv[i], "--value_size=%d%c", &n, &junk) == 1) {