summaryrefslogtreecommitdiff
path: root/benchmarks
diff options
context:
space:
mode:
Diffstat (limited to 'benchmarks')
-rw-r--r--benchmarks/db_bench.cc297
-rw-r--r--benchmarks/db_bench_log.cc92
-rw-r--r--benchmarks/db_bench_sqlite3.cc112
-rw-r--r--benchmarks/db_bench_tree_db.cc105
4 files changed, 414 insertions, 192 deletions
diff --git a/benchmarks/db_bench.cc b/benchmarks/db_bench.cc
index 3696023..429a61a 100644
--- a/benchmarks/db_bench.cc
+++ b/benchmarks/db_bench.cc
@@ -2,11 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.
-#include <stdio.h>
-#include <stdlib.h>
#include <sys/types.h>
+#include <atomic>
+#include <cstdio>
+#include <cstdlib>
+
#include "leveldb/cache.h"
+#include "leveldb/comparator.h"
#include "leveldb/db.h"
#include "leveldb/env.h"
#include "leveldb/filter_policy.h"
@@ -33,6 +36,7 @@
// readmissing -- read N missing keys in random order
// readhot -- read N times in random order from 1% section of DB
// seekrandom -- N random seeks
+// seekordered -- N ordered seeks
// open -- cost of opening a DB
// crc32c -- repeated crc32c of 4K of data
// Meta operations:
@@ -77,6 +81,9 @@ static double FLAGS_compression_ratio = 0.5;
// Print histogram of operation timings
static bool FLAGS_histogram = false;
+// Count the number of string comparisons performed
+static bool FLAGS_comparisons = false;
+
// Number of bytes to buffer in memtable before compacting
// (initialized to default value by "main")
static int FLAGS_write_buffer_size = 0;
@@ -100,6 +107,9 @@ static int FLAGS_open_files = 0;
// Negative means use default settings.
static int FLAGS_bloom_bits = -1;
+// Common key prefix length.
+static int FLAGS_key_prefix = 0;
+
// If true, do not destroy the existing database. If you set this
// flag and also specify a benchmark that wants a fresh database, that
// benchmark will fail.
@@ -116,6 +126,33 @@ namespace leveldb {
namespace {
leveldb::Env* g_env = nullptr;
+class CountComparator : public Comparator {
+ public:
+ CountComparator(const Comparator* wrapped) : wrapped_(wrapped) {}
+ ~CountComparator() override {}
+ int Compare(const Slice& a, const Slice& b) const override {
+ count_.fetch_add(1, std::memory_order_relaxed);
+ return wrapped_->Compare(a, b);
+ }
+ const char* Name() const override { return wrapped_->Name(); }
+ void FindShortestSeparator(std::string* start,
+ const Slice& limit) const override {
+ wrapped_->FindShortestSeparator(start, limit);
+ }
+
+ void FindShortSuccessor(std::string* key) const override {
+ return wrapped_->FindShortSuccessor(key);
+ }
+
+ size_t comparisons() const { return count_.load(std::memory_order_relaxed); }
+
+ void reset() { count_.store(0, std::memory_order_relaxed); }
+
+ private:
+ mutable std::atomic<size_t> count_{0};
+ const Comparator* const wrapped_;
+};
+
// Helper for quickly generating random data.
class RandomGenerator {
private:
@@ -148,6 +185,26 @@ class RandomGenerator {
}
};
+class KeyBuffer {
+ public:
+ KeyBuffer() {
+ assert(FLAGS_key_prefix < sizeof(buffer_));
+ memset(buffer_, 'a', FLAGS_key_prefix);
+ }
+ KeyBuffer& operator=(KeyBuffer& other) = delete;
+ KeyBuffer(KeyBuffer& other) = delete;
+
+ void Set(int k) {
+ std::snprintf(buffer_ + FLAGS_key_prefix,
+ sizeof(buffer_) - FLAGS_key_prefix, "%016d", k);
+ }
+
+ Slice slice() const { return Slice(buffer_, FLAGS_key_prefix + 16); }
+
+ private:
+ char buffer_[1024];
+};
+
#if defined(__linux)
static Slice TrimSpace(Slice s) {
size_t start = 0;
@@ -220,8 +277,8 @@ class Stats {
double micros = now - last_op_finish_;
hist_.Add(micros);
if (micros > 20000) {
- fprintf(stderr, "long op: %.1f micros%30s\r", micros, "");
- fflush(stderr);
+ std::fprintf(stderr, "long op: %.1f micros%30s\r", micros, "");
+ std::fflush(stderr);
}
last_op_finish_ = now;
}
@@ -242,8 +299,8 @@ class Stats {
next_report_ += 50000;
else
next_report_ += 100000;
- fprintf(stderr, "... finished %d ops%30s\r", done_, "");
- fflush(stderr);
+ std::fprintf(stderr, "... finished %d ops%30s\r", done_, "");
+ std::fflush(stderr);
}
}
@@ -260,18 +317,20 @@ class Stats {
// elapsed times.
double elapsed = (finish_ - start_) * 1e-6;
char rate[100];
- snprintf(rate, sizeof(rate), "%6.1f MB/s",
- (bytes_ / 1048576.0) / elapsed);
+ std::snprintf(rate, sizeof(rate), "%6.1f MB/s",
+ (bytes_ / 1048576.0) / elapsed);
extra = rate;
}
AppendWithSpace(&extra, message_);
- fprintf(stdout, "%-12s : %11.3f micros/op;%s%s\n", name.ToString().c_str(),
- seconds_ * 1e6 / done_, (extra.empty() ? "" : " "), extra.c_str());
+ std::fprintf(stdout, "%-12s : %11.3f micros/op;%s%s\n",
+ name.ToString().c_str(), seconds_ * 1e6 / done_,
+ (extra.empty() ? "" : " "), extra.c_str());
if (FLAGS_histogram) {
- fprintf(stdout, "Microseconds per op:\n%s\n", hist_.ToString().c_str());
+ std::fprintf(stdout, "Microseconds per op:\n%s\n",
+ hist_.ToString().c_str());
}
- fflush(stdout);
+ std::fflush(stdout);
}
};
@@ -302,7 +361,7 @@ struct ThreadState {
Stats stats;
SharedState* shared;
- ThreadState(int index) : tid(index), rand(1000 + index), shared(nullptr) {}
+ ThreadState(int index, int seed) : tid(index), rand(seed), shared(nullptr) {}
};
} // namespace
@@ -318,55 +377,61 @@ class Benchmark {
WriteOptions write_options_;
int reads_;
int heap_counter_;
+ CountComparator count_comparator_;
+ int total_thread_count_;
void PrintHeader() {
- const int kKeySize = 16;
+ const int kKeySize = 16 + FLAGS_key_prefix;
PrintEnvironment();
- fprintf(stdout, "Keys: %d bytes each\n", kKeySize);
- fprintf(stdout, "Values: %d bytes each (%d bytes after compression)\n",
- FLAGS_value_size,
- static_cast<int>(FLAGS_value_size * FLAGS_compression_ratio + 0.5));
- fprintf(stdout, "Entries: %d\n", num_);
- fprintf(stdout, "RawSize: %.1f MB (estimated)\n",
- ((static_cast<int64_t>(kKeySize + FLAGS_value_size) * num_) /
- 1048576.0));
- fprintf(stdout, "FileSize: %.1f MB (estimated)\n",
- (((kKeySize + FLAGS_value_size * FLAGS_compression_ratio) * num_) /
- 1048576.0));
+ std::fprintf(stdout, "Keys: %d bytes each\n", kKeySize);
+ std::fprintf(
+ stdout, "Values: %d bytes each (%d bytes after compression)\n",
+ FLAGS_value_size,
+ static_cast<int>(FLAGS_value_size * FLAGS_compression_ratio + 0.5));
+ std::fprintf(stdout, "Entries: %d\n", num_);
+ std::fprintf(stdout, "RawSize: %.1f MB (estimated)\n",
+ ((static_cast<int64_t>(kKeySize + FLAGS_value_size) * num_) /
+ 1048576.0));
+ std::fprintf(
+ stdout, "FileSize: %.1f MB (estimated)\n",
+ (((kKeySize + FLAGS_value_size * FLAGS_compression_ratio) * num_) /
+ 1048576.0));
PrintWarnings();
- fprintf(stdout, "------------------------------------------------\n");
+ std::fprintf(stdout, "------------------------------------------------\n");
}
void PrintWarnings() {
#if defined(__GNUC__) && !defined(__OPTIMIZE__)
- fprintf(
+ std::fprintf(
stdout,
"WARNING: Optimization is disabled: benchmarks unnecessarily slow\n");
#endif
#ifndef NDEBUG
- fprintf(stdout,
- "WARNING: Assertions are enabled; benchmarks unnecessarily slow\n");
+ std::fprintf(
+ stdout,
+ "WARNING: Assertions are enabled; benchmarks unnecessarily slow\n");
#endif
// See if snappy is working by attempting to compress a compressible string
const char text[] = "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy";
std::string compressed;
if (!port::Snappy_Compress(text, sizeof(text), &compressed)) {
- fprintf(stdout, "WARNING: Snappy compression is not enabled\n");
+ std::fprintf(stdout, "WARNING: Snappy compression is not enabled\n");
} else if (compressed.size() >= sizeof(text)) {
- fprintf(stdout, "WARNING: Snappy compression is not effective\n");
+ std::fprintf(stdout, "WARNING: Snappy compression is not effective\n");
}
}
void PrintEnvironment() {
- fprintf(stderr, "LevelDB: version %d.%d\n", kMajorVersion,
- kMinorVersion);
+ std::fprintf(stderr, "LevelDB: version %d.%d\n", kMajorVersion,
+ kMinorVersion);
#if defined(__linux)
time_t now = time(nullptr);
- fprintf(stderr, "Date: %s", ctime(&now)); // ctime() adds newline
+ std::fprintf(stderr, "Date: %s",
+ ctime(&now)); // ctime() adds newline
- FILE* cpuinfo = fopen("/proc/cpuinfo", "r");
+ FILE* cpuinfo = std::fopen("/proc/cpuinfo", "r");
if (cpuinfo != nullptr) {
char line[1000];
int num_cpus = 0;
@@ -386,9 +451,9 @@ class Benchmark {
cache_size = val.ToString();
}
}
- fclose(cpuinfo);
- fprintf(stderr, "CPU: %d * %s\n", num_cpus, cpu_type.c_str());
- fprintf(stderr, "CPUCache: %s\n", cache_size.c_str());
+ std::fclose(cpuinfo);
+ std::fprintf(stderr, "CPU: %d * %s\n", num_cpus, cpu_type.c_str());
+ std::fprintf(stderr, "CPUCache: %s\n", cache_size.c_str());
}
#endif
}
@@ -404,12 +469,14 @@ class Benchmark {
value_size_(FLAGS_value_size),
entries_per_batch_(1),
reads_(FLAGS_reads < 0 ? FLAGS_num : FLAGS_reads),
- heap_counter_(0) {
+ heap_counter_(0),
+ count_comparator_(BytewiseComparator()),
+ total_thread_count_(0) {
std::vector<std::string> files;
g_env->GetChildren(FLAGS_db, &files);
for (size_t i = 0; i < files.size(); i++) {
if (Slice(files[i]).starts_with("heap-")) {
- g_env->DeleteFile(std::string(FLAGS_db) + "/" + files[i]);
+ g_env->RemoveFile(std::string(FLAGS_db) + "/" + files[i]);
}
}
if (!FLAGS_use_existing_db) {
@@ -487,6 +554,8 @@ class Benchmark {
method = &Benchmark::ReadMissing;
} else if (name == Slice("seekrandom")) {
method = &Benchmark::SeekRandom;
+ } else if (name == Slice("seekordered")) {
+ method = &Benchmark::SeekOrdered;
} else if (name == Slice("readhot")) {
method = &Benchmark::ReadHot;
} else if (name == Slice("readrandomsmall")) {
@@ -515,14 +584,15 @@ class Benchmark {
PrintStats("leveldb.sstables");
} else {
if (!name.empty()) { // No error message for empty name
- fprintf(stderr, "unknown benchmark '%s'\n", name.ToString().c_str());
+ std::fprintf(stderr, "unknown benchmark '%s'\n",
+ name.ToString().c_str());
}
}
if (fresh_db) {
if (FLAGS_use_existing_db) {
- fprintf(stdout, "%-12s : skipped (--use_existing_db is true)\n",
- name.ToString().c_str());
+ std::fprintf(stdout, "%-12s : skipped (--use_existing_db is true)\n",
+ name.ToString().c_str());
method = nullptr;
} else {
delete db_;
@@ -583,7 +653,11 @@ class Benchmark {
arg[i].bm = this;
arg[i].method = method;
arg[i].shared = &shared;
- arg[i].thread = new ThreadState(i);
+ ++total_thread_count_;
+ // Seed the thread's random state deterministically based upon thread
+ // creation across all benchmarks. This ensures that the seeds are unique
+ // but reproducible when rerunning the same set of benchmarks.
+ arg[i].thread = new ThreadState(i, /*seed=*/1000 + total_thread_count_);
arg[i].thread->shared = &shared;
g_env->StartThread(ThreadBody, &arg[i]);
}
@@ -604,6 +678,11 @@ class Benchmark {
arg[0].thread->stats.Merge(arg[i].thread->stats);
}
arg[0].thread->stats.Report(name);
+ if (FLAGS_comparisons) {
+ fprintf(stdout, "Comparisons: %zu\n", count_comparator_.comparisons());
+ count_comparator_.reset();
+ fflush(stdout);
+ }
for (int i = 0; i < n; i++) {
delete arg[i].thread;
@@ -624,7 +703,7 @@ class Benchmark {
bytes += size;
}
// Print so result is not dead
- fprintf(stderr, "... crc=0x%x\r", static_cast<unsigned int>(crc));
+ std::fprintf(stderr, "... crc=0x%x\r", static_cast<unsigned int>(crc));
thread->stats.AddBytes(bytes);
thread->stats.AddMessage(label);
@@ -648,8 +727,8 @@ class Benchmark {
thread->stats.AddMessage("(snappy failure)");
} else {
char buf[100];
- snprintf(buf, sizeof(buf), "(output: %.1f%%)",
- (produced * 100.0) / bytes);
+ std::snprintf(buf, sizeof(buf), "(output: %.1f%%)",
+ (produced * 100.0) / bytes);
thread->stats.AddMessage(buf);
thread->stats.AddBytes(bytes);
}
@@ -686,13 +765,16 @@ class Benchmark {
options.write_buffer_size = FLAGS_write_buffer_size;
options.max_file_size = FLAGS_max_file_size;
options.block_size = FLAGS_block_size;
+ if (FLAGS_comparisons) {
+ options.comparator = &count_comparator_;
+ }
options.max_open_files = FLAGS_open_files;
options.filter_policy = filter_policy_;
options.reuse_logs = FLAGS_reuse_logs;
Status s = DB::Open(options, FLAGS_db, &db_);
if (!s.ok()) {
- fprintf(stderr, "open error: %s\n", s.ToString().c_str());
- exit(1);
+ std::fprintf(stderr, "open error: %s\n", s.ToString().c_str());
+ std::exit(1);
}
}
@@ -711,7 +793,7 @@ class Benchmark {
void DoWrite(ThreadState* thread, bool seq) {
if (num_ != FLAGS_num) {
char msg[100];
- snprintf(msg, sizeof(msg), "(%d ops)", num_);
+ std::snprintf(msg, sizeof(msg), "(%d ops)", num_);
thread->stats.AddMessage(msg);
}
@@ -719,20 +801,20 @@ class Benchmark {
WriteBatch batch;
Status s;
int64_t bytes = 0;
+ KeyBuffer key;
for (int i = 0; i < num_; i += entries_per_batch_) {
batch.Clear();
for (int j = 0; j < entries_per_batch_; j++) {
- const int k = seq ? i + j : (thread->rand.Next() % FLAGS_num);
- char key[100];
- snprintf(key, sizeof(key), "%016d", k);
- batch.Put(key, gen.Generate(value_size_));
- bytes += value_size_ + strlen(key);
+ const int k = seq ? i + j : thread->rand.Uniform(FLAGS_num);
+ key.Set(k);
+ batch.Put(key.slice(), gen.Generate(value_size_));
+ bytes += value_size_ + key.slice().size();
thread->stats.FinishedSingleOp();
}
s = db_->Write(write_options_, &batch);
if (!s.ok()) {
- fprintf(stderr, "put error: %s\n", s.ToString().c_str());
- exit(1);
+ std::fprintf(stderr, "put error: %s\n", s.ToString().c_str());
+ std::exit(1);
}
}
thread->stats.AddBytes(bytes);
@@ -768,28 +850,29 @@ class Benchmark {
ReadOptions options;
std::string value;
int found = 0;
+ KeyBuffer key;
for (int i = 0; i < reads_; i++) {
- char key[100];
- const int k = thread->rand.Next() % FLAGS_num;
- snprintf(key, sizeof(key), "%016d", k);
- if (db_->Get(options, key, &value).ok()) {
+ const int k = thread->rand.Uniform(FLAGS_num);
+ key.Set(k);
+ if (db_->Get(options, key.slice(), &value).ok()) {
found++;
}
thread->stats.FinishedSingleOp();
}
char msg[100];
- snprintf(msg, sizeof(msg), "(%d of %d found)", found, num_);
+ std::snprintf(msg, sizeof(msg), "(%d of %d found)", found, num_);
thread->stats.AddMessage(msg);
}
void ReadMissing(ThreadState* thread) {
ReadOptions options;
std::string value;
+ KeyBuffer key;
for (int i = 0; i < reads_; i++) {
- char key[100];
- const int k = thread->rand.Next() % FLAGS_num;
- snprintf(key, sizeof(key), "%016d.", k);
- db_->Get(options, key, &value);
+ const int k = thread->rand.Uniform(FLAGS_num);
+ key.Set(k);
+ Slice s = Slice(key.slice().data(), key.slice().size() - 1);
+ db_->Get(options, s, &value);
thread->stats.FinishedSingleOp();
}
}
@@ -798,11 +881,11 @@ class Benchmark {
ReadOptions options;
std::string value;
const int range = (FLAGS_num + 99) / 100;
+ KeyBuffer key;
for (int i = 0; i < reads_; i++) {
- char key[100];
- const int k = thread->rand.Next() % range;
- snprintf(key, sizeof(key), "%016d", k);
- db_->Get(options, key, &value);
+ const int k = thread->rand.Uniform(range);
+ key.Set(k);
+ db_->Get(options, key.slice(), &value);
thread->stats.FinishedSingleOp();
}
}
@@ -810,13 +893,13 @@ class Benchmark {
void SeekRandom(ThreadState* thread) {
ReadOptions options;
int found = 0;
+ KeyBuffer key;
for (int i = 0; i < reads_; i++) {
Iterator* iter = db_->NewIterator(options);
- char key[100];
- const int k = thread->rand.Next() % FLAGS_num;
- snprintf(key, sizeof(key), "%016d", k);
- iter->Seek(key);
- if (iter->Valid() && iter->key() == key) found++;
+ const int k = thread->rand.Uniform(FLAGS_num);
+ key.Set(k);
+ iter->Seek(key.slice());
+ if (iter->Valid() && iter->key() == key.slice()) found++;
delete iter;
thread->stats.FinishedSingleOp();
}
@@ -825,23 +908,42 @@ class Benchmark {
thread->stats.AddMessage(msg);
}
+ void SeekOrdered(ThreadState* thread) {
+ ReadOptions options;
+ Iterator* iter = db_->NewIterator(options);
+ int found = 0;
+ int k = 0;
+ KeyBuffer key;
+ for (int i = 0; i < reads_; i++) {
+ k = (k + (thread->rand.Uniform(100))) % FLAGS_num;
+ key.Set(k);
+ iter->Seek(key.slice());
+ if (iter->Valid() && iter->key() == key.slice()) found++;
+ thread->stats.FinishedSingleOp();
+ }
+ delete iter;
+ char msg[100];
+ std::snprintf(msg, sizeof(msg), "(%d of %d found)", found, num_);
+ thread->stats.AddMessage(msg);
+ }
+
void DoDelete(ThreadState* thread, bool seq) {
RandomGenerator gen;
WriteBatch batch;
Status s;
+ KeyBuffer key;
for (int i = 0; i < num_; i += entries_per_batch_) {
batch.Clear();
for (int j = 0; j < entries_per_batch_; j++) {
- const int k = seq ? i + j : (thread->rand.Next() % FLAGS_num);
- char key[100];
- snprintf(key, sizeof(key), "%016d", k);
- batch.Delete(key);
+ const int k = seq ? i + j : (thread->rand.Uniform(FLAGS_num));
+ key.Set(k);
+ batch.Delete(key.slice());
thread->stats.FinishedSingleOp();
}
s = db_->Write(write_options_, &batch);
if (!s.ok()) {
- fprintf(stderr, "del error: %s\n", s.ToString().c_str());
- exit(1);
+ std::fprintf(stderr, "del error: %s\n", s.ToString().c_str());
+ std::exit(1);
}
}
}
@@ -856,6 +958,7 @@ class Benchmark {
} else {
// Special thread that keeps writing until other threads are done.
RandomGenerator gen;
+ KeyBuffer key;
while (true) {
{
MutexLock l(&thread->shared->mu);
@@ -865,13 +968,13 @@ class Benchmark {
}
}
- const int k = thread->rand.Next() % FLAGS_num;
- char key[100];
- snprintf(key, sizeof(key), "%016d", k);
- Status s = db_->Put(write_options_, key, gen.Generate(value_size_));
+ const int k = thread->rand.Uniform(FLAGS_num);
+ key.Set(k);
+ Status s =
+ db_->Put(write_options_, key.slice(), gen.Generate(value_size_));
if (!s.ok()) {
- fprintf(stderr, "put error: %s\n", s.ToString().c_str());
- exit(1);
+ std::fprintf(stderr, "put error: %s\n", s.ToString().c_str());
+ std::exit(1);
}
}
@@ -887,7 +990,7 @@ class Benchmark {
if (!db_->GetProperty(key, &stats)) {
stats = "(failed)";
}
- fprintf(stdout, "\n%s\n", stats.c_str());
+ std::fprintf(stdout, "\n%s\n", stats.c_str());
}
static void WriteToFile(void* arg, const char* buf, int n) {
@@ -896,18 +999,19 @@ class Benchmark {
void HeapProfile() {
char fname[100];
- snprintf(fname, sizeof(fname), "%s/heap-%04d", FLAGS_db, ++heap_counter_);
+ std::snprintf(fname, sizeof(fname), "%s/heap-%04d", FLAGS_db,
+ ++heap_counter_);
WritableFile* file;
Status s = g_env->NewWritableFile(fname, &file);
if (!s.ok()) {
- fprintf(stderr, "%s\n", s.ToString().c_str());
+ std::fprintf(stderr, "%s\n", s.ToString().c_str());
return;
}
bool ok = port::GetHeapProfile(WriteToFile, file);
delete file;
if (!ok) {
- fprintf(stderr, "heap profiling not supported\n");
- g_env->DeleteFile(fname);
+ std::fprintf(stderr, "heap profiling not supported\n");
+ g_env->RemoveFile(fname);
}
}
};
@@ -932,6 +1036,9 @@ int main(int argc, char** argv) {
} else if (sscanf(argv[i], "--histogram=%d%c", &n, &junk) == 1 &&
(n == 0 || n == 1)) {
FLAGS_histogram = n;
+ } else if (sscanf(argv[i], "--comparisons=%d%c", &n, &junk) == 1 &&
+ (n == 0 || n == 1)) {
+ FLAGS_comparisons = n;
} else if (sscanf(argv[i], "--use_existing_db=%d%c", &n, &junk) == 1 &&
(n == 0 || n == 1)) {
FLAGS_use_existing_db = n;
@@ -952,6 +1059,8 @@ int main(int argc, char** argv) {
FLAGS_max_file_size = n;
} else if (sscanf(argv[i], "--block_size=%d%c", &n, &junk) == 1) {
FLAGS_block_size = n;
+ } else if (sscanf(argv[i], "--key_prefix=%d%c", &n, &junk) == 1) {
+ FLAGS_key_prefix = n;
} else if (sscanf(argv[i], "--cache_size=%d%c", &n, &junk) == 1) {
FLAGS_cache_size = n;
} else if (sscanf(argv[i], "--bloom_bits=%d%c", &n, &junk) == 1) {
@@ -961,8 +1070,8 @@ int main(int argc, char** argv) {
} else if (strncmp(argv[i], "--db=", 5) == 0) {
FLAGS_db = argv[i] + 5;
} else {
- fprintf(stderr, "Invalid flag '%s'\n", argv[i]);
- exit(1);
+ std::fprintf(stderr, "Invalid flag '%s'\n", argv[i]);
+ std::exit(1);
}
}
diff --git a/benchmarks/db_bench_log.cc b/benchmarks/db_bench_log.cc
new file mode 100644
index 0000000..a1845bf
--- /dev/null
+++ b/benchmarks/db_bench_log.cc
@@ -0,0 +1,92 @@
+// Copyright (c) 2019 The LevelDB Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file. See the AUTHORS file for names of contributors.
+
+#include <cinttypes>
+#include <cstdio>
+#include <string>
+
+#include "gtest/gtest.h"
+#include "benchmark/benchmark.h"
+#include "db/version_set.h"
+#include "leveldb/comparator.h"
+#include "leveldb/db.h"
+#include "leveldb/env.h"
+#include "leveldb/options.h"
+#include "port/port.h"
+#include "util/mutexlock.h"
+#include "util/testutil.h"
+
+namespace leveldb {
+
+namespace {
+
+std::string MakeKey(unsigned int num) {
+ char buf[30];
+ std::snprintf(buf, sizeof(buf), "%016u", num);
+ return std::string(buf);
+}
+
+void BM_LogAndApply(benchmark::State& state) {
+ const int num_base_files = state.range(0);
+
+ std::string dbname = testing::TempDir() + "leveldb_test_benchmark";
+ DestroyDB(dbname, Options());
+
+ DB* db = nullptr;
+ Options opts;
+ opts.create_if_missing = true;
+ Status s = DB::Open(opts, dbname, &db);
+ ASSERT_LEVELDB_OK(s);
+ ASSERT_TRUE(db != nullptr);
+
+ delete db;
+ db = nullptr;
+
+ Env* env = Env::Default();
+
+ port::Mutex mu;
+ MutexLock l(&mu);
+
+ InternalKeyComparator cmp(BytewiseComparator());
+ Options options;
+ VersionSet vset(dbname, &options, nullptr, &cmp);
+ bool save_manifest;
+ ASSERT_LEVELDB_OK(vset.Recover(&save_manifest));
+ VersionEdit vbase;
+ uint64_t fnum = 1;
+ for (int i = 0; i < num_base_files; i++) {
+ InternalKey start(MakeKey(2 * fnum), 1, kTypeValue);
+ InternalKey limit(MakeKey(2 * fnum + 1), 1, kTypeDeletion);
+ vbase.AddFile(2, fnum++, 1 /* file size */, start, limit);
+ }
+ ASSERT_LEVELDB_OK(vset.LogAndApply(&vbase, &mu));
+
+ uint64_t start_micros = env->NowMicros();
+
+ for (auto st : state) {
+ VersionEdit vedit;
+ vedit.RemoveFile(2, fnum);
+ InternalKey start(MakeKey(2 * fnum), 1, kTypeValue);
+ InternalKey limit(MakeKey(2 * fnum + 1), 1, kTypeDeletion);
+ vedit.AddFile(2, fnum++, 1 /* file size */, start, limit);
+ vset.LogAndApply(&vedit, &mu);
+ }
+
+ uint64_t stop_micros = env->NowMicros();
+ unsigned int us = stop_micros - start_micros;
+ char buf[16];
+ std::snprintf(buf, sizeof(buf), "%d", num_base_files);
+ std::fprintf(stderr,
+ "BM_LogAndApply/%-6s %8" PRIu64
+ " iters : %9u us (%7.0f us / iter)\n",
+ buf, state.iterations(), us, ((float)us) / state.iterations());
+}
+
+BENCHMARK(BM_LogAndApply)->Arg(1)->Arg(100)->Arg(10000)->Arg(100000);
+
+} // namespace
+
+} // namespace leveldb
+
+BENCHMARK_MAIN();
diff --git a/benchmarks/db_bench_sqlite3.cc b/benchmarks/db_bench_sqlite3.cc
index f183f4f..c9be652 100644
--- a/benchmarks/db_bench_sqlite3.cc
+++ b/benchmarks/db_bench_sqlite3.cc
@@ -3,8 +3,9 @@
// found in the LICENSE file. See the AUTHORS file for names of contributors.
#include <sqlite3.h>
-#include <stdio.h>
-#include <stdlib.h>
+
+#include <cstdio>
+#include <cstdlib>
#include "util/histogram.h"
#include "util/random.h"
@@ -69,6 +70,9 @@ static int FLAGS_num_pages = 4096;
// benchmark will fail.
static bool FLAGS_use_existing_db = false;
+// If true, the SQLite table has ROWIDs.
+static bool FLAGS_use_rowids = false;
+
// If true, we allow batch writes to occur
static bool FLAGS_transaction = true;
@@ -80,23 +84,23 @@ static const char* FLAGS_db = nullptr;
inline static void ExecErrorCheck(int status, char* err_msg) {
if (status != SQLITE_OK) {
- fprintf(stderr, "SQL error: %s\n", err_msg);
+ std::fprintf(stderr, "SQL error: %s\n", err_msg);
sqlite3_free(err_msg);
- exit(1);
+ std::exit(1);
}
}
inline static void StepErrorCheck(int status) {
if (status != SQLITE_DONE) {
- fprintf(stderr, "SQL step error: status = %d\n", status);
- exit(1);
+ std::fprintf(stderr, "SQL step error: status = %d\n", status);
+ std::exit(1);
}
}
inline static void ErrorCheck(int status) {
if (status != SQLITE_OK) {
- fprintf(stderr, "sqlite3 error: status = %d\n", status);
- exit(1);
+ std::fprintf(stderr, "sqlite3 error: status = %d\n", status);
+ std::exit(1);
}
}
@@ -178,36 +182,38 @@ class Benchmark {
void PrintHeader() {
const int kKeySize = 16;
PrintEnvironment();
- fprintf(stdout, "Keys: %d bytes each\n", kKeySize);
- fprintf(stdout, "Values: %d bytes each\n", FLAGS_value_size);
- fprintf(stdout, "Entries: %d\n", num_);
- fprintf(stdout, "RawSize: %.1f MB (estimated)\n",
- ((static_cast<int64_t>(kKeySize + FLAGS_value_size) * num_) /
- 1048576.0));
+ std::fprintf(stdout, "Keys: %d bytes each\n", kKeySize);
+ std::fprintf(stdout, "Values: %d bytes each\n", FLAGS_value_size);
+ std::fprintf(stdout, "Entries: %d\n", num_);
+ std::fprintf(stdout, "RawSize: %.1f MB (estimated)\n",
+ ((static_cast<int64_t>(kKeySize + FLAGS_value_size) * num_) /
+ 1048576.0));
PrintWarnings();
- fprintf(stdout, "------------------------------------------------\n");
+ std::fprintf(stdout, "------------------------------------------------\n");
}
void PrintWarnings() {
#if defined(__GNUC__) && !defined(__OPTIMIZE__)
- fprintf(
+ std::fprintf(
stdout,
"WARNING: Optimization is disabled: benchmarks unnecessarily slow\n");
#endif
#ifndef NDEBUG
- fprintf(stdout,
- "WARNING: Assertions are enabled; benchmarks unnecessarily slow\n");
+ std::fprintf(
+ stdout,
+ "WARNING: Assertions are enabled; benchmarks unnecessarily slow\n");
#endif
}
void PrintEnvironment() {
- fprintf(stderr, "SQLite: version %s\n", SQLITE_VERSION);
+ std::fprintf(stderr, "SQLite: version %s\n", SQLITE_VERSION);
#if defined(__linux)
time_t now = time(nullptr);
- fprintf(stderr, "Date: %s", ctime(&now)); // ctime() adds newline
+ std::fprintf(stderr, "Date: %s",
+ ctime(&now)); // ctime() adds newline
- FILE* cpuinfo = fopen("/proc/cpuinfo", "r");
+ FILE* cpuinfo = std::fopen("/proc/cpuinfo", "r");
if (cpuinfo != nullptr) {
char line[1000];
int num_cpus = 0;
@@ -227,9 +233,9 @@ class Benchmark {
cache_size = val.ToString();
}
}
- fclose(cpuinfo);
- fprintf(stderr, "CPU: %d * %s\n", num_cpus, cpu_type.c_str());
- fprintf(stderr, "CPUCache: %s\n", cache_size.c_str());
+ std::fclose(cpuinfo);
+ std::fprintf(stderr, "CPU: %d * %s\n", num_cpus, cpu_type.c_str());
+ std::fprintf(stderr, "CPUCache: %s\n", cache_size.c_str());
}
#endif
}
@@ -250,8 +256,8 @@ class Benchmark {
double micros = (now - last_op_finish_) * 1e6;
hist_.Add(micros);
if (micros > 20000) {
- fprintf(stderr, "long op: %.1f micros%30s\r", micros, "");
- fflush(stderr);
+ std::fprintf(stderr, "long op: %.1f micros%30s\r", micros, "");
+ std::fflush(stderr);
}
last_op_finish_ = now;
}
@@ -272,8 +278,8 @@ class Benchmark {
next_report_ += 50000;
else
next_report_ += 100000;
- fprintf(stderr, "... finished %d ops%30s\r", done_, "");
- fflush(stderr);
+ std::fprintf(stderr, "... finished %d ops%30s\r", done_, "");
+ std::fflush(stderr);
}
}
@@ -286,8 +292,8 @@ class Benchmark {
if (bytes_ > 0) {
char rate[100];
- snprintf(rate, sizeof(rate), "%6.1f MB/s",
- (bytes_ / 1048576.0) / (finish - start_));
+ std::snprintf(rate, sizeof(rate), "%6.1f MB/s",
+ (bytes_ / 1048576.0) / (finish - start_));
if (!message_.empty()) {
message_ = std::string(rate) + " " + message_;
} else {
@@ -295,13 +301,14 @@ class Benchmark {
}
}
- fprintf(stdout, "%-12s : %11.3f micros/op;%s%s\n", name.ToString().c_str(),
- (finish - start_) * 1e6 / done_, (message_.empty() ? "" : " "),
- message_.c_str());
+ std::fprintf(stdout, "%-12s : %11.3f micros/op;%s%s\n",
+ name.ToString().c_str(), (finish - start_) * 1e6 / done_,
+ (message_.empty() ? "" : " "), message_.c_str());
if (FLAGS_histogram) {
- fprintf(stdout, "Microseconds per op:\n%s\n", hist_.ToString().c_str());
+ std::fprintf(stdout, "Microseconds per op:\n%s\n",
+ hist_.ToString().c_str());
}
- fflush(stdout);
+ std::fflush(stdout);
}
public:
@@ -325,7 +332,7 @@ class Benchmark {
std::string file_name(test_dir);
file_name += "/";
file_name += files[i];
- Env::Default()->DeleteFile(file_name.c_str());
+ Env::Default()->RemoveFile(file_name.c_str());
}
}
}
@@ -401,7 +408,8 @@ class Benchmark {
} else {
known = false;
if (name != Slice()) { // No error message for empty name
- fprintf(stderr, "unknown benchmark '%s'\n", name.ToString().c_str());
+ std::fprintf(stderr, "unknown benchmark '%s'\n",
+ name.ToString().c_str());
}
}
if (known) {
@@ -421,26 +429,26 @@ class Benchmark {
// Open database
std::string tmp_dir;
Env::Default()->GetTestDirectory(&tmp_dir);
- snprintf(file_name, sizeof(file_name), "%s/dbbench_sqlite3-%d.db",
- tmp_dir.c_str(), db_num_);
+ std::snprintf(file_name, sizeof(file_name), "%s/dbbench_sqlite3-%d.db",
+ tmp_dir.c_str(), db_num_);
status = sqlite3_open(file_name, &db_);
if (status) {
- fprintf(stderr, "open error: %s\n", sqlite3_errmsg(db_));
- exit(1);
+ std::fprintf(stderr, "open error: %s\n", sqlite3_errmsg(db_));
+ std::exit(1);
}
// Change SQLite cache size
char cache_size[100];
- snprintf(cache_size, sizeof(cache_size), "PRAGMA cache_size = %d",
- FLAGS_num_pages);
+ std::snprintf(cache_size, sizeof(cache_size), "PRAGMA cache_size = %d",
+ FLAGS_num_pages);
status = sqlite3_exec(db_, cache_size, nullptr, nullptr, &err_msg);
ExecErrorCheck(status, err_msg);
// FLAGS_page_size is defaulted to 1024
if (FLAGS_page_size != 1024) {
char page_size[100];
- snprintf(page_size, sizeof(page_size), "PRAGMA page_size = %d",
- FLAGS_page_size);
+ std::snprintf(page_size, sizeof(page_size), "PRAGMA page_size = %d",
+ FLAGS_page_size);
status = sqlite3_exec(db_, page_size, nullptr, nullptr, &err_msg);
ExecErrorCheck(status, err_msg);
}
@@ -462,6 +470,7 @@ class Benchmark {
std::string locking_stmt = "PRAGMA locking_mode = EXCLUSIVE";
std::string create_stmt =
"CREATE TABLE test (key blob, value blob, PRIMARY KEY(key))";
+ if (!FLAGS_use_rowids) create_stmt += " WITHOUT ROWID";
std::string stmt_array[] = {locking_stmt, create_stmt};
int stmt_array_length = sizeof(stmt_array) / sizeof(std::string);
for (int i = 0; i < stmt_array_length; i++) {
@@ -487,7 +496,7 @@ class Benchmark {
if (num_entries != num_) {
char msg[100];
- snprintf(msg, sizeof(msg), "(%d ops)", num_entries);
+ std::snprintf(msg, sizeof(msg), "(%d ops)", num_entries);
message_ = msg;
}
@@ -534,7 +543,7 @@ class Benchmark {
const int k =
(order == SEQUENTIAL) ? i + j : (rand_.Next() % num_entries);
char key[100];
- snprintf(key, sizeof(key), "%016d", k);
+ std::snprintf(key, sizeof(key), "%016d", k);
// Bind KV values into replace_stmt
status = sqlite3_bind_blob(replace_stmt, 1, key, 16, SQLITE_STATIC);
@@ -607,7 +616,7 @@ class Benchmark {
// Create key value
char key[100];
int k = (order == SEQUENTIAL) ? i + j : (rand_.Next() % reads_);
- snprintf(key, sizeof(key), "%016d", k);
+ std::snprintf(key, sizeof(key), "%016d", k);
// Bind key value into read_stmt
status = sqlite3_bind_blob(read_stmt, 1, key, 16, SQLITE_STATIC);
@@ -678,6 +687,9 @@ int main(int argc, char** argv) {
} else if (sscanf(argv[i], "--use_existing_db=%d%c", &n, &junk) == 1 &&
(n == 0 || n == 1)) {
FLAGS_use_existing_db = n;
+ } else if (sscanf(argv[i], "--use_rowids=%d%c", &n, &junk) == 1 &&
+ (n == 0 || n == 1)) {
+ FLAGS_use_rowids = n;
} else if (sscanf(argv[i], "--num=%d%c", &n, &junk) == 1) {
FLAGS_num = n;
} else if (sscanf(argv[i], "--reads=%d%c", &n, &junk) == 1) {
@@ -696,8 +708,8 @@ int main(int argc, char** argv) {
} else if (strncmp(argv[i], "--db=", 5) == 0) {
FLAGS_db = argv[i] + 5;
} else {
- fprintf(stderr, "Invalid flag '%s'\n", argv[i]);
- exit(1);
+ std::fprintf(stderr, "Invalid flag '%s'\n", argv[i]);
+ std::exit(1);
}
}
diff --git a/benchmarks/db_bench_tree_db.cc b/benchmarks/db_bench_tree_db.cc
index b2f6646..533600b 100644
--- a/benchmarks/db_bench_tree_db.cc
+++ b/benchmarks/db_bench_tree_db.cc
@@ -3,8 +3,9 @@
// found in the LICENSE file. See the AUTHORS file for names of contributors.
#include <kcpolydb.h>
-#include <stdio.h>
-#include <stdlib.h>
+
+#include <cstdio>
+#include <cstdlib>
#include "util/histogram.h"
#include "util/random.h"
@@ -74,7 +75,7 @@ static const char* FLAGS_db = nullptr;
inline static void DBSynchronize(kyotocabinet::TreeDB* db_) {
// Synchronize will flush writes to disk
if (!db_->synchronize()) {
- fprintf(stderr, "synchronize error: %s\n", db_->error().name());
+ std::fprintf(stderr, "synchronize error: %s\n", db_->error().name());
}
}
@@ -149,42 +150,47 @@ class Benchmark {
void PrintHeader() {
const int kKeySize = 16;
PrintEnvironment();
- fprintf(stdout, "Keys: %d bytes each\n", kKeySize);
- fprintf(stdout, "Values: %d bytes each (%d bytes after compression)\n",
- FLAGS_value_size,
- static_cast<int>(FLAGS_value_size * FLAGS_compression_ratio + 0.5));
- fprintf(stdout, "Entries: %d\n", num_);
- fprintf(stdout, "RawSize: %.1f MB (estimated)\n",
- ((static_cast<int64_t>(kKeySize + FLAGS_value_size) * num_) /
- 1048576.0));
- fprintf(stdout, "FileSize: %.1f MB (estimated)\n",
- (((kKeySize + FLAGS_value_size * FLAGS_compression_ratio) * num_) /
- 1048576.0));
+ std::fprintf(stdout, "Keys: %d bytes each\n", kKeySize);
+ std::fprintf(
+ stdout, "Values: %d bytes each (%d bytes after compression)\n",
+ FLAGS_value_size,
+ static_cast<int>(FLAGS_value_size * FLAGS_compression_ratio + 0.5));
+ std::fprintf(stdout, "Entries: %d\n", num_);
+ std::fprintf(stdout, "RawSize: %.1f MB (estimated)\n",
+ ((static_cast<int64_t>(kKeySize + FLAGS_value_size) * num_) /
+ 1048576.0));
+ std::fprintf(
+ stdout, "FileSize: %.1f MB (estimated)\n",
+ (((kKeySize + FLAGS_value_size * FLAGS_compression_ratio) * num_) /
+ 1048576.0));
PrintWarnings();
- fprintf(stdout, "------------------------------------------------\n");
+ std::fprintf(stdout, "------------------------------------------------\n");
}
void PrintWarnings() {
#if defined(__GNUC__) && !defined(__OPTIMIZE__)
- fprintf(
+ std::fprintf(
stdout,
"WARNING: Optimization is disabled: benchmarks unnecessarily slow\n");
#endif
#ifndef NDEBUG
- fprintf(stdout,
- "WARNING: Assertions are enabled; benchmarks unnecessarily slow\n");
+ std::fprintf(
+ stdout,
+ "WARNING: Assertions are enabled; benchmarks unnecessarily slow\n");
#endif
}
void PrintEnvironment() {
- fprintf(stderr, "Kyoto Cabinet: version %s, lib ver %d, lib rev %d\n",
- kyotocabinet::VERSION, kyotocabinet::LIBVER, kyotocabinet::LIBREV);
+ std::fprintf(
+ stderr, "Kyoto Cabinet: version %s, lib ver %d, lib rev %d\n",
+ kyotocabinet::VERSION, kyotocabinet::LIBVER, kyotocabinet::LIBREV);
#if defined(__linux)
time_t now = time(nullptr);
- fprintf(stderr, "Date: %s", ctime(&now)); // ctime() adds newline
+ std::fprintf(stderr, "Date: %s",
+ ctime(&now)); // ctime() adds newline
- FILE* cpuinfo = fopen("/proc/cpuinfo", "r");
+ FILE* cpuinfo = std::fopen("/proc/cpuinfo", "r");
if (cpuinfo != nullptr) {
char line[1000];
int num_cpus = 0;
@@ -204,9 +210,10 @@ class Benchmark {
cache_size = val.ToString();
}
}
- fclose(cpuinfo);
- fprintf(stderr, "CPU: %d * %s\n", num_cpus, cpu_type.c_str());
- fprintf(stderr, "CPUCache: %s\n", cache_size.c_str());
+ std::fclose(cpuinfo);
+ std::fprintf(stderr, "CPU: %d * %s\n", num_cpus,
+ cpu_type.c_str());
+ std::fprintf(stderr, "CPUCache: %s\n", cache_size.c_str());
}
#endif
}
@@ -227,8 +234,8 @@ class Benchmark {
double micros = (now - last_op_finish_) * 1e6;
hist_.Add(micros);
if (micros > 20000) {
- fprintf(stderr, "long op: %.1f micros%30s\r", micros, "");
- fflush(stderr);
+ std::fprintf(stderr, "long op: %.1f micros%30s\r", micros, "");
+ std::fflush(stderr);
}
last_op_finish_ = now;
}
@@ -249,8 +256,8 @@ class Benchmark {
next_report_ += 50000;
else
next_report_ += 100000;
- fprintf(stderr, "... finished %d ops%30s\r", done_, "");
- fflush(stderr);
+ std::fprintf(stderr, "... finished %d ops%30s\r", done_, "");
+ std::fflush(stderr);
}
}
@@ -263,8 +270,8 @@ class Benchmark {
if (bytes_ > 0) {
char rate[100];
- snprintf(rate, sizeof(rate), "%6.1f MB/s",
- (bytes_ / 1048576.0) / (finish - start_));
+ std::snprintf(rate, sizeof(rate), "%6.1f MB/s",
+ (bytes_ / 1048576.0) / (finish - start_));
if (!message_.empty()) {
message_ = std::string(rate) + " " + message_;
} else {
@@ -272,13 +279,14 @@ class Benchmark {
}
}
- fprintf(stdout, "%-12s : %11.3f micros/op;%s%s\n", name.ToString().c_str(),
- (finish - start_) * 1e6 / done_, (message_.empty() ? "" : " "),
- message_.c_str());
+ std::fprintf(stdout, "%-12s : %11.3f micros/op;%s%s\n",
+ name.ToString().c_str(), (finish - start_) * 1e6 / done_,
+ (message_.empty() ? "" : " "), message_.c_str());
if (FLAGS_histogram) {
- fprintf(stdout, "Microseconds per op:\n%s\n", hist_.ToString().c_str());
+ std::fprintf(stdout, "Microseconds per op:\n%s\n",
+ hist_.ToString().c_str());
}
- fflush(stdout);
+ std::fflush(stdout);
}
public:
@@ -301,7 +309,7 @@ class Benchmark {
std::string file_name(test_dir);
file_name += "/";
file_name += files[i];
- Env::Default()->DeleteFile(file_name.c_str());
+ Env::Default()->RemoveFile(file_name.c_str());
}
}
}
@@ -309,7 +317,7 @@ class Benchmark {
~Benchmark() {
if (!db_->close()) {
- fprintf(stderr, "close error: %s\n", db_->error().name());
+ std::fprintf(stderr, "close error: %s\n", db_->error().name());
}
}
@@ -373,7 +381,8 @@ class Benchmark {
} else {
known = false;
if (name != Slice()) { // No error message for empty name
- fprintf(stderr, "unknown benchmark '%s'\n", name.ToString().c_str());
+ std::fprintf(stderr, "unknown benchmark '%s'\n",
+ name.ToString().c_str());
}
}
if (known) {
@@ -392,8 +401,8 @@ class Benchmark {
db_num_++;
std::string test_dir;
Env::Default()->GetTestDirectory(&test_dir);
- snprintf(file_name, sizeof(file_name), "%s/dbbench_polyDB-%d.kct",
- test_dir.c_str(), db_num_);
+ std::snprintf(file_name, sizeof(file_name), "%s/dbbench_polyDB-%d.kct",
+ test_dir.c_str(), db_num_);
// Create tuning options and open the database
int open_options =
@@ -412,7 +421,7 @@ class Benchmark {
open_options |= kyotocabinet::PolyDB::OAUTOSYNC;
}
if (!db_->open(file_name, open_options)) {
- fprintf(stderr, "open error: %s\n", db_->error().name());
+ std::fprintf(stderr, "open error: %s\n", db_->error().name());
}
}
@@ -432,7 +441,7 @@ class Benchmark {
if (num_entries != num_) {
char msg[100];
- snprintf(msg, sizeof(msg), "(%d ops)", num_entries);
+ std::snprintf(msg, sizeof(msg), "(%d ops)", num_entries);
message_ = msg;
}
@@ -440,11 +449,11 @@ class Benchmark {
for (int i = 0; i < num_entries; i++) {
const int k = (order == SEQUENTIAL) ? i : (rand_.Next() % num_entries);
char key[100];
- snprintf(key, sizeof(key), "%016d", k);
+ std::snprintf(key, sizeof(key), "%016d", k);
bytes_ += value_size + strlen(key);
std::string cpp_key = key;
if (!db_->set(cpp_key, gen_.Generate(value_size).ToString())) {
- fprintf(stderr, "set error: %s\n", db_->error().name());
+ std::fprintf(stderr, "set error: %s\n", db_->error().name());
}
FinishedSingleOp();
}
@@ -466,7 +475,7 @@ class Benchmark {
for (int i = 0; i < reads_; i++) {
char key[100];
const int k = rand_.Next() % reads_;
- snprintf(key, sizeof(key), "%016d", k);
+ std::snprintf(key, sizeof(key), "%016d", k);
db_->get(key, &value);
FinishedSingleOp();
}
@@ -504,8 +513,8 @@ int main(int argc, char** argv) {
} else if (strncmp(argv[i], "--db=", 5) == 0) {
FLAGS_db = argv[i] + 5;
} else {
- fprintf(stderr, "Invalid flag '%s'\n", argv[i]);
- exit(1);
+ std::fprintf(stderr, "Invalid flag '%s'\n", argv[i]);
+ std::exit(1);
}
}