leveldb
Classes | Public Member Functions | Private Member Functions | Static Private Member Functions | Private Attributes | List of all members
leveldb::Benchmark Class Reference
Collaboration diagram for leveldb::Benchmark:
Collaboration graph
[legend]

Classes

struct  ThreadArg
 

Public Member Functions

 Benchmark ()
 
 ~Benchmark ()
 
void Run ()
 

Private Member Functions

void PrintHeader ()
 
void PrintWarnings ()
 
void PrintEnvironment ()
 
void RunBenchmark (int n, Slice name, void(Benchmark::*method)(ThreadState *))
 
void Crc32c (ThreadState *thread)
 
void AcquireLoad (ThreadState *thread)
 
void SnappyCompress (ThreadState *thread)
 
void SnappyUncompress (ThreadState *thread)
 
void Open ()
 
void OpenBench (ThreadState *thread)
 
void WriteSeq (ThreadState *thread)
 
void WriteRandom (ThreadState *thread)
 
void DoWrite (ThreadState *thread, bool seq)
 
void ReadSequential (ThreadState *thread)
 
void ReadReverse (ThreadState *thread)
 
void ReadRandom (ThreadState *thread)
 
void ReadMissing (ThreadState *thread)
 
void ReadHot (ThreadState *thread)
 
void SeekRandom (ThreadState *thread)
 
void DoDelete (ThreadState *thread, bool seq)
 
void DeleteSeq (ThreadState *thread)
 
void DeleteRandom (ThreadState *thread)
 
void ReadWhileWriting (ThreadState *thread)
 
void Compact (ThreadState *thread)
 
void PrintStats (const char *key)
 
void HeapProfile ()
 

Static Private Member Functions

static void ThreadBody (void *v)
 
static void WriteToFile (void *arg, const char *buf, int n)
 

Private Attributes

Cachecache_
 
const FilterPolicyfilter_policy_
 
DBdb_
 
int num_
 
int value_size_
 
int entries_per_batch_
 
WriteOptions write_options_
 
int reads_
 
int heap_counter_
 

Detailed Description

Definition at line 317 of file db_bench.cc.

Constructor & Destructor Documentation

§ Benchmark()

leveldb::Benchmark::Benchmark ( )
inline

Definition at line 404 of file db_bench.cc.

408  : NULL),
409  db_(NULL),
410  num_(FLAGS_num),
414  heap_counter_(0) {
415  std::vector<std::string> files;
416  g_env->GetChildren(FLAGS_db, &files);
417  for (size_t i = 0; i < files.size(); i++) {
418  if (Slice(files[i]).starts_with("heap-")) {
419  g_env->DeleteFile(std::string(FLAGS_db) + "/" + files[i]);
420  }
421  }
422  if (!FLAGS_use_existing_db) {
423  DestroyDB(FLAGS_db, Options());
424  }
425  }
static int FLAGS_value_size
Definition: db_bench.cc:74
static const char * FLAGS_db
Definition: db_bench.cc:115
static int FLAGS_reads
Definition: db_bench.cc:68
const FilterPolicy * filter_policy_
Definition: db_bench.cc:320
Status DestroyDB(const std::string &dbname, const Options &options)
Definition: db_impl.cc:1537
static int FLAGS_cache_size
Definition: db_bench.cc:97
const FilterPolicy * NewBloomFilterPolicy(int bits_per_key)
Definition: bloom.cc:91
static int FLAGS_num
Definition: db_bench.cc:65
Cache * NewLRUCache(size_t capacity)
Definition: cache.cc:401
static bool FLAGS_use_existing_db
Definition: db_bench.cc:109
virtual Status DeleteFile(const std::string &fname)=0
static int FLAGS_bloom_bits
Definition: db_bench.cc:104
virtual Status GetChildren(const std::string &dir, std::vector< std::string > *result)=0
Here is the call graph for this function:

§ ~Benchmark()

leveldb::Benchmark::~Benchmark ( )
inline

Definition at line 427 of file db_bench.cc.

427  {
428  delete db_;
429  delete cache_;
430  delete filter_policy_;
431  }
const FilterPolicy * filter_policy_
Definition: db_bench.cc:320

Member Function Documentation

§ AcquireLoad()

void leveldb::Benchmark::AcquireLoad ( ThreadState *  thread)
inlineprivate

Definition at line 646 of file db_bench.cc.

646  {
647  int dummy;
648  port::AtomicPointer ap(&dummy);
649  int count = 0;
650  void *ptr = NULL;
651  thread->stats.AddMessage("(each op is 1000 loads)");
652  while (count < 100000) {
653  for (int i = 0; i < 1000; i++) {
654  ptr = ap.Acquire_Load();
655  }
656  count++;
657  thread->stats.FinishedSingleOp();
658  }
659  if (ptr == NULL) exit(1); // Disable unused variable warning.
660  }
Here is the caller graph for this function:

