Skip to content

Commit

Permalink
[RocksDB] Unit test to show Seek key comparison number
Browse files Browse the repository at this point in the history
Summary: Added SeekKeyComparison to show the uer key comparison incurred by Seek.

Test Plan:
make perf_context_test
export LEVELDB_TESTS=DBTest.SeekKeyComparison
./perf_context_test --write_buffer_size=500000 --total_keys=10000
./perf_context_test --write_buffer_size=250000 --total_keys=10000

Reviewers: dhruba, xjin

Reviewed By: xjin

CC: leveldb

Differential Revision: https://reviews.facebook.net/D12843
  • Loading branch information
haoboxu committed Sep 19, 2013
1 parent 72fcbf0 commit 4734dbb
Showing 1 changed file with 91 additions and 15 deletions.
106 changes: 91 additions & 15 deletions db/perf_context_test.cc
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <algorithm>
#include <iostream>
#include <vector>

Expand All @@ -7,26 +8,32 @@
#include "util/stop_watch.h"
#include "util/testharness.h"


namespace leveldb {
bool FLAGS_random_key = false;
int FLAGS_total_keys = 100;
int FLAGS_write_buffer_size = 1000000000;
int FLAGS_max_write_buffer_number = 8;
int FLAGS_min_write_buffer_number_to_merge = 7;

// Path to the database on file system
const std::string kDbName = test::TmpDir() + "/perf_context_test";
const std::string kDbName = leveldb::test::TmpDir() + "/perf_context_test";

std::shared_ptr<DB> OpenDb(size_t write_buffer_size) {
namespace leveldb {

std::shared_ptr<DB> OpenDb() {
DB* db;
Options options;
options.create_if_missing = true;
options.write_buffer_size = write_buffer_size;
options.write_buffer_size = FLAGS_write_buffer_size;
options.max_write_buffer_number = FLAGS_max_write_buffer_number;
options.min_write_buffer_number_to_merge =
FLAGS_min_write_buffer_number_to_merge;
Status s = DB::Open(options, kDbName, &db);
ASSERT_OK(s);
return std::shared_ptr<DB>(db);
}

class PerfContextTest { };

int kTotalKeys = 100;

TEST(PerfContextTest, StopWatchNanoOverhead) {
// profile the timer cost by itself!
const int kTotalIterations = 1000000;
Expand Down Expand Up @@ -68,7 +75,7 @@ TEST(PerfContextTest, StopWatchOverhead) {
void ProfileKeyComparison() {
DestroyDB(kDbName, Options()); // Start this test with a fresh DB

auto db = OpenDb(1000000000);
auto db = OpenDb();

WriteOptions write_options;
ReadOptions read_options;
Expand All @@ -77,9 +84,9 @@ void ProfileKeyComparison() {
uint64_t total_user_key_comparison_put = 0;
uint64_t max_user_key_comparison_get = 0;

std::cout << "Inserting " << kTotalKeys << " key/value pairs\n...\n";
std::cout << "Inserting " << FLAGS_total_keys << " key/value pairs\n...\n";

for (int i = 0; i < kTotalKeys; ++i) {
for (int i = 0; i < FLAGS_total_keys; ++i) {
std::string key = "k" + std::to_string(i);
std::string value = "v" + std::to_string(i);

Expand All @@ -102,28 +109,97 @@ void ProfileKeyComparison() {
<< "max user key comparison get: "
<< max_user_key_comparison_get << "\n"
<< "avg user key comparison get:"
<< total_user_key_comparison_get/kTotalKeys << "\n";
<< total_user_key_comparison_get/FLAGS_total_keys << "\n";

}

TEST(PerfContextTest, KeyComparisonCount) {
SetPerfLevel(kDisable);
SetPerfLevel(kEnableCount);
ProfileKeyComparison();

SetPerfLevel(kEnableCount);
SetPerfLevel(kDisable);
ProfileKeyComparison();

SetPerfLevel(kEnableTime);
ProfileKeyComparison();
}

// make perf_context_test
// export LEVELDB_TESTS=PerfContextTest.SeekKeyComparison
// For one memtable:
// ./perf_context_test --write_buffer_size=500000 --total_keys=10000
// For two memtables:
// ./perf_context_test --write_buffer_size=250000 --total_keys=10000
// Specify --random_key=1 to shuffle the key before insertion
// Results show that, for sequential insertion, worst-case Seek Key comparison
// is close to the total number of keys (linear), when there is only one
// memtable. When there are two memtables, even the avg Seek Key comparison
// starts to become linear to the input size.

TEST(PerfContextTest, SeekKeyComparison) {
DestroyDB(kDbName, Options());
auto db = OpenDb();
WriteOptions write_options;
ReadOptions read_options;

std::cout << "Inserting " << FLAGS_total_keys << " key/value pairs\n...\n";

std::vector<int> keys;
for (int i = 0; i < FLAGS_total_keys; ++i) {
keys.push_back(i);
}

if (FLAGS_random_key) {
std::random_shuffle(keys.begin(), keys.end());
}

for (const int i : keys) {
std::string key = "k" + std::to_string(i);
std::string value = "v" + std::to_string(i);

db->Put(write_options, key, value);
}

HistogramImpl histogram;
for (int i = 0; i < FLAGS_total_keys; ++i) {
std::string key = "k" + std::to_string(i);
std::string value = "v" + std::to_string(i);

std::unique_ptr<Iterator> iter(db->NewIterator(read_options));
perf_context.Reset();
iter->Seek(key);
ASSERT_TRUE(iter->Valid());
ASSERT_EQ(iter->value().ToString(), value);
histogram.Add(perf_context.user_key_comparison_count);
}
std::cout << histogram.ToString();
}

}

int main(int argc, char** argv) {

if (argc > 1) {
leveldb::kTotalKeys = std::stoi(argv[1]);
for (int i = 1; i < argc; i++) {
int n;
char junk;

if (sscanf(argv[i], "--write_buffer_size=%d%c", &n, &junk) == 1) {
FLAGS_write_buffer_size = n;
}

if (sscanf(argv[i], "--total_keys=%d%c", &n, &junk) == 1) {
FLAGS_total_keys = n;
}

if (sscanf(argv[i], "--random_key=%d%c", &n, &junk) == 1 &&
(n == 0 || n == 1)) {
FLAGS_random_key = n;
}

}

std::cout << kDbName << "\n";

leveldb::test::RunAllTests();
return 0;
}

0 comments on commit 4734dbb

Please sign in to comment.