1 //  Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
2 //  This source code is licensed under both the GPLv2 (found in the
3 //  COPYING file in the root directory) and Apache 2.0 License
4 //  (found in the LICENSE.Apache file in the root directory).
5 
6 #ifndef GFLAGS
7 #include <cstdio>
main()8 int main() {
9   fprintf(stderr, "Please install gflags to run rocksdb tools\n");
10   return 1;
11 }
12 #else
13 
14 #include "file/writable_file_writer.h"
15 #include "monitoring/histogram.h"
16 #include "rocksdb/env.h"
17 #include "test_util/testharness.h"
18 #include "test_util/testutil.h"
19 #include "util/gflags_compat.h"
20 
21 using GFLAGS_NAMESPACE::ParseCommandLineFlags;
22 using GFLAGS_NAMESPACE::SetUsageMessage;
23 
24 // A simple benchmark to simulate transactional logs
25 
26 DEFINE_int32(num_records, 6000, "Number of records.");
27 DEFINE_int32(record_size, 249, "Size of each record.");
28 DEFINE_int32(record_interval, 10000, "Interval between records (microSec)");
29 DEFINE_int32(bytes_per_sync, 0, "bytes_per_sync parameter in EnvOptions");
30 DEFINE_bool(enable_sync, false, "sync after each write.");
31 
32 namespace ROCKSDB_NAMESPACE {
RunBenchmark()33 void RunBenchmark() {
34   std::string file_name = test::PerThreadDBPath("log_write_benchmark.log");
35   DBOptions options;
36   Env* env = Env::Default();
37   EnvOptions env_options = env->OptimizeForLogWrite(EnvOptions(), options);
38   env_options.bytes_per_sync = FLAGS_bytes_per_sync;
39   std::unique_ptr<WritableFile> file;
40   env->NewWritableFile(file_name, &file, env_options);
41   std::unique_ptr<WritableFileWriter> writer;
42   writer.reset(new WritableFileWriter(std::move(file), file_name, env_options,
43                                       env, nullptr /* stats */,
44                                       options.listeners));
45 
46   std::string record;
47   record.assign(FLAGS_record_size, 'X');
48 
49   HistogramImpl hist;
50 
51   uint64_t start_time = env->NowMicros();
52   for (int i = 0; i < FLAGS_num_records; i++) {
53     uint64_t start_nanos = env->NowNanos();
54     writer->Append(record);
55     writer->Flush();
56     if (FLAGS_enable_sync) {
57       writer->Sync(false);
58     }
59     hist.Add(env->NowNanos() - start_nanos);
60 
61     if (i % 1000 == 1) {
62       fprintf(stderr, "Wrote %d records...\n", i);
63     }
64 
65     int time_to_sleep =
66         (i + 1) * FLAGS_record_interval - (env->NowMicros() - start_time);
67     if (time_to_sleep > 0) {
68       env->SleepForMicroseconds(time_to_sleep);
69     }
70   }
71 
72   fprintf(stderr, "Distribution of latency of append+flush: \n%s",
73           hist.ToString().c_str());
74 }
75 }  // namespace ROCKSDB_NAMESPACE
76 
main(int argc,char ** argv)77 int main(int argc, char** argv) {
78   SetUsageMessage(std::string("\nUSAGE:\n") + std::string(argv[0]) +
79                   " [OPTIONS]...");
80   ParseCommandLineFlags(&argc, &argv, true);
81 
82   ROCKSDB_NAMESPACE::RunBenchmark();
83   return 0;
84 }
85 
86 #endif  // GFLAGS
87