§ Compact()

void leveldb::Benchmark::Compact ( ThreadState *  thread)
inlineprivate

Definition at line 920 of file db_bench.cc.

920  {
921  db_->CompactRange(NULL, NULL);
922  }
virtual void CompactRange(const Slice *begin, const Slice *end)=0
Here is the call graph for this function:
Here is the caller graph for this function:

§ Crc32c()

void leveldb::Benchmark::Crc32c ( ThreadState *  thread)
inlineprivate

Definition at line 627 of file db_bench.cc.

627  {
628  // Checksum about 500MB of data total
629  const int size = 4096;
630  const char* label = "(4K per op)";
631  std::string data(size, 'x');
632  int64_t bytes = 0;
633  uint32_t crc = 0;
634  while (bytes < 500 * 1048576) {
635  crc = crc32c::Value(data.data(), size);
636  thread->stats.FinishedSingleOp();
637  bytes += size;
638  }
639  // Print so result is not dead
640  fprintf(stderr, "... crc=0x%x\r", static_cast<unsigned int>(crc));
641 
642  thread->stats.AddBytes(bytes);
643  thread->stats.AddMessage(label);
644  }
uint32_t Value(const char *data, size_t n)
Definition: crc32c.h:20
Here is the call graph for this function:
Here is the caller graph for this function:

§ DeleteRandom()

void leveldb::Benchmark::DeleteRandom ( ThreadState *  thread)
inlineprivate

Definition at line 886 of file db_bench.cc.

886  {
887  DoDelete(thread, false);
888  }
void DoDelete(ThreadState *thread, bool seq)
Definition: db_bench.cc:861
Here is the caller graph for this function:

§ DeleteSeq()

void leveldb::Benchmark::DeleteSeq ( ThreadState *  thread)
inlineprivate

Definition at line 882 of file db_bench.cc.

882  {
883  DoDelete(thread, true);
884  }
void DoDelete(ThreadState *thread, bool seq)
Definition: db_bench.cc:861
Here is the caller graph for this function:

§ DoDelete()

void leveldb::Benchmark::DoDelete ( ThreadState *  thread,
bool  seq 
)
inlineprivate

Definition at line 861 of file db_bench.cc.

861  {
862  RandomGenerator gen;
863  WriteBatch batch;
864  Status s;
865  for (int i = 0; i < num_; i += entries_per_batch_) {
866  batch.Clear();
867  for (int j = 0; j < entries_per_batch_; j++) {
868  const int k = seq ? i+j : (thread->rand.Next() % FLAGS_num);
869  char key[100];
870  snprintf(key, sizeof(key), "%016d", k);
871  batch.Delete(key);
872  thread->stats.FinishedSingleOp();
873  }
874  s = db_->Write(write_options_, &batch);
875  if (!s.ok()) {
876  fprintf(stderr, "del error: %s\n", s.ToString().c_str());
877  exit(1);
878  }
879  }
880  }
WriteOptions write_options_
Definition: db_bench.cc:325
virtual Status Write(const WriteOptions &options, WriteBatch *updates)=0
static int FLAGS_num
Definition: db_bench.cc:65
Here is the call graph for this function:

§ DoWrite()

void leveldb::Benchmark::DoWrite ( ThreadState *  thread,
bool  seq 
)
inlineprivate

Definition at line 744 of file db_bench.cc.

744  {
745  if (num_ != FLAGS_num) {
746  char msg[100];
747  snprintf(msg, sizeof(msg), "(%d ops)", num_);
748  thread->stats.AddMessage(msg);
749  }
750 
751  RandomGenerator gen;
752  WriteBatch batch;
753  Status s;
754  int64_t bytes = 0;
755  for (int i = 0; i < num_; i += entries_per_batch_) {
756  batch.Clear();
757  for (int j = 0; j < entries_per_batch_; j++) {
758  const int k = seq ? i+j : (thread->rand.Next() % FLAGS_num);
759  char key[100];
760  snprintf(key, sizeof(key), "%016d", k);
761  batch.Put(key, gen.Generate(value_size_));
762  bytes += value_size_ + strlen(key);
763  thread->stats.FinishedSingleOp();
764  }
765  s = db_->Write(write_options_, &batch);
766  if (!s.ok()) {
767  fprintf(stderr, "put error: %s\n", s.ToString().c_str());
768  exit(1);
769  }
770  }
771  thread->stats.AddBytes(bytes);
772  }
WriteOptions write_options_
Definition: db_bench.cc:325
virtual Status Write(const WriteOptions &options, WriteBatch *updates)=0
static int FLAGS_num
Definition: db_bench.cc:65
Here is the call graph for this function:

