// Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
//  This source code is licensed under both the GPLv2 (found in the
//  COPYING file in the root directory) and Apache 2.0 License
//  (found in the LICENSE.Apache file in the root directory).
/**
 * Copyright (C) 2011 the original author or authors.
 * See the notice.md file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.rocksdb.benchmark;

import java.io.IOException;
import java.lang.Runnable;
import java.lang.Math;
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.nio.ByteBuffer;
import java.nio.file.Files;
import java.util.Collection;
import java.util.Date;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.rocksdb.*;
import org.rocksdb.RocksMemEnv;
import org.rocksdb.util.SizeUnit;

class Stats {
  int id_;
  long start_;
  long finish_;
  double seconds_;
  long done_;
  long found_;
  long lastOpTime_;
  long nextReport_;
  long bytes_;
  StringBuilder message_;
  boolean excludeFromMerge_;

  // TODO(yhchiang): use the following arguments:
  //   (Long)Flag.stats_interval
  //   (Integer)Flag.stats_per_interval

  Stats(int id) {
    id_ = id;
    nextReport_ = 100;
    done_ = 0;
    bytes_ = 0;
    seconds_ = 0;
    start_ = System.nanoTime();
    lastOpTime_ = start_;
    finish_ = start_;
    found_ = 0;
    message_ = new StringBuilder("");
    excludeFromMerge_ = false;
  }

  void merge(final Stats other) {
    if (other.excludeFromMerge_) {
      return;
    }

    done_ += other.done_;
    found_ += other.found_;
    bytes_ += other.bytes_;
    seconds_ += other.seconds_;
    if (other.start_ < start_) start_ = other.start_;
    if (other.finish_ > finish_) finish_ = other.finish_;

    // Just keep the messages from one thread
    if (message_.length() == 0) {
      message_ = other.message_;
    }
  }

  void stop() {
    finish_ = System.nanoTime();
    seconds_ = (double) (finish_ - start_) * 1e-9;
  }

  void addMessage(String msg) {
    if (message_.length() > 0) {
      message_.append(" ");
    }
    message_.append(msg);
  }

  void setId(int id) { id_ = id; }
  void setExcludeFromMerge() { excludeFromMerge_ = true; }

  void finishedSingleOp(int bytes) {
    done_++;
    lastOpTime_ = System.nanoTime();
    bytes_ += bytes;
    if (done_ >= nextReport_) {
      if (nextReport_ < 1000) {
        nextReport_ += 100;
      } else if (nextReport_ < 5000) {
        nextReport_ += 500;
      } else if (nextReport_ < 10000) {
        nextReport_ += 1000;
      } else if (nextReport_ < 50000) {
        nextReport_ += 5000;
      } else if (nextReport_ < 100000) {
        nextReport_ += 10000;
      } else if (nextReport_ < 500000) {
        nextReport_ += 50000;
      } else {
        nextReport_ += 100000;
      }
      System.err.printf("... Task %s finished %d ops%30s\r", id_, done_, "");
    }
  }

  void report(String name) {
    // Pretend at least one op was done in case we are running a benchmark
    // that does not call FinishedSingleOp().
    if (done_ < 1) done_ = 1;

    StringBuilder extra = new StringBuilder("");
    if (bytes_ > 0) {
      // Rate is computed on actual elapsed time, not the sum of per-thread
      // elapsed times.
      double elapsed = (finish_ - start_) * 1e-9;
      extra.append(String.format("%6.1f MB/s", (bytes_ / 1048576.0) / elapsed));
    }
    extra.append(message_.toString());
    double elapsed = (finish_ - start_);
    double throughput = (double) done_ / (elapsed * 1e-9);

    System.out.format("%-12s : %11.3f micros/op %d ops/sec;%s%s\n",
            name, (elapsed * 1e-6) / done_,
            (long) throughput, (extra.length() == 0 ? "" : " "), extra.toString());
  }
}

public class DbBenchmark {
  enum Order {
    SEQUENTIAL,
    RANDOM
  }

  enum DBState {
    FRESH,
    EXISTING
  }

  static {
    RocksDB.loadLibrary();
  }

  abstract class BenchmarkTask implements Callable<Stats> {
    // TODO(yhchiang): use (Integer)Flag.perf_level.
    public BenchmarkTask(
        int tid, long randSeed, long numEntries, long keyRange) {
      tid_ = tid;
      rand_ = new Random(randSeed + tid * 1000);
      numEntries_ = numEntries;
      keyRange_ = keyRange;
      stats_ = new Stats(tid);
    }

    @Override public Stats call() throws RocksDBException {
      stats_.start_ = System.nanoTime();
      runTask();
      stats_.finish_ = System.nanoTime();
      return stats_;
    }

    abstract protected void runTask() throws RocksDBException;

    protected int tid_;
    protected Random rand_;
    protected long numEntries_;
    protected long keyRange_;
    protected Stats stats_;

    protected void getFixedKey(byte[] key, long sn) {
      generateKeyFromLong(key, sn);
    }

    protected void getRandomKey(byte[] key, long range) {
      generateKeyFromLong(key, Math.abs(rand_.nextLong() % range));
    }
  }

  abstract class WriteTask extends BenchmarkTask {
    public WriteTask(
        int tid, long randSeed, long numEntries, long keyRange,
        WriteOptions writeOpt, long entriesPerBatch) {
      super(tid, randSeed, numEntries, keyRange);
      writeOpt_ = writeOpt;
      entriesPerBatch_ = entriesPerBatch;
      maxWritesPerSecond_ = -1;
    }

    public WriteTask(
        int tid, long randSeed, long numEntries, long keyRange,
        WriteOptions writeOpt, long entriesPerBatch, long maxWritesPerSecond) {
      super(tid, randSeed, numEntries, keyRange);
      writeOpt_ = writeOpt;
      entriesPerBatch_ = entriesPerBatch;
      maxWritesPerSecond_ = maxWritesPerSecond;
    }

    @Override public void runTask() throws RocksDBException {
      if (numEntries_ != DbBenchmark.this.num_) {
        stats_.message_.append(String.format(" (%d ops)", numEntries_));
      }
      byte[] key = new byte[keySize_];
      byte[] value = new byte[valueSize_];

      try {
        if (entriesPerBatch_ == 1) {
          for (long i = 0; i < numEntries_; ++i) {
            getKey(key, i, keyRange_);
            DbBenchmark.this.gen_.generate(value);
            db_.put(writeOpt_, key, value);
            stats_.finishedSingleOp(keySize_ + valueSize_);
            writeRateControl(i);
            if (isFinished()) {
              return;
            }
          }
        } else {
          for (long i = 0; i < numEntries_; i += entriesPerBatch_) {
            WriteBatch batch = new WriteBatch();
            for (long j = 0; j < entriesPerBatch_; j++) {
              getKey(key, i + j, keyRange_);
              DbBenchmark.this.gen_.generate(value);
              batch.put(key, value);
              stats_.finishedSingleOp(keySize_ + valueSize_);
            }
            db_.write(writeOpt_, batch);
            batch.dispose();
            writeRateControl(i);
            if (isFinished()) {
              return;
            }
          }
        }
      } catch (InterruptedException e) {
        // thread has been terminated.
      }
    }

    protected void writeRateControl(long writeCount)
        throws InterruptedException {
      if (maxWritesPerSecond_ <= 0) return;
      long minInterval =
          writeCount * TimeUnit.SECONDS.toNanos(1) / maxWritesPerSecond_;
      long interval = System.nanoTime() - stats_.start_;
      if (minInterval - interval > TimeUnit.MILLISECONDS.toNanos(1)) {
        TimeUnit.NANOSECONDS.sleep(minInterval - interval);
      }
    }

    abstract protected void getKey(byte[] key, long id, long range);
    protected WriteOptions writeOpt_;
    protected long entriesPerBatch_;
    protected long maxWritesPerSecond_;
  }

  class WriteSequentialTask extends WriteTask {
    public WriteSequentialTask(
        int tid, long randSeed, long numEntries, long keyRange,
        WriteOptions writeOpt, long entriesPerBatch) {
      super(tid, randSeed, numEntries, keyRange,
            writeOpt, entriesPerBatch);
    }
    public WriteSequentialTask(
        int tid, long randSeed, long numEntries, long keyRange,
        WriteOptions writeOpt, long entriesPerBatch,
        long maxWritesPerSecond) {
      super(tid, randSeed, numEntries, keyRange,
            writeOpt, entriesPerBatch,
            maxWritesPerSecond);
    }
    @Override protected void getKey(byte[] key, long id, long range) {
      getFixedKey(key, id);
    }
  }

  class WriteRandomTask extends WriteTask {
    public WriteRandomTask(
        int tid, long randSeed, long numEntries, long keyRange,
        WriteOptions writeOpt, long entriesPerBatch) {
      super(tid, randSeed, numEntries, keyRange,
            writeOpt, entriesPerBatch);
    }
    public WriteRandomTask(
        int tid, long randSeed, long numEntries, long keyRange,
        WriteOptions writeOpt, long entriesPerBatch,
        long maxWritesPerSecond) {
      super(tid, randSeed, numEntries, keyRange,
            writeOpt, entriesPerBatch,
            maxWritesPerSecond);
    }
    @Override protected void getKey(byte[] key, long id, long range) {
      getRandomKey(key, range);
    }
  }

  class WriteUniqueRandomTask extends WriteTask {
    static final int MAX_BUFFER_SIZE = 10000000;
    public WriteUniqueRandomTask(
        int tid, long randSeed, long numEntries, long keyRange,
        WriteOptions writeOpt, long entriesPerBatch) {
      super(tid, randSeed, numEntries, keyRange,
            writeOpt, entriesPerBatch);
      initRandomKeySequence();
    }
    public WriteUniqueRandomTask(
        int tid, long randSeed, long numEntries, long keyRange,
        WriteOptions writeOpt, long entriesPerBatch,
        long maxWritesPerSecond) {
      super(tid, randSeed, numEntries, keyRange,
            writeOpt, entriesPerBatch,
            maxWritesPerSecond);
      initRandomKeySequence();
    }
    @Override protected void getKey(byte[] key, long id, long range) {
      generateKeyFromLong(key, nextUniqueRandom());
    }

    protected void initRandomKeySequence() {
      bufferSize_ = MAX_BUFFER_SIZE;
      if (bufferSize_ > keyRange_) {
        bufferSize_ = (int) keyRange_;
      }
      currentKeyCount_ = bufferSize_;
      keyBuffer_ = new long[MAX_BUFFER_SIZE];
      for (int k = 0; k < bufferSize_; ++k) {
        keyBuffer_[k] = k;
      }
    }

    /**
     * Semi-randomly return the next unique key.  It is guaranteed to be
     * fully random if keyRange_ <= MAX_BUFFER_SIZE.
     */
    long nextUniqueRandom() {
      if (bufferSize_ == 0) {
        System.err.println("bufferSize_ == 0.");
        return 0;
      }
      int r = rand_.nextInt(bufferSize_);
      // randomly pick one from the keyBuffer
      long randKey = keyBuffer_[r];
      if (currentKeyCount_ < keyRange_) {
        // if we have not yet inserted all keys, insert next new key to [r].
        keyBuffer_[r] = currentKeyCount_++;
      } else {
        // move the last element to [r] and decrease the size by 1.
        keyBuffer_[r] = keyBuffer_[--bufferSize_];
      }
      return randKey;
    }

    int bufferSize_;
    long currentKeyCount_;
    long[] keyBuffer_;
  }

  class ReadRandomTask extends BenchmarkTask {
    public ReadRandomTask(
        int tid, long randSeed, long numEntries, long keyRange) {
      super(tid, randSeed, numEntries, keyRange);
    }
    @Override public void runTask() throws RocksDBException {
      byte[] key = new byte[keySize_];
      byte[] value = new byte[valueSize_];
      for (long i = 0; i < numEntries_; i++) {
        getRandomKey(key, keyRange_);
        int len = db_.get(key, value);
        if (len != RocksDB.NOT_FOUND) {
          stats_.found_++;
          stats_.finishedSingleOp(keySize_ + valueSize_);
        } else {
          stats_.finishedSingleOp(keySize_);
        }
        if (isFinished()) {
          return;
        }
      }
    }
  }

  class ReadSequentialTask extends BenchmarkTask {
    public ReadSequentialTask(
        int tid, long randSeed, long numEntries, long keyRange) {
      super(tid, randSeed, numEntries, keyRange);
    }
    @Override public void runTask() throws RocksDBException {
      RocksIterator iter = db_.newIterator();
      long i;
      for (iter.seekToFirst(), i = 0;
           iter.isValid() && i < numEntries_;
           iter.next(), ++i) {
        stats_.found_++;
        stats_.finishedSingleOp(iter.key().length + iter.value().length);
        if (isFinished()) {
          iter.dispose();
          return;
        }
      }
      iter.dispose();
    }
  }

  public DbBenchmark(Map<Flag, Object> flags) throws Exception {
    benchmarks_ = (List<String>) flags.get(Flag.benchmarks);
    num_ = (Integer) flags.get(Flag.num);
    threadNum_ = (Integer) flags.get(Flag.threads);
    reads_ = (Integer) (flags.get(Flag.reads) == null ?
        flags.get(Flag.num) : flags.get(Flag.reads));
    keySize_ = (Integer) flags.get(Flag.key_size);
    valueSize_ = (Integer) flags.get(Flag.value_size);
    compressionRatio_ = (Double) flags.get(Flag.compression_ratio);
    useExisting_ = (Boolean) flags.get(Flag.use_existing_db);
    randSeed_ = (Long) flags.get(Flag.seed);
    databaseDir_ = (String) flags.get(Flag.db);
    writesPerSeconds_ = (Integer) flags.get(Flag.writes_per_second);
    memtable_ = (String) flags.get(Flag.memtablerep);
    maxWriteBufferNumber_ = (Integer) flags.get(Flag.max_write_buffer_number);
    prefixSize_ = (Integer) flags.get(Flag.prefix_size);
    keysPerPrefix_ = (Integer) flags.get(Flag.keys_per_prefix);
    hashBucketCount_ = (Long) flags.get(Flag.hash_bucket_count);
    usePlainTable_ = (Boolean) flags.get(Flag.use_plain_table);
    useMemenv_ = (Boolean) flags.get(Flag.use_mem_env);
    flags_ = flags;
    finishLock_ = new Object();
    // options.setPrefixSize((Integer)flags_.get(Flag.prefix_size));
    // options.setKeysPerPrefix((Long)flags_.get(Flag.keys_per_prefix));
    compressionType_ = (String) flags.get(Flag.compression_type);
    compression_ = CompressionType.NO_COMPRESSION;
    try {
      if (compressionType_!=null) {
          final CompressionType compressionType =
              CompressionType.getCompressionType(compressionType_);
          if (compressionType != null &&
              compressionType != CompressionType.NO_COMPRESSION) {
            System.loadLibrary(compressionType.getLibraryName());
          }

      }
    } catch (UnsatisfiedLinkError e) {
      System.err.format("Unable to load %s library:%s%n" +
                        "No compression is used.%n",
          compressionType_, e.toString());
      compressionType_ = "none";
    }
    gen_ = new RandomGenerator(randSeed_, compressionRatio_);
  }

  private void prepareReadOptions(ReadOptions options) {
    options.setVerifyChecksums((Boolean)flags_.get(Flag.verify_checksum));
    options.setTailing((Boolean)flags_.get(Flag.use_tailing_iterator));
  }

  private void prepareWriteOptions(WriteOptions options) {
    options.setSync((Boolean)flags_.get(Flag.sync));
    options.setDisableWAL((Boolean)flags_.get(Flag.disable_wal));
  }

  private void prepareOptions(Options options) throws RocksDBException {
    if (!useExisting_) {
      options.setCreateIfMissing(true);
    } else {
      options.setCreateIfMissing(false);
    }
    if (useMemenv_) {
      options.setEnv(new RocksMemEnv());
    }
    switch (memtable_) {
      case "skip_list":
        options.setMemTableConfig(new SkipListMemTableConfig());
        break;
      case "vector":
        options.setMemTableConfig(new VectorMemTableConfig());
        break;
      case "hash_linkedlist":
        options.setMemTableConfig(
            new HashLinkedListMemTableConfig()
                .setBucketCount(hashBucketCount_));
        options.useFixedLengthPrefixExtractor(prefixSize_);
        break;
      case "hash_skiplist":
      case "prefix_hash":
        options.setMemTableConfig(
            new HashSkipListMemTableConfig()
                .setBucketCount(hashBucketCount_));
        options.useFixedLengthPrefixExtractor(prefixSize_);
        break;
      default:
        System.err.format(
            "unable to detect the specified memtable, " +
                "use the default memtable factory %s%n",
            options.memTableFactoryName());
        break;
    }
    if (usePlainTable_) {
      options.setTableFormatConfig(
          new PlainTableConfig().setKeySize(keySize_));
    } else {
      BlockBasedTableConfig table_options = new BlockBasedTableConfig();
      table_options.setBlockSize((Long)flags_.get(Flag.block_size))
                   .setBlockCacheSize((Long)flags_.get(Flag.cache_size))
                   .setCacheNumShardBits(
                      (Integer)flags_.get(Flag.cache_numshardbits));
      options.setTableFormatConfig(table_options);
    }
    options.setWriteBufferSize(
        (Long)flags_.get(Flag.write_buffer_size));
    options.setMaxWriteBufferNumber(
        (Integer)flags_.get(Flag.max_write_buffer_number));
    options.setMaxBackgroundCompactions(
        (Integer)flags_.get(Flag.max_background_compactions));
    options.getEnv().setBackgroundThreads(
        (Integer)flags_.get(Flag.max_background_compactions));
    options.setMaxBackgroundFlushes(
        (Integer)flags_.get(Flag.max_background_flushes));
    options.setMaxOpenFiles(
        (Integer)flags_.get(Flag.open_files));
    options.setUseFsync(
        (Boolean)flags_.get(Flag.use_fsync));
    options.setWalDir(
        (String)flags_.get(Flag.wal_dir));
    options.setDeleteObsoleteFilesPeriodMicros(
        (Integer)flags_.get(Flag.delete_obsolete_files_period_micros));
    options.setTableCacheNumshardbits(
        (Integer)flags_.get(Flag.table_cache_numshardbits));
    options.setAllowMmapReads(
        (Boolean)flags_.get(Flag.mmap_read));
    options.setAllowMmapWrites(
        (Boolean)flags_.get(Flag.mmap_write));
    options.setAdviseRandomOnOpen(
        (Boolean)flags_.get(Flag.advise_random_on_open));
    options.setUseAdaptiveMutex(
        (Boolean)flags_.get(Flag.use_adaptive_mutex));
    options.setBytesPerSync(
        (Long)flags_.get(Flag.bytes_per_sync));
    options.setBloomLocality(
        (Integer)flags_.get(Flag.bloom_locality));
    options.setMinWriteBufferNumberToMerge(
        (Integer)flags_.get(Flag.min_write_buffer_number_to_merge));
    options.setMemtablePrefixBloomSizeRatio((Double) flags_.get(Flag.memtable_bloom_size_ratio));
    options.setNumLevels(
        (Integer)flags_.get(Flag.num_levels));
    options.setTargetFileSizeBase(
        (Integer)flags_.get(Flag.target_file_size_base));
    options.setTargetFileSizeMultiplier((Integer)flags_.get(Flag.target_file_size_multiplier));
    options.setMaxBytesForLevelBase(
        (Integer)flags_.get(Flag.max_bytes_for_level_base));
    options.setMaxBytesForLevelMultiplier((Double) flags_.get(Flag.max_bytes_for_level_multiplier));
    options.setLevelZeroStopWritesTrigger(
        (Integer)flags_.get(Flag.level0_stop_writes_trigger));
    options.setLevelZeroSlowdownWritesTrigger(
        (Integer)flags_.get(Flag.level0_slowdown_writes_trigger));
    options.setLevelZeroFileNumCompactionTrigger(
        (Integer)flags_.get(Flag.level0_file_num_compaction_trigger));
    options.setMaxCompactionBytes(
        (Long) flags_.get(Flag.max_compaction_bytes));
    options.setDisableAutoCompactions(
        (Boolean)flags_.get(Flag.disable_auto_compactions));
    options.setMaxSuccessiveMerges(
        (Integer)flags_.get(Flag.max_successive_merges));
    options.setWalTtlSeconds((Long)flags_.get(Flag.wal_ttl_seconds));
    options.setWalSizeLimitMB((Long)flags_.get(Flag.wal_size_limit_MB));
    if(flags_.get(Flag.java_comparator) != null) {
      options.setComparator(
          (AbstractComparator)flags_.get(Flag.java_comparator));
    }

    /* TODO(yhchiang): enable the following parameters
    options.setCompressionType((String)flags_.get(Flag.compression_type));
    options.setCompressionLevel((Integer)flags_.get(Flag.compression_level));
    options.setMinLevelToCompress((Integer)flags_.get(Flag.min_level_to_compress));
    options.setHdfs((String)flags_.get(Flag.hdfs)); // env
    options.setStatistics((Boolean)flags_.get(Flag.statistics));
    options.setUniversalSizeRatio(
        (Integer)flags_.get(Flag.universal_size_ratio));
    options.setUniversalMinMergeWidth(
        (Integer)flags_.get(Flag.universal_min_merge_width));
    options.setUniversalMaxMergeWidth(
        (Integer)flags_.get(Flag.universal_max_merge_width));
    options.setUniversalMaxSizeAmplificationPercent(
        (Integer)flags_.get(Flag.universal_max_size_amplification_percent));
    options.setUniversalCompressionSizePercent(
        (Integer)flags_.get(Flag.universal_compression_size_percent));
    // TODO(yhchiang): add RocksDB.openForReadOnly() to enable Flag.readonly
    // TODO(yhchiang): enable Flag.merge_operator by switch
    options.setAccessHintOnCompactionStart(
        (String)flags_.get(Flag.compaction_fadvice));
    // available values of fadvice are "NONE", "NORMAL", "SEQUENTIAL", "WILLNEED" for fadvice
    */
  }

  private void run() throws RocksDBException {
    if (!useExisting_) {
      destroyDb();
    }
    Options options = new Options();
    prepareOptions(options);
    open(options);

    printHeader(options);

    for (String benchmark : benchmarks_) {
      List<Callable<Stats>> tasks = new ArrayList<Callable<Stats>>();
      List<Callable<Stats>> bgTasks = new ArrayList<Callable<Stats>>();
      WriteOptions writeOpt = new WriteOptions();
      prepareWriteOptions(writeOpt);
      ReadOptions readOpt = new ReadOptions();
      prepareReadOptions(readOpt);
      int currentTaskId = 0;
      boolean known = true;

      switch (benchmark) {
        case "fillseq":
          tasks.add(new WriteSequentialTask(
              currentTaskId++, randSeed_, num_, num_, writeOpt, 1));
          break;
        case "fillbatch":
          tasks.add(new WriteRandomTask(
              currentTaskId++, randSeed_, num_ / 1000, num_, writeOpt, 1000));
          break;
        case "fillrandom":
          tasks.add(new WriteRandomTask(
              currentTaskId++, randSeed_, num_, num_, writeOpt, 1));
          break;
        case "filluniquerandom":
          tasks.add(new WriteUniqueRandomTask(
              currentTaskId++, randSeed_, num_, num_, writeOpt, 1));
          break;
        case "fillsync":
          writeOpt.setSync(true);
          tasks.add(new WriteRandomTask(
              currentTaskId++, randSeed_, num_ / 1000, num_ / 1000,
              writeOpt, 1));
          break;
        case "readseq":
          for (int t = 0; t < threadNum_; ++t) {
            tasks.add(new ReadSequentialTask(
                currentTaskId++, randSeed_, reads_ / threadNum_, num_));
          }
          break;
        case "readrandom":
          for (int t = 0; t < threadNum_; ++t) {
            tasks.add(new ReadRandomTask(
                currentTaskId++, randSeed_, reads_ / threadNum_, num_));
          }
          break;
        case "readwhilewriting":
          WriteTask writeTask = new WriteRandomTask(
              -1, randSeed_, Long.MAX_VALUE, num_, writeOpt, 1, writesPerSeconds_);
          writeTask.stats_.setExcludeFromMerge();
          bgTasks.add(writeTask);
          for (int t = 0; t < threadNum_; ++t) {
            tasks.add(new ReadRandomTask(
                currentTaskId++, randSeed_, reads_ / threadNum_, num_));
          }
          break;
        case "readhot":
          for (int t = 0; t < threadNum_; ++t) {
            tasks.add(new ReadRandomTask(
                currentTaskId++, randSeed_, reads_ / threadNum_, num_ / 100));
          }
          break;
        case "delete":
          destroyDb();
          open(options);
          break;
        default:
          known = false;
          System.err.println("Unknown benchmark: " + benchmark);
          break;
      }
      if (known) {
        ExecutorService executor = Executors.newCachedThreadPool();
        ExecutorService bgExecutor = Executors.newCachedThreadPool();
        try {
          // measure only the main executor time
          List<Future<Stats>> bgResults = new ArrayList<Future<Stats>>();
          for (Callable bgTask : bgTasks) {
            bgResults.add(bgExecutor.submit(bgTask));
          }
          start();
          List<Future<Stats>> results = executor.invokeAll(tasks);
          executor.shutdown();
          boolean finished = executor.awaitTermination(10, TimeUnit.SECONDS);
          if (!finished) {
            System.out.format(
                "Benchmark %s was not finished before timeout.",
                benchmark);
            executor.shutdownNow();
          }
          setFinished(true);
          bgExecutor.shutdown();
          finished = bgExecutor.awaitTermination(10, TimeUnit.SECONDS);
          if (!finished) {
            System.out.format(
                "Benchmark %s was not finished before timeout.",
                benchmark);
            bgExecutor.shutdownNow();
          }

          stop(benchmark, results, currentTaskId);
        } catch (InterruptedException e) {
          System.err.println(e);
        }
      }
      writeOpt.dispose();
      readOpt.dispose();
    }
    options.dispose();
    db_.close();
  }

  private void printHeader(Options options) {
    int kKeySize = 16;
    System.out.printf("Keys:     %d bytes each\n", kKeySize);
    System.out.printf("Values:   %d bytes each (%d bytes after compression)\n",
        valueSize_,
        (int) (valueSize_ * compressionRatio_ + 0.5));
    System.out.printf("Entries:  %d\n", num_);
    System.out.printf("RawSize:  %.1f MB (estimated)\n",
        ((double)(kKeySize + valueSize_) * num_) / SizeUnit.MB);
    System.out.printf("FileSize:   %.1f MB (estimated)\n",
        (((kKeySize + valueSize_ * compressionRatio_) * num_) / SizeUnit.MB));
    System.out.format("Memtable Factory: %s%n", options.memTableFactoryName());
    System.out.format("Prefix:   %d bytes%n", prefixSize_);
    System.out.format("Compression: %s%n", compressionType_);
    printWarnings();
    System.out.printf("------------------------------------------------\n");
  }

  void printWarnings() {
    boolean assertsEnabled = false;
    assert assertsEnabled = true; // Intentional side effect!!!
    if (assertsEnabled) {
      System.out.printf(
          "WARNING: Assertions are enabled; benchmarks unnecessarily slow\n");
    }
  }

  private void open(Options options) throws RocksDBException {
    System.out.println("Using database directory: " + databaseDir_);
    db_ = RocksDB.open(options, databaseDir_);
  }

  private void start() {
    setFinished(false);
    startTime_ = System.nanoTime();
  }

  private void stop(
      String benchmark, List<Future<Stats>> results, int concurrentThreads) {
    long endTime = System.nanoTime();
    double elapsedSeconds =
        1.0d * (endTime - startTime_) / TimeUnit.SECONDS.toNanos(1);

    Stats stats = new Stats(-1);
    int taskFinishedCount = 0;
    for (Future<Stats> result : results) {
      if (result.isDone()) {
        try {
          Stats taskStats = result.get(3, TimeUnit.SECONDS);
          if (!result.isCancelled()) {
            taskFinishedCount++;
          }
          stats.merge(taskStats);
        } catch (Exception e) {
          // then it's not successful, the output will indicate this
        }
      }
    }
    String extra = "";
    if (benchmark.indexOf("read") >= 0) {
      extra = String.format(" %d / %d found; ", stats.found_, stats.done_);
    } else {
      extra = String.format(" %d ops done; ", stats.done_);
    }

    System.out.printf(
        "%-16s : %11.5f micros/op; %6.1f MB/s;%s %d / %d task(s) finished.\n",
        benchmark, elapsedSeconds / stats.done_ * 1e6,
        (stats.bytes_ / 1048576.0) / elapsedSeconds, extra,
        taskFinishedCount, concurrentThreads);
  }

  public void generateKeyFromLong(byte[] slice, long n) {
    assert(n >= 0);
    int startPos = 0;

    if (keysPerPrefix_ > 0) {
      long numPrefix = (num_ + keysPerPrefix_ - 1) / keysPerPrefix_;
      long prefix = n % numPrefix;
      int bytesToFill = Math.min(prefixSize_, 8);
      for (int i = 0; i < bytesToFill; ++i) {
        slice[i] = (byte) (prefix % 256);
        prefix /= 256;
      }
      for (int i = 8; i < bytesToFill; ++i) {
        slice[i] = '0';
      }
      startPos = bytesToFill;
    }

    for (int i = slice.length - 1; i >= startPos; --i) {
      slice[i] = (byte) ('0' + (n % 10));
      n /= 10;
    }
  }

  private void destroyDb() {
    if (db_ != null) {
      db_.close();
    }
    // TODO(yhchiang): develop our own FileUtil
    // FileUtil.deleteDir(databaseDir_);
  }

  private void printStats() {
  }

  static void printHelp() {
    System.out.println("usage:");
    for (Flag flag : Flag.values()) {
      System.out.format("  --%s%n\t%s%n",
          flag.name(),
          flag.desc());
      if (flag.getDefaultValue() != null) {
        System.out.format("\tDEFAULT: %s%n",
            flag.getDefaultValue().toString());
      }
    }
  }

  public static void main(String[] args) throws Exception {
    Map<Flag, Object> flags = new EnumMap<Flag, Object>(Flag.class);
    for (Flag flag : Flag.values()) {
      if (flag.getDefaultValue() != null) {
        flags.put(flag, flag.getDefaultValue());
      }
    }
    for (String arg : args) {
      boolean valid = false;
      if (arg.equals("--help") || arg.equals("-h")) {
        printHelp();
        System.exit(0);
      }
      if (arg.startsWith("--")) {
        try {
          String[] parts = arg.substring(2).split("=");
          if (parts.length >= 1) {
            Flag key = Flag.valueOf(parts[0]);
            if (key != null) {
              Object value = null;
              if (parts.length >= 2) {
                value = key.parseValue(parts[1]);
              }
              flags.put(key, value);
              valid = true;
            }
          }
        }
        catch (Exception e) {
        }
      }
      if (!valid) {
        System.err.println("Invalid argument " + arg);
        System.exit(1);
      }
    }
    new DbBenchmark(flags).run();
  }

  private enum Flag {
    benchmarks(
        Arrays.asList(
            "fillseq",
            "readrandom",
            "fillrandom"),
        "Comma-separated list of operations to run in the specified order\n" +
        "\tActual benchmarks:\n" +
        "\t\tfillseq          -- write N values in sequential key order in async mode.\n" +
        "\t\tfillrandom       -- write N values in random key order in async mode.\n" +
        "\t\tfillbatch        -- write N/1000 batch where each batch has 1000 values\n" +
        "\t\t                   in random key order in sync mode.\n" +
        "\t\tfillsync         -- write N/100 values in random key order in sync mode.\n" +
        "\t\tfill100K         -- write N/1000 100K values in random order in async mode.\n" +
        "\t\treadseq          -- read N times sequentially.\n" +
        "\t\treadrandom       -- read N times in random order.\n" +
        "\t\treadhot          -- read N times in random order from 1% section of DB.\n" +
        "\t\treadwhilewriting -- measure the read performance of multiple readers\n" +
        "\t\t                   with a bg single writer.  The write rate of the bg\n" +
        "\t\t                   is capped by --writes_per_second.\n" +
        "\tMeta Operations:\n" +
        "\t\tdelete            -- delete DB") {
      @Override public Object parseValue(String value) {
        return new ArrayList<String>(Arrays.asList(value.split(",")));
      }
    },
    compression_ratio(0.5d,
        "Arrange to generate values that shrink to this fraction of\n" +
        "\ttheir original size after compression.") {
      @Override public Object parseValue(String value) {
        return Double.parseDouble(value);
      }
    },
    use_existing_db(false,
        "If true, do not destroy the existing database.  If you set this\n" +
        "\tflag and also specify a benchmark that wants a fresh database,\n" +
        "\tthat benchmark will fail.") {
      @Override public Object parseValue(String value) {
        return parseBoolean(value);
      }
    },
    num(1000000,
        "Number of key/values to place in database.") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },
    threads(1,
        "Number of concurrent threads to run.") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },
    reads(null,
        "Number of read operations to do.  If negative, do --nums reads.") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },
    key_size(16,
        "The size of each key in bytes.") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },
    value_size(100,
        "The size of each value in bytes.") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },
    write_buffer_size(4L * SizeUnit.MB,
        "Number of bytes to buffer in memtable before compacting\n" +
        "\t(initialized to default value by 'main'.)") {
      @Override public Object parseValue(String value) {
        return Long.parseLong(value);
      }
    },
    max_write_buffer_number(2,
             "The number of in-memory memtables. Each memtable is of size\n" +
             "\twrite_buffer_size.") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },
    prefix_size(0, "Controls the prefix size for HashSkipList, HashLinkedList,\n" +
                   "\tand plain table.") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },
    keys_per_prefix(0, "Controls the average number of keys generated\n" +
             "\tper prefix, 0 means no special handling of the prefix,\n" +
             "\ti.e. use the prefix comes with the generated random number.") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },
    memtablerep("skip_list",
        "The memtable format.  Available options are\n" +
        "\tskip_list,\n" +
        "\tvector,\n" +
        "\thash_linkedlist,\n" +
        "\thash_skiplist (prefix_hash.)") {
      @Override public Object parseValue(String value) {
        return value;
      }
    },
    hash_bucket_count(SizeUnit.MB,
        "The number of hash buckets used in the hash-bucket-based\n" +
        "\tmemtables.  Memtables that currently support this argument are\n" +
        "\thash_linkedlist and hash_skiplist.") {
      @Override public Object parseValue(String value) {
        return Long.parseLong(value);
      }
    },
    writes_per_second(10000,
        "The write-rate of the background writer used in the\n" +
        "\t`readwhilewriting` benchmark.  Non-positive number indicates\n" +
        "\tusing an unbounded write-rate in `readwhilewriting` benchmark.") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },
    use_plain_table(false,
        "Use plain-table sst format.") {
      @Override public Object parseValue(String value) {
        return parseBoolean(value);
      }
    },
    cache_size(-1L,
        "Number of bytes to use as a cache of uncompressed data.\n" +
        "\tNegative means use default settings.") {
      @Override public Object parseValue(String value) {
        return Long.parseLong(value);
      }
    },
    seed(0L,
        "Seed base for random number generators.") {
      @Override public Object parseValue(String value) {
        return Long.parseLong(value);
      }
    },
    num_levels(7,
        "The total number of levels.") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },
    numdistinct(1000L,
        "Number of distinct keys to use. Used in RandomWithVerify to\n" +
        "\tread/write on fewer keys so that gets are more likely to find the\n" +
        "\tkey and puts are more likely to update the same key.") {
      @Override public Object parseValue(String value) {
        return Long.parseLong(value);
      }
    },
    merge_keys(-1L,
        "Number of distinct keys to use for MergeRandom and\n" +
        "\tReadRandomMergeRandom.\n" +
        "\tIf negative, there will be FLAGS_num keys.") {
      @Override public Object parseValue(String value) {
        return Long.parseLong(value);
      }
    },
    bloom_locality(0,"Control bloom filter probes locality.") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },
    duration(0,"Time in seconds for the random-ops tests to run.\n" +
        "\tWhen 0 then num & reads determine the test duration.") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },
    num_multi_db(0,
        "Number of DBs used in the benchmark. 0 means single DB.") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },
    histogram(false,"Print histogram of operation timings.") {
      @Override public Object parseValue(String value) {
        return parseBoolean(value);
      }
    },
    min_write_buffer_number_to_merge(
        defaultOptions_.minWriteBufferNumberToMerge(),
        "The minimum number of write buffers that will be merged together\n" +
        "\tbefore writing to storage. This is cheap because it is an\n" +
        "\tin-memory merge. If this feature is not enabled, then all these\n" +
        "\twrite buffers are flushed to L0 as separate files and this\n" +
        "\tincreases read amplification because a get request has to check\n" +
        "\tin all of these files. Also, an in-memory merge may result in\n" +
        "\twriting less data to storage if there are duplicate records\n" +
        "\tin each of these individual write buffers.") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },
    max_background_compactions(
        defaultOptions_.maxBackgroundCompactions(),
        "The maximum number of concurrent background compactions\n" +
        "\tthat can occur in parallel.") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },
    max_background_flushes(
        defaultOptions_.maxBackgroundFlushes(),
        "The maximum number of concurrent background flushes\n" +
        "\tthat can occur in parallel.") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },
    /* TODO(yhchiang): enable the following
    compaction_style((int32_t) defaultOptions_.compactionStyle(),
        "style of compaction: level-based vs universal.") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },*/
    universal_size_ratio(0,
        "Percentage flexibility while comparing file size\n" +
        "\t(for universal compaction only).") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },
    universal_min_merge_width(0,"The minimum number of files in a\n" +
        "\tsingle compaction run (for universal compaction only).") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },
    universal_max_merge_width(0,"The max number of files to compact\n" +
        "\tin universal style compaction.") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },
    universal_max_size_amplification_percent(0,
        "The max size amplification for universal style compaction.") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },
    universal_compression_size_percent(-1,
        "The percentage of the database to compress for universal\n" +
        "\tcompaction. -1 means compress everything.") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },
    block_size(defaultBlockBasedTableOptions_.blockSize(),
        "Number of bytes in a block.") {
      @Override public Object parseValue(String value) {
        return Long.parseLong(value);
      }
    },
    compressed_cache_size(-1L,
        "Number of bytes to use as a cache of compressed data.") {
      @Override public Object parseValue(String value) {
        return Long.parseLong(value);
      }
    },
    open_files(defaultOptions_.maxOpenFiles(),
        "Maximum number of files to keep open at the same time\n" +
        "\t(use default if == 0)") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },
    bloom_bits(-1,"Bloom filter bits per key. Negative means\n" +
        "\tuse default settings.") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },
    memtable_bloom_size_ratio(0.0d, "Ratio of memtable used by the bloom filter.\n"
            + "\t0 means no bloom filter.") {
      @Override public Object parseValue(String value) {
        return Double.parseDouble(value);
      }
    },
    cache_numshardbits(-1,"Number of shards for the block cache\n" +
        "\tis 2 ** cache_numshardbits. Negative means use default settings.\n" +
        "\tThis is applied only if FLAGS_cache_size is non-negative.") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },
    verify_checksum(false,"Verify checksum for every block read\n" +
        "\tfrom storage.") {
      @Override public Object parseValue(String value) {
        return parseBoolean(value);
      }
    },
    statistics(false,"Database statistics.") {
      @Override public Object parseValue(String value) {
        return parseBoolean(value);
      }
    },
    writes(-1L, "Number of write operations to do. If negative, do\n" +
        "\t--num reads.") {
      @Override public Object parseValue(String value) {
        return Long.parseLong(value);
      }
    },
    sync(false,"Sync all writes to disk.") {
      @Override public Object parseValue(String value) {
        return parseBoolean(value);
      }
    },
    use_fsync(false,"If true, issue fsync instead of fdatasync.") {
      @Override public Object parseValue(String value) {
        return parseBoolean(value);
      }
    },
    disable_wal(false,"If true, do not write WAL for write.") {
      @Override public Object parseValue(String value) {
        return parseBoolean(value);
      }
    },
    wal_dir("", "If not empty, use the given dir for WAL.") {
      @Override public Object parseValue(String value) {
        return value;
      }
    },
    target_file_size_base(2 * 1048576,"Target file size at level-1") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },
    target_file_size_multiplier(1,
        "A multiplier to compute target level-N file size (N >= 2)") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },
    max_bytes_for_level_base(10 * 1048576,
      "Max bytes for level-1") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },
    max_bytes_for_level_multiplier(10.0d,
        "A multiplier to compute max bytes for level-N (N >= 2)") {
      @Override public Object parseValue(String value) {
        return Double.parseDouble(value);
      }
    },
    level0_stop_writes_trigger(12,"Number of files in level-0\n" +
        "\tthat will trigger put stop.") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },
    level0_slowdown_writes_trigger(8,"Number of files in level-0\n" +
        "\tthat will slow down writes.") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },
    level0_file_num_compaction_trigger(4,"Number of files in level-0\n" +
        "\twhen compactions start.") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },
    readwritepercent(90,"Ratio of reads to reads/writes (expressed\n" +
        "\tas percentage) for the ReadRandomWriteRandom workload. The\n" +
        "\tdefault value 90 means 90% operations out of all reads and writes\n" +
        "\toperations are reads. In other words, 9 gets for every 1 put.") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },
    mergereadpercent(70,"Ratio of merges to merges&reads (expressed\n" +
        "\tas percentage) for the ReadRandomMergeRandom workload. The\n" +
        "\tdefault value 70 means 70% out of all read and merge operations\n" +
        "\tare merges. In other words, 7 merges for every 3 gets.") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },
    deletepercent(2,"Percentage of deletes out of reads/writes/\n" +
        "\tdeletes (used in RandomWithVerify only). RandomWithVerify\n" +
        "\tcalculates writepercent as (100 - FLAGS_readwritepercent -\n" +
        "\tdeletepercent), so deletepercent must be smaller than (100 -\n" +
        "\tFLAGS_readwritepercent)") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },
    delete_obsolete_files_period_micros(0,"Option to delete\n" +
        "\tobsolete files periodically. 0 means that obsolete files are\n" +
        "\tdeleted after every compaction run.") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },
    compression_type("snappy",
        "Algorithm used to compress the database.") {
      @Override public Object parseValue(String value) {
        return value;
      }
    },
    compression_level(-1,
        "Compression level. For zlib this should be -1 for the\n" +
        "\tdefault level, or between 0 and 9.") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },
    min_level_to_compress(-1,"If non-negative, compression starts\n" +
        "\tfrom this level. Levels with number < min_level_to_compress are\n" +
        "\tnot compressed. Otherwise, apply compression_type to\n" +
        "\tall levels.") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },
    table_cache_numshardbits(4,"") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },
    stats_interval(0L, "Stats are reported every N operations when\n" +
        "\tthis is greater than zero. When 0 the interval grows over time.") {
      @Override public Object parseValue(String value) {
        return Long.parseLong(value);
      }
    },
    stats_per_interval(0,"Reports additional stats per interval when\n" +
        "\tthis is greater than 0.") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },
    perf_level(0,"Level of perf collection.") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },
    soft_rate_limit(0.0d,"") {
      @Override public Object parseValue(String value) {
        return Double.parseDouble(value);
      }
    },
    hard_rate_limit(0.0d,"When not equal to 0 this make threads\n" +
        "\tsleep at each stats reporting interval until the compaction\n" +
        "\tscore for all levels is less than or equal to this value.") {
      @Override public Object parseValue(String value) {
        return Double.parseDouble(value);
      }
    },
    rate_limit_delay_max_milliseconds(1000,
        "When hard_rate_limit is set then this is the max time a put will\n" +
        "\tbe stalled.") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },
    max_compaction_bytes(0L, "Limit number of bytes in one compaction to be lower than this\n" +
            "\threshold. But it's not guaranteed.") {
      @Override public Object parseValue(String value) {
        return Long.parseLong(value);
      }
    },
    readonly(false,"Run read only benchmarks.") {
      @Override public Object parseValue(String value) {
        return parseBoolean(value);
      }
    },
    disable_auto_compactions(false,"Do not auto trigger compactions.") {
      @Override public Object parseValue(String value) {
        return parseBoolean(value);
      }
    },
    wal_ttl_seconds(0L,"Set the TTL for the WAL Files in seconds.") {
      @Override public Object parseValue(String value) {
        return Long.parseLong(value);
      }
    },
    wal_size_limit_MB(0L,"Set the size limit for the WAL Files\n" +
        "\tin MB.") {
      @Override public Object parseValue(String value) {
        return Long.parseLong(value);
      }
    },
    /* TODO(yhchiang): enable the following
    direct_reads(rocksdb::EnvOptions().use_direct_reads,
        "Allow direct I/O reads.") {
      @Override public Object parseValue(String value) {
        return parseBoolean(value);
      }
      },
    direct_writes(rocksdb::EnvOptions().use_direct_reads,
      "Allow direct I/O reads.") {
      @Override public Object parseValue(String value) {
      return parseBoolean(value);
      }
      },
    */
    mmap_read(false,
        "Allow reads to occur via mmap-ing files.") {
      @Override public Object parseValue(String value) {
        return parseBoolean(value);
      }
    },
    mmap_write(false,
        "Allow writes to occur via mmap-ing files.") {
      @Override public Object parseValue(String value) {
        return parseBoolean(value);
      }
    },
    advise_random_on_open(defaultOptions_.adviseRandomOnOpen(),
        "Advise random access on table file open.") {
      @Override public Object parseValue(String value) {
        return parseBoolean(value);
      }
    },
    compaction_fadvice("NORMAL",
      "Access pattern advice when a file is compacted.") {
      @Override public Object parseValue(String value) {
        return value;
      }
    },
    use_tailing_iterator(false,
        "Use tailing iterator to access a series of keys instead of get.") {
      @Override public Object parseValue(String value) {
        return parseBoolean(value);
      }
    },
    use_adaptive_mutex(defaultOptions_.useAdaptiveMutex(),
        "Use adaptive mutex.") {
      @Override public Object parseValue(String value) {
        return parseBoolean(value);
      }
    },
    bytes_per_sync(defaultOptions_.bytesPerSync(),
        "Allows OS to incrementally sync files to disk while they are\n" +
        "\tbeing written, in the background. Issue one request for every\n" +
        "\tbytes_per_sync written. 0 turns it off.") {
      @Override public Object parseValue(String value) {
        return Long.parseLong(value);
      }
    },
    filter_deletes(false," On true, deletes use bloom-filter and drop\n" +
        "\tthe delete if key not present.") {
      @Override public Object parseValue(String value) {
        return parseBoolean(value);
      }
    },
    max_successive_merges(0,"Maximum number of successive merge\n" +
        "\toperations on a key in the memtable.") {
      @Override public Object parseValue(String value) {
        return Integer.parseInt(value);
      }
    },
    db(getTempDir("rocksdb-jni"),
       "Use the db with the following name.") {
      @Override public Object parseValue(String value) {
        return value;
      }
    },
    use_mem_env(false, "Use RocksMemEnv instead of default filesystem based\n" +
        "environment.") {
      @Override public Object parseValue(String value) {
        return parseBoolean(value);
      }
    },
    java_comparator(null, "Class name of a Java Comparator to use instead\n" +
        "\tof the default C++ ByteWiseComparatorImpl. Must be available on\n" +
        "\tthe classpath") {
      @Override
      protected Object parseValue(final String value) {
        try {
          final ComparatorOptions copt = new ComparatorOptions();
          final Class<AbstractComparator> clsComparator =
              (Class<AbstractComparator>)Class.forName(value);
          final Constructor cstr =
              clsComparator.getConstructor(ComparatorOptions.class);
          return cstr.newInstance(copt);
        } catch(final ClassNotFoundException cnfe) {
          throw new IllegalArgumentException("Java Comparator '" + value + "'" +
              " not found on the classpath", cnfe);
        } catch(final NoSuchMethodException nsme) {
          throw new IllegalArgumentException("Java Comparator '" + value + "'" +
              " does not have a public ComparatorOptions constructor", nsme);
        } catch(final IllegalAccessException | InstantiationException
            | InvocationTargetException ie) {
          throw new IllegalArgumentException("Unable to construct Java" +
              " Comparator '" + value + "'", ie);
        }
      }
    };

    private Flag(Object defaultValue, String desc) {
      defaultValue_ = defaultValue;
      desc_ = desc;
    }

    public Object getDefaultValue() {
      return defaultValue_;
    }

    public String desc() {
      return desc_;
    }

    public boolean parseBoolean(String value) {
      if (value.equals("1")) {
        return true;
      } else if (value.equals("0")) {
        return false;
      }
      return Boolean.parseBoolean(value);
    }

    protected abstract Object parseValue(String value);

    private final Object defaultValue_;
    private final String desc_;
  }

  private final static String DEFAULT_TEMP_DIR = "/tmp";

  private static String getTempDir(final String dirName) {
    try {
      return Files.createTempDirectory(dirName).toAbsolutePath().toString();
    } catch(final IOException ioe) {
      System.err.println("Unable to create temp directory, defaulting to: " +
          DEFAULT_TEMP_DIR);
      return DEFAULT_TEMP_DIR + File.pathSeparator + dirName;
    }
  }

  private static class RandomGenerator {
    private final byte[] data_;
    private int dataLength_;
    private int position_;
    private double compressionRatio_;
    Random rand_;

    private RandomGenerator(long seed, double compressionRatio) {
      // We use a limited amount of data over and over again and ensure
      // that it is larger than the compression window (32KB), and also
      byte[] value = new byte[100];
      // large enough to serve all typical value sizes we want to write.
      rand_ = new Random(seed);
      dataLength_ = value.length * 10000;
      data_ = new byte[dataLength_];
      compressionRatio_ = compressionRatio;
      int pos = 0;
      while (pos < dataLength_) {
        compressibleBytes(value);
        System.arraycopy(value, 0, data_, pos,
                         Math.min(value.length, dataLength_ - pos));
        pos += value.length;
      }
    }

    private void compressibleBytes(byte[] value) {
      int baseLength = value.length;
      if (compressionRatio_ < 1.0d) {
        baseLength = (int) (compressionRatio_ * value.length + 0.5);
      }
      if (baseLength <= 0) {
        baseLength = 1;
      }
      int pos;
      for (pos = 0; pos < baseLength; ++pos) {
        value[pos] = (byte) (' ' + rand_.nextInt(95));  // ' ' .. '~'
      }
      while (pos < value.length) {
        System.arraycopy(value, 0, value, pos,
                         Math.min(baseLength, value.length - pos));
        pos += baseLength;
      }
    }

    private void generate(byte[] value) {
      if (position_ + value.length > data_.length) {
        position_ = 0;
        assert(value.length <= data_.length);
      }
      position_ += value.length;
      System.arraycopy(data_, position_ - value.length,
                       value, 0, value.length);
    }
  }

  boolean isFinished() {
    synchronized(finishLock_) {
      return isFinished_;
    }
  }

  void setFinished(boolean flag) {
    synchronized(finishLock_) {
      isFinished_ = flag;
    }
  }

  RocksDB db_;
  final List<String> benchmarks_;
  final int num_;
  final int reads_;
  final int keySize_;
  final int valueSize_;
  final int threadNum_;
  final int writesPerSeconds_;
  final long randSeed_;
  final boolean useExisting_;
  final String databaseDir_;
  double compressionRatio_;
  RandomGenerator gen_;
  long startTime_;

  // env
  boolean useMemenv_;

  // memtable related
  final int maxWriteBufferNumber_;
  final int prefixSize_;
  final int keysPerPrefix_;
  final String memtable_;
  final long hashBucketCount_;

  // sst format related
  boolean usePlainTable_;

  Object finishLock_;
  boolean isFinished_;
  Map<Flag, Object> flags_;
  // as the scope of a static member equals to the scope of the problem,
  // we let its c++ pointer to be disposed in its finalizer.
  static Options defaultOptions_ = new Options();
  static BlockBasedTableConfig defaultBlockBasedTableOptions_ =
    new BlockBasedTableConfig();
  String compressionType_;
  CompressionType compression_;
}
