1fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
2fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com// Use of this source code is governed by a BSD-style license that can be
3fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com// found in the LICENSE file. See the AUTHORS file for names of contributors.
4fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
5fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com#include <stdio.h>
6fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com#include <stdlib.h>
7fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com#include <kcpolydb.h>
8fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com#include "util/histogram.h"
9fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com#include "util/random.h"
10fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com#include "util/testutil.h"
11fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
12fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com// Comma-separated list of operations to run in the specified order
13fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com//   Actual benchmarks:
14fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com//
15fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com//   fillseq       -- write N values in sequential key order in async mode
16fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com//   fillrandom    -- write N values in random key order in async mode
17fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com//   overwrite     -- overwrite N values in random key order in async mode
18fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com//   fillseqsync   -- write N/100 values in sequential key order in sync mode
19fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com//   fillrandsync  -- write N/100 values in random key order in sync mode
20fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com//   fillrand100K  -- write N/1000 100K values in random order in async mode
21fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com//   fillseq100K   -- write N/1000 100K values in seq order in async mode
22fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com//   readseq       -- read N times sequentially
23fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com//   readseq100K   -- read N/1000 100K values in sequential order in async mode
24fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com//   readrand100K  -- read N/1000 100K values in sequential order in async mode
25fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com//   readrandom    -- read N times in random order
26fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.comstatic const char* FLAGS_benchmarks =
27fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    "fillseq,"
28fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    "fillseqsync,"
29fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    "fillrandsync,"
30fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    "fillrandom,"
31fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    "overwrite,"
32fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    "readrandom,"
33fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    "readseq,"
34fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    "fillrand100K,"
35fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    "fillseq100K,"
36fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    "readseq100K,"
37fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    "readrand100K,"
38fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    ;
39fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
40fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com// Number of key/values to place in database
41fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.comstatic int FLAGS_num = 1000000;
42fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
43fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com// Number of read operations to do.  If negative, do FLAGS_num reads.
44fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.comstatic int FLAGS_reads = -1;
45fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
46fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com// Size of each value
47fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.comstatic int FLAGS_value_size = 100;
48fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
49fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com// Arrange to generate values that shrink to this fraction of
50fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com// their original size after compression
51fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.comstatic double FLAGS_compression_ratio = 0.5;
52fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
53fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com// Print histogram of operation timings
54fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.comstatic bool FLAGS_histogram = false;
55fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
56fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com// Cache size. Default 4 MB
57fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.comstatic int FLAGS_cache_size = 4194304;
58fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
59fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com// Page size. Default 1 KB
60fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.comstatic int FLAGS_page_size = 1024;
61fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
62fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com// If true, do not destroy the existing database.  If you set this
63fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com// flag and also specify a benchmark that wants a fresh database, that
64fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com// benchmark will fail.
65fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.comstatic bool FLAGS_use_existing_db = false;
66fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
67fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com// Compression flag. If true, compression is on. If false, compression
68fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com// is off.
69fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.comstatic bool FLAGS_compression = true;
70fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
71158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com// Use the db with the following name.
72158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.comstatic const char* FLAGS_db = NULL;
73158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com
74fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.cominline
75fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.comstatic void DBSynchronize(kyotocabinet::TreeDB* db_)
76fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com{
77fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  // Synchronize will flush writes to disk
78fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  if (!db_->synchronize()) {
79fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    fprintf(stderr, "synchronize error: %s\n", db_->error().name());
80fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  }
81fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com}
82fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
83fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.comnamespace leveldb {
84fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
85fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com// Helper for quickly generating random data.
86fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.comnamespace {
87fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.comclass RandomGenerator {
88fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com private:
89fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  std::string data_;
90fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  int pos_;
91fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
92fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com public:
93fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  RandomGenerator() {
94fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    // We use a limited amount of data over and over again and ensure
95fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    // that it is larger than the compression window (32KB), and also
96fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    // large enough to serve all typical value sizes we want to write.
97fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    Random rnd(301);
98fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    std::string piece;
99fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    while (data_.size() < 1048576) {
100fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      // Add a short fragment that is as compressible as specified
101fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      // by FLAGS_compression_ratio.
102fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      test::CompressibleString(&rnd, FLAGS_compression_ratio, 100, &piece);
103fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      data_.append(piece);
104fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    }
105fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    pos_ = 0;
106fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  }
107fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
108fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  Slice Generate(int len) {
109fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    if (pos_ + len > data_.size()) {
110fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      pos_ = 0;
111fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      assert(len < data_.size());
112fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    }
113fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    pos_ += len;
114fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    return Slice(data_.data() + pos_ - len, len);
115fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  }
116fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com};
117fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
118fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.comstatic Slice TrimSpace(Slice s) {
119fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  int start = 0;
120fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  while (start < s.size() && isspace(s[start])) {
121fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    start++;
122fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  }
123fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  int limit = s.size();
124fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  while (limit > start && isspace(s[limit-1])) {
125fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    limit--;
126fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  }
127fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  return Slice(s.data() + start, limit - start);
128fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com}
129fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
13045b9940be332834440bd5299419f396e38085ebehans@chromium.org}  // namespace
131fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
132fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.comclass Benchmark {
133fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com private:
134fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  kyotocabinet::TreeDB* db_;
135fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  int db_num_;
136fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  int num_;
137fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  int reads_;
138fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  double start_;
139fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  double last_op_finish_;
140fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  int64_t bytes_;
141fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  std::string message_;
142fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  Histogram hist_;
143fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  RandomGenerator gen_;
144fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  Random rand_;
145fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  kyotocabinet::LZOCompressor<kyotocabinet::LZO::RAW> comp_;
146fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
147fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  // State kept for progress messages
148fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  int done_;
149fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  int next_report_;     // When to report next
150fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
151fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  void PrintHeader() {
152fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    const int kKeySize = 16;
153fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    PrintEnvironment();
154fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    fprintf(stdout, "Keys:       %d bytes each\n", kKeySize);
155fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    fprintf(stdout, "Values:     %d bytes each (%d bytes after compression)\n",
156fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com            FLAGS_value_size,
157fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com            static_cast<int>(FLAGS_value_size * FLAGS_compression_ratio + 0.5));
158fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    fprintf(stdout, "Entries:    %d\n", num_);
159fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    fprintf(stdout, "RawSize:    %.1f MB (estimated)\n",
160fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com            ((static_cast<int64_t>(kKeySize + FLAGS_value_size) * num_)
161fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com             / 1048576.0));
162fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    fprintf(stdout, "FileSize:   %.1f MB (estimated)\n",
163fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com            (((kKeySize + FLAGS_value_size * FLAGS_compression_ratio) * num_)
164fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com             / 1048576.0));
165fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    PrintWarnings();
166fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    fprintf(stdout, "------------------------------------------------\n");
167fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  }
168fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
169fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  void PrintWarnings() {
170fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com#if defined(__GNUC__) && !defined(__OPTIMIZE__)
171fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    fprintf(stdout,
172fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com            "WARNING: Optimization is disabled: benchmarks unnecessarily slow\n"
173fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com            );
174fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com#endif
175fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com#ifndef NDEBUG
176fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    fprintf(stdout,
177fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com            "WARNING: Assertions are enabled; benchmarks unnecessarily slow\n");
178fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com#endif
179fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  }
180fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
181fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  void PrintEnvironment() {
182fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    fprintf(stderr, "Kyoto Cabinet:    version %s, lib ver %d, lib rev %d\n",
183fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com            kyotocabinet::VERSION, kyotocabinet::LIBVER, kyotocabinet::LIBREV);
184fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
185fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com#if defined(__linux)
186fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    time_t now = time(NULL);
187fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    fprintf(stderr, "Date:           %s", ctime(&now));  // ctime() adds newline
188fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
189fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    FILE* cpuinfo = fopen("/proc/cpuinfo", "r");
190fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    if (cpuinfo != NULL) {
191fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      char line[1000];
192fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      int num_cpus = 0;
193fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      std::string cpu_type;
194fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      std::string cache_size;
195fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      while (fgets(line, sizeof(line), cpuinfo) != NULL) {
196fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        const char* sep = strchr(line, ':');
197fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        if (sep == NULL) {
198fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com          continue;
199fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        }
200fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        Slice key = TrimSpace(Slice(line, sep - 1 - line));
201fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        Slice val = TrimSpace(Slice(sep + 1));
202fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        if (key == "model name") {
203fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com          ++num_cpus;
204fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com          cpu_type = val.ToString();
205fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        } else if (key == "cache size") {
206fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com          cache_size = val.ToString();
207fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        }
208fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      }
209fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      fclose(cpuinfo);
210fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      fprintf(stderr, "CPU:            %d * %s\n", num_cpus, cpu_type.c_str());
211fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      fprintf(stderr, "CPUCache:       %s\n", cache_size.c_str());
212fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    }
213fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com#endif
214fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  }
215fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
216fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  void Start() {
217fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    start_ = Env::Default()->NowMicros() * 1e-6;
218fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    bytes_ = 0;
219fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    message_.clear();
220fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    last_op_finish_ = start_;
221fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    hist_.Clear();
222fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    done_ = 0;
223fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    next_report_ = 100;
224fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  }
225fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
226fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  void FinishedSingleOp() {
227fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    if (FLAGS_histogram) {
228fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      double now = Env::Default()->NowMicros() * 1e-6;
229fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      double micros = (now - last_op_finish_) * 1e6;
230fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      hist_.Add(micros);
231fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      if (micros > 20000) {
232fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        fprintf(stderr, "long op: %.1f micros%30s\r", micros, "");
233fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        fflush(stderr);
234fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      }
235fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      last_op_finish_ = now;
236fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    }
237fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
238fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    done_++;
239fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    if (done_ >= next_report_) {
240fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      if      (next_report_ < 1000)   next_report_ += 100;
241fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      else if (next_report_ < 5000)   next_report_ += 500;
242fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      else if (next_report_ < 10000)  next_report_ += 1000;
243fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      else if (next_report_ < 50000)  next_report_ += 5000;
244fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      else if (next_report_ < 100000) next_report_ += 10000;
245fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      else if (next_report_ < 500000) next_report_ += 50000;
246fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      else                            next_report_ += 100000;
247fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      fprintf(stderr, "... finished %d ops%30s\r", done_, "");
248fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      fflush(stderr);
249fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    }
250fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  }
251fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
252fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  void Stop(const Slice& name) {
253fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    double finish = Env::Default()->NowMicros() * 1e-6;
254fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
255fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    // Pretend at least one op was done in case we are running a benchmark
256fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    // that does not call FinishedSingleOp().
257fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    if (done_ < 1) done_ = 1;
258fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
259fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    if (bytes_ > 0) {
260fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      char rate[100];
261fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      snprintf(rate, sizeof(rate), "%6.1f MB/s",
262fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com               (bytes_ / 1048576.0) / (finish - start_));
263fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      if (!message_.empty()) {
264fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        message_  = std::string(rate) + " " + message_;
265fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      } else {
266fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        message_ = rate;
267fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      }
268fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    }
269fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
270fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    fprintf(stdout, "%-12s : %11.3f micros/op;%s%s\n",
271fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com            name.ToString().c_str(),
272fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com            (finish - start_) * 1e6 / done_,
273fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com            (message_.empty() ? "" : " "),
274fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com            message_.c_str());
275fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    if (FLAGS_histogram) {
276fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      fprintf(stdout, "Microseconds per op:\n%s\n", hist_.ToString().c_str());
277fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    }
278fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    fflush(stdout);
279fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  }
280fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
281fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com public:
282fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  enum Order {
283fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    SEQUENTIAL,
284fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    RANDOM
285fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  };
286fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  enum DBState {
287fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    FRESH,
288fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    EXISTING
289fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  };
290fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
291fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  Benchmark()
292fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  : db_(NULL),
293fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    num_(FLAGS_num),
294fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    reads_(FLAGS_reads < 0 ? FLAGS_num : FLAGS_reads),
295fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    bytes_(0),
296fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    rand_(301) {
297fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    std::vector<std::string> files;
298158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com    std::string test_dir;
299158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com    Env::Default()->GetTestDirectory(&test_dir);
300158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com    Env::Default()->GetChildren(test_dir.c_str(), &files);
301fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    if (!FLAGS_use_existing_db) {
302fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      for (int i = 0; i < files.size(); i++) {
303fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        if (Slice(files[i]).starts_with("dbbench_polyDB")) {
304158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com          std::string file_name(test_dir);
305158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com          file_name += "/";
306158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com          file_name += files[i];
307158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com          Env::Default()->DeleteFile(file_name.c_str());
308fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        }
309fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      }
310fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    }
311fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  }
312fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
313fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  ~Benchmark() {
314fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    if (!db_->close()) {
315fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      fprintf(stderr, "close error: %s\n", db_->error().name());
316fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    }
317fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  }
318fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
319fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  void Run() {
320fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    PrintHeader();
321fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    Open(false);
322fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
323fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    const char* benchmarks = FLAGS_benchmarks;
324fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    while (benchmarks != NULL) {
325fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      const char* sep = strchr(benchmarks, ',');
326fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      Slice name;
327fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      if (sep == NULL) {
328fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        name = benchmarks;
329fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        benchmarks = NULL;
330fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      } else {
331fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        name = Slice(benchmarks, sep - benchmarks);
332fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        benchmarks = sep + 1;
333fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      }
334fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
335fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      Start();
336fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
337fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      bool known = true;
338fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      bool write_sync = false;
339fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      if (name == Slice("fillseq")) {
340fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        Write(write_sync, SEQUENTIAL, FRESH, num_, FLAGS_value_size, 1);
341fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
342fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      } else if (name == Slice("fillrandom")) {
343fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        Write(write_sync, RANDOM, FRESH, num_, FLAGS_value_size, 1);
344fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        DBSynchronize(db_);
345fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      } else if (name == Slice("overwrite")) {
346fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        Write(write_sync, RANDOM, EXISTING, num_, FLAGS_value_size, 1);
347fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        DBSynchronize(db_);
348fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      } else if (name == Slice("fillrandsync")) {
349fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        write_sync = true;
350fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        Write(write_sync, RANDOM, FRESH, num_ / 100, FLAGS_value_size, 1);
351fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        DBSynchronize(db_);
352fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      } else if (name == Slice("fillseqsync")) {
353fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        write_sync = true;
354fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        Write(write_sync, SEQUENTIAL, FRESH, num_ / 100, FLAGS_value_size, 1);
355fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        DBSynchronize(db_);
356fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      } else if (name == Slice("fillrand100K")) {
357fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        Write(write_sync, RANDOM, FRESH, num_ / 1000, 100 * 1000, 1);
358fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        DBSynchronize(db_);
359fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      } else if (name == Slice("fillseq100K")) {
360fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        Write(write_sync, SEQUENTIAL, FRESH, num_ / 1000, 100 * 1000, 1);
361fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        DBSynchronize(db_);
362fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      } else if (name == Slice("readseq")) {
363fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        ReadSequential();
364fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      } else if (name == Slice("readrandom")) {
365fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        ReadRandom();
366fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      } else if (name == Slice("readrand100K")) {
367fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        int n = reads_;
368fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        reads_ /= 1000;
369fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        ReadRandom();
370fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        reads_ = n;
371fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      } else if (name == Slice("readseq100K")) {
372fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        int n = reads_;
373fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        reads_ /= 1000;
374fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        ReadSequential();
375fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        reads_ = n;
376fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      } else {
377fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        known = false;
378fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        if (name != Slice()) {  // No error message for empty name
379fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com          fprintf(stderr, "unknown benchmark '%s'\n", name.ToString().c_str());
380fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        }
381fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      }
382fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      if (known) {
383fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        Stop(name);
384fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      }
385fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    }
386fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  }
387fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
388fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com private:
389fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    void Open(bool sync) {
390fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    assert(db_ == NULL);
391fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
392fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    // Initialize db_
393fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    db_ = new kyotocabinet::TreeDB();
394fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    char file_name[100];
395fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    db_num_++;
396158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com    std::string test_dir;
397158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com    Env::Default()->GetTestDirectory(&test_dir);
398158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com    snprintf(file_name, sizeof(file_name),
399158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com             "%s/dbbench_polyDB-%d.kct",
400158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com             test_dir.c_str(),
401158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com             db_num_);
402fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
403fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    // Create tuning options and open the database
404fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    int open_options = kyotocabinet::PolyDB::OWRITER |
405fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com                       kyotocabinet::PolyDB::OCREATE;
406fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    int tune_options = kyotocabinet::TreeDB::TSMALL |
407fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        kyotocabinet::TreeDB::TLINEAR;
408fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    if (FLAGS_compression) {
409fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      tune_options |= kyotocabinet::TreeDB::TCOMPRESS;
410fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      db_->tune_compressor(&comp_);
411fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    }
412fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    db_->tune_options(tune_options);
413fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    db_->tune_page_cache(FLAGS_cache_size);
414fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    db_->tune_page(FLAGS_page_size);
415fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    db_->tune_map(256LL<<20);
416fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    if (sync) {
417fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      open_options |= kyotocabinet::PolyDB::OAUTOSYNC;
418fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    }
419fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    if (!db_->open(file_name, open_options)) {
420fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      fprintf(stderr, "open error: %s\n", db_->error().name());
421fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    }
422fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  }
423fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
424fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  void Write(bool sync, Order order, DBState state,
425fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com             int num_entries, int value_size, int entries_per_batch) {
426fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    // Create new database if state == FRESH
427fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    if (state == FRESH) {
428fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      if (FLAGS_use_existing_db) {
429fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        message_ = "skipping (--use_existing_db is true)";
430fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        return;
431fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      }
432fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      delete db_;
433fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      db_ = NULL;
434fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      Open(sync);
435fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      Start();  // Do not count time taken to destroy/open
436fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    }
437fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
438fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    if (num_entries != num_) {
439fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      char msg[100];
440fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      snprintf(msg, sizeof(msg), "(%d ops)", num_entries);
441fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      message_ = msg;
442fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    }
443fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
444fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    // Write to database
445fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    for (int i = 0; i < num_entries; i++)
446fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    {
447fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      const int k = (order == SEQUENTIAL) ? i : (rand_.Next() % num_entries);
448fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      char key[100];
449fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      snprintf(key, sizeof(key), "%016d", k);
450fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      bytes_ += value_size + strlen(key);
451fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      std::string cpp_key = key;
452fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      if (!db_->set(cpp_key, gen_.Generate(value_size).ToString())) {
453fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com        fprintf(stderr, "set error: %s\n", db_->error().name());
454fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      }
455fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      FinishedSingleOp();
456fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    }
457fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  }
458fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
459fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  void ReadSequential() {
460fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    kyotocabinet::DB::Cursor* cur = db_->cursor();
461fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    cur->jump();
462fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    std::string ckey, cvalue;
463fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    while (cur->get(&ckey, &cvalue, true)) {
464fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      bytes_ += ckey.size() + cvalue.size();
465fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      FinishedSingleOp();
466fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    }
467fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    delete cur;
468fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  }
469fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
470fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  void ReadRandom() {
471fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    std::string value;
472fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    for (int i = 0; i < reads_; i++) {
473fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      char key[100];
474fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      const int k = rand_.Next() % reads_;
475fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      snprintf(key, sizeof(key), "%016d", k);
476fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      db_->get(key, &value);
477fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      FinishedSingleOp();
478fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    }
479fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  }
480fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com};
481fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
48245b9940be332834440bd5299419f396e38085ebehans@chromium.org}  // namespace leveldb
483fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
484fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.comint main(int argc, char** argv) {
485158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com  std::string default_db_path;
486fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  for (int i = 1; i < argc; i++) {
487fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    double d;
488fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    int n;
489fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    char junk;
490fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    if (leveldb::Slice(argv[i]).starts_with("--benchmarks=")) {
491fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      FLAGS_benchmarks = argv[i] + strlen("--benchmarks=");
492fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    } else if (sscanf(argv[i], "--compression_ratio=%lf%c", &d, &junk) == 1) {
493fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      FLAGS_compression_ratio = d;
494fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    } else if (sscanf(argv[i], "--histogram=%d%c", &n, &junk) == 1 &&
495fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com               (n == 0 || n == 1)) {
496fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      FLAGS_histogram = n;
497fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    } else if (sscanf(argv[i], "--num=%d%c", &n, &junk) == 1) {
498fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      FLAGS_num = n;
499fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    } else if (sscanf(argv[i], "--reads=%d%c", &n, &junk) == 1) {
500fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      FLAGS_reads = n;
501fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    } else if (sscanf(argv[i], "--value_size=%d%c", &n, &junk) == 1) {
502fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      FLAGS_value_size = n;
503fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    } else if (sscanf(argv[i], "--cache_size=%d%c", &n, &junk) == 1) {
504fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      FLAGS_cache_size = n;
505fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    } else if (sscanf(argv[i], "--page_size=%d%c", &n, &junk) == 1) {
506fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      FLAGS_page_size = n;
507fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    } else if (sscanf(argv[i], "--compression=%d%c", &n, &junk) == 1 &&
508fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com               (n == 0 || n == 1)) {
509fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      FLAGS_compression = (n == 1) ? true : false;
510158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com    } else if (strncmp(argv[i], "--db=", 5) == 0) {
511158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com      FLAGS_db = argv[i] + 5;
512fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    } else {
513fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      fprintf(stderr, "Invalid flag '%s'\n", argv[i]);
514fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com      exit(1);
515fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com    }
516fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  }
517fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com
518158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com  // Choose a location for the test database if none given with --db=<path>
519158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com  if (FLAGS_db == NULL) {
520158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com      leveldb::Env::Default()->GetTestDirectory(&default_db_path);
521158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com      default_db_path += "/dbbench";
522158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com      FLAGS_db = default_db_path.c_str();
523158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com  }
524158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com
525fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  leveldb::Benchmark benchmark;
526fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  benchmark.Run();
527fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com  return 0;
528fcd2d5698e5723d926ddb8451830ccaf55126dd5gabor@google.com}
529