§ HeapProfile()

void leveldb::Benchmark::HeapProfile ( )
inlineprivate

Definition at line 936 of file db_bench.cc.

936  {
937  char fname[100];
938  snprintf(fname, sizeof(fname), "%s/heap-%04d", FLAGS_db, ++heap_counter_);
939  WritableFile* file;
940  Status s = g_env->NewWritableFile(fname, &file);
941  if (!s.ok()) {
942  fprintf(stderr, "%s\n", s.ToString().c_str());
943  return;
944  }
945  bool ok = port::GetHeapProfile(WriteToFile, file);
946  delete file;
947  if (!ok) {
948  fprintf(stderr, "heap profiling not supported\n");
949  g_env->DeleteFile(fname);
950  }
951  }
static const char * FLAGS_db
Definition: db_bench.cc:115
virtual Status NewWritableFile(const std::string &fname, WritableFile **result)=0
static void WriteToFile(void *arg, const char *buf, int n)
Definition: db_bench.cc:932
virtual Status DeleteFile(const std::string &fname)=0
Here is the call graph for this function:

§ Open()

void leveldb::Benchmark::Open ( )
inlineprivate

Definition at line 709 of file db_bench.cc.

709  {
710  assert(db_ == NULL);
711  Options options;
712  options.env = g_env;
713  options.create_if_missing = !FLAGS_use_existing_db;
714  options.block_cache = cache_;
715  options.write_buffer_size = FLAGS_write_buffer_size;
716  options.max_file_size = FLAGS_max_file_size;
717  options.block_size = FLAGS_block_size;
718  options.max_open_files = FLAGS_open_files;
719  options.filter_policy = filter_policy_;
720  options.reuse_logs = FLAGS_reuse_logs;
721  Status s = DB::Open(options, FLAGS_db, &db_);
722  if (!s.ok()) {
723  fprintf(stderr, "open error: %s\n", s.ToString().c_str());
724  exit(1);
725  }
726  }
static int FLAGS_open_files
Definition: db_bench.cc:100
static const char * FLAGS_db
Definition: db_bench.cc:115
const FilterPolicy * filter_policy_
Definition: db_bench.cc:320
static int FLAGS_max_file_size
Definition: db_bench.cc:89
static Status Open(const Options &options, const std::string &name, DB **dbptr)
Definition: db_impl.cc:1490
static int FLAGS_write_buffer_size
Definition: db_bench.cc:85
static int FLAGS_block_size
Definition: db_bench.cc:93
static bool FLAGS_reuse_logs
Definition: db_bench.cc:112
static bool FLAGS_use_existing_db
Definition: db_bench.cc:109
Here is the call graph for this function:

§ OpenBench()

void leveldb::Benchmark::OpenBench ( ThreadState *  thread)
inlineprivate

Definition at line 728 of file db_bench.cc.

728  {
729  for (int i = 0; i < num_; i++) {
730  delete db_;
731  Open();
732  thread->stats.FinishedSingleOp();
733  }
734  }
Here is the caller graph for this function:

§ PrintEnvironment()

void leveldb::Benchmark::PrintEnvironment ( )
inlineprivate

Definition at line 368 of file db_bench.cc.

368  {
369  fprintf(stderr, "LevelDB: version %d.%d\n",
371 
372 #if defined(__linux)
373  time_t now = time(NULL);
374  fprintf(stderr, "Date: %s", ctime(&now)); // ctime() adds newline
375 
376  FILE* cpuinfo = fopen("/proc/cpuinfo", "r");
377  if (cpuinfo != NULL) {
378  char line[1000];
379  int num_cpus = 0;
380  std::string cpu_type;
381  std::string cache_size;
382  while (fgets(line, sizeof(line), cpuinfo) != NULL) {
383  const char* sep = strchr(line, ':');
384  if (sep == NULL) {
385  continue;
386  }
387  Slice key = TrimSpace(Slice(line, sep - 1 - line));
388  Slice val = TrimSpace(Slice(sep + 1));
389  if (key == "model name") {
390  ++num_cpus;
391  cpu_type = val.ToString();
392  } else if (key == "cache size") {
393  cache_size = val.ToString();
394  }
395  }
396  fclose(cpuinfo);
397  fprintf(stderr, "CPU: %d * %s\n", num_cpus, cpu_type.c_str());
398  fprintf(stderr, "CPUCache: %s\n", cache_size.c_str());
399  }
400 #endif
401  }
static const int kMinorVersion
Definition: db.h:17
static const int kMajorVersion
Definition: db.h:16
Here is the call graph for this function:

§ PrintHeader()

void leveldb::Benchmark::PrintHeader ( )
inlineprivate

Definition at line 329 of file db_bench.cc.

329  {
330  const int kKeySize = 16;
332  fprintf(stdout, "Keys: %d bytes each\n", kKeySize);
333  fprintf(stdout, "Values: %d bytes each (%d bytes after compression)\n",
335  static_cast<int>(FLAGS_value_size * FLAGS_compression_ratio + 0.5));
336  fprintf(stdout, "Entries: %d\n", num_);
337  fprintf(stdout, "RawSize: %.1f MB (estimated)\n",
338  ((static_cast<int64_t>(kKeySize + FLAGS_value_size) * num_)
339  / 1048576.0));
340  fprintf(stdout, "FileSize: %.1f MB (estimated)\n",
341  (((kKeySize + FLAGS_value_size * FLAGS_compression_ratio) * num_)
342  / 1048576.0));
343  PrintWarnings();
344  fprintf(stdout, "------------------------------------------------\n");
345  }
void PrintEnvironment()
Definition: db_bench.cc:368
static int FLAGS_value_size
Definition: db_bench.cc:74
void PrintWarnings()
Definition: db_bench.cc:347
static double FLAGS_compression_ratio
Definition: db_bench.cc:78

§ PrintStats()

void leveldb::Benchmark::PrintStats ( const char *  key)
inlineprivate

Definition at line 924 of file db_bench.cc.

924  {
925  std::string stats;
926  if (!db_->GetProperty(key, &stats)) {
927  stats = "(failed)";
928  }
929  fprintf(stdout, "\n%s\n", stats.c_str());
930  }
virtual bool GetProperty(const Slice &property, std::string *value)=0
Here is the call graph for this function:

§ PrintWarnings()

void leveldb::Benchmark::PrintWarnings ( )
inlineprivate

Definition at line 347 of file db_bench.cc.

347  {
348 #if defined(__GNUC__) && !defined(__OPTIMIZE__)
349  fprintf(stdout,
350  "WARNING: Optimization is disabled: benchmarks unnecessarily slow\n"
351  );
352 #endif
353 #ifndef NDEBUG
354  fprintf(stdout,
355  "WARNING: Assertions are enabled; benchmarks unnecessarily slow\n");
356 #endif
357 
358  // See if snappy is working by attempting to compress a compressible string
359  const char text[] = "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy";
360  std::string compressed;
361  if (!port::Snappy_Compress(text, sizeof(text), &compressed)) {
362  fprintf(stdout, "WARNING: Snappy compression is not enabled\n");
363  } else if (compressed.size() >= sizeof(text)) {
364  fprintf(stdout, "WARNING: Snappy compression is not effective\n");
365  }
366  }

§ ReadHot()

void leveldb::Benchmark::ReadHot ( ThreadState *  thread)
inlineprivate

Definition at line 830 of file db_bench.cc.

830  {
831  ReadOptions options;
832  std::string value;
833  const int range = (FLAGS_num + 99) / 100;
834  for (int i = 0; i < reads_; i++) {
835  char key[100];
836  const int k = thread->rand.Next() % range;
837  snprintf(key, sizeof(key), "%016d", k);
838  db_->Get(options, key, &value);
839  thread->stats.FinishedSingleOp();
840  }
841  }
virtual Status Get(const ReadOptions &options, const Slice &key, std::string *value)=0
static int FLAGS_num
Definition: db_bench.cc:65
Here is the call graph for this function:
Here is the caller graph for this function:

§ ReadMissing()

void leveldb::Benchmark::ReadMissing ( ThreadState *  thread)
inlineprivate

Definition at line 818 of file db_bench.cc.

818  {
819  ReadOptions options;
820  std::string value;
821  for (int i = 0; i < reads_; i++) {
822  char key[100];
823  const int k = thread->rand.Next() % FLAGS_num;
824  snprintf(key, sizeof(key), "%016d.", k);
825  db_->Get(options, key, &value);
826  thread->stats.FinishedSingleOp();
827  }
828  }
virtual Status Get(const ReadOptions &options, const Slice &key, std::string *value)=0
static int FLAGS_num
Definition: db_bench.cc:65
Here is the call graph for this function:
Here is the caller graph for this function:

§ ReadRandom()

void leveldb::Benchmark::ReadRandom ( ThreadState *  thread)
inlineprivate

Definition at line 800 of file db_bench.cc.

800  {
801  ReadOptions options;
802  std::string value;
803  int found = 0;
804  for (int i = 0; i < reads_; i++) {
805  char key[100];
806  const int k = thread->rand.Next() % FLAGS_num;
807  snprintf(key, sizeof(key), "%016d", k);
808  if (db_->Get(options, key, &value).ok()) {
809  found++;
810  }
811  thread->stats.FinishedSingleOp();
812  }
813  char msg[100];
814  snprintf(msg, sizeof(msg), "(%d of %d found)", found, num_);
815  thread->stats.AddMessage(msg);
816  }
virtual Status Get(const ReadOptions &options, const Slice &key, std::string *value)=0
static int FLAGS_num
Definition: db_bench.cc:65
bool ok() const
Definition: status.h:52
Here is the call graph for this function:
Here is the caller graph for this function:

§ ReadReverse()

void leveldb::Benchmark::ReadReverse ( ThreadState *  thread)
inlineprivate

Definition at line 787 of file db_bench.cc.

787  {
788  Iterator* iter = db_->NewIterator(ReadOptions());
789  int i = 0;
790  int64_t bytes = 0;
791  for (iter->SeekToLast(); i < reads_ && iter->Valid(); iter->Prev()) {
792  bytes += iter->key().size() + iter->value().size();
793  thread->stats.FinishedSingleOp();
794  ++i;
795  }
796  delete iter;
797  thread->stats.AddBytes(bytes);
798  }
virtual Slice key() const =0
virtual Iterator * NewIterator(const ReadOptions &options)=0
size_t size() const
Definition: slice.h:43
Here is the call graph for this function:
Here is the caller graph for this function:

§ ReadSequential()

void leveldb::Benchmark::ReadSequential ( ThreadState *  thread)
inlineprivate

Definition at line 774 of file db_bench.cc.

774  {
775  Iterator* iter = db_->NewIterator(ReadOptions());
776  int i = 0;
777  int64_t bytes = 0;
778  for (iter->SeekToFirst(); i < reads_ && iter->Valid(); iter->Next()) {
779  bytes += iter->key().size() + iter->value().size();
780  thread->stats.FinishedSingleOp();
781  ++i;
782  }
783  delete iter;
784  thread->stats.AddBytes(bytes);
785  }
virtual Slice key() const =0
virtual Iterator * NewIterator(const ReadOptions &options)=0
size_t size() const
Definition: slice.h:43
Here is the call graph for this function:
Here is the caller graph for this function:

§ ReadWhileWriting()

void leveldb::Benchmark::ReadWhileWriting ( ThreadState *  thread)
inlineprivate

Definition at line 890 of file db_bench.cc.

890  {
891  if (thread->tid > 0) {
892  ReadRandom(thread);
893  } else {
894  // Special thread that keeps writing until other threads are done.
895  RandomGenerator gen;
896  while (true) {
897  {
898  MutexLock l(&thread->shared->mu);
899  if (thread->shared->num_done + 1 >= thread->shared->num_initialized) {
900  // Other threads have finished
901  break;
902  }
903  }
904 
905  const int k = thread->rand.Next() % FLAGS_num;
906  char key[100];
907  snprintf(key, sizeof(key), "%016d", k);
908  Status s = db_->Put(write_options_, key, gen.Generate(value_size_));
909  if (!s.ok()) {
910  fprintf(stderr, "put error: %s\n", s.ToString().c_str());
911  exit(1);
912  }
913  }
914 
915  // Do not count any of the preceding work/delay in stats.
916  thread->stats.Start();
917  }
918  }
void ReadRandom(ThreadState *thread)
Definition: db_bench.cc:800
virtual Status Put(const WriteOptions &options, const Slice &key, const Slice &value)=0
Definition: db_impl.cc:1476
WriteOptions write_options_
Definition: db_bench.cc:325
static int FLAGS_num
Definition: db_bench.cc:65
Here is the call graph for this function:
Here is the caller graph for this function:

§ Run()

void leveldb::Benchmark::Run ( )
inline

Definition at line 433 of file db_bench.cc.

433  {
434  PrintHeader();
435  Open();
436 
437  const char* benchmarks = FLAGS_benchmarks;
438  while (benchmarks != NULL) {
439  const char* sep = strchr(benchmarks, ',');
440  Slice name;
441  if (sep == NULL) {
442  name = benchmarks;
443  benchmarks = NULL;
444  } else {
445  name = Slice(benchmarks, sep - benchmarks);
446  benchmarks = sep + 1;
447  }
448 
449  // Reset parameters that may be overridden below
450  num_ = FLAGS_num;
453  entries_per_batch_ = 1;
454  write_options_ = WriteOptions();
455 
456  void (Benchmark::*method)(ThreadState*) = NULL;
457  bool fresh_db = false;
458  int num_threads = FLAGS_threads;
459 
460  if (name == Slice("open")) {
461  method = &Benchmark::OpenBench;
462  num_ /= 10000;
463  if (num_ < 1) num_ = 1;
464  } else if (name == Slice("fillseq")) {
465  fresh_db = true;
466  method = &Benchmark::WriteSeq;
467  } else if (name == Slice("fillbatch")) {
468  fresh_db = true;
469  entries_per_batch_ = 1000;
470  method = &Benchmark::WriteSeq;
471  } else if (name == Slice("fillrandom")) {
472  fresh_db = true;
473  method = &Benchmark::WriteRandom;
474  } else if (name == Slice("overwrite")) {
475  fresh_db = false;
476  method = &Benchmark::WriteRandom;
477  } else if (name == Slice("fillsync")) {
478  fresh_db = true;
479  num_ /= 1000;
480  write_options_.sync = true;
481  method = &Benchmark::WriteRandom;
482  } else if (name == Slice("fill100K")) {
483  fresh_db = true;
484  num_ /= 1000;
485  value_size_ = 100 * 1000;
486  method = &Benchmark::WriteRandom;
487  } else if (name == Slice("readseq")) {
488  method = &Benchmark::ReadSequential;
489  } else if (name == Slice("readreverse")) {
490  method = &Benchmark::ReadReverse;
491  } else if (name == Slice("readrandom")) {
492  method = &Benchmark::ReadRandom;
493  } else if (name == Slice("readmissing")) {
494  method = &Benchmark::ReadMissing;
495  } else if (name == Slice("seekrandom")) {
496  method = &Benchmark::SeekRandom;
497  } else if (name == Slice("readhot")) {
498  method = &Benchmark::ReadHot;
499  } else if (name == Slice("readrandomsmall")) {
500  reads_ /= 1000;
501  method = &Benchmark::ReadRandom;
502  } else if (name == Slice("deleteseq")) {
503  method = &Benchmark::DeleteSeq;
504  } else if (name == Slice("deleterandom")) {
505  method = &Benchmark::DeleteRandom;
506  } else if (name == Slice("readwhilewriting")) {
507  num_threads++; // Add extra thread for writing
508  method = &Benchmark::ReadWhileWriting;
509  } else if (name == Slice("compact")) {
510  method = &Benchmark::Compact;
511  } else if (name == Slice("crc32c")) {
512  method = &Benchmark::Crc32c;
513  } else if (name == Slice("acquireload")) {
514  method = &Benchmark::AcquireLoad;
515  } else if (name == Slice("snappycomp")) {
516  method = &Benchmark::SnappyCompress;
517  } else if (name == Slice("snappyuncomp")) {
518  method = &Benchmark::SnappyUncompress;
519  } else if (name == Slice("heapprofile")) {
520  HeapProfile();
521  } else if (name == Slice("stats")) {
522  PrintStats("leveldb.stats");
523  } else if (name == Slice("sstables")) {
524  PrintStats("leveldb.sstables");
525  } else {
526  if (name != Slice()) { // No error message for empty name
527  fprintf(stderr, "unknown benchmark '%s'\n", name.ToString().c_str());
528  }
529  }
530 
531  if (fresh_db) {
532  if (FLAGS_use_existing_db) {
533  fprintf(stdout, "%-12s : skipped (--use_existing_db is true)\n",
534  name.ToString().c_str());
535  method = NULL;
536  } else {
537  delete db_;
538  db_ = NULL;
539  DestroyDB(FLAGS_db, Options());
540  Open();
541  }
542  }
543 
544  if (method != NULL) {
545  RunBenchmark(num_threads, name, method);
546  }
547  }
548  }
static int FLAGS_threads
Definition: db_bench.cc:71
void ReadReverse(ThreadState *thread)
Definition: db_bench.cc:787
void SnappyUncompress(ThreadState *thread)
Definition: db_bench.cc:687
void PrintStats(const char *key)
Definition: db_bench.cc:924
static int FLAGS_value_size
Definition: db_bench.cc:74
static const char * FLAGS_db
Definition: db_bench.cc:115
void ReadRandom(ThreadState *thread)
Definition: db_bench.cc:800
static int FLAGS_reads
Definition: db_bench.cc:68
Status DestroyDB(const std::string &dbname, const Options &options)
Definition: db_impl.cc:1537
void ReadMissing(ThreadState *thread)
Definition: db_bench.cc:818
static const char * FLAGS_benchmarks
Definition: db_bench.cc:44
void SnappyCompress(ThreadState *thread)
Definition: db_bench.cc:662
void WriteRandom(ThreadState *thread)
Definition: db_bench.cc:740
WriteOptions write_options_
Definition: db_bench.cc:325
void DeleteRandom(ThreadState *thread)
Definition: db_bench.cc:886
void AcquireLoad(ThreadState *thread)
Definition: db_bench.cc:646
void Compact(ThreadState *thread)
Definition: db_bench.cc:920
void OpenBench(ThreadState *thread)
Definition: db_bench.cc:728
void ReadSequential(ThreadState *thread)
Definition: db_bench.cc:774
static int FLAGS_num
Definition: db_bench.cc:65
void ReadHot(ThreadState *thread)
Definition: db_bench.cc:830
void RunBenchmark(int n, Slice name, void(Benchmark::*method)(ThreadState *))
Definition: db_bench.cc:586
void SeekRandom(ThreadState *thread)
Definition: db_bench.cc:843
static bool FLAGS_use_existing_db
Definition: db_bench.cc:109
void ReadWhileWriting(ThreadState *thread)
Definition: db_bench.cc:890
void Crc32c(ThreadState *thread)
Definition: db_bench.cc:627
void WriteSeq(ThreadState *thread)
Definition: db_bench.cc:736
void DeleteSeq(ThreadState *thread)
Definition: db_bench.cc:882
Here is the call graph for this function:
Here is the caller graph for this function:

§ RunBenchmark()

void leveldb::Benchmark::RunBenchmark ( int  n,
Slice  name,
void(Benchmark::*)(ThreadState *)  method 
)
inlineprivate

Definition at line 586 of file db_bench.cc.

587  {
588  SharedState shared;
589  shared.total = n;
590  shared.num_initialized = 0;
591  shared.num_done = 0;
592  shared.start = false;
593 
594  ThreadArg* arg = new ThreadArg[n];
595  for (int i = 0; i < n; i++) {
596  arg[i].bm = this;
597  arg[i].method = method;
598  arg[i].shared = &shared;
599  arg[i].thread = new ThreadState(i);
600  arg[i].thread->shared = &shared;
601  g_env->StartThread(ThreadBody, &arg[i]);
602  }
603 
604  shared.mu.Lock();
605  while (shared.num_initialized < n) {
606  shared.cv.Wait();
607  }
608 
609  shared.start = true;
610  shared.cv.SignalAll();
611  while (shared.num_done < n) {
612  shared.cv.Wait();
613  }
614  shared.mu.Unlock();
615 
616  for (int i = 1; i < n; i++) {
617  arg[0].thread->stats.Merge(arg[i].thread->stats);
618  }
619  arg[0].thread->stats.Report(name);
620 
621  for (int i = 0; i < n; i++) {
622  delete arg[i].thread;
623  }
624  delete[] arg;
625  }
static void ThreadBody(void *v)
Definition: db_bench.cc:558
virtual void StartThread(void(*function)(void *arg), void *arg)=0
Here is the call graph for this function:

§ SeekRandom()

void leveldb::Benchmark::SeekRandom ( ThreadState *  thread)
inlineprivate

Definition at line 843 of file db_bench.cc.

843  {
844  ReadOptions options;
845  int found = 0;
846  for (int i = 0; i < reads_; i++) {
847  Iterator* iter = db_->NewIterator(options);
848  char key[100];
849  const int k = thread->rand.Next() % FLAGS_num;
850  snprintf(key, sizeof(key), "%016d", k);
851  iter->Seek(key);
852  if (iter->Valid() && iter->key() == key) found++;
853  delete iter;
854  thread->stats.FinishedSingleOp();
855  }
856  char msg[100];
857  snprintf(msg, sizeof(msg), "(%d of %d found)", found, num_);
858  thread->stats.AddMessage(msg);
859  }
virtual void Next()=0
static int FLAGS_num
Definition: db_bench.cc:65
virtual Iterator * NewIterator(const ReadOptions &options)=0
Here is the call graph for this function:
Here is the caller graph for this function:

§ SnappyCompress()

void leveldb::Benchmark::SnappyCompress ( ThreadState *  thread)
inlineprivate

Definition at line 662 of file db_bench.cc.

662  {
663  RandomGenerator gen;
664  Slice input = gen.Generate(Options().block_size);
665  int64_t bytes = 0;
666  int64_t produced = 0;
667  bool ok = true;
668  std::string compressed;
669  while (ok && bytes < 1024 * 1048576) { // Compress 1G
670  ok = port::Snappy_Compress(input.data(), input.size(), &compressed);
671  produced += compressed.size();
672  bytes += input.size();
673  thread->stats.FinishedSingleOp();
674  }
675 
676  if (!ok) {
677  thread->stats.AddMessage("(snappy failure)");
678  } else {
679  char buf[100];
680  snprintf(buf, sizeof(buf), "(output: %.1f%%)",
681  (produced * 100.0) / bytes);
682  thread->stats.AddMessage(buf);
683  thread->stats.AddBytes(bytes);
684  }
685  }
Here is the call graph for this function:
Here is the caller graph for this function:

§ SnappyUncompress()

void leveldb::Benchmark::SnappyUncompress ( ThreadState *  thread)
inlineprivate

Definition at line 687 of file db_bench.cc.

687  {
688  RandomGenerator gen;
689  Slice input = gen.Generate(Options().block_size);
690  std::string compressed;
691  bool ok = port::Snappy_Compress(input.data(), input.size(), &compressed);
692  int64_t bytes = 0;
693  char* uncompressed = new char[input.size()];
694  while (ok && bytes < 1024 * 1048576) { // Compress 1G
695  ok = port::Snappy_Uncompress(compressed.data(), compressed.size(),
696  uncompressed);
697  bytes += input.size();
698  thread->stats.FinishedSingleOp();
699  }
700  delete[] uncompressed;
701 
702  if (!ok) {
703  thread->stats.AddMessage("(snappy failure)");
704  } else {
705  thread->stats.AddBytes(bytes);
706  }
707  }
Here is the call graph for this function:
Here is the caller graph for this function:

§ ThreadBody()

static void leveldb::Benchmark::ThreadBody ( void *  v)
inlinestaticprivate

Definition at line 558 of file db_bench.cc.

558  {
559  ThreadArg* arg = reinterpret_cast<ThreadArg*>(v);
560  SharedState* shared = arg->shared;
561  ThreadState* thread = arg->thread;
562  {
563  MutexLock l(&shared->mu);
564  shared->num_initialized++;
565  if (shared->num_initialized >= shared->total) {
566  shared->cv.SignalAll();
567  }
568  while (!shared->start) {
569  shared->cv.Wait();
570  }
571  }
572 
573  thread->stats.Start();
574  (arg->bm->*(arg->method))(thread);
575  thread->stats.Stop();
576 
577  {
578  MutexLock l(&shared->mu);
579  shared->num_done++;
580  if (shared->num_done >= shared->total) {
581  shared->cv.SignalAll();
582  }
583  }
584  }

§ WriteRandom()

void leveldb::Benchmark::WriteRandom ( ThreadState *  thread)
inlineprivate

Definition at line 740 of file db_bench.cc.

740  {
741  DoWrite(thread, false);
742  }
void DoWrite(ThreadState *thread, bool seq)
Definition: db_bench.cc:744
Here is the caller graph for this function:

§ WriteSeq()

void leveldb::Benchmark::WriteSeq ( ThreadState *  thread)
inlineprivate

Definition at line 736 of file db_bench.cc.

736  {
737  DoWrite(thread, true);
738  }
void DoWrite(ThreadState *thread, bool seq)
Definition: db_bench.cc:744
Here is the caller graph for this function:

§ WriteToFile()

static void leveldb::Benchmark::WriteToFile ( void *  arg,
const char *  buf,
int  n 
)
inlinestaticprivate

Definition at line 932 of file db_bench.cc.

932  {
933  reinterpret_cast<WritableFile*>(arg)->Append(Slice(buf, n));
934  }

Member Data Documentation

§ cache_

Cache* leveldb::Benchmark::cache_
private

Definition at line 319 of file db_bench.cc.

§ db_

DB* leveldb::Benchmark::db_
private

Definition at line 321 of file db_bench.cc.

§ entries_per_batch_

int leveldb::Benchmark::entries_per_batch_
private

Definition at line 324 of file db_bench.cc.

§ filter_policy_

const FilterPolicy* leveldb::Benchmark::filter_policy_
private

Definition at line 320 of file db_bench.cc.

§ heap_counter_

int leveldb::Benchmark::heap_counter_
private

Definition at line 327 of file db_bench.cc.

§ num_

int leveldb::Benchmark::num_
private

Definition at line 322 of file db_bench.cc.

§ reads_

int leveldb::Benchmark::reads_
private

Definition at line 326 of file db_bench.cc.

§ value_size_

int leveldb::Benchmark::value_size_
private

Definition at line 323 of file db_bench.cc.

§ write_options_

WriteOptions leveldb::Benchmark::write_options_
private

Definition at line 325 of file db_bench.cc.


The documentation for this class was generated from the following file: