_ZN7leveldb10BuildTableERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEPNS_3EnvERKNS_7OptionsEPNS_10TableCacheEPNS_8IteratorEPNS_12FileMetaDataE:
   18|     48|                  TableCache* table_cache, Iterator* iter, FileMetaData* meta) {
   19|     48|  Status s;
   20|     48|  meta->file_size = 0;
   21|     48|  iter->SeekToFirst();
   22|       |
   23|     48|  std::string fname = TableFileName(dbname, meta->number);
   24|     48|  if (iter->Valid()) {
  ------------------
  |  Branch (24:7): [True: 36, False: 12]
  ------------------
   25|     36|    WritableFile* file;
   26|     36|    s = env->NewWritableFile(fname, &file);
   27|     36|    if (!s.ok()) {
  ------------------
  |  Branch (27:9): [True: 0, False: 36]
  ------------------
   28|      0|      return s;
   29|      0|    }
   30|       |
   31|     36|    TableBuilder* builder = new TableBuilder(options, file);
   32|     36|    meta->smallest.DecodeFrom(iter->key());
   33|     36|    Slice key;
   34|    291|    for (; iter->Valid(); iter->Next()) {
  ------------------
  |  Branch (34:12): [True: 255, False: 36]
  ------------------
   35|    255|      key = iter->key();
   36|    255|      builder->Add(key, iter->value());
   37|    255|    }
   38|     36|    if (!key.empty()) {
  ------------------
  |  Branch (38:9): [True: 36, False: 0]
  ------------------
   39|     36|      meta->largest.DecodeFrom(key);
   40|     36|    }
   41|       |
   42|       |    // Finish and check for builder errors
   43|     36|    s = builder->Finish();
   44|     36|    if (s.ok()) {
  ------------------
  |  Branch (44:9): [True: 36, False: 0]
  ------------------
   45|     36|      meta->file_size = builder->FileSize();
   46|     36|      assert(meta->file_size > 0);
   47|     36|    }
   48|     36|    delete builder;
   49|       |
   50|       |    // Finish and check for file errors
   51|     36|    if (s.ok()) {
  ------------------
  |  Branch (51:9): [True: 36, False: 0]
  ------------------
   52|     36|      s = file->Sync();
   53|     36|    }
   54|     36|    if (s.ok()) {
  ------------------
  |  Branch (54:9): [True: 36, False: 0]
  ------------------
   55|     36|      s = file->Close();
   56|     36|    }
   57|     36|    delete file;
   58|     36|    file = nullptr;
   59|       |
   60|     36|    if (s.ok()) {
  ------------------
  |  Branch (60:9): [True: 36, False: 0]
  ------------------
   61|       |      // Verify that the table is usable
   62|     36|      Iterator* it = table_cache->NewIterator(ReadOptions(), meta->number,
   63|     36|                                              meta->file_size);
   64|     36|      s = it->status();
   65|     36|      delete it;
   66|     36|    }
   67|     36|  }
   68|       |
   69|       |  // Check for input iterator errors
   70|     48|  if (!iter->status().ok()) {
  ------------------
  |  Branch (70:7): [True: 0, False: 48]
  ------------------
   71|      0|    s = iter->status();
   72|      0|  }
   73|       |
   74|     48|  if (s.ok() && meta->file_size > 0) {
  ------------------
  |  Branch (74:7): [True: 48, False: 0]
  |  Branch (74:17): [True: 36, False: 12]
  ------------------
   75|       |    // Keep it
   76|     36|  } else {
   77|     12|    env->RemoveFile(fname);
   78|     12|  }
   79|     48|  return s;
   80|     48|}

_ZN7leveldb15SanitizeOptionsERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEPKNS_21InternalKeyComparatorEPKNS_20InternalFilterPolicyERKNS_7OptionsE:
   97|    100|                        const Options& src) {
   98|    100|  Options result = src;
   99|    100|  result.comparator = icmp;
  100|    100|  result.filter_policy = (src.filter_policy != nullptr) ? ipolicy : nullptr;
  ------------------
  |  Branch (100:26): [True: 0, False: 100]
  ------------------
  101|    100|  ClipToRange(&result.max_open_files, 64 + kNumNonTableCacheFiles, 50000);
  102|    100|  ClipToRange(&result.write_buffer_size, 64 << 10, 1 << 30);
  103|    100|  ClipToRange(&result.max_file_size, 1 << 20, 1 << 30);
  104|    100|  ClipToRange(&result.block_size, 1 << 10, 4 << 20);
  105|    100|  if (result.info_log == nullptr) {
  ------------------
  |  Branch (105:7): [True: 100, False: 0]
  ------------------
  106|       |    // Open a log file in the same directory as the db
  107|    100|    src.env->CreateDir(dbname);  // In case it does not exist
  108|    100|    src.env->RenameFile(InfoLogFileName(dbname), OldInfoLogFileName(dbname));
  109|    100|    Status s = src.env->NewLogger(InfoLogFileName(dbname), &result.info_log);
  110|    100|    if (!s.ok()) {
  ------------------
  |  Branch (110:9): [True: 0, False: 100]
  ------------------
  111|       |      // No place suitable for logging
  112|      0|      result.info_log = nullptr;
  113|      0|    }
  114|    100|  }
  115|    100|  if (result.block_cache == nullptr) {
  ------------------
  |  Branch (115:7): [True: 100, False: 0]
  ------------------
  116|    100|    result.block_cache = NewLRUCache(8 << 20);
  117|    100|  }
  118|    100|  return result;
  119|    100|}
_ZN7leveldb6DBImplC2ERKNS_7OptionsERKNSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEE:
  127|    100|    : env_(raw_options.env),
  128|    100|      internal_comparator_(raw_options.comparator),
  129|    100|      internal_filter_policy_(raw_options.filter_policy),
  130|    100|      options_(SanitizeOptions(dbname, &internal_comparator_,
  131|    100|                               &internal_filter_policy_, raw_options)),
  132|    100|      owns_info_log_(options_.info_log != raw_options.info_log),
  133|    100|      owns_cache_(options_.block_cache != raw_options.block_cache),
  134|    100|      dbname_(dbname),
  135|    100|      table_cache_(new TableCache(dbname_, options_, TableCacheSize(options_))),
  136|    100|      db_lock_(nullptr),
  137|    100|      shutting_down_(false),
  138|    100|      background_work_finished_signal_(&mutex_),
  139|    100|      mem_(nullptr),
  140|    100|      imm_(nullptr),
  141|    100|      has_imm_(false),
  142|    100|      logfile_(nullptr),
  143|    100|      logfile_number_(0),
  144|    100|      log_(nullptr),
  145|    100|      seed_(0),
  146|    100|      tmp_batch_(new WriteBatch),
  147|    100|      background_compaction_scheduled_(false),
  148|    100|      manual_compaction_(nullptr),
  149|    100|      versions_(new VersionSet(dbname_, &options_, table_cache_,
  150|    100|                               &internal_comparator_)) {}
_ZN7leveldb6DBImplD2Ev:
  152|    100|DBImpl::~DBImpl() {
  153|       |  // Wait for background work to finish.
  154|    100|  mutex_.Lock();
  155|    100|  shutting_down_.store(true, std::memory_order_release);
  156|    102|  while (background_compaction_scheduled_) {
  ------------------
  |  Branch (156:10): [True: 2, False: 100]
  ------------------
  157|      2|    background_work_finished_signal_.Wait();
  158|      2|  }
  159|    100|  mutex_.Unlock();
  160|       |
  161|    100|  if (db_lock_ != nullptr) {
  ------------------
  |  Branch (161:7): [True: 100, False: 0]
  ------------------
  162|    100|    env_->UnlockFile(db_lock_);
  163|    100|  }
  164|       |
  165|    100|  delete versions_;
  166|    100|  if (mem_ != nullptr) mem_->Unref();
  ------------------
  |  Branch (166:7): [True: 100, False: 0]
  ------------------
  167|    100|  if (imm_ != nullptr) imm_->Unref();
  ------------------
  |  Branch (167:7): [True: 0, False: 100]
  ------------------
  168|    100|  delete tmp_batch_;
  169|    100|  delete log_;
  170|    100|  delete logfile_;
  171|    100|  delete table_cache_;
  172|       |
  173|    100|  if (owns_info_log_) {
  ------------------
  |  Branch (173:7): [True: 100, False: 0]
  ------------------
  174|    100|    delete options_.info_log;
  175|    100|  }
  176|    100|  if (owns_cache_) {
  ------------------
  |  Branch (176:7): [True: 100, False: 0]
  ------------------
  177|    100|    delete options_.block_cache;
  178|    100|  }
  179|    100|}
_ZN7leveldb6DBImpl5NewDBEv:
  181|     47|Status DBImpl::NewDB() {
  182|     47|  VersionEdit new_db;
  183|     47|  new_db.SetComparatorName(user_comparator()->Name());
  184|     47|  new_db.SetLogNumber(0);
  185|     47|  new_db.SetNextFile(2);
  186|     47|  new_db.SetLastSequence(0);
  187|       |
  188|     47|  const std::string manifest = DescriptorFileName(dbname_, 1);
  189|     47|  WritableFile* file;
  190|     47|  Status s = env_->NewWritableFile(manifest, &file);
  191|     47|  if (!s.ok()) {
  ------------------
  |  Branch (191:7): [True: 0, False: 47]
  ------------------
  192|      0|    return s;
  193|      0|  }
  194|     47|  {
  195|     47|    log::Writer log(file);
  196|     47|    std::string record;
  197|     47|    new_db.EncodeTo(&record);
  198|     47|    s = log.AddRecord(record);
  199|     47|    if (s.ok()) {
  ------------------
  |  Branch (199:9): [True: 47, False: 0]
  ------------------
  200|     47|      s = file->Sync();
  201|     47|    }
  202|     47|    if (s.ok()) {
  ------------------
  |  Branch (202:9): [True: 47, False: 0]
  ------------------
  203|     47|      s = file->Close();
  204|     47|    }
  205|     47|  }
  206|     47|  delete file;
  207|     47|  if (s.ok()) {
  ------------------
  |  Branch (207:7): [True: 47, False: 0]
  ------------------
  208|       |    // Make "CURRENT" file that points to the new manifest file.
  209|     47|    s = SetCurrentFile(env_, dbname_, 1);
  210|     47|  } else {
  211|      0|    env_->RemoveFile(manifest);
  212|      0|  }
  213|     47|  return s;
  214|     47|}
_ZNK7leveldb6DBImpl16MaybeIgnoreErrorEPNS_6StatusE:
  216|    105|void DBImpl::MaybeIgnoreError(Status* s) const {
  217|    105|  if (s->ok() || options_.paranoid_checks) {
  ------------------
  |  Branch (217:7): [True: 105, False: 0]
  |  Branch (217:18): [True: 0, False: 0]
  ------------------
  218|       |    // No change needed
  219|    105|  } else {
  220|      0|    Log(options_.info_log, "Ignoring error %s", s->ToString().c_str());
  221|      0|    *s = Status::OK();
  222|      0|  }
  223|    105|}
_ZN7leveldb6DBImpl19RemoveObsoleteFilesEv:
  225|    124|void DBImpl::RemoveObsoleteFiles() {
  226|    124|  mutex_.AssertHeld();
  227|       |
  228|    124|  if (!bg_error_.ok()) {
  ------------------
  |  Branch (228:7): [True: 0, False: 124]
  ------------------
  229|       |    // After a background error, we don't know whether a new version may
  230|       |    // or may not have been committed, so we cannot safely garbage collect.
  231|      0|    return;
  232|      0|  }
  233|       |
  234|       |  // Make a set of all of the live files
  235|    124|  std::set<uint64_t> live = pending_outputs_;
  236|    124|  versions_->AddLiveFiles(&live);
  237|       |
  238|    124|  std::vector<std::string> filenames;
  239|    124|  env_->GetChildren(dbname_, &filenames);  // Ignoring errors on purpose
  240|    124|  uint64_t number;
  241|    124|  FileType type;
  242|    124|  std::vector<std::string> files_to_delete;
  243|  1.28k|  for (std::string& filename : filenames) {
  ------------------
  |  Branch (243:30): [True: 1.28k, False: 124]
  ------------------
  244|  1.28k|    if (ParseFileName(filename, &number, &type)) {
  ------------------
  |  Branch (244:9): [True: 1.03k, False: 248]
  ------------------
  245|  1.03k|      bool keep = true;
  246|  1.03k|      switch (type) {
  ------------------
  |  Branch (246:15): [True: 1.03k, False: 0]
  ------------------
  247|    196|        case kLogFile:
  ------------------
  |  Branch (247:9): [True: 196, False: 840]
  ------------------
  248|    196|          keep = ((number >= versions_->LogNumber()) ||
  ------------------
  |  Branch (248:19): [True: 124, False: 72]
  ------------------
  249|     72|                  (number == versions_->PrevLogNumber()));
  ------------------
  |  Branch (249:19): [True: 0, False: 72]
  ------------------
  250|    196|          break;
  251|    224|        case kDescriptorFile:
  ------------------
  |  Branch (251:9): [True: 224, False: 812]
  ------------------
  252|       |          // Keep my manifest file, and any newer incarnations'
  253|       |          // (in case there is a race that allows other incarnations)
  254|    224|          keep = (number >= versions_->ManifestFileNumber());
  255|    224|          break;
  256|    172|        case kTableFile:
  ------------------
  |  Branch (256:9): [True: 172, False: 864]
  ------------------
  257|    172|          keep = (live.find(number) != live.end());
  258|    172|          break;
  259|      0|        case kTempFile:
  ------------------
  |  Branch (259:9): [True: 0, False: 1.03k]
  ------------------
  260|       |          // Any temp files that are currently being written to must
  261|       |          // be recorded in pending_outputs_, which is inserted into "live"
  262|      0|          keep = (live.find(number) != live.end());
  263|      0|          break;
  264|    124|        case kCurrentFile:
  ------------------
  |  Branch (264:9): [True: 124, False: 912]
  ------------------
  265|    248|        case kDBLockFile:
  ------------------
  |  Branch (265:9): [True: 124, False: 912]
  ------------------
  266|    444|        case kInfoLogFile:
  ------------------
  |  Branch (266:9): [True: 196, False: 840]
  ------------------
  267|    444|          keep = true;
  268|    444|          break;
  269|  1.03k|      }
  270|       |
  271|  1.03k|      if (!keep) {
  ------------------
  |  Branch (271:11): [True: 192, False: 844]
  ------------------
  272|    192|        files_to_delete.push_back(std::move(filename));
  273|    192|        if (type == kTableFile) {
  ------------------
  |  Branch (273:13): [True: 20, False: 172]
  ------------------
  274|     20|          table_cache_->Evict(number);
  275|     20|        }
  276|    192|        Log(options_.info_log, "Delete type=%d #%lld\n", static_cast<int>(type),
  277|    192|            static_cast<unsigned long long>(number));
  278|    192|      }
  279|  1.03k|    }
  280|  1.28k|  }
  281|       |
  282|       |  // While deleting all files unblock other threads. All files being deleted
  283|       |  // have unique names which will not collide with newly created files and
  284|       |  // are therefore safe to delete while allowing other threads to proceed.
  285|    124|  mutex_.Unlock();
  286|    192|  for (const std::string& filename : files_to_delete) {
  ------------------
  |  Branch (286:36): [True: 192, False: 124]
  ------------------
  287|    192|    env_->RemoveFile(dbname_ + "/" + filename);
  288|    192|  }
  289|    124|  mutex_.Lock();
  290|    124|}
_ZN7leveldb6DBImpl7RecoverEPNS_11VersionEditEPb:
  292|    100|Status DBImpl::Recover(VersionEdit* edit, bool* save_manifest) {
  293|    100|  mutex_.AssertHeld();
  294|       |
  295|       |  // Ignore error from CreateDir since the creation of the DB is
  296|       |  // committed only when the descriptor is created, and this directory
  297|       |  // may already exist from a previous failed creation attempt.
  298|    100|  env_->CreateDir(dbname_);
  299|    100|  assert(db_lock_ == nullptr);
  300|    100|  Status s = env_->LockFile(LockFileName(dbname_), &db_lock_);
  301|    100|  if (!s.ok()) {
  ------------------
  |  Branch (301:7): [True: 0, False: 100]
  ------------------
  302|      0|    return s;
  303|      0|  }
  304|       |
  305|    100|  if (!env_->FileExists(CurrentFileName(dbname_))) {
  ------------------
  |  Branch (305:7): [True: 47, False: 53]
  ------------------
  306|     47|    if (options_.create_if_missing) {
  ------------------
  |  Branch (306:9): [True: 47, False: 0]
  ------------------
  307|     47|      Log(options_.info_log, "Creating DB %s since it was missing.",
  308|     47|          dbname_.c_str());
  309|     47|      s = NewDB();
  310|     47|      if (!s.ok()) {
  ------------------
  |  Branch (310:11): [True: 0, False: 47]
  ------------------
  311|      0|        return s;
  312|      0|      }
  313|     47|    } else {
  314|      0|      return Status::InvalidArgument(
  315|      0|          dbname_, "does not exist (create_if_missing is false)");
  316|      0|    }
  317|     53|  } else {
  318|     53|    if (options_.error_if_exists) {
  ------------------
  |  Branch (318:9): [True: 0, False: 53]
  ------------------
  319|      0|      return Status::InvalidArgument(dbname_,
  320|      0|                                     "exists (error_if_exists is true)");
  321|      0|    }
  322|     53|  }
  323|       |
  324|    100|  s = versions_->Recover(save_manifest);
  325|    100|  if (!s.ok()) {
  ------------------
  |  Branch (325:7): [True: 0, False: 100]
  ------------------
  326|      0|    return s;
  327|      0|  }
  328|    100|  SequenceNumber max_sequence(0);
  329|       |
  330|       |  // Recover from all newer log files than the ones named in the
  331|       |  // descriptor (new log files may have been added by the previous
  332|       |  // incarnation without registering them in the descriptor).
  333|       |  //
  334|       |  // Note that PrevLogNumber() is no longer used, but we pay
  335|       |  // attention to it in case we are recovering a database
  336|       |  // produced by an older version of leveldb.
  337|    100|  const uint64_t min_log = versions_->LogNumber();
  338|    100|  const uint64_t prev_log = versions_->PrevLogNumber();
  339|    100|  std::vector<std::string> filenames;
  340|    100|  s = env_->GetChildren(dbname_, &filenames);
  341|    100|  if (!s.ok()) {
  ------------------
  |  Branch (341:7): [True: 0, False: 100]
  ------------------
  342|      0|    return s;
  343|      0|  }
  344|    100|  std::set<uint64_t> expected;
  345|    100|  versions_->AddLiveFiles(&expected);
  346|    100|  uint64_t number;
  347|    100|  FileType type;
  348|    100|  std::vector<uint64_t> logs;
  349|    883|  for (size_t i = 0; i < filenames.size(); i++) {
  ------------------
  |  Branch (349:22): [True: 783, False: 100]
  ------------------
  350|    783|    if (ParseFileName(filenames[i], &number, &type)) {
  ------------------
  |  Branch (350:9): [True: 583, False: 200]
  ------------------
  351|    583|      expected.erase(number);
  352|    583|      if (type == kLogFile && ((number >= min_log) || (number == prev_log)))
  ------------------
  |  Branch (352:11): [True: 54, False: 529]
  |  Branch (352:32): [True: 54, False: 0]
  |  Branch (352:55): [True: 0, False: 0]
  ------------------
  353|     54|        logs.push_back(number);
  354|    583|    }
  355|    783|  }
  356|    100|  if (!expected.empty()) {
  ------------------
  |  Branch (356:7): [True: 0, False: 100]
  ------------------
  357|      0|    char buf[50];
  358|      0|    std::snprintf(buf, sizeof(buf), "%d missing files; e.g.",
  359|      0|                  static_cast<int>(expected.size()));
  360|      0|    return Status::Corruption(buf, TableFileName(dbname_, *(expected.begin())));
  361|      0|  }
  362|       |
  363|       |  // Recover in the order in which the logs were generated
  364|    100|  std::sort(logs.begin(), logs.end());
  365|    154|  for (size_t i = 0; i < logs.size(); i++) {
  ------------------
  |  Branch (365:22): [True: 54, False: 100]
  ------------------
  366|     54|    s = RecoverLogFile(logs[i], (i == logs.size() - 1), save_manifest, edit,
  367|     54|                       &max_sequence);
  368|     54|    if (!s.ok()) {
  ------------------
  |  Branch (368:9): [True: 0, False: 54]
  ------------------
  369|      0|      return s;
  370|      0|    }
  371|       |
  372|       |    // The previous incarnation may not have written any MANIFEST
  373|       |    // records after allocating this log number.  So we manually
  374|       |    // update the file number allocation counter in VersionSet.
  375|     54|    versions_->MarkFileNumberUsed(logs[i]);
  376|     54|  }
  377|       |
  378|    100|  if (versions_->LastSequence() < max_sequence) {
  ------------------
  |  Branch (378:7): [True: 30, False: 70]
  ------------------
  379|     30|    versions_->SetLastSequence(max_sequence);
  380|     30|  }
  381|       |
  382|    100|  return Status::OK();
  383|    100|}
_ZN7leveldb6DBImpl14RecoverLogFileEmbPbPNS_11VersionEditEPm:
  387|     54|                              SequenceNumber* max_sequence) {
  388|     54|  struct LogReporter : public log::Reader::Reporter {
  389|     54|    Env* env;
  390|     54|    Logger* info_log;
  391|     54|    const char* fname;
  392|     54|    Status* status;  // null if options_.paranoid_checks==false
  393|     54|    void Corruption(size_t bytes, const Status& s) override {
  394|     54|      Log(info_log, "%s%s: dropping %d bytes; %s",
  395|     54|          (this->status == nullptr ? "(ignoring error) " : ""), fname,
  396|     54|          static_cast<int>(bytes), s.ToString().c_str());
  397|     54|      if (this->status != nullptr && this->status->ok()) *this->status = s;
  398|     54|    }
  399|     54|  };
  400|       |
  401|     54|  mutex_.AssertHeld();
  402|       |
  403|       |  // Open the log file
  404|     54|  std::string fname = LogFileName(dbname_, log_number);
  405|     54|  SequentialFile* file;
  406|     54|  Status status = env_->NewSequentialFile(fname, &file);
  407|     54|  if (!status.ok()) {
  ------------------
  |  Branch (407:7): [True: 0, False: 54]
  ------------------
  408|      0|    MaybeIgnoreError(&status);
  409|      0|    return status;
  410|      0|  }
  411|       |
  412|       |  // Create the log reader.
  413|     54|  LogReporter reporter;
  414|     54|  reporter.env = env_;
  415|     54|  reporter.info_log = options_.info_log;
  416|     54|  reporter.fname = fname.c_str();
  417|     54|  reporter.status = (options_.paranoid_checks ? &status : nullptr);
  ------------------
  |  Branch (417:22): [True: 0, False: 54]
  ------------------
  418|       |  // We intentionally make log::Reader do checksumming even if
  419|       |  // paranoid_checks==false so that corruptions cause entire commits
  420|       |  // to be skipped instead of propagating bad information (like overly
  421|       |  // large sequence numbers).
  422|     54|  log::Reader reader(file, &reporter, true /*checksum*/, 0 /*initial_offset*/);
  423|     54|  Log(options_.info_log, "Recovering log #%llu",
  424|     54|      (unsigned long long)log_number);
  425|       |
  426|       |  // Read all the records and add to a memtable
  427|     54|  std::string scratch;
  428|     54|  Slice record;
  429|     54|  WriteBatch batch;
  430|     54|  int compactions = 0;
  431|     54|  MemTable* mem = nullptr;
  432|    159|  while (reader.ReadRecord(&record, &scratch) && status.ok()) {
  ------------------
  |  Branch (432:10): [True: 105, False: 54]
  |  Branch (432:50): [True: 105, False: 0]
  ------------------
  433|    105|    if (record.size() < 12) {
  ------------------
  |  Branch (433:9): [True: 0, False: 105]
  ------------------
  434|      0|      reporter.Corruption(record.size(),
  435|      0|                          Status::Corruption("log record too small"));
  436|      0|      continue;
  437|      0|    }
  438|    105|    WriteBatchInternal::SetContents(&batch, record);
  439|       |
  440|    105|    if (mem == nullptr) {
  ------------------
  |  Branch (440:9): [True: 30, False: 75]
  ------------------
  441|     30|      mem = new MemTable(internal_comparator_);
  442|     30|      mem->Ref();
  443|     30|    }
  444|    105|    status = WriteBatchInternal::InsertInto(&batch, mem);
  445|    105|    MaybeIgnoreError(&status);
  446|    105|    if (!status.ok()) {
  ------------------
  |  Branch (446:9): [True: 0, False: 105]
  ------------------
  447|      0|      break;
  448|      0|    }
  449|    105|    const SequenceNumber last_seq = WriteBatchInternal::Sequence(&batch) +
  450|    105|                                    WriteBatchInternal::Count(&batch) - 1;
  451|    105|    if (last_seq > *max_sequence) {
  ------------------
  |  Branch (451:9): [True: 105, False: 0]
  ------------------
  452|    105|      *max_sequence = last_seq;
  453|    105|    }
  454|       |
  455|    105|    if (mem->ApproximateMemoryUsage() > options_.write_buffer_size) {
  ------------------
  |  Branch (455:9): [True: 0, False: 105]
  ------------------
  456|      0|      compactions++;
  457|      0|      *save_manifest = true;
  458|      0|      status = WriteLevel0Table(mem, edit, nullptr);
  459|      0|      mem->Unref();
  460|      0|      mem = nullptr;
  461|      0|      if (!status.ok()) {
  ------------------
  |  Branch (461:11): [True: 0, False: 0]
  ------------------
  462|       |        // Reflect errors immediately so that conditions like full
  463|       |        // file-systems cause the DB::Open() to fail.
  464|      0|        break;
  465|      0|      }
  466|      0|    }
  467|    105|  }
  468|       |
  469|     54|  delete file;
  470|       |
  471|       |  // See if we should keep reusing the last log file.
  472|     54|  if (status.ok() && options_.reuse_logs && last_log && compactions == 0) {
  ------------------
  |  Branch (472:7): [True: 54, False: 0]
  |  Branch (472:22): [True: 0, False: 54]
  |  Branch (472:45): [True: 0, False: 0]
  |  Branch (472:57): [True: 0, False: 0]
  ------------------
  473|      0|    assert(logfile_ == nullptr);
  474|      0|    assert(log_ == nullptr);
  475|      0|    assert(mem_ == nullptr);
  476|      0|    uint64_t lfile_size;
  477|      0|    if (env_->GetFileSize(fname, &lfile_size).ok() &&
  ------------------
  |  Branch (477:9): [True: 0, False: 0]
  |  Branch (477:9): [True: 0, False: 0]
  ------------------
  478|      0|        env_->NewAppendableFile(fname, &logfile_).ok()) {
  ------------------
  |  Branch (478:9): [True: 0, False: 0]
  ------------------
  479|      0|      Log(options_.info_log, "Reusing old log %s \n", fname.c_str());
  480|      0|      log_ = new log::Writer(logfile_, lfile_size);
  481|      0|      logfile_number_ = log_number;
  482|      0|      if (mem != nullptr) {
  ------------------
  |  Branch (482:11): [True: 0, False: 0]
  ------------------
  483|      0|        mem_ = mem;
  484|      0|        mem = nullptr;
  485|      0|      } else {
  486|       |        // mem can be nullptr if lognum exists but was empty.
  487|      0|        mem_ = new MemTable(internal_comparator_);
  488|      0|        mem_->Ref();
  489|      0|      }
  490|      0|    }
  491|      0|  }
  492|       |
  493|     54|  if (mem != nullptr) {
  ------------------
  |  Branch (493:7): [True: 30, False: 24]
  ------------------
  494|       |    // mem did not get reused; compact it.
  495|     30|    if (status.ok()) {
  ------------------
  |  Branch (495:9): [True: 30, False: 0]
  ------------------
  496|     30|      *save_manifest = true;
  497|     30|      status = WriteLevel0Table(mem, edit, nullptr);
  498|     30|    }
  499|     30|    mem->Unref();
  500|     30|  }
  501|       |
  502|     54|  return status;
  503|     54|}
_ZN7leveldb6DBImpl16WriteLevel0TableEPNS_8MemTableEPNS_11VersionEditEPNS_7VersionE:
  506|     48|                                Version* base) {
  507|     48|  mutex_.AssertHeld();
  508|     48|  const uint64_t start_micros = env_->NowMicros();
  509|     48|  FileMetaData meta;
  510|     48|  meta.number = versions_->NewFileNumber();
  511|     48|  pending_outputs_.insert(meta.number);
  512|     48|  Iterator* iter = mem->NewIterator();
  513|     48|  Log(options_.info_log, "Level-0 table #%llu: started",
  514|     48|      (unsigned long long)meta.number);
  515|       |
  516|     48|  Status s;
  517|     48|  {
  518|     48|    mutex_.Unlock();
  519|     48|    s = BuildTable(dbname_, env_, options_, table_cache_, iter, &meta);
  520|     48|    mutex_.Lock();
  521|     48|  }
  522|       |
  523|     48|  Log(options_.info_log, "Level-0 table #%llu: %lld bytes %s",
  524|     48|      (unsigned long long)meta.number, (unsigned long long)meta.file_size,
  525|     48|      s.ToString().c_str());
  526|     48|  delete iter;
  527|     48|  pending_outputs_.erase(meta.number);
  528|       |
  529|       |  // Note that if file_size is zero, the file has been deleted and
  530|       |  // should not be added to the manifest.
  531|     48|  int level = 0;
  532|     48|  if (s.ok() && meta.file_size > 0) {
  ------------------
  |  Branch (532:7): [True: 48, False: 0]
  |  Branch (532:17): [True: 36, False: 12]
  ------------------
  533|     36|    const Slice min_user_key = meta.smallest.user_key();
  534|     36|    const Slice max_user_key = meta.largest.user_key();
  535|     36|    if (base != nullptr) {
  ------------------
  |  Branch (535:9): [True: 6, False: 30]
  ------------------
  536|      6|      level = base->PickLevelForMemTableOutput(min_user_key, max_user_key);
  537|      6|    }
  538|     36|    edit->AddFile(level, meta.number, meta.file_size, meta.smallest,
  539|     36|                  meta.largest);
  540|     36|  }
  541|       |
  542|     48|  CompactionStats stats;
  543|     48|  stats.micros = env_->NowMicros() - start_micros;
  544|     48|  stats.bytes_written = meta.file_size;
  545|     48|  stats_[level].Add(stats);
  546|     48|  return s;
  547|     48|}
_ZN7leveldb6DBImpl15CompactMemTableEv:
  549|     18|void DBImpl::CompactMemTable() {
  550|     18|  mutex_.AssertHeld();
  551|     18|  assert(imm_ != nullptr);
  552|       |
  553|       |  // Save the contents of the memtable as a new Table
  554|     18|  VersionEdit edit;
  555|     18|  Version* base = versions_->current();
  556|     18|  base->Ref();
  557|     18|  Status s = WriteLevel0Table(imm_, &edit, base);
  558|     18|  base->Unref();
  559|       |
  560|     18|  if (s.ok() && shutting_down_.load(std::memory_order_acquire)) {
  ------------------
  |  Branch (560:7): [True: 18, False: 0]
  |  Branch (560:17): [True: 0, False: 18]
  ------------------
  561|      0|    s = Status::IOError("Deleting DB during memtable compaction");
  562|      0|  }
  563|       |
  564|       |  // Replace immutable memtable with the generated Table
  565|     18|  if (s.ok()) {
  ------------------
  |  Branch (565:7): [True: 18, False: 0]
  ------------------
  566|     18|    edit.SetPrevLogNumber(0);
  567|     18|    edit.SetLogNumber(logfile_number_);  // Earlier logs no longer needed
  568|     18|    s = versions_->LogAndApply(&edit, &mutex_);
  569|     18|  }
  570|       |
  571|     18|  if (s.ok()) {
  ------------------
  |  Branch (571:7): [True: 18, False: 0]
  ------------------
  572|       |    // Commit to the new state
  573|     18|    imm_->Unref();
  574|     18|    imm_ = nullptr;
  575|     18|    has_imm_.store(false, std::memory_order_release);
  576|     18|    RemoveObsoleteFiles();
  577|     18|  } else {
  578|      0|    RecordBackgroundError(s);
  579|      0|  }
  580|     18|}
_ZN7leveldb6DBImpl12CompactRangeEPKNS_5SliceES3_:
  582|     18|void DBImpl::CompactRange(const Slice* begin, const Slice* end) {
  583|     18|  int max_level_with_files = 1;
  584|     18|  {
  585|     18|    MutexLock l(&mutex_);
  586|     18|    Version* base = versions_->current();
  587|    126|    for (int level = 1; level < config::kNumLevels; level++) {
  ------------------
  |  Branch (587:25): [True: 108, False: 18]
  ------------------
  588|    108|      if (base->OverlapInLevel(level, begin, end)) {
  ------------------
  |  Branch (588:11): [True: 2, False: 106]
  ------------------
  589|      2|        max_level_with_files = level;
  590|      2|      }
  591|    108|    }
  592|     18|  }
  593|     18|  TEST_CompactMemTable();  // TODO(sanjay): Skip if memtable does not overlap
  594|     36|  for (int level = 0; level < max_level_with_files; level++) {
  ------------------
  |  Branch (594:23): [True: 18, False: 18]
  ------------------
  595|     18|    TEST_CompactRange(level, begin, end);
  596|     18|  }
  597|     18|}
_ZN7leveldb6DBImpl17TEST_CompactRangeEiPKNS_5SliceES3_:
  600|     18|                               const Slice* end) {
  601|     18|  assert(level >= 0);
  602|     18|  assert(level + 1 < config::kNumLevels);
  603|       |
  604|     18|  InternalKey begin_storage, end_storage;
  605|       |
  606|     18|  ManualCompaction manual;
  607|     18|  manual.level = level;
  608|     18|  manual.done = false;
  609|     18|  if (begin == nullptr) {
  ------------------
  |  Branch (609:7): [True: 0, False: 18]
  ------------------
  610|      0|    manual.begin = nullptr;
  611|     18|  } else {
  612|     18|    begin_storage = InternalKey(*begin, kMaxSequenceNumber, kValueTypeForSeek);
  613|     18|    manual.begin = &begin_storage;
  614|     18|  }
  615|     18|  if (end == nullptr) {
  ------------------
  |  Branch (615:7): [True: 0, False: 18]
  ------------------
  616|      0|    manual.end = nullptr;
  617|     18|  } else {
  618|     18|    end_storage = InternalKey(*end, 0, static_cast<ValueType>(0));
  619|     18|    manual.end = &end_storage;
  620|     18|  }
  621|       |
  622|     18|  MutexLock l(&mutex_);
  623|     60|  while (!manual.done && !shutting_down_.load(std::memory_order_acquire) &&
  ------------------
  |  Branch (623:10): [True: 42, False: 18]
  |  Branch (623:26): [True: 42, False: 0]
  ------------------
  624|     42|         bg_error_.ok()) {
  ------------------
  |  Branch (624:10): [True: 42, False: 0]
  ------------------
  625|     42|    if (manual_compaction_ == nullptr) {  // Idle
  ------------------
  |  Branch (625:9): [True: 21, False: 21]
  ------------------
  626|     21|      manual_compaction_ = &manual;
  627|     21|      MaybeScheduleCompaction();
  628|     21|    } else {  // Running either my compaction or another compaction.
  629|     21|      background_work_finished_signal_.Wait();
  630|     21|    }
  631|     42|  }
  632|       |  // Finish current background compaction in the case where
  633|       |  // `background_work_finished_signal_` was signalled due to an error.
  634|     19|  while (background_compaction_scheduled_) {
  ------------------
  |  Branch (634:10): [True: 1, False: 18]
  ------------------
  635|      1|    background_work_finished_signal_.Wait();
  636|      1|  }
  637|     18|  if (manual_compaction_ == &manual) {
  ------------------
  |  Branch (637:7): [True: 0, False: 18]
  ------------------
  638|       |    // Cancel my manual compaction since we aborted early for some reason.
  639|      0|    manual_compaction_ = nullptr;
  640|      0|  }
  641|     18|}
_ZN7leveldb6DBImpl20TEST_CompactMemTableEv:
  643|     18|Status DBImpl::TEST_CompactMemTable() {
  644|       |  // nullptr batch means just wait for earlier writes to be done
  645|     18|  Status s = Write(WriteOptions(), nullptr);
  646|     18|  if (s.ok()) {
  ------------------
  |  Branch (646:7): [True: 18, False: 0]
  ------------------
  647|       |    // Wait until the compaction completes
  648|     18|    MutexLock l(&mutex_);
  649|     36|    while (imm_ != nullptr && bg_error_.ok() &&
  ------------------
  |  Branch (649:12): [True: 18, False: 18]
  |  Branch (649:31): [True: 18, False: 0]
  ------------------
  650|     18|           !shutting_down_.load(std::memory_order_acquire)) {
  ------------------
  |  Branch (650:12): [True: 18, False: 0]
  ------------------
  651|     18|      background_work_finished_signal_.Wait();
  652|     18|    }
  653|     18|    if (imm_ != nullptr) {
  ------------------
  |  Branch (653:9): [True: 0, False: 18]
  ------------------
  654|      0|      s = bg_error_;
  655|      0|    }
  656|     18|  }
  657|     18|  return s;
  658|     18|}
_ZN7leveldb6DBImpl23MaybeScheduleCompactionEv:
  668|    184|void DBImpl::MaybeScheduleCompaction() {
  669|    184|  mutex_.AssertHeld();
  670|    184|  if (background_compaction_scheduled_) {
  ------------------
  |  Branch (670:7): [True: 4, False: 180]
  ------------------
  671|       |    // Already scheduled
  672|    180|  } else if (shutting_down_.load(std::memory_order_acquire)) {
  ------------------
  |  Branch (672:14): [True: 2, False: 178]
  ------------------
  673|       |    // DB is being deleted; no more background compactions
  674|    178|  } else if (!bg_error_.ok()) {
  ------------------
  |  Branch (674:14): [True: 0, False: 178]
  ------------------
  675|       |    // Already got an error; no more changes
  676|    178|  } else if (imm_ == nullptr && manual_compaction_ == nullptr &&
  ------------------
  |  Branch (676:14): [True: 161, False: 17]
  |  Branch (676:33): [True: 140, False: 21]
  ------------------
  677|    140|             !versions_->NeedsCompaction()) {
  ------------------
  |  Branch (677:14): [True: 133, False: 7]
  ------------------
  678|       |    // No work to be done
  679|    133|  } else {
  680|     45|    background_compaction_scheduled_ = true;
  681|     45|    env_->Schedule(&DBImpl::BGWork, this);
  682|     45|  }
  683|    184|}
_ZN7leveldb6DBImpl6BGWorkEPv:
  685|     45|void DBImpl::BGWork(void* db) {
  686|     45|  reinterpret_cast<DBImpl*>(db)->BackgroundCall();
  687|     45|}
_ZN7leveldb6DBImpl14BackgroundCallEv:
  689|     45|void DBImpl::BackgroundCall() {
  690|     45|  MutexLock l(&mutex_);
  691|     45|  assert(background_compaction_scheduled_);
  692|     45|  if (shutting_down_.load(std::memory_order_acquire)) {
  ------------------
  |  Branch (692:7): [True: 2, False: 43]
  ------------------
  693|       |    // No more background work when shutting down.
  694|     43|  } else if (!bg_error_.ok()) {
  ------------------
  |  Branch (694:14): [True: 0, False: 43]
  ------------------
  695|       |    // No more background work after a background error.
  696|     43|  } else {
  697|     43|    BackgroundCompaction();
  698|     43|  }
  699|       |
  700|     45|  background_compaction_scheduled_ = false;
  701|       |
  702|       |  // Previous compaction may have produced too many files in a level,
  703|       |  // so reschedule another compaction if needed.
  704|     45|  MaybeScheduleCompaction();
  705|     45|  background_work_finished_signal_.SignalAll();
  706|     45|}
_ZN7leveldb6DBImpl20BackgroundCompactionEv:
  708|     43|void DBImpl::BackgroundCompaction() {
  709|     43|  mutex_.AssertHeld();
  710|       |
  711|     43|  if (imm_ != nullptr) {
  ------------------
  |  Branch (711:7): [True: 18, False: 25]
  ------------------
  712|     18|    CompactMemTable();
  713|     18|    return;
  714|     18|  }
  715|       |
  716|     25|  Compaction* c;
  717|     25|  bool is_manual = (manual_compaction_ != nullptr);
  718|     25|  InternalKey manual_end;
  719|     25|  if (is_manual) {
  ------------------
  |  Branch (719:7): [True: 21, False: 4]
  ------------------
  720|     21|    ManualCompaction* m = manual_compaction_;
  721|     21|    c = versions_->CompactRange(m->level, m->begin, m->end);
  722|     21|    m->done = (c == nullptr);
  723|     21|    if (c != nullptr) {
  ------------------
  |  Branch (723:9): [True: 3, False: 18]
  ------------------
  724|      3|      manual_end = c->input(0, c->num_input_files(0) - 1)->largest;
  725|      3|    }
  726|     21|    Log(options_.info_log,
  727|     21|        "Manual compaction at level-%d from %s .. %s; will stop at %s\n",
  728|     21|        m->level, (m->begin ? m->begin->DebugString().c_str() : "(begin)"),
  ------------------
  |  Branch (728:20): [True: 21, False: 0]
  ------------------
  729|     21|        (m->end ? m->end->DebugString().c_str() : "(end)"),
  ------------------
  |  Branch (729:10): [True: 21, False: 0]
  ------------------
  730|     21|        (m->done ? "(end)" : manual_end.DebugString().c_str()));
  ------------------
  |  Branch (730:10): [True: 18, False: 3]
  ------------------
  731|     21|  } else {
  732|      4|    c = versions_->PickCompaction();
  733|      4|  }
  734|       |
  735|     25|  Status status;
  736|     25|  if (c == nullptr) {
  ------------------
  |  Branch (736:7): [True: 18, False: 7]
  ------------------
  737|       |    // Nothing to do
  738|     18|  } else if (!is_manual && c->IsTrivialMove()) {
  ------------------
  |  Branch (738:14): [True: 4, False: 3]
  |  Branch (738:28): [True: 1, False: 3]
  ------------------
  739|       |    // Move file to next level
  740|      1|    assert(c->num_input_files(0) == 1);
  741|      1|    FileMetaData* f = c->input(0, 0);
  742|      1|    c->edit()->RemoveFile(c->level(), f->number);
  743|      1|    c->edit()->AddFile(c->level() + 1, f->number, f->file_size, f->smallest,
  744|      1|                       f->largest);
  745|      1|    status = versions_->LogAndApply(c->edit(), &mutex_);
  746|      1|    if (!status.ok()) {
  ------------------
  |  Branch (746:9): [True: 0, False: 1]
  ------------------
  747|      0|      RecordBackgroundError(status);
  748|      0|    }
  749|      1|    VersionSet::LevelSummaryStorage tmp;
  750|      1|    Log(options_.info_log, "Moved #%lld to level-%d %lld bytes %s: %s\n",
  751|      1|        static_cast<unsigned long long>(f->number), c->level() + 1,
  752|      1|        static_cast<unsigned long long>(f->file_size),
  753|      1|        status.ToString().c_str(), versions_->LevelSummary(&tmp));
  754|      6|  } else {
  755|      6|    CompactionState* compact = new CompactionState(c);
  756|      6|    status = DoCompactionWork(compact);
  757|      6|    if (!status.ok()) {
  ------------------
  |  Branch (757:9): [True: 0, False: 6]
  ------------------
  758|      0|      RecordBackgroundError(status);
  759|      0|    }
  760|      6|    CleanupCompaction(compact);
  761|      6|    c->ReleaseInputs();
  762|      6|    RemoveObsoleteFiles();
  763|      6|  }
  764|     25|  delete c;
  765|       |
  766|     25|  if (status.ok()) {
  ------------------
  |  Branch (766:7): [True: 25, False: 0]
  ------------------
  767|       |    // Done
  768|     25|  } else if (shutting_down_.load(std::memory_order_acquire)) {
  ------------------
  |  Branch (768:14): [True: 0, False: 0]
  ------------------
  769|       |    // Ignore compaction errors found during shutting down
  770|      0|  } else {
  771|      0|    Log(options_.info_log, "Compaction error: %s", status.ToString().c_str());
  772|      0|  }
  773|       |
  774|     25|  if (is_manual) {
  ------------------
  |  Branch (774:7): [True: 21, False: 4]
  ------------------
  775|     21|    ManualCompaction* m = manual_compaction_;
  776|     21|    if (!status.ok()) {
  ------------------
  |  Branch (776:9): [True: 0, False: 21]
  ------------------
  777|      0|      m->done = true;
  778|      0|    }
  779|     21|    if (!m->done) {
  ------------------
  |  Branch (779:9): [True: 3, False: 18]
  ------------------
  780|       |      // We only compacted part of the requested range.  Update *m
  781|       |      // to the range that is left to be compacted.
  782|      3|      m->tmp_storage = manual_end;
  783|      3|      m->begin = &m->tmp_storage;
  784|      3|    }
  785|     21|    manual_compaction_ = nullptr;
  786|     21|  }
  787|     25|}
_ZN7leveldb6DBImpl17CleanupCompactionEPNS0_15CompactionStateE:
  789|      6|void DBImpl::CleanupCompaction(CompactionState* compact) {
  790|      6|  mutex_.AssertHeld();
  791|      6|  if (compact->builder != nullptr) {
  ------------------
  |  Branch (791:7): [True: 0, False: 6]
  ------------------
  792|       |    // May happen if we get a shutdown call in the middle of compaction
  793|      0|    compact->builder->Abandon();
  794|      0|    delete compact->builder;
  795|      6|  } else {
  796|      6|    assert(compact->outfile == nullptr);
  797|      6|  }
  798|      6|  delete compact->outfile;
  799|     12|  for (size_t i = 0; i < compact->outputs.size(); i++) {
  ------------------
  |  Branch (799:22): [True: 6, False: 6]
  ------------------
  800|      6|    const CompactionState::Output& out = compact->outputs[i];
  801|      6|    pending_outputs_.erase(out.number);
  802|      6|  }
  803|      6|  delete compact;
  804|      6|}
_ZN7leveldb6DBImpl24OpenCompactionOutputFileEPNS0_15CompactionStateE:
  806|      6|Status DBImpl::OpenCompactionOutputFile(CompactionState* compact) {
  807|      6|  assert(compact != nullptr);
  808|      6|  assert(compact->builder == nullptr);
  809|      6|  uint64_t file_number;
  810|      6|  {
  811|      6|    mutex_.Lock();
  812|      6|    file_number = versions_->NewFileNumber();
  813|      6|    pending_outputs_.insert(file_number);
  814|      6|    CompactionState::Output out;
  815|      6|    out.number = file_number;
  816|      6|    out.smallest.Clear();
  817|      6|    out.largest.Clear();
  818|      6|    compact->outputs.push_back(out);
  819|      6|    mutex_.Unlock();
  820|      6|  }
  821|       |
  822|       |  // Make the output file
  823|      6|  std::string fname = TableFileName(dbname_, file_number);
  824|      6|  Status s = env_->NewWritableFile(fname, &compact->outfile);
  825|      6|  if (s.ok()) {
  ------------------
  |  Branch (825:7): [True: 6, False: 0]
  ------------------
  826|      6|    compact->builder = new TableBuilder(options_, compact->outfile);
  827|      6|  }
  828|      6|  return s;
  829|      6|}
_ZN7leveldb6DBImpl26FinishCompactionOutputFileEPNS0_15CompactionStateEPNS_8IteratorE:
  832|      6|                                          Iterator* input) {
  833|      6|  assert(compact != nullptr);
  834|      6|  assert(compact->outfile != nullptr);
  835|      6|  assert(compact->builder != nullptr);
  836|       |
  837|      6|  const uint64_t output_number = compact->current_output()->number;
  838|      6|  assert(output_number != 0);
  839|       |
  840|       |  // Check for iterator errors
  841|      6|  Status s = input->status();
  842|      6|  const uint64_t current_entries = compact->builder->NumEntries();
  843|      6|  if (s.ok()) {
  ------------------
  |  Branch (843:7): [True: 6, False: 0]
  ------------------
  844|      6|    s = compact->builder->Finish();
  845|      6|  } else {
  846|      0|    compact->builder->Abandon();
  847|      0|  }
  848|      6|  const uint64_t current_bytes = compact->builder->FileSize();
  849|      6|  compact->current_output()->file_size = current_bytes;
  850|      6|  compact->total_bytes += current_bytes;
  851|      6|  delete compact->builder;
  852|      6|  compact->builder = nullptr;
  853|       |
  854|       |  // Finish and check for file errors
  855|      6|  if (s.ok()) {
  ------------------
  |  Branch (855:7): [True: 6, False: 0]
  ------------------
  856|      6|    s = compact->outfile->Sync();
  857|      6|  }
  858|      6|  if (s.ok()) {
  ------------------
  |  Branch (858:7): [True: 6, False: 0]
  ------------------
  859|      6|    s = compact->outfile->Close();
  860|      6|  }
  861|      6|  delete compact->outfile;
  862|      6|  compact->outfile = nullptr;
  863|       |
  864|      6|  if (s.ok() && current_entries > 0) {
  ------------------
  |  Branch (864:7): [True: 6, False: 0]
  |  Branch (864:17): [True: 6, False: 0]
  ------------------
  865|       |    // Verify that the table is usable
  866|      6|    Iterator* iter =
  867|      6|        table_cache_->NewIterator(ReadOptions(), output_number, current_bytes);
  868|      6|    s = iter->status();
  869|      6|    delete iter;
  870|      6|    if (s.ok()) {
  ------------------
  |  Branch (870:9): [True: 6, False: 0]
  ------------------
  871|      6|      Log(options_.info_log, "Generated table #%llu@%d: %lld keys, %lld bytes",
  872|      6|          (unsigned long long)output_number, compact->compaction->level(),
  873|      6|          (unsigned long long)current_entries,
  874|      6|          (unsigned long long)current_bytes);
  875|      6|    }
  876|      6|  }
  877|      6|  return s;
  878|      6|}
_ZN7leveldb6DBImpl24InstallCompactionResultsEPNS0_15CompactionStateE:
  880|      6|Status DBImpl::InstallCompactionResults(CompactionState* compact) {
  881|      6|  mutex_.AssertHeld();
  882|      6|  Log(options_.info_log, "Compacted %d@%d + %d@%d files => %lld bytes",
  883|      6|      compact->compaction->num_input_files(0), compact->compaction->level(),
  884|      6|      compact->compaction->num_input_files(1), compact->compaction->level() + 1,
  885|      6|      static_cast<long long>(compact->total_bytes));
  886|       |
  887|       |  // Add compaction outputs
  888|      6|  compact->compaction->AddInputDeletions(compact->compaction->edit());
  889|      6|  const int level = compact->compaction->level();
  890|     12|  for (size_t i = 0; i < compact->outputs.size(); i++) {
  ------------------
  |  Branch (890:22): [True: 6, False: 6]
  ------------------
  891|      6|    const CompactionState::Output& out = compact->outputs[i];
  892|      6|    compact->compaction->edit()->AddFile(level + 1, out.number, out.file_size,
  893|      6|                                         out.smallest, out.largest);
  894|      6|  }
  895|      6|  return versions_->LogAndApply(compact->compaction->edit(), &mutex_);
  896|      6|}
_ZN7leveldb6DBImpl16DoCompactionWorkEPNS0_15CompactionStateE:
  898|      6|Status DBImpl::DoCompactionWork(CompactionState* compact) {
  899|      6|  const uint64_t start_micros = env_->NowMicros();
  900|      6|  int64_t imm_micros = 0;  // Micros spent doing imm_ compactions
  901|       |
  902|      6|  Log(options_.info_log, "Compacting %d@%d + %d@%d files",
  903|      6|      compact->compaction->num_input_files(0), compact->compaction->level(),
  904|      6|      compact->compaction->num_input_files(1),
  905|      6|      compact->compaction->level() + 1);
  906|       |
  907|      6|  assert(versions_->NumLevelFiles(compact->compaction->level()) > 0);
  908|      6|  assert(compact->builder == nullptr);
  909|      6|  assert(compact->outfile == nullptr);
  910|      6|  if (snapshots_.empty()) {
  ------------------
  |  Branch (910:7): [True: 6, False: 0]
  ------------------
  911|      6|    compact->smallest_snapshot = versions_->LastSequence();
  912|      6|  } else {
  913|      0|    compact->smallest_snapshot = snapshots_.oldest()->sequence_number();
  914|      0|  }
  915|       |
  916|      6|  Iterator* input = versions_->MakeInputIterator(compact->compaction);
  917|       |
  918|       |  // Release mutex while we're actually doing the compaction work
  919|      6|  mutex_.Unlock();
  920|       |
  921|      6|  input->SeekToFirst();
  922|      6|  Status status;
  923|      6|  ParsedInternalKey ikey;
  924|      6|  std::string current_user_key;
  925|      6|  bool has_current_user_key = false;
  926|      6|  SequenceNumber last_sequence_for_key = kMaxSequenceNumber;
  927|    326|  while (input->Valid() && !shutting_down_.load(std::memory_order_acquire)) {
  ------------------
  |  Branch (927:10): [True: 320, False: 6]
  |  Branch (927:28): [True: 320, False: 0]
  ------------------
  928|       |    // Prioritize immutable compaction work
  929|    320|    if (has_imm_.load(std::memory_order_relaxed)) {
  ------------------
  |  Branch (929:9): [True: 0, False: 320]
  ------------------
  930|      0|      const uint64_t imm_start = env_->NowMicros();
  931|      0|      mutex_.Lock();
  932|      0|      if (imm_ != nullptr) {
  ------------------
  |  Branch (932:11): [True: 0, False: 0]
  ------------------
  933|      0|        CompactMemTable();
  934|       |        // Wake up MakeRoomForWrite() if necessary.
  935|      0|        background_work_finished_signal_.SignalAll();
  936|      0|      }
  937|      0|      mutex_.Unlock();
  938|      0|      imm_micros += (env_->NowMicros() - imm_start);
  939|      0|    }
  940|       |
  941|    320|    Slice key = input->key();
  942|    320|    if (compact->compaction->ShouldStopBefore(key) &&
  ------------------
  |  Branch (942:9): [True: 0, False: 320]
  ------------------
  943|      0|        compact->builder != nullptr) {
  ------------------
  |  Branch (943:9): [True: 0, False: 0]
  ------------------
  944|      0|      status = FinishCompactionOutputFile(compact, input);
  945|      0|      if (!status.ok()) {
  ------------------
  |  Branch (945:11): [True: 0, False: 0]
  ------------------
  946|      0|        break;
  947|      0|      }
  948|      0|    }
  949|       |
  950|       |    // Handle key/value, add to state, etc.
  951|    320|    bool drop = false;
  952|    320|    if (!ParseInternalKey(key, &ikey)) {
  ------------------
  |  Branch (952:9): [True: 0, False: 320]
  ------------------
  953|       |      // Do not hide error keys
  954|      0|      current_user_key.clear();
  955|      0|      has_current_user_key = false;
  956|      0|      last_sequence_for_key = kMaxSequenceNumber;
  957|    320|    } else {
  958|    320|      if (!has_current_user_key ||
  ------------------
  |  Branch (958:11): [True: 6, False: 314]
  |  Branch (958:11): [True: 320, False: 0]
  ------------------
  959|    314|          user_comparator()->Compare(ikey.user_key, Slice(current_user_key)) !=
  ------------------
  |  Branch (959:11): [True: 314, False: 0]
  ------------------
  960|    320|              0) {
  961|       |        // First occurrence of this user key
  962|    320|        current_user_key.assign(ikey.user_key.data(), ikey.user_key.size());
  963|    320|        has_current_user_key = true;
  964|    320|        last_sequence_for_key = kMaxSequenceNumber;
  965|    320|      }
  966|       |
  967|    320|      if (last_sequence_for_key <= compact->smallest_snapshot) {
  ------------------
  |  Branch (967:11): [True: 0, False: 320]
  ------------------
  968|       |        // Hidden by an newer entry for same user key
  969|      0|        drop = true;  // (A)
  970|    320|      } else if (ikey.type == kTypeDeletion &&
  ------------------
  |  Branch (970:18): [True: 6, False: 314]
  ------------------
  971|      6|                 ikey.sequence <= compact->smallest_snapshot &&
  ------------------
  |  Branch (971:18): [True: 6, False: 0]
  ------------------
  972|      6|                 compact->compaction->IsBaseLevelForKey(ikey.user_key)) {
  ------------------
  |  Branch (972:18): [True: 6, False: 0]
  ------------------
  973|       |        // For this user key:
  974|       |        // (1) there is no data in higher levels
  975|       |        // (2) data in lower levels will have larger sequence numbers
  976|       |        // (3) data in layers that are being compacted here and have
  977|       |        //     smaller sequence numbers will be dropped in the next
  978|       |        //     few iterations of this loop (by rule (A) above).
  979|       |        // Therefore this deletion marker is obsolete and can be dropped.
  980|      6|        drop = true;
  981|      6|      }
  982|       |
  983|    320|      last_sequence_for_key = ikey.sequence;
  984|    320|    }
  985|       |#if 0
  986|       |    Log(options_.info_log,
  987|       |        "  Compact: %s, seq %d, type: %d %d, drop: %d, is_base: %d, "
  988|       |        "%d smallest_snapshot: %d",
  989|       |        ikey.user_key.ToString().c_str(),
  990|       |        (int)ikey.sequence, ikey.type, kTypeValue, drop,
  991|       |        compact->compaction->IsBaseLevelForKey(ikey.user_key),
  992|       |        (int)last_sequence_for_key, (int)compact->smallest_snapshot);
  993|       |#endif
  994|       |
  995|    320|    if (!drop) {
  ------------------
  |  Branch (995:9): [True: 314, False: 6]
  ------------------
  996|       |      // Open output file if necessary
  997|    314|      if (compact->builder == nullptr) {
  ------------------
  |  Branch (997:11): [True: 6, False: 308]
  ------------------
  998|      6|        status = OpenCompactionOutputFile(compact);
  999|      6|        if (!status.ok()) {
  ------------------
  |  Branch (999:13): [True: 0, False: 6]
  ------------------
 1000|      0|          break;
 1001|      0|        }
 1002|      6|      }
 1003|    314|      if (compact->builder->NumEntries() == 0) {
  ------------------
  |  Branch (1003:11): [True: 6, False: 308]
  ------------------
 1004|      6|        compact->current_output()->smallest.DecodeFrom(key);
 1005|      6|      }
 1006|    314|      compact->current_output()->largest.DecodeFrom(key);
 1007|    314|      compact->builder->Add(key, input->value());
 1008|       |
 1009|       |      // Close output file if it is big enough
 1010|    314|      if (compact->builder->FileSize() >=
  ------------------
  |  Branch (1010:11): [True: 0, False: 314]
  ------------------
 1011|    314|          compact->compaction->MaxOutputFileSize()) {
 1012|      0|        status = FinishCompactionOutputFile(compact, input);
 1013|      0|        if (!status.ok()) {
  ------------------
  |  Branch (1013:13): [True: 0, False: 0]
  ------------------
 1014|      0|          break;
 1015|      0|        }
 1016|      0|      }
 1017|    314|    }
 1018|       |
 1019|    320|    input->Next();
 1020|    320|  }
 1021|       |
 1022|      6|  if (status.ok() && shutting_down_.load(std::memory_order_acquire)) {
  ------------------
  |  Branch (1022:7): [True: 6, False: 0]
  |  Branch (1022:22): [True: 0, False: 6]
  ------------------
 1023|      0|    status = Status::IOError("Deleting DB during compaction");
 1024|      0|  }
 1025|      6|  if (status.ok() && compact->builder != nullptr) {
  ------------------
  |  Branch (1025:7): [True: 6, False: 0]
  |  Branch (1025:22): [True: 6, False: 0]
  ------------------
 1026|      6|    status = FinishCompactionOutputFile(compact, input);
 1027|      6|  }
 1028|      6|  if (status.ok()) {
  ------------------
  |  Branch (1028:7): [True: 6, False: 0]
  ------------------
 1029|      6|    status = input->status();
 1030|      6|  }
 1031|      6|  delete input;
 1032|      6|  input = nullptr;
 1033|       |
 1034|      6|  CompactionStats stats;
 1035|      6|  stats.micros = env_->NowMicros() - start_micros - imm_micros;
 1036|     18|  for (int which = 0; which < 2; which++) {
  ------------------
  |  Branch (1036:23): [True: 12, False: 6]
  ------------------
 1037|     32|    for (int i = 0; i < compact->compaction->num_input_files(which); i++) {
  ------------------
  |  Branch (1037:21): [True: 20, False: 12]
  ------------------
 1038|     20|      stats.bytes_read += compact->compaction->input(which, i)->file_size;
 1039|     20|    }
 1040|     12|  }
 1041|     12|  for (size_t i = 0; i < compact->outputs.size(); i++) {
  ------------------
  |  Branch (1041:22): [True: 6, False: 6]
  ------------------
 1042|      6|    stats.bytes_written += compact->outputs[i].file_size;
 1043|      6|  }
 1044|       |
 1045|      6|  mutex_.Lock();
 1046|      6|  stats_[compact->compaction->level() + 1].Add(stats);
 1047|       |
 1048|      6|  if (status.ok()) {
  ------------------
  |  Branch (1048:7): [True: 6, False: 0]
  ------------------
 1049|      6|    status = InstallCompactionResults(compact);
 1050|      6|  }
 1051|      6|  if (!status.ok()) {
  ------------------
  |  Branch (1051:7): [True: 0, False: 6]
  ------------------
 1052|      0|    RecordBackgroundError(status);
 1053|      0|  }
 1054|      6|  VersionSet::LevelSummaryStorage tmp;
 1055|      6|  Log(options_.info_log, "compacted to: %s", versions_->LevelSummary(&tmp));
 1056|      6|  return status;
 1057|      6|}
_ZN7leveldb6DBImpl19NewInternalIteratorERKNS_11ReadOptionsEPmPj:
 1085|     34|                                      uint32_t* seed) {
 1086|     34|  mutex_.Lock();
 1087|     34|  *latest_snapshot = versions_->LastSequence();
 1088|       |
 1089|       |  // Collect together all needed child iterators
 1090|     34|  std::vector<Iterator*> list;
 1091|     34|  list.push_back(mem_->NewIterator());
 1092|     34|  mem_->Ref();
 1093|     34|  if (imm_ != nullptr) {
  ------------------
  |  Branch (1093:7): [True: 0, False: 34]
  ------------------
 1094|      0|    list.push_back(imm_->NewIterator());
 1095|      0|    imm_->Ref();
 1096|      0|  }
 1097|     34|  versions_->current()->AddIterators(options, &list);
 1098|     34|  Iterator* internal_iter =
 1099|     34|      NewMergingIterator(&internal_comparator_, &list[0], list.size());
 1100|     34|  versions_->current()->Ref();
 1101|       |
 1102|     34|  IterState* cleanup = new IterState(&mutex_, mem_, imm_, versions_->current());
 1103|     34|  internal_iter->RegisterCleanup(CleanupIteratorState, cleanup, nullptr);
 1104|       |
 1105|     34|  *seed = ++seed_;
 1106|     34|  mutex_.Unlock();
 1107|     34|  return internal_iter;
 1108|     34|}
_ZN7leveldb6DBImpl3GetERKNS_11ReadOptionsERKNS_5SliceEPNSt3__112basic_stringIcNS7_11char_traitsIcEENS7_9allocatorIcEEEE:
 1122|     22|                   std::string* value) {
 1123|     22|  Status s;
 1124|     22|  MutexLock l(&mutex_);
 1125|     22|  SequenceNumber snapshot;
 1126|     22|  if (options.snapshot != nullptr) {
  ------------------
  |  Branch (1126:7): [True: 0, False: 22]
  ------------------
 1127|      0|    snapshot =
 1128|      0|        static_cast<const SnapshotImpl*>(options.snapshot)->sequence_number();
 1129|     22|  } else {
 1130|     22|    snapshot = versions_->LastSequence();
 1131|     22|  }
 1132|       |
 1133|     22|  MemTable* mem = mem_;
 1134|     22|  MemTable* imm = imm_;
 1135|     22|  Version* current = versions_->current();
 1136|     22|  mem->Ref();
 1137|     22|  if (imm != nullptr) imm->Ref();
  ------------------
  |  Branch (1137:7): [True: 0, False: 22]
  ------------------
 1138|     22|  current->Ref();
 1139|       |
 1140|     22|  bool have_stat_update = false;
 1141|     22|  Version::GetStats stats;
 1142|       |
 1143|       |  // Unlock while reading from files and memtables
 1144|     22|  {
 1145|     22|    mutex_.Unlock();
 1146|       |    // First look in the memtable, then in the immutable memtable (if any).
 1147|     22|    LookupKey lkey(key, snapshot);
 1148|     22|    if (mem->Get(lkey, value, &s)) {
  ------------------
  |  Branch (1148:9): [True: 1, False: 21]
  ------------------
 1149|       |      // Done
 1150|     21|    } else if (imm != nullptr && imm->Get(lkey, value, &s)) {
  ------------------
  |  Branch (1150:16): [True: 0, False: 21]
  |  Branch (1150:34): [True: 0, False: 0]
  ------------------
 1151|       |      // Done
 1152|     21|    } else {
 1153|     21|      s = current->Get(options, lkey, value, &stats);
 1154|     21|      have_stat_update = true;
 1155|     21|    }
 1156|     22|    mutex_.Lock();
 1157|     22|  }
 1158|       |
 1159|     22|  if (have_stat_update && current->UpdateStats(stats)) {
  ------------------
  |  Branch (1159:7): [True: 21, False: 1]
  |  Branch (1159:27): [True: 0, False: 21]
  ------------------
 1160|      0|    MaybeScheduleCompaction();
 1161|      0|  }
 1162|     22|  mem->Unref();
 1163|     22|  if (imm != nullptr) imm->Unref();
  ------------------
  |  Branch (1163:7): [True: 0, False: 22]
  ------------------
 1164|     22|  current->Unref();
 1165|     22|  return s;
 1166|     22|}
_ZN7leveldb6DBImpl11NewIteratorERKNS_11ReadOptionsE:
 1168|     34|Iterator* DBImpl::NewIterator(const ReadOptions& options) {
 1169|     34|  SequenceNumber latest_snapshot;
 1170|     34|  uint32_t seed;
 1171|     34|  Iterator* iter = NewInternalIterator(options, &latest_snapshot, &seed);
 1172|     34|  return NewDBIterator(this, user_comparator(), iter,
 1173|     34|                       (options.snapshot != nullptr
  ------------------
  |  Branch (1173:25): [True: 24, False: 10]
  ------------------
 1174|     34|                            ? static_cast<const SnapshotImpl*>(options.snapshot)
 1175|     24|                                  ->sequence_number()
 1176|     34|                            : latest_snapshot),
 1177|     34|                       seed);
 1178|     34|}
_ZN7leveldb6DBImpl16RecordReadSampleENS_5SliceE:
 1180|      8|void DBImpl::RecordReadSample(Slice key) {
 1181|      8|  MutexLock l(&mutex_);
 1182|      8|  if (versions_->current()->RecordReadSample(key)) {
  ------------------
  |  Branch (1182:7): [True: 0, False: 8]
  ------------------
 1183|      0|    MaybeScheduleCompaction();
 1184|      0|  }
 1185|      8|}
_ZN7leveldb6DBImpl11GetSnapshotEv:
 1187|     24|const Snapshot* DBImpl::GetSnapshot() {
 1188|     24|  MutexLock l(&mutex_);
 1189|     24|  return snapshots_.New(versions_->LastSequence());
 1190|     24|}
_ZN7leveldb6DBImpl15ReleaseSnapshotEPKNS_8SnapshotE:
 1192|     24|void DBImpl::ReleaseSnapshot(const Snapshot* snapshot) {
 1193|     24|  MutexLock l(&mutex_);
 1194|     24|  snapshots_.Delete(static_cast<const SnapshotImpl*>(snapshot));
 1195|     24|}
_ZN7leveldb6DBImpl3PutERKNS_12WriteOptionsERKNS_5SliceES6_:
 1198|    418|Status DBImpl::Put(const WriteOptions& o, const Slice& key, const Slice& val) {
 1199|    418|  return DB::Put(o, key, val);
 1200|    418|}
_ZN7leveldb6DBImpl6DeleteERKNS_12WriteOptionsERKNS_5SliceE:
 1202|     16|Status DBImpl::Delete(const WriteOptions& options, const Slice& key) {
 1203|     16|  return DB::Delete(options, key);
 1204|     16|}
_ZN7leveldb6DBImpl5WriteERKNS_12WriteOptionsEPNS_10WriteBatchE:
 1206|    452|Status DBImpl::Write(const WriteOptions& options, WriteBatch* updates) {
 1207|    452|  Writer w(&mutex_);
 1208|    452|  w.batch = updates;
 1209|    452|  w.sync = options.sync;
 1210|    452|  w.done = false;
 1211|       |
 1212|    452|  MutexLock l(&mutex_);
 1213|    452|  writers_.push_back(&w);
 1214|    452|  while (!w.done && &w != writers_.front()) {
  ------------------
  |  Branch (1214:10): [True: 452, False: 0]
  |  Branch (1214:21): [True: 0, False: 452]
  ------------------
 1215|      0|    w.cv.Wait();
 1216|      0|  }
 1217|    452|  if (w.done) {
  ------------------
  |  Branch (1217:7): [True: 0, False: 452]
  ------------------
 1218|      0|    return w.status;
 1219|      0|  }
 1220|       |
 1221|       |  // May temporarily unlock and wait.
 1222|    452|  Status status = MakeRoomForWrite(updates == nullptr);
 1223|    452|  uint64_t last_sequence = versions_->LastSequence();
 1224|    452|  Writer* last_writer = &w;
 1225|    452|  if (status.ok() && updates != nullptr) {  // nullptr batch is for compactions
  ------------------
  |  Branch (1225:7): [True: 452, False: 0]
  |  Branch (1225:22): [True: 434, False: 18]
  ------------------
 1226|    434|    WriteBatch* write_batch = BuildBatchGroup(&last_writer);
 1227|    434|    WriteBatchInternal::SetSequence(write_batch, last_sequence + 1);
 1228|    434|    last_sequence += WriteBatchInternal::Count(write_batch);
 1229|       |
 1230|       |    // Add to log and apply to memtable.  We can release the lock
 1231|       |    // during this phase since &w is currently responsible for logging
 1232|       |    // and protects against concurrent loggers and concurrent writes
 1233|       |    // into mem_.
 1234|    434|    {
 1235|    434|      mutex_.Unlock();
 1236|    434|      status = log_->AddRecord(WriteBatchInternal::Contents(write_batch));
 1237|    434|      bool sync_error = false;
 1238|    434|      if (status.ok() && options.sync) {
  ------------------
  |  Branch (1238:11): [True: 434, False: 0]
  |  Branch (1238:26): [True: 0, False: 434]
  ------------------
 1239|      0|        status = logfile_->Sync();
 1240|      0|        if (!status.ok()) {
  ------------------
  |  Branch (1240:13): [True: 0, False: 0]
  ------------------
 1241|      0|          sync_error = true;
 1242|      0|        }
 1243|      0|      }
 1244|    434|      if (status.ok()) {
  ------------------
  |  Branch (1244:11): [True: 434, False: 0]
  ------------------
 1245|    434|        status = WriteBatchInternal::InsertInto(write_batch, mem_);
 1246|    434|      }
 1247|    434|      mutex_.Lock();
 1248|    434|      if (sync_error) {
  ------------------
  |  Branch (1248:11): [True: 0, False: 434]
  ------------------
 1249|       |        // The state of the log file is indeterminate: the log record we
 1250|       |        // just added may or may not show up when the DB is re-opened.
 1251|       |        // So we force the DB into a mode where all future writes fail.
 1252|      0|        RecordBackgroundError(status);
 1253|      0|      }
 1254|    434|    }
 1255|    434|    if (write_batch == tmp_batch_) tmp_batch_->Clear();
  ------------------
  |  Branch (1255:9): [True: 0, False: 434]
  ------------------
 1256|       |
 1257|    434|    versions_->SetLastSequence(last_sequence);
 1258|    434|  }
 1259|       |
 1260|    452|  while (true) {
  ------------------
  |  Branch (1260:10): [True: 452, Folded]
  ------------------
 1261|    452|    Writer* ready = writers_.front();
 1262|    452|    writers_.pop_front();
 1263|    452|    if (ready != &w) {
  ------------------
  |  Branch (1263:9): [True: 0, False: 452]
  ------------------
 1264|      0|      ready->status = status;
 1265|      0|      ready->done = true;
 1266|      0|      ready->cv.Signal();
 1267|      0|    }
 1268|    452|    if (ready == last_writer) break;
  ------------------
  |  Branch (1268:9): [True: 452, False: 0]
  ------------------
 1269|    452|  }
 1270|       |
 1271|       |  // Notify new head of write queue
 1272|    452|  if (!writers_.empty()) {
  ------------------
  |  Branch (1272:7): [True: 0, False: 452]
  ------------------
 1273|      0|    writers_.front()->cv.Signal();
 1274|      0|  }
 1275|       |
 1276|    452|  return status;
 1277|    452|}
_ZN7leveldb6DBImpl15BuildBatchGroupEPPNS0_6WriterE:
 1281|    434|WriteBatch* DBImpl::BuildBatchGroup(Writer** last_writer) {
 1282|    434|  mutex_.AssertHeld();
 1283|    434|  assert(!writers_.empty());
 1284|    434|  Writer* first = writers_.front();
 1285|    434|  WriteBatch* result = first->batch;
 1286|    434|  assert(result != nullptr);
 1287|       |
 1288|    434|  size_t size = WriteBatchInternal::ByteSize(first->batch);
 1289|       |
 1290|       |  // Allow the group to grow up to a maximum size, but if the
 1291|       |  // original write is small, limit the growth so we do not slow
 1292|       |  // down the small write too much.
 1293|    434|  size_t max_size = 1 << 20;
 1294|    434|  if (size <= (128 << 10)) {
  ------------------
  |  Branch (1294:7): [True: 387, False: 47]
  ------------------
 1295|    387|    max_size = size + (128 << 10);
 1296|    387|  }
 1297|       |
 1298|    434|  *last_writer = first;
 1299|    434|  std::deque<Writer*>::iterator iter = writers_.begin();
 1300|    434|  ++iter;  // Advance past "first"
 1301|    434|  for (; iter != writers_.end(); ++iter) {
  ------------------
  |  Branch (1301:10): [True: 0, False: 434]
  ------------------
 1302|      0|    Writer* w = *iter;
 1303|      0|    if (w->sync && !first->sync) {
  ------------------
  |  Branch (1303:9): [True: 0, False: 0]
  |  Branch (1303:20): [True: 0, False: 0]
  ------------------
 1304|       |      // Do not include a sync write into a batch handled by a non-sync write.
 1305|      0|      break;
 1306|      0|    }
 1307|       |
 1308|      0|    if (w->batch != nullptr) {
  ------------------
  |  Branch (1308:9): [True: 0, False: 0]
  ------------------
 1309|      0|      size += WriteBatchInternal::ByteSize(w->batch);
 1310|      0|      if (size > max_size) {
  ------------------
  |  Branch (1310:11): [True: 0, False: 0]
  ------------------
 1311|       |        // Do not make batch too big
 1312|      0|        break;
 1313|      0|      }
 1314|       |
 1315|       |      // Append to *result
 1316|      0|      if (result == first->batch) {
  ------------------
  |  Branch (1316:11): [True: 0, False: 0]
  ------------------
 1317|       |        // Switch to temporary batch instead of disturbing caller's batch
 1318|      0|        result = tmp_batch_;
 1319|      0|        assert(WriteBatchInternal::Count(result) == 0);
 1320|      0|        WriteBatchInternal::Append(result, first->batch);
 1321|      0|      }
 1322|      0|      WriteBatchInternal::Append(result, w->batch);
 1323|      0|    }
 1324|      0|    *last_writer = w;
 1325|      0|  }
 1326|    434|  return result;
 1327|    434|}
_ZN7leveldb6DBImpl16MakeRoomForWriteEb:
 1331|    452|Status DBImpl::MakeRoomForWrite(bool force) {
 1332|    452|  mutex_.AssertHeld();
 1333|    452|  assert(!writers_.empty());
 1334|    452|  bool allow_delay = !force;
 1335|    452|  Status s;
 1336|    470|  while (true) {
  ------------------
  |  Branch (1336:10): [True: 470, Folded]
  ------------------
 1337|    470|    if (!bg_error_.ok()) {
  ------------------
  |  Branch (1337:9): [True: 0, False: 470]
  ------------------
 1338|       |      // Yield previous error
 1339|      0|      s = bg_error_;
 1340|      0|      break;
 1341|    470|    } else if (allow_delay && versions_->NumLevelFiles(0) >=
  ------------------
  |  Branch (1341:16): [True: 434, False: 36]
  |  Branch (1341:31): [True: 0, False: 434]
  ------------------
 1342|    434|                                  config::kL0_SlowdownWritesTrigger) {
 1343|       |      // We are getting close to hitting a hard limit on the number of
 1344|       |      // L0 files.  Rather than delaying a single write by several
 1345|       |      // seconds when we hit the hard limit, start delaying each
 1346|       |      // individual write by 1ms to reduce latency variance.  Also,
 1347|       |      // this delay hands over some CPU to the compaction thread in
 1348|       |      // case it is sharing the same core as the writer.
 1349|      0|      mutex_.Unlock();
 1350|      0|      env_->SleepForMicroseconds(1000);
 1351|      0|      allow_delay = false;  // Do not delay a single write more than once
 1352|      0|      mutex_.Lock();
 1353|    470|    } else if (!force &&
  ------------------
  |  Branch (1353:16): [True: 452, False: 18]
  ------------------
 1354|    452|               (mem_->ApproximateMemoryUsage() <= options_.write_buffer_size)) {
  ------------------
  |  Branch (1354:16): [True: 452, False: 0]
  ------------------
 1355|       |      // There is room in current memtable
 1356|    452|      break;
 1357|    452|    } else if (imm_ != nullptr) {
  ------------------
  |  Branch (1357:16): [True: 0, False: 18]
  ------------------
 1358|       |      // We have filled up the current memtable, but the previous
 1359|       |      // one is still being compacted, so we wait.
 1360|      0|      Log(options_.info_log, "Current memtable full; waiting...\n");
 1361|      0|      background_work_finished_signal_.Wait();
 1362|     18|    } else if (versions_->NumLevelFiles(0) >= config::kL0_StopWritesTrigger) {
  ------------------
  |  Branch (1362:16): [True: 0, False: 18]
  ------------------
 1363|       |      // There are too many level-0 files.
 1364|      0|      Log(options_.info_log, "Too many L0 files; waiting...\n");
 1365|      0|      background_work_finished_signal_.Wait();
 1366|     18|    } else {
 1367|       |      // Attempt to switch to a new memtable and trigger compaction of old
 1368|     18|      assert(versions_->PrevLogNumber() == 0);
 1369|     18|      uint64_t new_log_number = versions_->NewFileNumber();
 1370|     18|      WritableFile* lfile = nullptr;
 1371|     18|      s = env_->NewWritableFile(LogFileName(dbname_, new_log_number), &lfile);
 1372|     18|      if (!s.ok()) {
  ------------------
  |  Branch (1372:11): [True: 0, False: 18]
  ------------------
 1373|       |        // Avoid chewing through file number space in a tight loop.
 1374|      0|        versions_->ReuseFileNumber(new_log_number);
 1375|      0|        break;
 1376|      0|      }
 1377|       |
 1378|     18|      delete log_;
 1379|       |
 1380|     18|      s = logfile_->Close();
 1381|     18|      if (!s.ok()) {
  ------------------
  |  Branch (1381:11): [True: 0, False: 18]
  ------------------
 1382|       |        // We may have lost some data written to the previous log file.
 1383|       |        // Switch to the new log file anyway, but record as a background
 1384|       |        // error so we do not attempt any more writes.
 1385|       |        //
 1386|       |        // We could perhaps attempt to save the memtable corresponding
 1387|       |        // to log file and suppress the error if that works, but that
 1388|       |        // would add more complexity in a critical code path.
 1389|      0|        RecordBackgroundError(s);
 1390|      0|      }
 1391|     18|      delete logfile_;
 1392|       |
 1393|     18|      logfile_ = lfile;
 1394|     18|      logfile_number_ = new_log_number;
 1395|     18|      log_ = new log::Writer(lfile);
 1396|     18|      imm_ = mem_;
 1397|     18|      has_imm_.store(true, std::memory_order_release);
 1398|     18|      mem_ = new MemTable(internal_comparator_);
 1399|     18|      mem_->Ref();
 1400|     18|      force = false;  // Do not force another compaction if have room
 1401|     18|      MaybeScheduleCompaction();
 1402|     18|    }
 1403|    470|  }
 1404|    452|  return s;
 1405|    452|}
_ZN7leveldb6DBImpl11GetPropertyERKNS_5SliceEPNSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEE:
 1407|     14|bool DBImpl::GetProperty(const Slice& property, std::string* value) {
 1408|     14|  value->clear();
 1409|       |
 1410|     14|  MutexLock l(&mutex_);
 1411|     14|  Slice in = property;
 1412|     14|  Slice prefix("leveldb.");
 1413|     14|  if (!in.starts_with(prefix)) return false;
  ------------------
  |  Branch (1413:7): [True: 14, False: 0]
  ------------------
 1414|      0|  in.remove_prefix(prefix.size());
 1415|       |
 1416|      0|  if (in.starts_with("num-files-at-level")) {
  ------------------
  |  Branch (1416:7): [True: 0, False: 0]
  ------------------
 1417|      0|    in.remove_prefix(strlen("num-files-at-level"));
 1418|      0|    uint64_t level;
 1419|      0|    bool ok = ConsumeDecimalNumber(&in, &level) && in.empty();
  ------------------
  |  Branch (1419:15): [True: 0, False: 0]
  |  Branch (1419:52): [True: 0, False: 0]
  ------------------
 1420|      0|    if (!ok || level >= config::kNumLevels) {
  ------------------
  |  Branch (1420:9): [True: 0, False: 0]
  |  Branch (1420:16): [True: 0, False: 0]
  ------------------
 1421|      0|      return false;
 1422|      0|    } else {
 1423|      0|      char buf[100];
 1424|      0|      std::snprintf(buf, sizeof(buf), "%d",
 1425|      0|                    versions_->NumLevelFiles(static_cast<int>(level)));
 1426|      0|      *value = buf;
 1427|      0|      return true;
 1428|      0|    }
 1429|      0|  } else if (in == "stats") {
  ------------------
  |  Branch (1429:14): [True: 0, False: 0]
  ------------------
 1430|      0|    char buf[200];
 1431|      0|    std::snprintf(buf, sizeof(buf),
 1432|      0|                  "                               Compactions\n"
 1433|      0|                  "Level  Files Size(MB) Time(sec) Read(MB) Write(MB)\n"
 1434|      0|                  "--------------------------------------------------\n");
 1435|      0|    value->append(buf);
 1436|      0|    for (int level = 0; level < config::kNumLevels; level++) {
  ------------------
  |  Branch (1436:25): [True: 0, False: 0]
  ------------------
 1437|      0|      int files = versions_->NumLevelFiles(level);
 1438|      0|      if (stats_[level].micros > 0 || files > 0) {
  ------------------
  |  Branch (1438:11): [True: 0, False: 0]
  |  Branch (1438:39): [True: 0, False: 0]
  ------------------
 1439|      0|        std::snprintf(buf, sizeof(buf), "%3d %8d %8.0f %9.0f %8.0f %9.0f\n",
 1440|      0|                      level, files, versions_->NumLevelBytes(level) / 1048576.0,
 1441|      0|                      stats_[level].micros / 1e6,
 1442|      0|                      stats_[level].bytes_read / 1048576.0,
 1443|      0|                      stats_[level].bytes_written / 1048576.0);
 1444|      0|        value->append(buf);
 1445|      0|      }
 1446|      0|    }
 1447|      0|    return true;
 1448|      0|  } else if (in == "sstables") {
  ------------------
  |  Branch (1448:14): [True: 0, False: 0]
  ------------------
 1449|      0|    *value = versions_->current()->DebugString();
 1450|      0|    return true;
 1451|      0|  } else if (in == "approximate-memory-usage") {
  ------------------
  |  Branch (1451:14): [True: 0, False: 0]
  ------------------
 1452|      0|    size_t total_usage = options_.block_cache->TotalCharge();
 1453|      0|    if (mem_) {
  ------------------
  |  Branch (1453:9): [True: 0, False: 0]
  ------------------
 1454|      0|      total_usage += mem_->ApproximateMemoryUsage();
 1455|      0|    }
 1456|      0|    if (imm_) {
  ------------------
  |  Branch (1456:9): [True: 0, False: 0]
  ------------------
 1457|      0|      total_usage += imm_->ApproximateMemoryUsage();
 1458|      0|    }
 1459|      0|    char buf[50];
 1460|      0|    std::snprintf(buf, sizeof(buf), "%llu",
 1461|      0|                  static_cast<unsigned long long>(total_usage));
 1462|      0|    value->append(buf);
 1463|      0|    return true;
 1464|      0|  }
 1465|       |
 1466|      0|  return false;
 1467|      0|}
_ZN7leveldb2DB3PutERKNS_12WriteOptionsERKNS_5SliceES6_:
 1489|    418|Status DB::Put(const WriteOptions& opt, const Slice& key, const Slice& value) {
 1490|    418|  WriteBatch batch;
 1491|    418|  batch.Put(key, value);
 1492|    418|  return Write(opt, &batch);
 1493|    418|}
_ZN7leveldb2DB6DeleteERKNS_12WriteOptionsERKNS_5SliceE:
 1495|     16|Status DB::Delete(const WriteOptions& opt, const Slice& key) {
 1496|     16|  WriteBatch batch;
 1497|     16|  batch.Delete(key);
 1498|     16|  return Write(opt, &batch);
 1499|     16|}
_ZN7leveldb2DBD2Ev:
 1501|    100|DB::~DB() = default;
_ZN7leveldb2DB4OpenERKNS_7OptionsERKNSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEPPS0_:
 1503|    100|Status DB::Open(const Options& options, const std::string& dbname, DB** dbptr) {
 1504|    100|  *dbptr = nullptr;
 1505|       |
 1506|    100|  DBImpl* impl = new DBImpl(options, dbname);
 1507|    100|  impl->mutex_.Lock();
 1508|    100|  VersionEdit edit;
 1509|       |  // Recover handles create_if_missing, error_if_exists
 1510|    100|  bool save_manifest = false;
 1511|    100|  Status s = impl->Recover(&edit, &save_manifest);
 1512|    100|  if (s.ok() && impl->mem_ == nullptr) {
  ------------------
  |  Branch (1512:7): [True: 100, False: 0]
  |  Branch (1512:17): [True: 100, False: 0]
  ------------------
 1513|       |    // Create new log and a corresponding memtable.
 1514|    100|    uint64_t new_log_number = impl->versions_->NewFileNumber();
 1515|    100|    WritableFile* lfile;
 1516|    100|    s = options.env->NewWritableFile(LogFileName(dbname, new_log_number),
 1517|    100|                                     &lfile);
 1518|    100|    if (s.ok()) {
  ------------------
  |  Branch (1518:9): [True: 100, False: 0]
  ------------------
 1519|    100|      edit.SetLogNumber(new_log_number);
 1520|    100|      impl->logfile_ = lfile;
 1521|    100|      impl->logfile_number_ = new_log_number;
 1522|    100|      impl->log_ = new log::Writer(lfile);
 1523|    100|      impl->mem_ = new MemTable(impl->internal_comparator_);
 1524|    100|      impl->mem_->Ref();
 1525|    100|    }
 1526|    100|  }
 1527|    100|  if (s.ok() && save_manifest) {
  ------------------
  |  Branch (1527:7): [True: 100, False: 0]
  |  Branch (1527:17): [True: 100, False: 0]
  ------------------
 1528|    100|    edit.SetPrevLogNumber(0);  // No older logs needed after recovery.
 1529|    100|    edit.SetLogNumber(impl->logfile_number_);
 1530|    100|    s = impl->versions_->LogAndApply(&edit, &impl->mutex_);
 1531|    100|  }
 1532|    100|  if (s.ok()) {
  ------------------
  |  Branch (1532:7): [True: 100, False: 0]
  ------------------
 1533|    100|    impl->RemoveObsoleteFiles();
 1534|    100|    impl->MaybeScheduleCompaction();
 1535|    100|  }
 1536|    100|  impl->mutex_.Unlock();
 1537|    100|  if (s.ok()) {
  ------------------
  |  Branch (1537:7): [True: 100, False: 0]
  ------------------
 1538|    100|    assert(impl->mem_ != nullptr);
 1539|    100|    *dbptr = impl;
 1540|    100|  } else {
 1541|      0|    delete impl;
 1542|      0|  }
 1543|    100|  return s;
 1544|    100|}
_ZN7leveldb8SnapshotD2Ev:
 1546|    124|Snapshot::~Snapshot() = default;
db_impl.cc:_ZN7leveldbL14TableCacheSizeERKNS_7OptionsE:
  121|    100|static int TableCacheSize(const Options& sanitized_options) {
  122|       |  // Reserve ten files or so for other uses and give the rest to TableCache.
  123|    100|  return sanitized_options.max_open_files - kNumNonTableCacheFiles;
  124|    100|}
_ZN7leveldb6DBImpl15CompactionStateC2EPNS_10CompactionE:
   65|      6|      : compaction(c),
   66|      6|        smallest_snapshot(0),
   67|      6|        outfile(nullptr),
   68|      6|        builder(nullptr),
   69|      6|        total_bytes(0) {}
_ZN7leveldb6DBImpl15CompactionState14current_outputEv:
   62|    332|  Output* current_output() { return &outputs[outputs.size() - 1]; }
db_impl.cc:_ZN7leveldb12_GLOBAL__N_19IterStateC2EPNS_4port5MutexEPNS_8MemTableES6_PNS_7VersionE:
 1068|     34|      : mu(mutex), version(version), mem(mem), imm(imm) {}
db_impl.cc:_ZN7leveldb12_GLOBAL__N_120CleanupIteratorStateEPvS1_:
 1071|     34|static void CleanupIteratorState(void* arg1, void* arg2) {
 1072|     34|  IterState* state = reinterpret_cast<IterState*>(arg1);
 1073|     34|  state->mu->Lock();
 1074|     34|  state->mem->Unref();
 1075|     34|  if (state->imm != nullptr) state->imm->Unref();
  ------------------
  |  Branch (1075:7): [True: 0, False: 34]
  ------------------
 1076|     34|  state->version->Unref();
 1077|     34|  state->mu->Unlock();
 1078|     34|  delete state;
 1079|     34|}
_ZN7leveldb6DBImpl6WriterC2EPNS_4port5MutexE:
   45|    452|      : batch(nullptr), sync(false), done(false), cv(mu) {}
db_impl.cc:_ZN7leveldbL11ClipToRangeIiiEEvPT_T0_S3_:
   90|    100|static void ClipToRange(T* ptr, V minvalue, V maxvalue) {
   91|    100|  if (static_cast<V>(*ptr) > maxvalue) *ptr = maxvalue;
  ------------------
  |  Branch (91:7): [True: 0, False: 100]
  ------------------
   92|    100|  if (static_cast<V>(*ptr) < minvalue) *ptr = minvalue;
  ------------------
  |  Branch (92:7): [True: 0, False: 100]
  ------------------
   93|    100|}
db_impl.cc:_ZN7leveldbL11ClipToRangeImiEEvPT_T0_S3_:
   90|    300|static void ClipToRange(T* ptr, V minvalue, V maxvalue) {
   91|    300|  if (static_cast<V>(*ptr) > maxvalue) *ptr = maxvalue;
  ------------------
  |  Branch (91:7): [True: 0, False: 300]
  ------------------
   92|    300|  if (static_cast<V>(*ptr) < minvalue) *ptr = minvalue;
  ------------------
  |  Branch (92:7): [True: 0, False: 300]
  ------------------
   93|    300|}

_ZN7leveldb6DBImpl15CompactionStatsC2Ev:
   91|    754|    CompactionStats() : micros(0), bytes_read(0), bytes_written(0) {}
_ZNK7leveldb6DBImpl15user_comparatorEv:
  154|    395|  const Comparator* user_comparator() const {
  155|    395|    return internal_comparator_.user_comparator();
  156|    395|  }
_ZN7leveldb6DBImpl15CompactionStats3AddERKS1_:
   93|     54|    void Add(const CompactionStats& c) {
   94|     54|      this->micros += c.micros;
   95|     54|      this->bytes_read += c.bytes_read;
   96|     54|      this->bytes_written += c.bytes_written;
   97|     54|    }

_ZN7leveldb13NewDBIteratorEPNS_6DBImplEPKNS_10ComparatorEPNS_8IteratorEmj:
  314|     34|                        uint32_t seed) {
  315|     34|  return new DBIter(db, user_key_comparator, internal_iter, sequence, seed);
  316|     34|}
db_iter.cc:_ZN7leveldb12_GLOBAL__N_16DBIterC2EPNS_6DBImplEPKNS_10ComparatorEPNS_8IteratorEmj:
   50|     34|      : db_(db),
   51|     34|        user_comparator_(cmp),
   52|     34|        iter_(iter),
   53|     34|        sequence_(s),
   54|     34|        direction_(kForward),
   55|     34|        valid_(false),
   56|     34|        rnd_(seed),
   57|     34|        bytes_until_read_sampling_(RandomCompactionPeriod()) {}
db_iter.cc:_ZN7leveldb12_GLOBAL__N_16DBIter22RandomCompactionPeriodEv:
  105|     42|  size_t RandomCompactionPeriod() {
  106|     42|    return rnd_.Uniform(2 * config::kReadBytesPeriod);
  107|     42|  }
db_iter.cc:_ZN7leveldb12_GLOBAL__N_16DBIterD2Ev:
   62|     34|  ~DBIter() override { delete iter_; }
db_iter.cc:_ZNK7leveldb12_GLOBAL__N_16DBIter5ValidEv:
   63|    184|  bool Valid() const override { return valid_; }
db_iter.cc:_ZN7leveldb12_GLOBAL__N_16DBIter11SeekToFirstEv:
  292|     10|void DBIter::SeekToFirst() {
  293|     10|  direction_ = kForward;
  294|     10|  ClearSavedValue();
  295|     10|  iter_->SeekToFirst();
  296|     10|  if (iter_->Valid()) {
  ------------------
  |  Branch (296:7): [True: 10, False: 0]
  ------------------
  297|     10|    FindNextUserEntry(false, &saved_key_ /* temporary storage */);
  298|     10|  } else {
  299|      0|    valid_ = false;
  300|      0|  }
  301|     10|}
db_iter.cc:_ZN7leveldb12_GLOBAL__N_16DBIter15ClearSavedValueEv:
   95|     10|  inline void ClearSavedValue() {
   96|     10|    if (saved_value_.capacity() > 1048576) {
  ------------------
  |  Branch (96:9): [True: 0, False: 10]
  ------------------
   97|      0|      std::string empty;
   98|      0|      swap(empty, saved_value_);
   99|     10|    } else {
  100|     10|      saved_value_.clear();
  101|     10|    }
  102|     10|  }
db_iter.cc:_ZN7leveldb12_GLOBAL__N_16DBIter17FindNextUserEntryEbPNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  177|    177|void DBIter::FindNextUserEntry(bool skipping, std::string* skip) {
  178|       |  // Loop until we hit an acceptable entry to yield
  179|    177|  assert(iter_->Valid());
  180|    177|  assert(direction_ == kForward);
  181|    178|  do {
  182|    178|    ParsedInternalKey ikey;
  183|    178|    if (ParseKey(&ikey) && ikey.sequence <= sequence_) {
  ------------------
  |  Branch (183:9): [True: 178, False: 0]
  |  Branch (183:28): [True: 178, False: 0]
  ------------------
  184|    178|      switch (ikey.type) {
  ------------------
  |  Branch (184:15): [True: 178, False: 0]
  ------------------
  185|      4|        case kTypeDeletion:
  ------------------
  |  Branch (185:9): [True: 4, False: 174]
  ------------------
  186|       |          // Arrange to skip all upcoming entries for this key since
  187|       |          // they are hidden by this deletion.
  188|      4|          SaveKey(ikey.user_key, skip);
  189|      4|          skipping = true;
  190|      4|          break;
  191|    174|        case kTypeValue:
  ------------------
  |  Branch (191:9): [True: 174, False: 4]
  ------------------
  192|    174|          if (skipping &&
  ------------------
  |  Branch (192:15): [True: 167, False: 7]
  |  Branch (192:15): [True: 0, False: 174]
  ------------------
  193|    167|              user_comparator_->Compare(ikey.user_key, *skip) <= 0) {
  ------------------
  |  Branch (193:15): [True: 0, False: 167]
  ------------------
  194|       |            // Entry hidden
  195|    174|          } else {
  196|    174|            valid_ = true;
  197|    174|            saved_key_.clear();
  198|    174|            return;
  199|    174|          }
  200|      0|          break;
  201|    178|      }
  202|    178|    }
  203|      4|    iter_->Next();
  204|      4|  } while (iter_->Valid());
  ------------------
  |  Branch (204:12): [True: 1, False: 3]
  ------------------
  205|      3|  saved_key_.clear();
  206|      3|  valid_ = false;
  207|      3|}
db_iter.cc:_ZN7leveldb12_GLOBAL__N_16DBIter8ParseKeyEPNS_17ParsedInternalKeyE:
  122|    178|inline bool DBIter::ParseKey(ParsedInternalKey* ikey) {
  123|    178|  Slice k = iter_->key();
  124|       |
  125|    178|  size_t bytes_read = k.size() + iter_->value().size();
  126|    186|  while (bytes_until_read_sampling_ < bytes_read) {
  ------------------
  |  Branch (126:10): [True: 8, False: 178]
  ------------------
  127|      8|    bytes_until_read_sampling_ += RandomCompactionPeriod();
  128|      8|    db_->RecordReadSample(k);
  129|      8|  }
  130|    178|  assert(bytes_until_read_sampling_ >= bytes_read);
  131|    178|  bytes_until_read_sampling_ -= bytes_read;
  132|       |
  133|    178|  if (!ParseInternalKey(k, ikey)) {
  ------------------
  |  Branch (133:7): [True: 0, False: 178]
  ------------------
  134|      0|    status_ = Status::Corruption("corrupted internal key in DBIter");
  135|      0|    return false;
  136|    178|  } else {
  137|    178|    return true;
  138|    178|  }
  139|    178|}
db_iter.cc:_ZN7leveldb12_GLOBAL__N_16DBIter7SaveKeyERKNS_5SliceEPNSt3__112basic_stringIcNS5_11char_traitsIcEENS5_9allocatorIcEEEE:
   91|    178|  inline void SaveKey(const Slice& k, std::string* dst) {
   92|    178|    dst->assign(k.data(), k.size());
   93|    178|  }
db_iter.cc:_ZN7leveldb12_GLOBAL__N_16DBIter4NextEv:
  141|    174|void DBIter::Next() {
  142|    174|  assert(valid_);
  143|       |
  144|    174|  if (direction_ == kReverse) {  // Switch directions?
  ------------------
  |  Branch (144:7): [True: 0, False: 174]
  ------------------
  145|      0|    direction_ = kForward;
  146|       |    // iter_ is pointing just before the entries for this->key(),
  147|       |    // so advance into the range of entries for this->key() and then
  148|       |    // use the normal skipping code below.
  149|      0|    if (!iter_->Valid()) {
  ------------------
  |  Branch (149:9): [True: 0, False: 0]
  ------------------
  150|      0|      iter_->SeekToFirst();
  151|      0|    } else {
  152|      0|      iter_->Next();
  153|      0|    }
  154|      0|    if (!iter_->Valid()) {
  ------------------
  |  Branch (154:9): [True: 0, False: 0]
  ------------------
  155|      0|      valid_ = false;
  156|      0|      saved_key_.clear();
  157|      0|      return;
  158|      0|    }
  159|       |    // saved_key_ already contains the key to skip past.
  160|    174|  } else {
  161|       |    // Store in saved_key_ the current key so we skip it below.
  162|    174|    SaveKey(ExtractUserKey(iter_->key()), &saved_key_);
  163|       |
  164|       |    // iter_ is pointing to current key. We can now safely move to the next to
  165|       |    // avoid checking current key.
  166|    174|    iter_->Next();
  167|    174|    if (!iter_->Valid()) {
  ------------------
  |  Branch (167:9): [True: 7, False: 167]
  ------------------
  168|      7|      valid_ = false;
  169|      7|      saved_key_.clear();
  170|      7|      return;
  171|      7|    }
  172|    174|  }
  173|       |
  174|    167|  FindNextUserEntry(true, &saved_key_);
  175|    167|}

_ZN7leveldb17AppendInternalKeyEPNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEERKNS_17ParsedInternalKeyE:
   21|    152|void AppendInternalKey(std::string* result, const ParsedInternalKey& key) {
   22|    152|  result->append(key.user_key.data(), key.user_key.size());
   23|    152|  PutFixed64(result, PackSequenceAndType(key.sequence, key.type));
   24|    152|}
_ZNK7leveldb17ParsedInternalKey11DebugStringEv:
   26|     45|std::string ParsedInternalKey::DebugString() const {
   27|     45|  std::ostringstream ss;
   28|     45|  ss << '\'' << EscapeString(user_key.ToString()) << "' @ " << sequence << " : "
   29|     45|     << static_cast<int>(type);
   30|     45|  return ss.str();
   31|     45|}
_ZNK7leveldb11InternalKey11DebugStringEv:
   33|     45|std::string InternalKey::DebugString() const {
   34|     45|  ParsedInternalKey parsed;
   35|     45|  if (ParseInternalKey(rep_, &parsed)) {
  ------------------
  |  Branch (35:7): [True: 45, False: 0]
  ------------------
   36|     45|    return parsed.DebugString();
   37|     45|  }
   38|      0|  std::ostringstream ss;
   39|      0|  ss << "(bad)" << EscapeString(rep_);
   40|      0|  return ss.str();
   41|     45|}
_ZNK7leveldb21InternalKeyComparator7CompareERKNS_5SliceES3_:
   47|  3.94k|int InternalKeyComparator::Compare(const Slice& akey, const Slice& bkey) const {
   48|       |  // Order by:
   49|       |  //    increasing user key (according to user-supplied comparator)
   50|       |  //    decreasing sequence number
   51|       |  //    decreasing type (though sequence# should be enough to disambiguate)
   52|  3.94k|  int r = user_comparator_->Compare(ExtractUserKey(akey), ExtractUserKey(bkey));
   53|  3.94k|  if (r == 0) {
  ------------------
  |  Branch (53:7): [True: 57, False: 3.88k]
  ------------------
   54|     57|    const uint64_t anum = DecodeFixed64(akey.data() + akey.size() - 8);
   55|     57|    const uint64_t bnum = DecodeFixed64(bkey.data() + bkey.size() - 8);
   56|     57|    if (anum > bnum) {
  ------------------
  |  Branch (56:9): [True: 0, False: 57]
  ------------------
   57|      0|      r = -1;
   58|     57|    } else if (anum < bnum) {
  ------------------
  |  Branch (58:16): [True: 56, False: 1]
  ------------------
   59|     56|      r = +1;
   60|     56|    }
   61|     57|  }
   62|  3.94k|  return r;
   63|  3.94k|}
_ZNK7leveldb21InternalKeyComparator21FindShortestSeparatorEPNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERKNS_5SliceE:
   66|    312|                                                  const Slice& limit) const {
   67|       |  // Attempt to shorten the user portion of the key
   68|    312|  Slice user_start = ExtractUserKey(*start);
   69|    312|  Slice user_limit = ExtractUserKey(limit);
   70|    312|  std::string tmp(user_start.data(), user_start.size());
   71|    312|  user_comparator_->FindShortestSeparator(&tmp, user_limit);
   72|    312|  if (tmp.size() < user_start.size() &&
  ------------------
  |  Branch (72:7): [True: 270, False: 42]
  |  Branch (72:7): [True: 270, False: 42]
  ------------------
   73|    270|      user_comparator_->Compare(user_start, tmp) < 0) {
  ------------------
  |  Branch (73:7): [True: 270, False: 0]
  ------------------
   74|       |    // User key has become shorter physically, but larger logically.
   75|       |    // Tack on the earliest possible number to the shortened user key.
   76|    270|    PutFixed64(&tmp,
   77|    270|               PackSequenceAndType(kMaxSequenceNumber, kValueTypeForSeek));
   78|    270|    assert(this->Compare(*start, tmp) < 0);
   79|       |    assert(this->Compare(tmp, limit) < 0);
   80|    270|    start->swap(tmp);
   81|    270|  }
   82|    312|}
_ZNK7leveldb21InternalKeyComparator18FindShortSuccessorEPNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
   84|     42|void InternalKeyComparator::FindShortSuccessor(std::string* key) const {
   85|     42|  Slice user_key = ExtractUserKey(*key);
   86|     42|  std::string tmp(user_key.data(), user_key.size());
   87|     42|  user_comparator_->FindShortSuccessor(&tmp);
   88|     42|  if (tmp.size() < user_key.size() &&
  ------------------
  |  Branch (88:7): [True: 41, False: 1]
  |  Branch (88:7): [True: 41, False: 1]
  ------------------
   89|     41|      user_comparator_->Compare(user_key, tmp) < 0) {
  ------------------
  |  Branch (89:7): [True: 41, False: 0]
  ------------------
   90|       |    // User key has become shorter physically, but larger logically.
   91|       |    // Tack on the earliest possible number to the shortened user key.
   92|     41|    PutFixed64(&tmp,
   93|     41|               PackSequenceAndType(kMaxSequenceNumber, kValueTypeForSeek));
   94|       |    assert(this->Compare(*key, tmp) < 0);
   95|     41|    key->swap(tmp);
   96|     41|  }
   97|     42|}
_ZN7leveldb9LookupKeyC2ERKNS_5SliceEm:
  117|     22|LookupKey::LookupKey(const Slice& user_key, SequenceNumber s) {
  118|     22|  size_t usize = user_key.size();
  119|     22|  size_t needed = usize + 13;  // A conservative estimate
  120|     22|  char* dst;
  121|     22|  if (needed <= sizeof(space_)) {
  ------------------
  |  Branch (121:7): [True: 14, False: 8]
  ------------------
  122|     14|    dst = space_;
  123|     14|  } else {
  124|      8|    dst = new char[needed];
  125|      8|  }
  126|     22|  start_ = dst;
  127|     22|  dst = EncodeVarint32(dst, usize + 8);
  128|     22|  kstart_ = dst;
  129|     22|  std::memcpy(dst, user_key.data(), usize);
  130|     22|  dst += usize;
  131|     22|  EncodeFixed64(dst, PackSequenceAndType(s, kValueTypeForSeek));
  132|     22|  dst += 8;
  133|     22|  end_ = dst;
  134|     22|}
dbformat.cc:_ZN7leveldbL19PackSequenceAndTypeEmNS_9ValueTypeE:
   15|    485|static uint64_t PackSequenceAndType(uint64_t seq, ValueType t) {
   16|    485|  assert(seq <= kMaxSequenceNumber);
   17|       |  assert(t <= kValueTypeForSeek);
   18|    485|  return (seq << 8) | t;
   19|    485|}

_ZN7leveldb21InternalKeyComparatorC2EPKNS_10ComparatorE:
  107|    100|  explicit InternalKeyComparator(const Comparator* c) : user_comparator_(c) {}
_ZN7leveldb20InternalFilterPolicyC2EPKNS_12FilterPolicyE:
  125|    100|  explicit InternalFilterPolicy(const FilterPolicy* p) : user_policy_(p) {}
_ZNK7leveldb21InternalKeyComparator15user_comparatorEv:
  114|    830|  const Comparator* user_comparator() const { return user_comparator_; }
_ZNK7leveldb11InternalKey8user_keyEv:
  154|    373|  Slice user_key() const { return ExtractUserKey(rep_); }
_ZN7leveldb14ExtractUserKeyERKNS_5SliceE:
   95|  9.09k|inline Slice ExtractUserKey(const Slice& internal_key) {
   96|       |  assert(internal_key.size() >= 8);
   97|  9.09k|  return Slice(internal_key.data(), internal_key.size() - 8);
   98|  9.09k|}
_ZN7leveldb11InternalKeyC2Ev:
  139|  1.00k|  InternalKey() {}  // Leave rep_ as empty to indicate it is invalid
_ZN7leveldb11InternalKeyC2ERKNS_5SliceEmNS_9ValueTypeE:
  140|    152|  InternalKey(const Slice& user_key, SequenceNumber s, ValueType t) {
  141|    152|    AppendInternalKey(&rep_, ParsedInternalKey(user_key, s, t));
  142|    152|  }
_ZN7leveldb17ParsedInternalKeyC2ERKNS_5SliceERKmNS_9ValueTypeE:
   76|    152|      : user_key(u), sequence(seq), type(t) {}
_ZN7leveldb11InternalKey5ClearEv:
  161|     48|  void Clear() { rep_.clear(); }
_ZN7leveldb17ParsedInternalKeyC2Ev:
   74|    247|  ParsedInternalKey() {}  // Intentionally left uninitialized (for speed)
_ZN7leveldb16ParseInternalKeyERKNS_5SliceEPNS_17ParsedInternalKeyE:
  172|    561|                             ParsedInternalKey* result) {
  173|    561|  const size_t n = internal_key.size();
  174|    561|  if (n < 8) return false;
  ------------------
  |  Branch (174:7): [True: 0, False: 561]
  ------------------
  175|    561|  uint64_t num = DecodeFixed64(internal_key.data() + n - 8);
  176|    561|  uint8_t c = num & 0xff;
  177|    561|  result->sequence = num >> 8;
  178|    561|  result->type = static_cast<ValueType>(c);
  179|    561|  result->user_key = Slice(internal_key.data(), n - 8);
  180|    561|  return (c <= static_cast<uint8_t>(kTypeValue));
  181|    561|}
_ZN7leveldb11InternalKey10DecodeFromERKNS_5SliceE:
  144|    617|  bool DecodeFrom(const Slice& s) {
  145|    617|    rep_.assign(s.data(), s.size());
  146|    617|    return !rep_.empty();
  147|    617|  }
_ZN7leveldb9LookupKeyD2Ev:
  218|     22|inline LookupKey::~LookupKey() {
  219|     22|  if (start_ != space_) delete[] start_;
  ------------------
  |  Branch (219:7): [True: 8, False: 14]
  ------------------
  220|     22|}
_ZNK7leveldb11InternalKey6EncodeEv:
  149|    920|  Slice Encode() const {
  150|       |    assert(!rep_.empty());
  151|    920|    return rep_;
  152|    920|  }
_ZNK7leveldb9LookupKey12memtable_keyEv:
  196|     22|  Slice memtable_key() const { return Slice(start_, end_ - start_); }
_ZNK7leveldb9LookupKey12internal_keyEv:
  199|     21|  Slice internal_key() const { return Slice(kstart_, end_ - kstart_); }
_ZNK7leveldb9LookupKey8user_keyEv:
  202|     26|  Slice user_key() const { return Slice(kstart_, end_ - kstart_ - 8); }
_ZNK7leveldb21InternalKeyComparator7CompareERKNS_11InternalKeyES3_:
  167|    241|                                          const InternalKey& b) const {
  168|    241|  return Compare(a.Encode(), b.Encode());
  169|    241|}

_ZN7leveldb11LogFileNameERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEm:
   28|    172|std::string LogFileName(const std::string& dbname, uint64_t number) {
   29|       |  assert(number > 0);
   30|    172|  return MakeFileName(dbname, number, "log");
   31|    172|}
_ZN7leveldb13TableFileNameERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEm:
   33|    126|std::string TableFileName(const std::string& dbname, uint64_t number) {
   34|       |  assert(number > 0);
   35|    126|  return MakeFileName(dbname, number, "ldb");
   36|    126|}
_ZN7leveldb18DescriptorFileNameERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEm:
   43|    294|std::string DescriptorFileName(const std::string& dbname, uint64_t number) {
   44|       |  assert(number > 0);
   45|    294|  char buf[100];
   46|    294|  std::snprintf(buf, sizeof(buf), "/MANIFEST-%06llu",
   47|    294|                static_cast<unsigned long long>(number));
   48|    294|  return dbname + buf;
   49|    294|}
_ZN7leveldb15CurrentFileNameERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
   51|    347|std::string CurrentFileName(const std::string& dbname) {
   52|    347|  return dbname + "/CURRENT";
   53|    347|}
_ZN7leveldb12LockFileNameERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
   55|    100|std::string LockFileName(const std::string& dbname) { return dbname + "/LOCK"; }
_ZN7leveldb12TempFileNameERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEm:
   57|    147|std::string TempFileName(const std::string& dbname, uint64_t number) {
   58|       |  assert(number > 0);
   59|    147|  return MakeFileName(dbname, number, "dbtmp");
   60|    147|}
_ZN7leveldb15InfoLogFileNameERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
   62|    200|std::string InfoLogFileName(const std::string& dbname) {
   63|    200|  return dbname + "/LOG";
   64|    200|}
_ZN7leveldb18OldInfoLogFileNameERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
   67|    100|std::string OldInfoLogFileName(const std::string& dbname) {
   68|    100|  return dbname + "/LOG.old";
   69|    100|}
_ZN7leveldb13ParseFileNameERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEPmPNS_8FileTypeE:
   79|  2.06k|                   FileType* type) {
   80|  2.06k|  Slice rest(filename);
   81|  2.06k|  if (rest == "CURRENT") {
  ------------------
  |  Branch (81:7): [True: 224, False: 1.84k]
  ------------------
   82|    224|    *number = 0;
   83|    224|    *type = kCurrentFile;
   84|  1.84k|  } else if (rest == "LOCK") {
  ------------------
  |  Branch (84:14): [True: 224, False: 1.61k]
  ------------------
   85|    224|    *number = 0;
   86|    224|    *type = kDBLockFile;
   87|  1.61k|  } else if (rest == "LOG" || rest == "LOG.old") {
  ------------------
  |  Branch (87:14): [True: 224, False: 1.39k]
  |  Branch (87:14): [True: 349, False: 1.27k]
  |  Branch (87:31): [True: 125, False: 1.27k]
  ------------------
   88|    349|    *number = 0;
   89|    349|    *type = kInfoLogFile;
   90|  1.27k|  } else if (rest.starts_with("MANIFEST-")) {
  ------------------
  |  Branch (90:14): [True: 325, False: 945]
  ------------------
   91|    325|    rest.remove_prefix(strlen("MANIFEST-"));
   92|    325|    uint64_t num;
   93|    325|    if (!ConsumeDecimalNumber(&rest, &num)) {
  ------------------
  |  Branch (93:9): [True: 0, False: 325]
  ------------------
   94|      0|      return false;
   95|      0|    }
   96|    325|    if (!rest.empty()) {
  ------------------
  |  Branch (96:9): [True: 0, False: 325]
  ------------------
   97|      0|      return false;
   98|      0|    }
   99|    325|    *type = kDescriptorFile;
  100|    325|    *number = num;
  101|    945|  } else {
  102|       |    // Avoid strtoull() to keep filename format independent of the
  103|       |    // current locale
  104|    945|    uint64_t num;
  105|    945|    if (!ConsumeDecimalNumber(&rest, &num)) {
  ------------------
  |  Branch (105:9): [True: 448, False: 497]
  ------------------
  106|    448|      return false;
  107|    448|    }
  108|    497|    Slice suffix = rest;
  109|    497|    if (suffix == Slice(".log")) {
  ------------------
  |  Branch (109:9): [True: 250, False: 247]
  ------------------
  110|    250|      *type = kLogFile;
  111|    250|    } else if (suffix == Slice(".sst") || suffix == Slice(".ldb")) {
  ------------------
  |  Branch (111:16): [True: 0, False: 247]
  |  Branch (111:16): [True: 247, False: 0]
  |  Branch (111:43): [True: 247, False: 0]
  ------------------
  112|    247|      *type = kTableFile;
  113|    247|    } else if (suffix == Slice(".dbtmp")) {
  ------------------
  |  Branch (113:16): [True: 0, False: 0]
  ------------------
  114|      0|      *type = kTempFile;
  115|      0|    } else {
  116|      0|      return false;
  117|      0|    }
  118|    497|    *number = num;
  119|    497|  }
  120|  1.61k|  return true;
  121|  2.06k|}
_ZN7leveldb14SetCurrentFileEPNS_3EnvERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEm:
  124|    147|                      uint64_t descriptor_number) {
  125|       |  // Remove leading "dbname/" and add newline to manifest file name
  126|    147|  std::string manifest = DescriptorFileName(dbname, descriptor_number);
  127|    147|  Slice contents = manifest;
  128|    147|  assert(contents.starts_with(dbname + "/"));
  129|    147|  contents.remove_prefix(dbname.size() + 1);
  130|    147|  std::string tmp = TempFileName(dbname, descriptor_number);
  131|    147|  Status s = WriteStringToFileSync(env, contents.ToString() + "\n", tmp);
  132|    147|  if (s.ok()) {
  ------------------
  |  Branch (132:7): [True: 147, False: 0]
  ------------------
  133|    147|    s = env->RenameFile(tmp, CurrentFileName(dbname));
  134|    147|  }
  135|    147|  if (!s.ok()) {
  ------------------
  |  Branch (135:7): [True: 0, False: 147]
  ------------------
  136|      0|    env->RemoveFile(tmp);
  137|      0|  }
  138|    147|  return s;
  139|    147|}
filename.cc:_ZN7leveldbL12MakeFileNameERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEmPKc:
   21|    445|                                const char* suffix) {
   22|    445|  char buf[100];
   23|    445|  std::snprintf(buf, sizeof(buf), "/%06llu.%s",
   24|    445|                static_cast<unsigned long long>(number), suffix);
   25|    445|  return dbname + buf;
   26|    445|}

_ZN7leveldb3log6Reader8ReporterD2Ev:
   16|    154|Reader::Reporter::~Reporter() = default;
_ZN7leveldb3log6ReaderC2EPNS_14SequentialFileEPNS1_8ReporterEbm:
   20|    154|    : file_(file),
   21|    154|      reporter_(reporter),
   22|    154|      checksum_(checksum),
   23|    154|      backing_store_(new char[kBlockSize]),
   24|    154|      buffer_(),
   25|    154|      eof_(false),
   26|    154|      last_record_offset_(0),
   27|    154|      end_of_buffer_offset_(0),
   28|    154|      initial_offset_(initial_offset),
   29|    154|      resyncing_(initial_offset > 0) {}
_ZN7leveldb3log6ReaderD2Ev:
   31|    154|Reader::~Reader() { delete[] backing_store_; }
_ZN7leveldb3log6Reader10ReadRecordEPNS_5SliceEPNSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEE:
   56|    429|bool Reader::ReadRecord(Slice* record, std::string* scratch) {
   57|    429|  if (last_record_offset_ < initial_offset_) {
  ------------------
  |  Branch (57:7): [True: 0, False: 429]
  ------------------
   58|      0|    if (!SkipToInitialBlock()) {
  ------------------
  |  Branch (58:9): [True: 0, False: 0]
  ------------------
   59|      0|      return false;
   60|      0|    }
   61|      0|  }
   62|       |
   63|    429|  scratch->clear();
   64|    429|  record->clear();
   65|    429|  bool in_fragmented_record = false;
   66|       |  // Record offset of the logical record that we're reading
   67|       |  // 0 is a dummy value to make compilers happy
   68|    429|  uint64_t prospective_record_offset = 0;
   69|       |
   70|    429|  Slice fragment;
   71|  1.23k|  while (true) {
  ------------------
  |  Branch (71:10): [True: 1.23k, Folded]
  ------------------
   72|  1.23k|    const unsigned int record_type = ReadPhysicalRecord(&fragment);
   73|       |
   74|       |    // ReadPhysicalRecord may have only had an empty trailer remaining in its
   75|       |    // internal buffer. Calculate the offset of the next physical record now
   76|       |    // that it has returned, properly accounting for its header size.
   77|  1.23k|    uint64_t physical_record_offset =
   78|  1.23k|        end_of_buffer_offset_ - buffer_.size() - kHeaderSize - fragment.size();
   79|       |
   80|  1.23k|    if (resyncing_) {
  ------------------
  |  Branch (80:9): [True: 0, False: 1.23k]
  ------------------
   81|      0|      if (record_type == kMiddleType) {
  ------------------
  |  Branch (81:11): [True: 0, False: 0]
  ------------------
   82|      0|        continue;
   83|      0|      } else if (record_type == kLastType) {
  ------------------
  |  Branch (83:18): [True: 0, False: 0]
  ------------------
   84|      0|        resyncing_ = false;
   85|      0|        continue;
   86|      0|      } else {
   87|      0|        resyncing_ = false;
   88|      0|      }
   89|      0|    }
   90|       |
   91|  1.23k|    switch (record_type) {
   92|    243|      case kFullType:
  ------------------
  |  Branch (92:7): [True: 243, False: 993]
  ------------------
   93|    243|        if (in_fragmented_record) {
  ------------------
  |  Branch (93:13): [True: 0, False: 243]
  ------------------
   94|       |          // Handle bug in earlier versions of log::Writer where
   95|       |          // it could emit an empty kFirstType record at the tail end
   96|       |          // of a block followed by a kFullType or kFirstType record
   97|       |          // at the beginning of the next block.
   98|      0|          if (!scratch->empty()) {
  ------------------
  |  Branch (98:15): [True: 0, False: 0]
  ------------------
   99|      0|            ReportCorruption(scratch->size(), "partial record without end(1)");
  100|      0|          }
  101|      0|        }
  102|    243|        prospective_record_offset = physical_record_offset;
  103|    243|        scratch->clear();
  104|    243|        *record = fragment;
  105|    243|        last_record_offset_ = prospective_record_offset;
  106|    243|        return true;
  107|       |
  108|     32|      case kFirstType:
  ------------------
  |  Branch (108:7): [True: 32, False: 1.20k]
  ------------------
  109|     32|        if (in_fragmented_record) {
  ------------------
  |  Branch (109:13): [True: 0, False: 32]
  ------------------
  110|       |          // Handle bug in earlier versions of log::Writer where
  111|       |          // it could emit an empty kFirstType record at the tail end
  112|       |          // of a block followed by a kFullType or kFirstType record
  113|       |          // at the beginning of the next block.
  114|      0|          if (!scratch->empty()) {
  ------------------
  |  Branch (114:15): [True: 0, False: 0]
  ------------------
  115|      0|            ReportCorruption(scratch->size(), "partial record without end(2)");
  116|      0|          }
  117|      0|        }
  118|     32|        prospective_record_offset = physical_record_offset;
  119|     32|        scratch->assign(fragment.data(), fragment.size());
  120|     32|        in_fragmented_record = true;
  121|     32|        break;
  122|       |
  123|    775|      case kMiddleType:
  ------------------
  |  Branch (123:7): [True: 775, False: 461]
  ------------------
  124|    775|        if (!in_fragmented_record) {
  ------------------
  |  Branch (124:13): [True: 0, False: 775]
  ------------------
  125|      0|          ReportCorruption(fragment.size(),
  126|      0|                           "missing start of fragmented record(1)");
  127|    775|        } else {
  128|    775|          scratch->append(fragment.data(), fragment.size());
  129|    775|        }
  130|    775|        break;
  131|       |
  132|     32|      case kLastType:
  ------------------
  |  Branch (132:7): [True: 32, False: 1.20k]
  ------------------
  133|     32|        if (!in_fragmented_record) {
  ------------------
  |  Branch (133:13): [True: 0, False: 32]
  ------------------
  134|      0|          ReportCorruption(fragment.size(),
  135|      0|                           "missing start of fragmented record(2)");
  136|     32|        } else {
  137|     32|          scratch->append(fragment.data(), fragment.size());
  138|     32|          *record = Slice(*scratch);
  139|     32|          last_record_offset_ = prospective_record_offset;
  140|     32|          return true;
  141|     32|        }
  142|      0|        break;
  143|       |
  144|    154|      case kEof:
  ------------------
  |  Branch (144:7): [True: 154, False: 1.08k]
  ------------------
  145|    154|        if (in_fragmented_record) {
  ------------------
  |  Branch (145:13): [True: 0, False: 154]
  ------------------
  146|       |          // This can be caused by the writer dying immediately after
  147|       |          // writing a physical record but before completing the next; don't
  148|       |          // treat it as a corruption, just ignore the entire logical record.
  149|      0|          scratch->clear();
  150|      0|        }
  151|    154|        return false;
  152|       |
  153|      0|      case kBadRecord:
  ------------------
  |  Branch (153:7): [True: 0, False: 1.23k]
  ------------------
  154|      0|        if (in_fragmented_record) {
  ------------------
  |  Branch (154:13): [True: 0, False: 0]
  ------------------
  155|      0|          ReportCorruption(scratch->size(), "error in middle of record");
  156|      0|          in_fragmented_record = false;
  157|      0|          scratch->clear();
  158|      0|        }
  159|      0|        break;
  160|       |
  161|      0|      default: {
  ------------------
  |  Branch (161:7): [True: 0, False: 1.23k]
  ------------------
  162|      0|        char buf[40];
  163|      0|        std::snprintf(buf, sizeof(buf), "unknown record type %u", record_type);
  164|      0|        ReportCorruption(
  165|      0|            (fragment.size() + (in_fragmented_record ? scratch->size() : 0)),
  ------------------
  |  Branch (165:33): [True: 0, False: 0]
  ------------------
  166|      0|            buf);
  167|      0|        in_fragmented_record = false;
  168|      0|        scratch->clear();
  169|      0|        break;
  170|     32|      }
  171|  1.23k|    }
  172|  1.23k|  }
  173|      0|  return false;
  174|    429|}
_ZN7leveldb3log6Reader18ReadPhysicalRecordEPNS_5SliceE:
  189|  1.23k|unsigned int Reader::ReadPhysicalRecord(Slice* result) {
  190|  2.19k|  while (true) {
  ------------------
  |  Branch (190:10): [True: 2.19k, Folded]
  ------------------
  191|  2.19k|    if (buffer_.size() < kHeaderSize) {
  ------------------
  |  Branch (191:9): [True: 1.11k, False: 1.08k]
  ------------------
  192|  1.11k|      if (!eof_) {
  ------------------
  |  Branch (192:11): [True: 961, False: 154]
  ------------------
  193|       |        // Last read was a full read, so this is a trailer to skip
  194|    961|        buffer_.clear();
  195|    961|        Status status = file_->Read(kBlockSize, &buffer_, backing_store_);
  196|    961|        end_of_buffer_offset_ += buffer_.size();
  197|    961|        if (!status.ok()) {
  ------------------
  |  Branch (197:13): [True: 0, False: 961]
  ------------------
  198|      0|          buffer_.clear();
  199|      0|          ReportDrop(kBlockSize, status);
  200|      0|          eof_ = true;
  201|      0|          return kEof;
  202|    961|        } else if (buffer_.size() < kBlockSize) {
  ------------------
  |  Branch (202:20): [True: 154, False: 807]
  ------------------
  203|    154|          eof_ = true;
  204|    154|        }
  205|    961|        continue;
  206|    961|      } else {
  207|       |        // Note that if buffer_ is non-empty, we have a truncated header at the
  208|       |        // end of the file, which can be caused by the writer crashing in the
  209|       |        // middle of writing the header. Instead of considering this an error,
  210|       |        // just report EOF.
  211|    154|        buffer_.clear();
  212|    154|        return kEof;
  213|    154|      }
  214|  1.11k|    }
  215|       |
  216|       |    // Parse the header
  217|  1.08k|    const char* header = buffer_.data();
  218|  1.08k|    const uint32_t a = static_cast<uint32_t>(header[4]) & 0xff;
  219|  1.08k|    const uint32_t b = static_cast<uint32_t>(header[5]) & 0xff;
  220|  1.08k|    const unsigned int type = header[6];
  221|  1.08k|    const uint32_t length = a | (b << 8);
  222|  1.08k|    if (kHeaderSize + length > buffer_.size()) {
  ------------------
  |  Branch (222:9): [True: 0, False: 1.08k]
  ------------------
  223|      0|      size_t drop_size = buffer_.size();
  224|      0|      buffer_.clear();
  225|      0|      if (!eof_) {
  ------------------
  |  Branch (225:11): [True: 0, False: 0]
  ------------------
  226|      0|        ReportCorruption(drop_size, "bad record length");
  227|      0|        return kBadRecord;
  228|      0|      }
  229|       |      // If the end of the file has been reached without reading |length| bytes
  230|       |      // of payload, assume the writer died in the middle of writing the record.
  231|       |      // Don't report a corruption.
  232|      0|      return kEof;
  233|      0|    }
  234|       |
  235|  1.08k|    if (type == kZeroType && length == 0) {
  ------------------
  |  Branch (235:9): [True: 0, False: 1.08k]
  |  Branch (235:30): [True: 0, False: 0]
  ------------------
  236|       |      // Skip zero length record without reporting any drops since
  237|       |      // such records are produced by the mmap based writing code in
  238|       |      // env_posix.cc that preallocates file regions.
  239|      0|      buffer_.clear();
  240|      0|      return kBadRecord;
  241|      0|    }
  242|       |
  243|       |    // Check crc
  244|  1.08k|    if (checksum_) {
  ------------------
  |  Branch (244:9): [True: 1.08k, False: 0]
  ------------------
  245|  1.08k|      uint32_t expected_crc = crc32c::Unmask(DecodeFixed32(header));
  246|  1.08k|      uint32_t actual_crc = crc32c::Value(header + 6, 1 + length);
  247|  1.08k|      if (actual_crc != expected_crc) {
  ------------------
  |  Branch (247:11): [True: 0, False: 1.08k]
  ------------------
  248|       |        // Drop the rest of the buffer since "length" itself may have
  249|       |        // been corrupted and if we trust it, we could find some
  250|       |        // fragment of a real log record that just happens to look
  251|       |        // like a valid log record.
  252|      0|        size_t drop_size = buffer_.size();
  253|      0|        buffer_.clear();
  254|      0|        ReportCorruption(drop_size, "checksum mismatch");
  255|      0|        return kBadRecord;
  256|      0|      }
  257|  1.08k|    }
  258|       |
  259|  1.08k|    buffer_.remove_prefix(kHeaderSize + length);
  260|       |
  261|       |    // Skip physical record that started before initial_offset_
  262|  1.08k|    if (end_of_buffer_offset_ - buffer_.size() - kHeaderSize - length <
  ------------------
  |  Branch (262:9): [True: 0, False: 1.08k]
  ------------------
  263|  1.08k|        initial_offset_) {
  264|      0|      result->clear();
  265|      0|      return kBadRecord;
  266|      0|    }
  267|       |
  268|  1.08k|    *result = Slice(header + kHeaderSize, length);
  269|  1.08k|    return type;
  270|  1.08k|  }
  271|  1.23k|}

_ZN7leveldb3log6WriterC2EPNS_12WritableFileE:
   23|    265|Writer::Writer(WritableFile* dest) : dest_(dest), block_offset_(0) {
   24|    265|  InitTypeCrc(type_crc_);
   25|    265|}
_ZN7leveldb3log6WriterD2Ev:
   32|    265|Writer::~Writer() = default;
_ZN7leveldb3log6Writer9AddRecordERKNS_5SliceE:
   34|    706|Status Writer::AddRecord(const Slice& slice) {
   35|    706|  const char* ptr = slice.data();
   36|    706|  size_t left = slice.size();
   37|       |
   38|       |  // Fragment the record if necessary and emit it.  Note that if slice
   39|       |  // is empty, we still want to iterate once to emit a single
   40|       |  // zero-length record
   41|    706|  Status s;
   42|    706|  bool begin = true;
   43|  2.72k|  do {
   44|  2.72k|    const int leftover = kBlockSize - block_offset_;
   45|  2.72k|    assert(leftover >= 0);
   46|  2.72k|    if (leftover < kHeaderSize) {
  ------------------
  |  Branch (46:9): [True: 2.01k, False: 706]
  ------------------
   47|       |      // Switch to a new block
   48|  2.01k|      if (leftover > 0) {
  ------------------
  |  Branch (48:11): [True: 0, False: 2.01k]
  ------------------
   49|       |        // Fill the trailer (literal below relies on kHeaderSize being 7)
   50|      0|        static_assert(kHeaderSize == 7, "");
   51|      0|        dest_->Append(Slice("\x00\x00\x00\x00\x00\x00", leftover));
   52|      0|      }
   53|  2.01k|      block_offset_ = 0;
   54|  2.01k|    }
   55|       |
   56|       |    // Invariant: we never leave < kHeaderSize bytes in a block.
   57|  2.72k|    assert(kBlockSize - block_offset_ - kHeaderSize >= 0);
   58|       |
   59|  2.72k|    const size_t avail = kBlockSize - block_offset_ - kHeaderSize;
   60|  2.72k|    const size_t fragment_length = (left < avail) ? left : avail;
  ------------------
  |  Branch (60:36): [True: 706, False: 2.01k]
  ------------------
   61|       |
   62|  2.72k|    RecordType type;
   63|  2.72k|    const bool end = (left == fragment_length);
   64|  2.72k|    if (begin && end) {
  ------------------
  |  Branch (64:9): [True: 706, False: 2.01k]
  |  Branch (64:18): [True: 572, False: 134]
  ------------------
   65|    572|      type = kFullType;
   66|  2.14k|    } else if (begin) {
  ------------------
  |  Branch (66:16): [True: 134, False: 2.01k]
  ------------------
   67|    134|      type = kFirstType;
   68|  2.01k|    } else if (end) {
  ------------------
  |  Branch (68:16): [True: 134, False: 1.88k]
  ------------------
   69|    134|      type = kLastType;
   70|  1.88k|    } else {
   71|  1.88k|      type = kMiddleType;
   72|  1.88k|    }
   73|       |
   74|  2.72k|    s = EmitPhysicalRecord(type, ptr, fragment_length);
   75|  2.72k|    ptr += fragment_length;
   76|  2.72k|    left -= fragment_length;
   77|  2.72k|    begin = false;
   78|  2.72k|  } while (s.ok() && left > 0);
  ------------------
  |  Branch (78:12): [True: 2.72k, False: 0]
  |  Branch (78:22): [True: 2.01k, False: 706]
  ------------------
   79|    706|  return s;
   80|    706|}
_ZN7leveldb3log6Writer18EmitPhysicalRecordENS0_10RecordTypeEPKcm:
   83|  2.72k|                                  size_t length) {
   84|  2.72k|  assert(length <= 0xffff);  // Must fit in two bytes
   85|  2.72k|  assert(block_offset_ + kHeaderSize + length <= kBlockSize);
   86|       |
   87|       |  // Format the header
   88|  2.72k|  char buf[kHeaderSize];
   89|  2.72k|  buf[4] = static_cast<char>(length & 0xff);
   90|  2.72k|  buf[5] = static_cast<char>(length >> 8);
   91|  2.72k|  buf[6] = static_cast<char>(t);
   92|       |
   93|       |  // Compute the crc of the record type and the payload.
   94|  2.72k|  uint32_t crc = crc32c::Extend(type_crc_[t], ptr, length);
   95|  2.72k|  crc = crc32c::Mask(crc);  // Adjust for storage
   96|  2.72k|  EncodeFixed32(buf, crc);
   97|       |
   98|       |  // Write the header and the payload
   99|  2.72k|  Status s = dest_->Append(Slice(buf, kHeaderSize));
  100|  2.72k|  if (s.ok()) {
  ------------------
  |  Branch (100:7): [True: 2.72k, False: 0]
  ------------------
  101|  2.72k|    s = dest_->Append(Slice(ptr, length));
  102|  2.72k|    if (s.ok()) {
  ------------------
  |  Branch (102:9): [True: 2.72k, False: 0]
  ------------------
  103|  2.72k|      s = dest_->Flush();
  104|  2.72k|    }
  105|  2.72k|  }
  106|  2.72k|  block_offset_ += kHeaderSize + length;
  107|  2.72k|  return s;
  108|  2.72k|}
log_writer.cc:_ZN7leveldb3logL11InitTypeCrcEPj:
   16|    265|static void InitTypeCrc(uint32_t* type_crc) {
   17|  1.59k|  for (int i = 0; i <= kMaxRecordType; i++) {
  ------------------
  |  Branch (17:19): [True: 1.32k, False: 265]
  ------------------
   18|  1.32k|    char t = static_cast<char>(i);
   19|  1.32k|    type_crc[i] = crc32c::Value(&t, 1);
   20|  1.32k|  }
   21|    265|}

_ZN7leveldb8MemTableC2ERKNS_21InternalKeyComparatorE:
   22|    148|    : comparator_(comparator), refs_(0), table_(comparator_, &arena_) {}
_ZN7leveldb8MemTableD2Ev:
   24|    148|MemTable::~MemTable() { assert(refs_ == 0); }
_ZN7leveldb8MemTable22ApproximateMemoryUsageEv:
   26|    557|size_t MemTable::ApproximateMemoryUsage() { return arena_.MemoryUsage(); }
_ZNK7leveldb8MemTable13KeyComparatorclEPKcS3_:
   29|  2.29k|                                        const char* bptr) const {
   30|       |  // Internal keys are encoded as length-prefixed strings.
   31|  2.29k|  Slice a = GetLengthPrefixedSlice(aptr);
   32|  2.29k|  Slice b = GetLengthPrefixedSlice(bptr);
   33|  2.29k|  return comparator.Compare(a, b);
   34|  2.29k|}
_ZN7leveldb8MemTable11NewIteratorEv:
   74|     82|Iterator* MemTable::NewIterator() { return new MemTableIterator(&table_); }
_ZN7leveldb8MemTable3AddEmNS_9ValueTypeERKNS_5SliceES4_:
   77|    539|                   const Slice& value) {
   78|       |  // Format of an entry is concatenation of:
   79|       |  //  key_size     : varint32 of internal_key.size()
   80|       |  //  key bytes    : char[internal_key.size()]
   81|       |  //  tag          : uint64((sequence << 8) | type)
   82|       |  //  value_size   : varint32 of value.size()
   83|       |  //  value bytes  : char[value.size()]
   84|    539|  size_t key_size = key.size();
   85|    539|  size_t val_size = value.size();
   86|    539|  size_t internal_key_size = key_size + 8;
   87|    539|  const size_t encoded_len = VarintLength(internal_key_size) +
   88|    539|                             internal_key_size + VarintLength(val_size) +
   89|    539|                             val_size;
   90|    539|  char* buf = arena_.Allocate(encoded_len);
   91|    539|  char* p = EncodeVarint32(buf, internal_key_size);
   92|    539|  std::memcpy(p, key.data(), key_size);
   93|    539|  p += key_size;
   94|    539|  EncodeFixed64(p, (s << 8) | type);
   95|    539|  p += 8;
   96|    539|  p = EncodeVarint32(p, val_size);
   97|    539|  std::memcpy(p, value.data(), val_size);
   98|       |  assert(p + val_size == buf + encoded_len);
   99|    539|  table_.Insert(buf);
  100|    539|}
_ZN7leveldb8MemTable3GetERKNS_9LookupKeyEPNSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEPNS_6StatusE:
  102|     22|bool MemTable::Get(const LookupKey& key, std::string* value, Status* s) {
  103|     22|  Slice memkey = key.memtable_key();
  104|     22|  Table::Iterator iter(&table_);
  105|     22|  iter.Seek(memkey.data());
  106|     22|  if (iter.Valid()) {
  ------------------
  |  Branch (106:7): [True: 5, False: 17]
  ------------------
  107|       |    // entry format is:
  108|       |    //    klength  varint32
  109|       |    //    userkey  char[klength]
  110|       |    //    tag      uint64
  111|       |    //    vlength  varint32
  112|       |    //    value    char[vlength]
  113|       |    // Check that it belongs to same user key.  We do not check the
  114|       |    // sequence number since the Seek() call above should have skipped
  115|       |    // all entries with overly large sequence numbers.
  116|      5|    const char* entry = iter.key();
  117|      5|    uint32_t key_length;
  118|      5|    const char* key_ptr = GetVarint32Ptr(entry, entry + 5, &key_length);
  119|      5|    if (comparator_.comparator.user_comparator()->Compare(
  ------------------
  |  Branch (119:9): [True: 1, False: 4]
  ------------------
  120|      5|            Slice(key_ptr, key_length - 8), key.user_key()) == 0) {
  121|       |      // Correct user key
  122|      1|      const uint64_t tag = DecodeFixed64(key_ptr + key_length - 8);
  123|      1|      switch (static_cast<ValueType>(tag & 0xff)) {
  ------------------
  |  Branch (123:15): [True: 1, False: 0]
  ------------------
  124|      0|        case kTypeValue: {
  ------------------
  |  Branch (124:9): [True: 0, False: 1]
  ------------------
  125|      0|          Slice v = GetLengthPrefixedSlice(key_ptr + key_length);
  126|      0|          value->assign(v.data(), v.size());
  127|      0|          return true;
  128|      0|        }
  129|      1|        case kTypeDeletion:
  ------------------
  |  Branch (129:9): [True: 1, False: 0]
  ------------------
  130|      1|          *s = Status::NotFound(Slice());
  131|      1|          return true;
  132|      1|      }
  133|      1|    }
  134|      5|  }
  135|     21|  return false;
  136|     22|}
memtable.cc:_ZN7leveldbL22GetLengthPrefixedSliceEPKc:
   14|  5.48k|static Slice GetLengthPrefixedSlice(const char* data) {
   15|  5.48k|  uint32_t len;
   16|  5.48k|  const char* p = data;
   17|  5.48k|  p = GetVarint32Ptr(p, p + 5, &len);  // +5: we assume "p" is not corrupted
   18|  5.48k|  return Slice(p, len);
   19|  5.48k|}
_ZN7leveldb16MemTableIteratorC2EPNS_8SkipListIPKcNS_8MemTable13KeyComparatorEEE:
   48|     82|  explicit MemTableIterator(MemTable::Table* table) : iter_(table) {}
_ZN7leveldb16MemTableIteratorD2Ev:
   53|     82|  ~MemTableIterator() override = default;
_ZNK7leveldb16MemTableIterator5ValidEv:
   55|    405|  bool Valid() const override { return iter_.Valid(); }
_ZN7leveldb16MemTableIterator11SeekToFirstEv:
   57|     58|  void SeekToFirst() override { iter_.SeekToFirst(); }
_ZN7leveldb16MemTableIterator4NextEv:
   59|    285|  void Next() override { iter_.Next(); }
_ZNK7leveldb16MemTableIterator3keyEv:
   61|    321|  Slice key() const override { return GetLengthPrefixedSlice(iter_.key()); }
_ZNK7leveldb16MemTableIterator5valueEv:
   62|    285|  Slice value() const override {
   63|    285|    Slice key_slice = GetLengthPrefixedSlice(iter_.key());
   64|    285|    return GetLengthPrefixedSlice(key_slice.data() + key_slice.size());
   65|    285|  }
_ZNK7leveldb16MemTableIterator6statusEv:
   67|     48|  Status status() const override { return Status::OK(); }

_ZN7leveldb8MemTable5UnrefEv:
   33|    204|  void Unref() {
   34|    204|    --refs_;
   35|    204|    assert(refs_ >= 0);
   36|    204|    if (refs_ <= 0) {
  ------------------
  |  Branch (36:9): [True: 148, False: 56]
  ------------------
   37|    148|      delete this;
   38|    148|    }
   39|    204|  }
_ZN7leveldb8MemTable3RefEv:
   30|    204|  void Ref() { ++refs_; }
_ZN7leveldb8MemTable13KeyComparatorC2ERKNS_21InternalKeyComparatorE:
   71|    148|    explicit KeyComparator(const InternalKeyComparator& c) : comparator(c) {}

_ZN7leveldb8SkipListIPKcNS_8MemTable13KeyComparatorEE8Iterator11SeekToFirstEv:
  227|     58|inline void SkipList<Key, Comparator>::Iterator::SeekToFirst() {
  228|     58|  node_ = list_->head_->Next(0);
  229|     58|}
_ZN7leveldb8SkipListIPKcNS_8MemTable13KeyComparatorEE4Node4NextEi:
  151|  2.93k|  Node* Next(int n) {
  152|  2.93k|    assert(n >= 0);
  153|       |    // Use an 'acquire load' so that we observe a fully initialized
  154|       |    // version of the returned Node.
  155|  2.93k|    return next_[n].load(std::memory_order_acquire);
  156|  2.93k|  }
_ZNK7leveldb8SkipListIPKcNS_8MemTable13KeyComparatorEE12GetMaxHeightEv:
  102|  1.21k|  inline int GetMaxHeight() const {
  103|  1.21k|    return max_height_.load(std::memory_order_relaxed);
  104|  1.21k|  }
_ZN7leveldb8SkipListIPKcNS_8MemTable13KeyComparatorEE8Iterator4NextEv:
  205|    285|inline void SkipList<Key, Comparator>::Iterator::Next() {
  206|       |  assert(Valid());
  207|    285|  node_ = node_->Next(0);
  208|    285|}
_ZN7leveldb8SkipListIPKcNS_8MemTable13KeyComparatorEEC2ES4_PNS_5ArenaE:
  324|    148|    : compare_(cmp),
  325|    148|      arena_(arena),
  326|    148|      head_(NewNode(0 /* any key will do */, kMaxHeight)),
  327|    148|      max_height_(1),
  328|    148|      rnd_(0xdeadbeef) {
  329|  1.92k|  for (int i = 0; i < kMaxHeight; i++) {
  ------------------
  |  Branch (329:19): [True: 1.77k, False: 148]
  ------------------
  330|  1.77k|    head_->SetNext(i, nullptr);
  331|  1.77k|  }
  332|    148|}
_ZN7leveldb8SkipListIPKcNS_8MemTable13KeyComparatorEE7NewNodeERKS2_i:
  181|    687|    const Key& key, int height) {
  182|    687|  char* const node_memory = arena_->AllocateAligned(
  183|    687|      sizeof(Node) + sizeof(std::atomic<Node*>) * (height - 1));
  184|    687|  return new (node_memory) Node(key);
  185|    687|}
_ZN7leveldb8SkipListIPKcNS_8MemTable13KeyComparatorEE4NodeC2ERKS2_:
  145|    687|  explicit Node(const Key& k) : key(k) {}
_ZN7leveldb8SkipListIPKcNS_8MemTable13KeyComparatorEE4Node7SetNextEiPS6_:
  157|  2.47k|  void SetNext(int n, Node* x) {
  158|  2.47k|    assert(n >= 0);
  159|       |    // Use a 'release store' so that anybody who reads through this
  160|       |    // pointer observes a fully initialized version of the inserted node.
  161|  2.47k|    next_[n].store(x, std::memory_order_release);
  162|  2.47k|  }
_ZN7leveldb8SkipListIPKcNS_8MemTable13KeyComparatorEE8IteratorC2EPKS5_:
  188|    104|inline SkipList<Key, Comparator>::Iterator::Iterator(const SkipList* list) {
  189|    104|  list_ = list;
  190|    104|  node_ = nullptr;
  191|    104|}
_ZNK7leveldb8SkipListIPKcNS_8MemTable13KeyComparatorEE8Iterator5ValidEv:
  194|    427|inline bool SkipList<Key, Comparator>::Iterator::Valid() const {
  195|    427|  return node_ != nullptr;
  196|    427|}
_ZN7leveldb8SkipListIPKcNS_8MemTable13KeyComparatorEE8Iterator4SeekERKS2_:
  222|     22|inline void SkipList<Key, Comparator>::Iterator::Seek(const Key& target) {
  223|     22|  node_ = list_->FindGreaterOrEqual(target, nullptr);
  224|     22|}
_ZNK7leveldb8SkipListIPKcNS_8MemTable13KeyComparatorEE18FindGreaterOrEqualERKS2_PPNS5_4NodeE:
  261|    561|                                              Node** prev) const {
  262|    561|  Node* x = head_;
  263|    561|  int level = GetMaxHeight() - 1;
  264|  2.59k|  while (true) {
  ------------------
  |  Branch (264:10): [True: 2.59k, Folded]
  ------------------
  265|  2.59k|    Node* next = x->Next(level);
  266|  2.59k|    if (KeyIsAfterNode(key, next)) {
  ------------------
  |  Branch (266:9): [True: 1.42k, False: 1.17k]
  ------------------
  267|       |      // Keep searching in this list
  268|  1.42k|      x = next;
  269|  1.42k|    } else {
  270|  1.17k|      if (prev != nullptr) prev[level] = x;
  ------------------
  |  Branch (270:11): [True: 1.14k, False: 31]
  ------------------
  271|  1.17k|      if (level == 0) {
  ------------------
  |  Branch (271:11): [True: 561, False: 610]
  ------------------
  272|    561|        return next;
  273|    610|      } else {
  274|       |        // Switch to next list
  275|    610|        level--;
  276|    610|      }
  277|  1.17k|    }
  278|  2.59k|  }
  279|    561|}
_ZNK7leveldb8SkipListIPKcNS_8MemTable13KeyComparatorEE14KeyIsAfterNodeERKS2_PNS5_4NodeE:
  253|  2.59k|bool SkipList<Key, Comparator>::KeyIsAfterNode(const Key& key, Node* n) const {
  254|       |  // null n is considered infinite
  255|  2.59k|  return (n != nullptr) && (compare_(n->key, key) < 0);
  ------------------
  |  Branch (255:10): [True: 2.29k, False: 295]
  |  Branch (255:28): [True: 1.42k, False: 876]
  ------------------
  256|  2.59k|}
_ZNK7leveldb8SkipListIPKcNS_8MemTable13KeyComparatorEE8Iterator3keyEv:
  199|    611|inline const Key& SkipList<Key, Comparator>::Iterator::key() const {
  200|       |  assert(Valid());
  201|    611|  return node_->key;
  202|    611|}
_ZN7leveldb8SkipListIPKcNS_8MemTable13KeyComparatorEE6InsertERKS2_:
  335|    539|void SkipList<Key, Comparator>::Insert(const Key& key) {
  336|       |  // TODO(opt): We can use a barrier-free variant of FindGreaterOrEqual()
  337|       |  // here since Insert() is externally synchronized.
  338|    539|  Node* prev[kMaxHeight];
  339|    539|  Node* x = FindGreaterOrEqual(key, prev);
  340|       |
  341|       |  // Our data structure does not allow duplicate insertion
  342|    539|  assert(x == nullptr || !Equal(key, x->key));
  343|       |
  344|    539|  int height = RandomHeight();
  345|    539|  if (height > GetMaxHeight()) {
  ------------------
  |  Branch (345:7): [True: 110, False: 429]
  ------------------
  346|    220|    for (int i = GetMaxHeight(); i < height; i++) {
  ------------------
  |  Branch (346:34): [True: 110, False: 110]
  ------------------
  347|    110|      prev[i] = head_;
  348|    110|    }
  349|       |    // It is ok to mutate max_height_ without any synchronization
  350|       |    // with concurrent readers.  A concurrent reader that observes
  351|       |    // the new value of max_height_ will see either the old value of
  352|       |    // new level pointers from head_ (nullptr), or a new value set in
  353|       |    // the loop below.  In the former case the reader will
  354|       |    // immediately drop to the next level since nullptr sorts after all
  355|       |    // keys.  In the latter case the reader will use the new node.
  356|    110|    max_height_.store(height, std::memory_order_relaxed);
  357|    110|  }
  358|       |
  359|    539|  x = NewNode(key, height);
  360|  1.23k|  for (int i = 0; i < height; i++) {
  ------------------
  |  Branch (360:19): [True: 695, False: 539]
  ------------------
  361|       |    // NoBarrier_SetNext() suffices since we will add a barrier when
  362|       |    // we publish a pointer to "x" in prev[i].
  363|    695|    x->NoBarrier_SetNext(i, prev[i]->NoBarrier_Next(i));
  364|    695|    prev[i]->SetNext(i, x);
  365|    695|  }
  366|    539|}
_ZN7leveldb8SkipListIPKcNS_8MemTable13KeyComparatorEE12RandomHeightEv:
  240|    539|int SkipList<Key, Comparator>::RandomHeight() {
  241|       |  // Increase height with probability 1 in kBranching
  242|    539|  static const unsigned int kBranching = 4;
  243|    539|  int height = 1;
  244|    695|  while (height < kMaxHeight && rnd_.OneIn(kBranching)) {
  ------------------
  |  Branch (244:10): [True: 695, False: 0]
  |  Branch (244:33): [True: 156, False: 539]
  ------------------
  245|    156|    height++;
  246|    156|  }
  247|    539|  assert(height > 0);
  248|       |  assert(height <= kMaxHeight);
  249|    539|  return height;
  250|    539|}
_ZN7leveldb8SkipListIPKcNS_8MemTable13KeyComparatorEE4Node17NoBarrier_SetNextEiPS6_:
  169|    695|  void NoBarrier_SetNext(int n, Node* x) {
  170|       |    assert(n >= 0);
  171|    695|    next_[n].store(x, std::memory_order_relaxed);
  172|    695|  }
_ZN7leveldb8SkipListIPKcNS_8MemTable13KeyComparatorEE4Node14NoBarrier_NextEi:
  165|    695|  Node* NoBarrier_Next(int n) {
  166|       |    assert(n >= 0);
  167|    695|    return next_[n].load(std::memory_order_relaxed);
  168|    695|  }

_ZN7leveldb12SnapshotListC2Ev:
   41|    100|  SnapshotList() : head_(0) {
   42|    100|    head_.prev_ = &head_;
   43|    100|    head_.next_ = &head_;
   44|    100|  }
_ZN7leveldb12SnapshotImplC2Em:
   20|    124|      : sequence_number_(sequence_number) {}
_ZNK7leveldb12SnapshotList5emptyEv:
   46|      6|  bool empty() const { return head_.next_ == &head_; }
_ZNK7leveldb12SnapshotImpl15sequence_numberEv:
   22|     24|  SequenceNumber sequence_number() const { return sequence_number_; }
_ZN7leveldb12SnapshotList3NewEm:
   57|     24|  SnapshotImpl* New(SequenceNumber sequence_number) {
   58|     24|    assert(empty() || newest()->sequence_number_ <= sequence_number);
   59|       |
   60|     24|    SnapshotImpl* snapshot = new SnapshotImpl(sequence_number);
   61|       |
   62|       |#if !defined(NDEBUG)
   63|       |    snapshot->list_ = this;
   64|       |#endif  // !defined(NDEBUG)
   65|     24|    snapshot->next_ = &head_;
   66|     24|    snapshot->prev_ = head_.prev_;
   67|     24|    snapshot->prev_->next_ = snapshot;
   68|     24|    snapshot->next_->prev_ = snapshot;
   69|     24|    return snapshot;
   70|     24|  }
_ZN7leveldb12SnapshotList6DeleteEPKNS_12SnapshotImplE:
   79|     24|  void Delete(const SnapshotImpl* snapshot) {
   80|       |#if !defined(NDEBUG)
   81|       |    assert(snapshot->list_ == this);
   82|       |#endif  // !defined(NDEBUG)
   83|     24|    snapshot->prev_->next_ = snapshot->next_;
   84|     24|    snapshot->next_->prev_ = snapshot->prev_;
   85|     24|    delete snapshot;
   86|     24|  }

_ZN7leveldb10TableCacheC2ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERKNS_7OptionsEi:
   34|    100|    : env_(options.env),
   35|    100|      dbname_(dbname),
   36|    100|      options_(options),
   37|    100|      cache_(NewLRUCache(entries)) {}
_ZN7leveldb10TableCacheD2Ev:
   39|    100|TableCache::~TableCache() { delete cache_; }
_ZN7leveldb10TableCache9FindTableEmmPPNS_5Cache6HandleE:
   42|    110|                             Cache::Handle** handle) {
   43|    110|  Status s;
   44|    110|  char buf[sizeof(file_number)];
   45|    110|  EncodeFixed64(buf, file_number);
   46|    110|  Slice key(buf, sizeof(buf));
   47|    110|  *handle = cache_->Lookup(key);
   48|    110|  if (*handle == nullptr) {
  ------------------
  |  Branch (48:7): [True: 72, False: 38]
  ------------------
   49|     72|    std::string fname = TableFileName(dbname_, file_number);
   50|     72|    RandomAccessFile* file = nullptr;
   51|     72|    Table* table = nullptr;
   52|     72|    s = env_->NewRandomAccessFile(fname, &file);
   53|     72|    if (!s.ok()) {
  ------------------
  |  Branch (53:9): [True: 0, False: 72]
  ------------------
   54|      0|      std::string old_fname = SSTTableFileName(dbname_, file_number);
   55|      0|      if (env_->NewRandomAccessFile(old_fname, &file).ok()) {
  ------------------
  |  Branch (55:11): [True: 0, False: 0]
  ------------------
   56|      0|        s = Status::OK();
   57|      0|      }
   58|      0|    }
   59|     72|    if (s.ok()) {
  ------------------
  |  Branch (59:9): [True: 72, False: 0]
  ------------------
   60|     72|      s = Table::Open(options_, file, file_size, &table);
   61|     72|    }
   62|       |
   63|     72|    if (!s.ok()) {
  ------------------
  |  Branch (63:9): [True: 0, False: 72]
  ------------------
   64|      0|      assert(table == nullptr);
   65|      0|      delete file;
   66|       |      // We do not cache error results so that if the error is transient,
   67|       |      // or somebody repairs the file, we recover automatically.
   68|     72|    } else {
   69|     72|      TableAndFile* tf = new TableAndFile;
   70|     72|      tf->file = file;
   71|     72|      tf->table = table;
   72|     72|      *handle = cache_->Insert(key, tf, 1, &DeleteEntry);
   73|     72|    }
   74|     72|  }
   75|    110|  return s;
   76|    110|}
_ZN7leveldb10TableCache11NewIteratorERKNS_11ReadOptionsEmmPPNS_5TableE:
   80|    100|                                  Table** tableptr) {
   81|    100|  if (tableptr != nullptr) {
  ------------------
  |  Branch (81:7): [True: 0, False: 100]
  ------------------
   82|      0|    *tableptr = nullptr;
   83|      0|  }
   84|       |
   85|    100|  Cache::Handle* handle = nullptr;
   86|    100|  Status s = FindTable(file_number, file_size, &handle);
   87|    100|  if (!s.ok()) {
  ------------------
  |  Branch (87:7): [True: 0, False: 100]
  ------------------
   88|      0|    return NewErrorIterator(s);
   89|      0|  }
   90|       |
   91|    100|  Table* table = reinterpret_cast<TableAndFile*>(cache_->Value(handle))->table;
   92|    100|  Iterator* result = table->NewIterator(options);
   93|    100|  result->RegisterCleanup(&UnrefEntry, cache_, handle);
   94|    100|  if (tableptr != nullptr) {
  ------------------
  |  Branch (94:7): [True: 0, False: 100]
  ------------------
   95|      0|    *tableptr = table;
   96|      0|  }
   97|    100|  return result;
   98|    100|}
_ZN7leveldb10TableCache3GetERKNS_11ReadOptionsEmmRKNS_5SliceEPvPFvS7_S6_S6_E:
  103|     10|                                             const Slice&)) {
  104|     10|  Cache::Handle* handle = nullptr;
  105|     10|  Status s = FindTable(file_number, file_size, &handle);
  106|     10|  if (s.ok()) {
  ------------------
  |  Branch (106:7): [True: 10, False: 0]
  ------------------
  107|     10|    Table* t = reinterpret_cast<TableAndFile*>(cache_->Value(handle))->table;
  108|     10|    s = t->InternalGet(options, k, arg, handle_result);
  109|     10|    cache_->Release(handle);
  110|     10|  }
  111|     10|  return s;
  112|     10|}
_ZN7leveldb10TableCache5EvictEm:
  114|     20|void TableCache::Evict(uint64_t file_number) {
  115|     20|  char buf[sizeof(file_number)];
  116|     20|  EncodeFixed64(buf, file_number);
  117|     20|  cache_->Erase(Slice(buf, sizeof(buf)));
  118|     20|}
table_cache.cc:_ZN7leveldbL11DeleteEntryERKNS_5SliceEPv:
   19|     72|static void DeleteEntry(const Slice& key, void* value) {
   20|     72|  TableAndFile* tf = reinterpret_cast<TableAndFile*>(value);
   21|     72|  delete tf->table;
   22|     72|  delete tf->file;
   23|     72|  delete tf;
   24|     72|}
table_cache.cc:_ZN7leveldbL10UnrefEntryEPvS0_:
   26|    100|static void UnrefEntry(void* arg1, void* arg2) {
   27|    100|  Cache* cache = reinterpret_cast<Cache*>(arg1);
   28|    100|  Cache::Handle* h = reinterpret_cast<Cache::Handle*>(arg2);
   29|    100|  cache->Release(h);
   30|    100|}

_ZN7leveldb11VersionEdit5ClearEv:
   26|    612|void VersionEdit::Clear() {
   27|    612|  comparator_.clear();
   28|    612|  log_number_ = 0;
   29|    612|  prev_log_number_ = 0;
   30|    612|  last_sequence_ = 0;
   31|    612|  next_file_number_ = 0;
   32|    612|  has_comparator_ = false;
   33|    612|  has_log_number_ = false;
   34|    612|  has_prev_log_number_ = false;
   35|    612|  has_next_file_number_ = false;
   36|    612|  has_last_sequence_ = false;
   37|    612|  compact_pointers_.clear();
   38|    612|  deleted_files_.clear();
   39|    612|  new_files_.clear();
   40|    612|}
_ZNK7leveldb11VersionEdit8EncodeToEPNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
   42|    272|void VersionEdit::EncodeTo(std::string* dst) const {
   43|    272|  if (has_comparator_) {
  ------------------
  |  Branch (43:7): [True: 147, False: 125]
  ------------------
   44|    147|    PutVarint32(dst, kComparator);
   45|    147|    PutLengthPrefixedSlice(dst, comparator_);
   46|    147|  }
   47|    272|  if (has_log_number_) {
  ------------------
  |  Branch (47:7): [True: 172, False: 100]
  ------------------
   48|    172|    PutVarint32(dst, kLogNumber);
   49|    172|    PutVarint64(dst, log_number_);
   50|    172|  }
   51|    272|  if (has_prev_log_number_) {
  ------------------
  |  Branch (51:7): [True: 125, False: 147]
  ------------------
   52|    125|    PutVarint32(dst, kPrevLogNumber);
   53|    125|    PutVarint64(dst, prev_log_number_);
   54|    125|  }
   55|    272|  if (has_next_file_number_) {
  ------------------
  |  Branch (55:7): [True: 172, False: 100]
  ------------------
   56|    172|    PutVarint32(dst, kNextFileNumber);
   57|    172|    PutVarint64(dst, next_file_number_);
   58|    172|  }
   59|    272|  if (has_last_sequence_) {
  ------------------
  |  Branch (59:7): [True: 172, False: 100]
  ------------------
   60|    172|    PutVarint32(dst, kLastSequence);
   61|    172|    PutVarint64(dst, last_sequence_);
   62|    172|  }
   63|       |
   64|    294|  for (size_t i = 0; i < compact_pointers_.size(); i++) {
  ------------------
  |  Branch (64:22): [True: 22, False: 272]
  ------------------
   65|     22|    PutVarint32(dst, kCompactPointer);
   66|     22|    PutVarint32(dst, compact_pointers_[i].first);  // level
   67|     22|    PutLengthPrefixedSlice(dst, compact_pointers_[i].second.Encode());
   68|     22|  }
   69|       |
   70|    272|  for (const auto& deleted_file_kvp : deleted_files_) {
  ------------------
  |  Branch (70:37): [True: 21, False: 272]
  ------------------
   71|     21|    PutVarint32(dst, kDeletedFile);
   72|     21|    PutVarint32(dst, deleted_file_kvp.first);   // level
   73|     21|    PutVarint64(dst, deleted_file_kvp.second);  // file number
   74|     21|  }
   75|       |
   76|    390|  for (size_t i = 0; i < new_files_.size(); i++) {
  ------------------
  |  Branch (76:22): [True: 118, False: 272]
  ------------------
   77|    118|    const FileMetaData& f = new_files_[i].second;
   78|    118|    PutVarint32(dst, kNewFile);
   79|    118|    PutVarint32(dst, new_files_[i].first);  // level
   80|    118|    PutVarint64(dst, f.number);
   81|    118|    PutVarint64(dst, f.file_size);
   82|    118|    PutLengthPrefixedSlice(dst, f.smallest.Encode());
   83|    118|    PutLengthPrefixedSlice(dst, f.largest.Encode());
   84|    118|  }
   85|    272|}
_ZN7leveldb11VersionEdit10DecodeFromERKNS_5SliceE:
  106|    170|Status VersionEdit::DecodeFrom(const Slice& src) {
  107|    170|  Clear();
  108|    170|  Slice input = src;
  109|    170|  const char* msg = nullptr;
  110|    170|  uint32_t tag;
  111|       |
  112|       |  // Temporary storage for parsing
  113|    170|  int level;
  114|    170|  uint64_t number;
  115|    170|  FileMetaData f;
  116|    170|  Slice str;
  117|    170|  InternalKey key;
  118|       |
  119|    826|  while (msg == nullptr && GetVarint32(&input, &tag)) {
  ------------------
  |  Branch (119:10): [True: 826, False: 0]
  |  Branch (119:28): [True: 656, False: 170]
  ------------------
  120|    656|    switch (tag) {
  121|    100|      case kComparator:
  ------------------
  |  Branch (121:7): [True: 100, False: 556]
  ------------------
  122|    100|        if (GetLengthPrefixedSlice(&input, &str)) {
  ------------------
  |  Branch (122:13): [True: 100, False: 0]
  ------------------
  123|    100|          comparator_ = str.ToString();
  124|    100|          has_comparator_ = true;
  125|    100|        } else {
  126|      0|          msg = "comparator name";
  127|      0|        }
  128|    100|        break;
  129|       |
  130|    117|      case kLogNumber:
  ------------------
  |  Branch (130:7): [True: 117, False: 539]
  ------------------
  131|    117|        if (GetVarint64(&input, &log_number_)) {
  ------------------
  |  Branch (131:13): [True: 117, False: 0]
  ------------------
  132|    117|          has_log_number_ = true;
  133|    117|        } else {
  134|      0|          msg = "log number";
  135|      0|        }
  136|    117|        break;
  137|       |
  138|     70|      case kPrevLogNumber:
  ------------------
  |  Branch (138:7): [True: 70, False: 586]
  ------------------
  139|     70|        if (GetVarint64(&input, &prev_log_number_)) {
  ------------------
  |  Branch (139:13): [True: 70, False: 0]
  ------------------
  140|     70|          has_prev_log_number_ = true;
  141|     70|        } else {
  142|      0|          msg = "previous log number";
  143|      0|        }
  144|     70|        break;
  145|       |
  146|    117|      case kNextFileNumber:
  ------------------
  |  Branch (146:7): [True: 117, False: 539]
  ------------------
  147|    117|        if (GetVarint64(&input, &next_file_number_)) {
  ------------------
  |  Branch (147:13): [True: 117, False: 0]
  ------------------
  148|    117|          has_next_file_number_ = true;
  149|    117|        } else {
  150|      0|          msg = "next file number";
  151|      0|        }
  152|    117|        break;
  153|       |
  154|    117|      case kLastSequence:
  ------------------
  |  Branch (154:7): [True: 117, False: 539]
  ------------------
  155|    117|        if (GetVarint64(&input, &last_sequence_)) {
  ------------------
  |  Branch (155:13): [True: 117, False: 0]
  ------------------
  156|    117|          has_last_sequence_ = true;
  157|    117|        } else {
  158|      0|          msg = "last sequence number";
  159|      0|        }
  160|    117|        break;
  161|       |
  162|     18|      case kCompactPointer:
  ------------------
  |  Branch (162:7): [True: 18, False: 638]
  ------------------
  163|     18|        if (GetLevel(&input, &level) && GetInternalKey(&input, &key)) {
  ------------------
  |  Branch (163:13): [True: 18, False: 0]
  |  Branch (163:41): [True: 18, False: 0]
  ------------------
  164|     18|          compact_pointers_.push_back(std::make_pair(level, key));
  165|     18|        } else {
  166|      0|          msg = "compaction pointer";
  167|      0|        }
  168|     18|        break;
  169|       |
  170|     21|      case kDeletedFile:
  ------------------
  |  Branch (170:7): [True: 21, False: 635]
  ------------------
  171|     21|        if (GetLevel(&input, &level) && GetVarint64(&input, &number)) {
  ------------------
  |  Branch (171:13): [True: 21, False: 0]
  |  Branch (171:41): [True: 21, False: 0]
  ------------------
  172|     21|          deleted_files_.insert(std::make_pair(level, number));
  173|     21|        } else {
  174|      0|          msg = "deleted file";
  175|      0|        }
  176|     21|        break;
  177|       |
  178|     96|      case kNewFile:
  ------------------
  |  Branch (178:7): [True: 96, False: 560]
  ------------------
  179|     96|        if (GetLevel(&input, &level) && GetVarint64(&input, &f.number) &&
  ------------------
  |  Branch (179:13): [True: 96, False: 0]
  |  Branch (179:41): [True: 96, False: 0]
  ------------------
  180|     96|            GetVarint64(&input, &f.file_size) &&
  ------------------
  |  Branch (180:13): [True: 96, False: 0]
  ------------------
  181|     96|            GetInternalKey(&input, &f.smallest) &&
  ------------------
  |  Branch (181:13): [True: 96, False: 0]
  ------------------
  182|     96|            GetInternalKey(&input, &f.largest)) {
  ------------------
  |  Branch (182:13): [True: 96, False: 0]
  ------------------
  183|     96|          new_files_.push_back(std::make_pair(level, f));
  184|     96|        } else {
  185|      0|          msg = "new-file entry";
  186|      0|        }
  187|     96|        break;
  188|       |
  189|      0|      default:
  ------------------
  |  Branch (189:7): [True: 0, False: 656]
  ------------------
  190|      0|        msg = "unknown tag";
  191|      0|        break;
  192|    656|    }
  193|    656|  }
  194|       |
  195|    170|  if (msg == nullptr && !input.empty()) {
  ------------------
  |  Branch (195:7): [True: 170, False: 0]
  |  Branch (195:25): [True: 0, False: 170]
  ------------------
  196|      0|    msg = "invalid tag";
  197|      0|  }
  198|       |
  199|    170|  Status result;
  200|    170|  if (msg != nullptr) {
  ------------------
  |  Branch (200:7): [True: 0, False: 170]
  ------------------
  201|      0|    result = Status::Corruption("VersionEdit", msg);
  202|      0|  }
  203|    170|  return result;
  204|    170|}
version_edit.cc:_ZN7leveldbL8GetLevelEPNS_5SliceEPi:
   96|    135|static bool GetLevel(Slice* input, int* level) {
   97|    135|  uint32_t v;
   98|    135|  if (GetVarint32(input, &v) && v < config::kNumLevels) {
  ------------------
  |  Branch (98:7): [True: 135, False: 0]
  |  Branch (98:33): [True: 135, False: 0]
  ------------------
   99|    135|    *level = v;
  100|    135|    return true;
  101|    135|  } else {
  102|      0|    return false;
  103|      0|  }
  104|    135|}
version_edit.cc:_ZN7leveldbL14GetInternalKeyEPNS_5SliceEPNS_11InternalKeyE:
   87|    210|static bool GetInternalKey(Slice* input, InternalKey* dst) {
   88|    210|  Slice str;
   89|    210|  if (GetLengthPrefixedSlice(input, &str)) {
  ------------------
  |  Branch (89:7): [True: 210, False: 0]
  ------------------
   90|    210|    return dst->DecodeFrom(str);
   91|    210|  } else {
   92|      0|    return false;
   93|      0|  }
   94|    210|}

_ZN7leveldb11VersionEditC2Ev:
   31|    442|  VersionEdit() { Clear(); }
_ZN7leveldb11VersionEdit17SetComparatorNameERKNS_5SliceE:
   36|    147|  void SetComparatorName(const Slice& name) {
   37|    147|    has_comparator_ = true;
   38|    147|    comparator_ = name.ToString();
   39|    147|  }
_ZN7leveldb11VersionEdit12SetLogNumberEm:
   40|    272|  void SetLogNumber(uint64_t num) {
   41|    272|    has_log_number_ = true;
   42|    272|    log_number_ = num;
   43|    272|  }
_ZN7leveldb11VersionEdit11SetNextFileEm:
   48|    172|  void SetNextFile(uint64_t num) {
   49|    172|    has_next_file_number_ = true;
   50|    172|    next_file_number_ = num;
   51|    172|  }
_ZN7leveldb11VersionEdit15SetLastSequenceEm:
   52|    172|  void SetLastSequence(SequenceNumber seq) {
   53|    172|    has_last_sequence_ = true;
   54|    172|    last_sequence_ = seq;
   55|    172|  }
_ZN7leveldb11VersionEditD2Ev:
   32|    442|  ~VersionEdit() = default;
_ZN7leveldb12FileMetaDataC2Ev:
   19|    336|  FileMetaData() : refs(0), allowed_seeks(1 << 30), file_size(0) {}
_ZN7leveldb11VersionEdit7AddFileEimmRKNS_11InternalKeyES3_:
   64|    118|               const InternalKey& smallest, const InternalKey& largest) {
   65|    118|    FileMetaData f;
   66|    118|    f.number = file;
   67|    118|    f.file_size = file_size;
   68|    118|    f.smallest = smallest;
   69|    118|    f.largest = largest;
   70|    118|    new_files_.push_back(std::make_pair(level, f));
   71|    118|  }
_ZN7leveldb11VersionEdit16SetPrevLogNumberEm:
   44|    125|  void SetPrevLogNumber(uint64_t num) {
   45|    125|    has_prev_log_number_ = true;
   46|    125|    prev_log_number_ = num;
   47|    125|  }
_ZN7leveldb11VersionEdit10RemoveFileEim:
   74|     21|  void RemoveFile(int level, uint64_t file) {
   75|     21|    deleted_files_.insert(std::make_pair(level, file));
   76|     21|  }
_ZN7leveldb11VersionEdit17SetCompactPointerEiRKNS_11InternalKeyE:
   56|     22|  void SetCompactPointer(int level, const InternalKey& key) {
   57|     22|    compact_pointers_.push_back(std::make_pair(level, key));
   58|     22|  }

_ZN7leveldb7VersionD2Ev:
   67|    425|Version::~Version() {
   68|    425|  assert(refs_ == 0);
   69|       |
   70|       |  // Remove from linked list
   71|    425|  prev_->next_ = next_;
   72|    425|  next_->prev_ = prev_;
   73|       |
   74|       |  // Drop references to files
   75|  3.40k|  for (int level = 0; level < config::kNumLevels; level++) {
  ------------------
  |  Branch (75:23): [True: 2.97k, False: 425]
  ------------------
   76|  3.20k|    for (size_t i = 0; i < files_[level].size(); i++) {
  ------------------
  |  Branch (76:24): [True: 233, False: 2.97k]
  ------------------
   77|    233|      FileMetaData* f = files_[level][i];
   78|    233|      assert(f->refs > 0);
   79|    233|      f->refs--;
   80|    233|      if (f->refs <= 0) {
  ------------------
  |  Branch (80:11): [True: 118, False: 115]
  ------------------
   81|    118|        delete f;
   82|    118|      }
   83|    233|    }
   84|  2.97k|  }
   85|    425|}
_ZN7leveldb8FindFileERKNS_21InternalKeyComparatorERKNSt3__16vectorIPNS_12FileMetaDataENS3_9allocatorIS6_EEEERKNS_5SliceE:
   88|    126|             const std::vector<FileMetaData*>& files, const Slice& key) {
   89|    126|  uint32_t left = 0;
   90|    126|  uint32_t right = files.size();
   91|    145|  while (left < right) {
  ------------------
  |  Branch (91:10): [True: 19, False: 126]
  ------------------
   92|     19|    uint32_t mid = (left + right) / 2;
   93|     19|    const FileMetaData* f = files[mid];
   94|     19|    if (icmp.InternalKeyComparator::Compare(f->largest.Encode(), key) < 0) {
  ------------------
  |  Branch (94:9): [True: 9, False: 10]
  ------------------
   95|       |      // Key at "mid.largest" is < "target".  Therefore all
   96|       |      // files at or before "mid" are uninteresting.
   97|      9|      left = mid + 1;
   98|     10|    } else {
   99|       |      // Key at "mid.largest" is >= "target".  Therefore all files
  100|       |      // after "mid" are uninteresting.
  101|     10|      right = mid;
  102|     10|    }
  103|     19|  }
  104|    126|  return right;
  105|    126|}
_ZN7leveldb21SomeFileOverlapsRangeERKNS_21InternalKeyComparatorEbRKNSt3__16vectorIPNS_12FileMetaDataENS3_9allocatorIS6_EEEEPKNS_5SliceESE_:
  125|    118|                           const Slice* largest_user_key) {
  126|    118|  const Comparator* ucmp = icmp.user_comparator();
  127|    118|  if (!disjoint_sorted_files) {
  ------------------
  |  Branch (127:7): [True: 6, False: 112]
  ------------------
  128|       |    // Need to check against all files
  129|      6|    for (size_t i = 0; i < files.size(); i++) {
  ------------------
  |  Branch (129:24): [True: 4, False: 2]
  ------------------
  130|      4|      const FileMetaData* f = files[i];
  131|      4|      if (AfterFile(ucmp, smallest_user_key, f) ||
  ------------------
  |  Branch (131:11): [True: 0, False: 4]
  ------------------
  132|      4|          BeforeFile(ucmp, largest_user_key, f)) {
  ------------------
  |  Branch (132:11): [True: 0, False: 4]
  ------------------
  133|       |        // No overlap
  134|      4|      } else {
  135|      4|        return true;  // Overlap
  136|      4|      }
  137|      4|    }
  138|      2|    return false;
  139|      6|  }
  140|       |
  141|       |  // Binary search over file list
  142|    112|  uint32_t index = 0;
  143|    112|  if (smallest_user_key != nullptr) {
  ------------------
  |  Branch (143:7): [True: 112, False: 0]
  ------------------
  144|       |    // Find the earliest possible internal key for smallest_user_key
  145|    112|    InternalKey small_key(*smallest_user_key, kMaxSequenceNumber,
  146|    112|                          kValueTypeForSeek);
  147|    112|    index = FindFile(icmp, files, small_key.Encode());
  148|    112|  }
  149|       |
  150|    112|  if (index >= files.size()) {
  ------------------
  |  Branch (150:7): [True: 110, False: 2]
  ------------------
  151|       |    // beginning of range is after all files, so no overlap.
  152|    110|    return false;
  153|    110|  }
  154|       |
  155|      2|  return !BeforeFile(ucmp, largest_user_key, files[index]);
  156|    112|}
_ZNK7leveldb7Version24NewConcatenatingIteratorERKNS_11ReadOptionsEi:
  223|     16|                                            int level) const {
  224|     16|  return NewTwoLevelIterator(
  225|     16|      new LevelFileNumIterator(vset_->icmp_, &files_[level]), &GetFileIterator,
  226|     16|      vset_->table_cache_, options);
  227|     16|}
_ZN7leveldb7Version12AddIteratorsERKNS_11ReadOptionsEPNSt3__16vectorIPNS_8IteratorENS4_9allocatorIS7_EEEE:
  230|     34|                           std::vector<Iterator*>* iters) {
  231|       |  // Merge all level zero files together since they may overlap
  232|     66|  for (size_t i = 0; i < files_[0].size(); i++) {
  ------------------
  |  Branch (232:22): [True: 32, False: 34]
  ------------------
  233|     32|    iters->push_back(vset_->table_cache_->NewIterator(
  234|     32|        options, files_[0][i]->number, files_[0][i]->file_size));
  235|     32|  }
  236|       |
  237|       |  // For levels > 0, we can use a concatenating iterator that sequentially
  238|       |  // walks through the non-overlapping files in the level, opening them
  239|       |  // lazily.
  240|    238|  for (int level = 1; level < config::kNumLevels; level++) {
  ------------------
  |  Branch (240:23): [True: 204, False: 34]
  ------------------
  241|    204|    if (!files_[level].empty()) {
  ------------------
  |  Branch (241:9): [True: 16, False: 188]
  ------------------
  242|     16|      iters->push_back(NewConcatenatingIterator(options, level));
  243|     16|    }
  244|    204|  }
  245|     34|}
_ZN7leveldb7Version18ForEachOverlappingENS_5SliceES1_PvPFbS2_iPNS_12FileMetaDataEE:
  282|     29|                                 bool (*func)(void*, int, FileMetaData*)) {
  283|     29|  const Comparator* ucmp = vset_->icmp_.user_comparator();
  284|       |
  285|       |  // Search level-0 in order from newest to oldest.
  286|     29|  std::vector<FileMetaData*> tmp;
  287|     29|  tmp.reserve(files_[0].size());
  288|     52|  for (uint32_t i = 0; i < files_[0].size(); i++) {
  ------------------
  |  Branch (288:24): [True: 23, False: 29]
  ------------------
  289|     23|    FileMetaData* f = files_[0][i];
  290|     23|    if (ucmp->Compare(user_key, f->smallest.user_key()) >= 0 &&
  ------------------
  |  Branch (290:9): [True: 20, False: 3]
  |  Branch (290:9): [True: 16, False: 7]
  ------------------
  291|     20|        ucmp->Compare(user_key, f->largest.user_key()) <= 0) {
  ------------------
  |  Branch (291:9): [True: 16, False: 4]
  ------------------
  292|     16|      tmp.push_back(f);
  293|     16|    }
  294|     23|  }
  295|     29|  if (!tmp.empty()) {
  ------------------
  |  Branch (295:7): [True: 12, False: 17]
  ------------------
  296|     12|    std::sort(tmp.begin(), tmp.end(), NewestFirst);
  297|     28|    for (uint32_t i = 0; i < tmp.size(); i++) {
  ------------------
  |  Branch (297:26): [True: 16, False: 12]
  ------------------
  298|     16|      if (!(*func)(arg, 0, tmp[i])) {
  ------------------
  |  Branch (298:11): [True: 0, False: 16]
  ------------------
  299|      0|        return;
  300|      0|      }
  301|     16|    }
  302|     12|  }
  303|       |
  304|       |  // Search other levels.
  305|    191|  for (int level = 1; level < config::kNumLevels; level++) {
  ------------------
  |  Branch (305:23): [True: 164, False: 27]
  ------------------
  306|    164|    size_t num_files = files_[level].size();
  307|    164|    if (num_files == 0) continue;
  ------------------
  |  Branch (307:9): [True: 150, False: 14]
  ------------------
  308|       |
  309|       |    // Binary search to find earliest index whose largest key >= internal_key.
  310|     14|    uint32_t index = FindFile(vset_->icmp_, files_[level], internal_key);
  311|     14|    if (index < num_files) {
  ------------------
  |  Branch (311:9): [True: 8, False: 6]
  ------------------
  312|      8|      FileMetaData* f = files_[level][index];
  313|      8|      if (ucmp->Compare(user_key, f->smallest.user_key()) < 0) {
  ------------------
  |  Branch (313:11): [True: 4, False: 4]
  ------------------
  314|       |        // All of "f" is past any data for user_key
  315|      4|      } else {
  316|      4|        if (!(*func)(arg, level, f)) {
  ------------------
  |  Branch (316:13): [True: 2, False: 2]
  ------------------
  317|      2|          return;
  318|      2|        }
  319|      4|      }
  320|      8|    }
  321|     14|  }
  322|     29|}
_ZN7leveldb7Version3GetERKNS_11ReadOptionsERKNS_9LookupKeyEPNSt3__112basic_stringIcNS7_11char_traitsIcEENS7_9allocatorIcEEEEPNS0_8GetStatsE:
  325|     21|                    std::string* value, GetStats* stats) {
  326|     21|  stats->seek_file = nullptr;
  327|     21|  stats->seek_file_level = -1;
  328|       |
  329|     21|  struct State {
  330|     21|    Saver saver;
  331|     21|    GetStats* stats;
  332|     21|    const ReadOptions* options;
  333|     21|    Slice ikey;
  334|     21|    FileMetaData* last_file_read;
  335|     21|    int last_file_read_level;
  336|       |
  337|     21|    VersionSet* vset;
  338|     21|    Status s;
  339|     21|    bool found;
  340|       |
  341|     21|    static bool Match(void* arg, int level, FileMetaData* f) {
  342|     21|      State* state = reinterpret_cast<State*>(arg);
  343|       |
  344|     21|      if (state->stats->seek_file == nullptr &&
  345|     21|          state->last_file_read != nullptr) {
  346|       |        // We have had more than one seek for this read.  Charge the 1st file.
  347|     21|        state->stats->seek_file = state->last_file_read;
  348|     21|        state->stats->seek_file_level = state->last_file_read_level;
  349|     21|      }
  350|       |
  351|     21|      state->last_file_read = f;
  352|     21|      state->last_file_read_level = level;
  353|       |
  354|     21|      state->s = state->vset->table_cache_->Get(*state->options, f->number,
  355|     21|                                                f->file_size, state->ikey,
  356|     21|                                                &state->saver, SaveValue);
  357|     21|      if (!state->s.ok()) {
  358|     21|        state->found = true;
  359|     21|        return false;
  360|     21|      }
  361|     21|      switch (state->saver.state) {
  362|     21|        case kNotFound:
  363|     21|          return true;  // Keep searching in other files
  364|     21|        case kFound:
  365|     21|          state->found = true;
  366|     21|          return false;
  367|     21|        case kDeleted:
  368|     21|          return false;
  369|     21|        case kCorrupt:
  370|     21|          state->s =
  371|     21|              Status::Corruption("corrupted key for ", state->saver.user_key);
  372|     21|          state->found = true;
  373|     21|          return false;
  374|     21|      }
  375|       |
  376|       |      // Not reached. Added to avoid false compilation warnings of
  377|       |      // "control reaches end of non-void function".
  378|     21|      return false;
  379|     21|    }
  380|     21|  };
  381|       |
  382|     21|  State state;
  383|     21|  state.found = false;
  384|     21|  state.stats = stats;
  385|     21|  state.last_file_read = nullptr;
  386|     21|  state.last_file_read_level = -1;
  387|       |
  388|     21|  state.options = &options;
  389|     21|  state.ikey = k.internal_key();
  390|     21|  state.vset = vset_;
  391|       |
  392|     21|  state.saver.state = kNotFound;
  393|     21|  state.saver.ucmp = vset_->icmp_.user_comparator();
  394|     21|  state.saver.user_key = k.user_key();
  395|     21|  state.saver.value = value;
  396|       |
  397|     21|  ForEachOverlapping(state.saver.user_key, state.ikey, &state, &State::Match);
  398|       |
  399|     21|  return state.found ? state.s : Status::NotFound(Slice());
  ------------------
  |  Branch (399:10): [True: 0, False: 21]
  ------------------
  400|     21|}
_ZN7leveldb7Version11UpdateStatsERKNS0_8GetStatsE:
  402|     23|bool Version::UpdateStats(const GetStats& stats) {
  403|     23|  FileMetaData* f = stats.seek_file;
  404|     23|  if (f != nullptr) {
  ------------------
  |  Branch (404:7): [True: 4, False: 19]
  ------------------
  405|      4|    f->allowed_seeks--;
  406|      4|    if (f->allowed_seeks <= 0 && file_to_compact_ == nullptr) {
  ------------------
  |  Branch (406:9): [True: 0, False: 4]
  |  Branch (406:34): [True: 0, False: 0]
  ------------------
  407|      0|      file_to_compact_ = f;
  408|      0|      file_to_compact_level_ = stats.seek_file_level;
  409|      0|      return true;
  410|      0|    }
  411|      4|  }
  412|     23|  return false;
  413|     23|}
_ZN7leveldb7Version16RecordReadSampleENS_5SliceE:
  415|      8|bool Version::RecordReadSample(Slice internal_key) {
  416|      8|  ParsedInternalKey ikey;
  417|      8|  if (!ParseInternalKey(internal_key, &ikey)) {
  ------------------
  |  Branch (417:7): [True: 0, False: 8]
  ------------------
  418|      0|    return false;
  419|      0|  }
  420|       |
  421|      8|  struct State {
  422|      8|    GetStats stats;  // Holds first matching file
  423|      8|    int matches;
  424|       |
  425|      8|    static bool Match(void* arg, int level, FileMetaData* f) {
  426|      8|      State* state = reinterpret_cast<State*>(arg);
  427|      8|      state->matches++;
  428|      8|      if (state->matches == 1) {
  429|       |        // Remember first match.
  430|      8|        state->stats.seek_file = f;
  431|      8|        state->stats.seek_file_level = level;
  432|      8|      }
  433|       |      // We can stop iterating once we have a second match.
  434|      8|      return state->matches < 2;
  435|      8|    }
  436|      8|  };
  437|       |
  438|      8|  State state;
  439|      8|  state.matches = 0;
  440|      8|  ForEachOverlapping(ikey.user_key, internal_key, &state, &State::Match);
  441|       |
  442|       |  // Must have at least two matches since we want to merge across
  443|       |  // files. But what if we have a single file that contains many
  444|       |  // overwrites and deletions?  Should we have another mechanism for
  445|       |  // finding such files?
  446|      8|  if (state.matches >= 2) {
  ------------------
  |  Branch (446:7): [True: 2, False: 6]
  ------------------
  447|       |    // 1MB cost is about 1 seek (see comment in Builder::Apply).
  448|      2|    return UpdateStats(state.stats);
  449|      2|  }
  450|      6|  return false;
  451|      8|}
_ZN7leveldb7Version3RefEv:
  453|    631|void Version::Ref() { ++refs_; }
_ZN7leveldb7Version5UnrefEv:
  455|    631|void Version::Unref() {
  456|    631|  assert(this != &vset_->dummy_versions_);
  457|    631|  assert(refs_ >= 1);
  458|    631|  --refs_;
  459|    631|  if (refs_ == 0) {
  ------------------
  |  Branch (459:7): [True: 325, False: 306]
  ------------------
  460|    325|    delete this;
  461|    325|  }
  462|    631|}
_ZN7leveldb7Version14OverlapInLevelEiPKNS_5SliceES3_:
  465|    118|                             const Slice* largest_user_key) {
  466|    118|  return SomeFileOverlapsRange(vset_->icmp_, (level > 0), files_[level],
  467|    118|                               smallest_user_key, largest_user_key);
  468|    118|}
_ZN7leveldb7Version26PickLevelForMemTableOutputERKNS_5SliceES3_:
  471|      6|                                        const Slice& largest_user_key) {
  472|      6|  int level = 0;
  473|      6|  if (!OverlapInLevel(0, &smallest_user_key, &largest_user_key)) {
  ------------------
  |  Branch (473:7): [True: 2, False: 4]
  ------------------
  474|       |    // Push to next level if there is no overlap in next level,
  475|       |    // and the #bytes overlapping in the level after that are limited.
  476|      2|    InternalKey start(smallest_user_key, kMaxSequenceNumber, kValueTypeForSeek);
  477|      2|    InternalKey limit(largest_user_key, 0, static_cast<ValueType>(0));
  478|      2|    std::vector<FileMetaData*> overlaps;
  479|      6|    while (level < config::kMaxMemCompactLevel) {
  ------------------
  |  Branch (479:12): [True: 4, False: 2]
  ------------------
  480|      4|      if (OverlapInLevel(level + 1, &smallest_user_key, &largest_user_key)) {
  ------------------
  |  Branch (480:11): [True: 0, False: 4]
  ------------------
  481|      0|        break;
  482|      0|      }
  483|      4|      if (level + 2 < config::kNumLevels) {
  ------------------
  |  Branch (483:11): [True: 4, False: 0]
  ------------------
  484|       |        // Check that file does not overlap too many grandparent bytes.
  485|      4|        GetOverlappingInputs(level + 2, &start, &limit, &overlaps);
  486|      4|        const int64_t sum = TotalFileSize(overlaps);
  487|      4|        if (sum > MaxGrandParentOverlapBytes(vset_->options_)) {
  ------------------
  |  Branch (487:13): [True: 0, False: 4]
  ------------------
  488|      0|          break;
  489|      0|        }
  490|      4|      }
  491|      4|      level++;
  492|      4|    }
  493|      2|  }
  494|      6|  return level;
  495|      6|}
_ZN7leveldb7Version20GetOverlappingInputsEiPKNS_11InternalKeyES3_PNSt3__16vectorIPNS_12FileMetaDataENS4_9allocatorIS7_EEEE:
  500|     45|                                   std::vector<FileMetaData*>* inputs) {
  501|     45|  assert(level >= 0);
  502|     45|  assert(level < config::kNumLevels);
  503|     45|  inputs->clear();
  504|     45|  Slice user_begin, user_end;
  505|     45|  if (begin != nullptr) {
  ------------------
  |  Branch (505:7): [True: 45, False: 0]
  ------------------
  506|     45|    user_begin = begin->user_key();
  507|     45|  }
  508|     45|  if (end != nullptr) {
  ------------------
  |  Branch (508:7): [True: 45, False: 0]
  ------------------
  509|     45|    user_end = end->user_key();
  510|     45|  }
  511|     45|  const Comparator* user_cmp = vset_->icmp_.user_comparator();
  512|    112|  for (size_t i = 0; i < files_[level].size();) {
  ------------------
  |  Branch (512:22): [True: 67, False: 45]
  ------------------
  513|     67|    FileMetaData* f = files_[level][i++];
  514|     67|    const Slice file_start = f->smallest.user_key();
  515|     67|    const Slice file_limit = f->largest.user_key();
  516|     67|    if (begin != nullptr && user_cmp->Compare(file_limit, user_begin) < 0) {
  ------------------
  |  Branch (516:9): [True: 67, False: 0]
  |  Branch (516:29): [True: 12, False: 55]
  ------------------
  517|       |      // "f" is completely before specified range; skip it
  518|     55|    } else if (end != nullptr && user_cmp->Compare(file_start, user_end) > 0) {
  ------------------
  |  Branch (518:16): [True: 55, False: 0]
  |  Branch (518:34): [True: 10, False: 45]
  ------------------
  519|       |      // "f" is completely after specified range; skip it
  520|     45|    } else {
  521|     45|      inputs->push_back(f);
  522|     45|      if (level == 0) {
  ------------------
  |  Branch (522:11): [True: 43, False: 2]
  ------------------
  523|       |        // Level-0 files may overlap each other.  So check if the newly
  524|       |        // added file has expanded the range.  If so, restart search.
  525|     43|        if (begin != nullptr && user_cmp->Compare(file_start, user_begin) < 0) {
  ------------------
  |  Branch (525:13): [True: 43, False: 0]
  |  Branch (525:33): [True: 2, False: 41]
  ------------------
  526|      2|          user_begin = file_start;
  527|      2|          inputs->clear();
  528|      2|          i = 0;
  529|     41|        } else if (end != nullptr &&
  ------------------
  |  Branch (529:20): [True: 41, False: 0]
  ------------------
  530|     41|                   user_cmp->Compare(file_limit, user_end) > 0) {
  ------------------
  |  Branch (530:20): [True: 6, False: 35]
  ------------------
  531|      6|          user_end = file_limit;
  532|      6|          inputs->clear();
  533|      6|          i = 0;
  534|      6|        }
  535|     43|      }
  536|     45|    }
  537|     67|  }
  538|     45|}
_ZN7leveldb10VersionSetC2ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEPKNS_7OptionsEPNS_10TableCacheEPKNS_21InternalKeyComparatorE:
  736|    100|    : env_(options->env),
  737|    100|      dbname_(dbname),
  738|    100|      options_(options),
  739|    100|      table_cache_(table_cache),
  740|    100|      icmp_(*cmp),
  741|    100|      next_file_number_(2),
  742|    100|      manifest_file_number_(0),  // Filled by Recover()
  743|    100|      last_sequence_(0),
  744|    100|      log_number_(0),
  745|    100|      prev_log_number_(0),
  746|    100|      descriptor_file_(nullptr),
  747|    100|      descriptor_log_(nullptr),
  748|    100|      dummy_versions_(this),
  749|    100|      current_(nullptr) {
  750|    100|  AppendVersion(new Version(this));
  751|    100|}
_ZN7leveldb10VersionSetD2Ev:
  753|    100|VersionSet::~VersionSet() {
  754|    100|  current_->Unref();
  755|       |  assert(dummy_versions_.next_ == &dummy_versions_);  // List must be empty
  756|    100|  delete descriptor_log_;
  757|    100|  delete descriptor_file_;
  758|    100|}
_ZN7leveldb10VersionSet13AppendVersionEPNS_7VersionE:
  760|    325|void VersionSet::AppendVersion(Version* v) {
  761|       |  // Make "v" current
  762|    325|  assert(v->refs_ == 0);
  763|    325|  assert(v != current_);
  764|    325|  if (current_ != nullptr) {
  ------------------
  |  Branch (764:7): [True: 225, False: 100]
  ------------------
  765|    225|    current_->Unref();
  766|    225|  }
  767|    325|  current_ = v;
  768|    325|  v->Ref();
  769|       |
  770|       |  // Append to linked list
  771|    325|  v->prev_ = dummy_versions_.prev_;
  772|    325|  v->next_ = &dummy_versions_;
  773|    325|  v->prev_->next_ = v;
  774|    325|  v->next_->prev_ = v;
  775|    325|}
_ZN7leveldb10VersionSet11LogAndApplyEPNS_11VersionEditEPNS_4port5MutexE:
  777|    125|Status VersionSet::LogAndApply(VersionEdit* edit, port::Mutex* mu) {
  778|    125|  if (edit->has_log_number_) {
  ------------------
  |  Branch (778:7): [True: 118, False: 7]
  ------------------
  779|    118|    assert(edit->log_number_ >= log_number_);
  780|    118|    assert(edit->log_number_ < next_file_number_);
  781|    118|  } else {
  782|      7|    edit->SetLogNumber(log_number_);
  783|      7|  }
  784|       |
  785|    125|  if (!edit->has_prev_log_number_) {
  ------------------
  |  Branch (785:7): [True: 7, False: 118]
  ------------------
  786|      7|    edit->SetPrevLogNumber(prev_log_number_);
  787|      7|  }
  788|       |
  789|    125|  edit->SetNextFile(next_file_number_);
  790|    125|  edit->SetLastSequence(last_sequence_);
  791|       |
  792|    125|  Version* v = new Version(this);
  793|    125|  {
  794|    125|    Builder builder(this, current_);
  795|    125|    builder.Apply(edit);
  796|    125|    builder.SaveTo(v);
  797|    125|  }
  798|    125|  Finalize(v);
  799|       |
  800|       |  // Initialize new descriptor log file if necessary by creating
  801|       |  // a temporary file that contains a snapshot of the current version.
  802|    125|  std::string new_manifest_file;
  803|    125|  Status s;
  804|    125|  if (descriptor_log_ == nullptr) {
  ------------------
  |  Branch (804:7): [True: 100, False: 25]
  ------------------
  805|       |    // No reason to unlock *mu here since we only hit this path in the
  806|       |    // first call to LogAndApply (when opening the database).
  807|    100|    assert(descriptor_file_ == nullptr);
  808|    100|    new_manifest_file = DescriptorFileName(dbname_, manifest_file_number_);
  809|    100|    s = env_->NewWritableFile(new_manifest_file, &descriptor_file_);
  810|    100|    if (s.ok()) {
  ------------------
  |  Branch (810:9): [True: 100, False: 0]
  ------------------
  811|    100|      descriptor_log_ = new log::Writer(descriptor_file_);
  812|    100|      s = WriteSnapshot(descriptor_log_);
  813|    100|    }
  814|    100|  }
  815|       |
  816|       |  // Unlock during expensive MANIFEST log write
  817|    125|  {
  818|    125|    mu->Unlock();
  819|       |
  820|       |    // Write new record to MANIFEST log
  821|    125|    if (s.ok()) {
  ------------------
  |  Branch (821:9): [True: 125, False: 0]
  ------------------
  822|    125|      std::string record;
  823|    125|      edit->EncodeTo(&record);
  824|    125|      s = descriptor_log_->AddRecord(record);
  825|    125|      if (s.ok()) {
  ------------------
  |  Branch (825:11): [True: 125, False: 0]
  ------------------
  826|    125|        s = descriptor_file_->Sync();
  827|    125|      }
  828|    125|      if (!s.ok()) {
  ------------------
  |  Branch (828:11): [True: 0, False: 125]
  ------------------
  829|      0|        Log(options_->info_log, "MANIFEST write: %s\n", s.ToString().c_str());
  830|      0|      }
  831|    125|    }
  832|       |
  833|       |    // If we just created a new descriptor file, install it by writing a
  834|       |    // new CURRENT file that points to it.
  835|    125|    if (s.ok() && !new_manifest_file.empty()) {
  ------------------
  |  Branch (835:9): [True: 125, False: 0]
  |  Branch (835:19): [True: 100, False: 25]
  ------------------
  836|    100|      s = SetCurrentFile(env_, dbname_, manifest_file_number_);
  837|    100|    }
  838|       |
  839|    125|    mu->Lock();
  840|    125|  }
  841|       |
  842|       |  // Install the new version
  843|    125|  if (s.ok()) {
  ------------------
  |  Branch (843:7): [True: 125, False: 0]
  ------------------
  844|    125|    AppendVersion(v);
  845|    125|    log_number_ = edit->log_number_;
  846|    125|    prev_log_number_ = edit->prev_log_number_;
  847|    125|  } else {
  848|      0|    delete v;
  849|      0|    if (!new_manifest_file.empty()) {
  ------------------
  |  Branch (849:9): [True: 0, False: 0]
  ------------------
  850|      0|      delete descriptor_log_;
  851|      0|      delete descriptor_file_;
  852|      0|      descriptor_log_ = nullptr;
  853|      0|      descriptor_file_ = nullptr;
  854|      0|      env_->RemoveFile(new_manifest_file);
  855|      0|    }
  856|      0|  }
  857|       |
  858|    125|  return s;
  859|    125|}
_ZN7leveldb10VersionSet7RecoverEPb:
  861|    100|Status VersionSet::Recover(bool* save_manifest) {
  862|    100|  struct LogReporter : public log::Reader::Reporter {
  863|    100|    Status* status;
  864|    100|    void Corruption(size_t bytes, const Status& s) override {
  865|    100|      if (this->status->ok()) *this->status = s;
  866|    100|    }
  867|    100|  };
  868|       |
  869|       |  // Read "CURRENT" file, which contains a pointer to the current manifest file
  870|    100|  std::string current;
  871|    100|  Status s = ReadFileToString(env_, CurrentFileName(dbname_), &current);
  872|    100|  if (!s.ok()) {
  ------------------
  |  Branch (872:7): [True: 0, False: 100]
  ------------------
  873|      0|    return s;
  874|      0|  }
  875|    100|  if (current.empty() || current[current.size() - 1] != '\n') {
  ------------------
  |  Branch (875:7): [True: 0, False: 100]
  |  Branch (875:26): [True: 0, False: 100]
  ------------------
  876|      0|    return Status::Corruption("CURRENT file does not end with newline");
  877|      0|  }
  878|    100|  current.resize(current.size() - 1);
  879|       |
  880|    100|  std::string dscname = dbname_ + "/" + current;
  881|    100|  SequentialFile* file;
  882|    100|  s = env_->NewSequentialFile(dscname, &file);
  883|    100|  if (!s.ok()) {
  ------------------
  |  Branch (883:7): [True: 0, False: 100]
  ------------------
  884|      0|    if (s.IsNotFound()) {
  ------------------
  |  Branch (884:9): [True: 0, False: 0]
  ------------------
  885|      0|      return Status::Corruption("CURRENT points to a non-existent file",
  886|      0|                                s.ToString());
  887|      0|    }
  888|      0|    return s;
  889|      0|  }
  890|       |
  891|    100|  bool have_log_number = false;
  892|    100|  bool have_prev_log_number = false;
  893|    100|  bool have_next_file = false;
  894|    100|  bool have_last_sequence = false;
  895|    100|  uint64_t next_file = 0;
  896|    100|  uint64_t last_sequence = 0;
  897|    100|  uint64_t log_number = 0;
  898|    100|  uint64_t prev_log_number = 0;
  899|    100|  Builder builder(this, current_);
  900|    100|  int read_records = 0;
  901|       |
  902|    100|  {
  903|    100|    LogReporter reporter;
  904|    100|    reporter.status = &s;
  905|    100|    log::Reader reader(file, &reporter, true /*checksum*/,
  906|    100|                       0 /*initial_offset*/);
  907|    100|    Slice record;
  908|    100|    std::string scratch;
  909|    270|    while (reader.ReadRecord(&record, &scratch) && s.ok()) {
  ------------------
  |  Branch (909:12): [True: 170, False: 100]
  |  Branch (909:52): [True: 170, False: 0]
  ------------------
  910|    170|      ++read_records;
  911|    170|      VersionEdit edit;
  912|    170|      s = edit.DecodeFrom(record);
  913|    170|      if (s.ok()) {
  ------------------
  |  Branch (913:11): [True: 170, False: 0]
  ------------------
  914|    170|        if (edit.has_comparator_ &&
  ------------------
  |  Branch (914:13): [True: 100, False: 70]
  ------------------
  915|    100|            edit.comparator_ != icmp_.user_comparator()->Name()) {
  ------------------
  |  Branch (915:13): [True: 0, False: 100]
  ------------------
  916|      0|          s = Status::InvalidArgument(
  917|      0|              edit.comparator_ + " does not match existing comparator ",
  918|      0|              icmp_.user_comparator()->Name());
  919|      0|        }
  920|    170|      }
  921|       |
  922|    170|      if (s.ok()) {
  ------------------
  |  Branch (922:11): [True: 170, False: 0]
  ------------------
  923|    170|        builder.Apply(&edit);
  924|    170|      }
  925|       |
  926|    170|      if (edit.has_log_number_) {
  ------------------
  |  Branch (926:11): [True: 117, False: 53]
  ------------------
  927|    117|        log_number = edit.log_number_;
  928|    117|        have_log_number = true;
  929|    117|      }
  930|       |
  931|    170|      if (edit.has_prev_log_number_) {
  ------------------
  |  Branch (931:11): [True: 70, False: 100]
  ------------------
  932|     70|        prev_log_number = edit.prev_log_number_;
  933|     70|        have_prev_log_number = true;
  934|     70|      }
  935|       |
  936|    170|      if (edit.has_next_file_number_) {
  ------------------
  |  Branch (936:11): [True: 117, False: 53]
  ------------------
  937|    117|        next_file = edit.next_file_number_;
  938|    117|        have_next_file = true;
  939|    117|      }
  940|       |
  941|    170|      if (edit.has_last_sequence_) {
  ------------------
  |  Branch (941:11): [True: 117, False: 53]
  ------------------
  942|    117|        last_sequence = edit.last_sequence_;
  943|    117|        have_last_sequence = true;
  944|    117|      }
  945|    170|    }
  946|    100|  }
  947|    100|  delete file;
  948|    100|  file = nullptr;
  949|       |
  950|    100|  if (s.ok()) {
  ------------------
  |  Branch (950:7): [True: 100, False: 0]
  ------------------
  951|    100|    if (!have_next_file) {
  ------------------
  |  Branch (951:9): [True: 0, False: 100]
  ------------------
  952|      0|      s = Status::Corruption("no meta-nextfile entry in descriptor");
  953|    100|    } else if (!have_log_number) {
  ------------------
  |  Branch (953:16): [True: 0, False: 100]
  ------------------
  954|      0|      s = Status::Corruption("no meta-lognumber entry in descriptor");
  955|    100|    } else if (!have_last_sequence) {
  ------------------
  |  Branch (955:16): [True: 0, False: 100]
  ------------------
  956|      0|      s = Status::Corruption("no last-sequence-number entry in descriptor");
  957|      0|    }
  958|       |
  959|    100|    if (!have_prev_log_number) {
  ------------------
  |  Branch (959:9): [True: 47, False: 53]
  ------------------
  960|     47|      prev_log_number = 0;
  961|     47|    }
  962|       |
  963|    100|    MarkFileNumberUsed(prev_log_number);
  964|    100|    MarkFileNumberUsed(log_number);
  965|    100|  }
  966|       |
  967|    100|  if (s.ok()) {
  ------------------
  |  Branch (967:7): [True: 100, False: 0]
  ------------------
  968|    100|    Version* v = new Version(this);
  969|    100|    builder.SaveTo(v);
  970|       |    // Install recovered version
  971|    100|    Finalize(v);
  972|    100|    AppendVersion(v);
  973|    100|    manifest_file_number_ = next_file;
  974|    100|    next_file_number_ = next_file + 1;
  975|    100|    last_sequence_ = last_sequence;
  976|    100|    log_number_ = log_number;
  977|    100|    prev_log_number_ = prev_log_number;
  978|       |
  979|       |    // See if we can reuse the existing MANIFEST file.
  980|    100|    if (ReuseManifest(dscname, current)) {
  ------------------
  |  Branch (980:9): [True: 0, False: 100]
  ------------------
  981|       |      // No need to save new manifest
  982|    100|    } else {
  983|    100|      *save_manifest = true;
  984|    100|    }
  985|    100|  } else {
  986|      0|    std::string error = s.ToString();
  987|      0|    Log(options_->info_log, "Error recovering version set with %d records: %s",
  988|      0|        read_records, error.c_str());
  989|      0|  }
  990|       |
  991|    100|  return s;
  992|    100|}
_ZN7leveldb10VersionSet13ReuseManifestERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEES9_:
  995|    100|                               const std::string& dscbase) {
  996|    100|  if (!options_->reuse_logs) {
  ------------------
  |  Branch (996:7): [True: 100, False: 0]
  ------------------
  997|    100|    return false;
  998|    100|  }
  999|      0|  FileType manifest_type;
 1000|      0|  uint64_t manifest_number;
 1001|      0|  uint64_t manifest_size;
 1002|      0|  if (!ParseFileName(dscbase, &manifest_number, &manifest_type) ||
  ------------------
  |  Branch (1002:7): [True: 0, False: 0]
  |  Branch (1002:7): [True: 0, False: 0]
  ------------------
 1003|      0|      manifest_type != kDescriptorFile ||
  ------------------
  |  Branch (1003:7): [True: 0, False: 0]
  ------------------
 1004|      0|      !env_->GetFileSize(dscname, &manifest_size).ok() ||
  ------------------
  |  Branch (1004:7): [True: 0, False: 0]
  ------------------
 1005|       |      // Make new compacted MANIFEST if old one is too big
 1006|      0|      manifest_size >= TargetFileSize(options_)) {
  ------------------
  |  Branch (1006:7): [True: 0, False: 0]
  ------------------
 1007|      0|    return false;
 1008|      0|  }
 1009|       |
 1010|      0|  assert(descriptor_file_ == nullptr);
 1011|      0|  assert(descriptor_log_ == nullptr);
 1012|      0|  Status r = env_->NewAppendableFile(dscname, &descriptor_file_);
 1013|      0|  if (!r.ok()) {
  ------------------
  |  Branch (1013:7): [True: 0, False: 0]
  ------------------
 1014|      0|    Log(options_->info_log, "Reuse MANIFEST: %s\n", r.ToString().c_str());
 1015|      0|    assert(descriptor_file_ == nullptr);
 1016|      0|    return false;
 1017|      0|  }
 1018|       |
 1019|      0|  Log(options_->info_log, "Reusing MANIFEST %s\n", dscname.c_str());
 1020|      0|  descriptor_log_ = new log::Writer(descriptor_file_, manifest_size);
 1021|      0|  manifest_file_number_ = manifest_number;
 1022|      0|  return true;
 1023|      0|}
_ZN7leveldb10VersionSet18MarkFileNumberUsedEm:
 1025|    254|void VersionSet::MarkFileNumberUsed(uint64_t number) {
 1026|    254|  if (next_file_number_ <= number) {
  ------------------
  |  Branch (1026:7): [True: 54, False: 200]
  ------------------
 1027|     54|    next_file_number_ = number + 1;
 1028|     54|  }
 1029|    254|}
_ZN7leveldb10VersionSet8FinalizeEPNS_7VersionE:
 1031|    225|void VersionSet::Finalize(Version* v) {
 1032|       |  // Precomputed best level for next compaction
 1033|    225|  int best_level = -1;
 1034|    225|  double best_score = -1;
 1035|       |
 1036|  1.57k|  for (int level = 0; level < config::kNumLevels - 1; level++) {
  ------------------
  |  Branch (1036:23): [True: 1.35k, False: 225]
  ------------------
 1037|  1.35k|    double score;
 1038|  1.35k|    if (level == 0) {
  ------------------
  |  Branch (1038:9): [True: 225, False: 1.12k]
  ------------------
 1039|       |      // We treat level-0 specially by bounding the number of files
 1040|       |      // instead of number of bytes for two reasons:
 1041|       |      //
 1042|       |      // (1) With larger write-buffer sizes, it is nice not to do too
 1043|       |      // many level-0 compactions.
 1044|       |      //
 1045|       |      // (2) The files in level-0 are merged on every read and
 1046|       |      // therefore we wish to avoid too many files when the individual
 1047|       |      // file size is small (perhaps because of a small write-buffer
 1048|       |      // setting, or very high compression ratios, or lots of
 1049|       |      // overwrites/deletions).
 1050|    225|      score = v->files_[level].size() /
 1051|    225|              static_cast<double>(config::kL0_CompactionTrigger);
 1052|  1.12k|    } else {
 1053|       |      // Compute the ratio of current size to size limit.
 1054|  1.12k|      const uint64_t level_bytes = TotalFileSize(v->files_[level]);
 1055|  1.12k|      score =
 1056|  1.12k|          static_cast<double>(level_bytes) / MaxBytesForLevel(options_, level);
 1057|  1.12k|    }
 1058|       |
 1059|  1.35k|    if (score > best_score) {
  ------------------
  |  Branch (1059:9): [True: 249, False: 1.10k]
  ------------------
 1060|    249|      best_level = level;
 1061|    249|      best_score = score;
 1062|    249|    }
 1063|  1.35k|  }
 1064|       |
 1065|    225|  v->compaction_level_ = best_level;
 1066|    225|  v->compaction_score_ = best_score;
 1067|    225|}
_ZN7leveldb10VersionSet13WriteSnapshotEPNS_3log6WriterE:
 1069|    100|Status VersionSet::WriteSnapshot(log::Writer* log) {
 1070|       |  // TODO: Break up into multiple records to reduce memory usage on recovery?
 1071|       |
 1072|       |  // Save metadata
 1073|    100|  VersionEdit edit;
 1074|    100|  edit.SetComparatorName(icmp_.user_comparator()->Name());
 1075|       |
 1076|       |  // Save compaction pointers
 1077|    800|  for (int level = 0; level < config::kNumLevels; level++) {
  ------------------
  |  Branch (1077:23): [True: 700, False: 100]
  ------------------
 1078|    700|    if (!compact_pointer_[level].empty()) {
  ------------------
  |  Branch (1078:9): [True: 15, False: 685]
  ------------------
 1079|     15|      InternalKey key;
 1080|     15|      key.DecodeFrom(compact_pointer_[level]);
 1081|     15|      edit.SetCompactPointer(level, key);
 1082|     15|    }
 1083|    700|  }
 1084|       |
 1085|       |  // Save files
 1086|    800|  for (int level = 0; level < config::kNumLevels; level++) {
  ------------------
  |  Branch (1086:23): [True: 700, False: 100]
  ------------------
 1087|    700|    const std::vector<FileMetaData*>& files = current_->files_[level];
 1088|    775|    for (size_t i = 0; i < files.size(); i++) {
  ------------------
  |  Branch (1088:24): [True: 75, False: 700]
  ------------------
 1089|     75|      const FileMetaData* f = files[i];
 1090|     75|      edit.AddFile(level, f->number, f->file_size, f->smallest, f->largest);
 1091|     75|    }
 1092|    700|  }
 1093|       |
 1094|    100|  std::string record;
 1095|    100|  edit.EncodeTo(&record);
 1096|    100|  return log->AddRecord(record);
 1097|    100|}
_ZNK7leveldb10VersionSet13NumLevelFilesEi:
 1099|    452|int VersionSet::NumLevelFiles(int level) const {
 1100|    452|  assert(level >= 0);
 1101|       |  assert(level < config::kNumLevels);
 1102|    452|  return current_->files_[level].size();
 1103|    452|}
_ZNK7leveldb10VersionSet12LevelSummaryEPNS0_19LevelSummaryStorageE:
 1105|      7|const char* VersionSet::LevelSummary(LevelSummaryStorage* scratch) const {
 1106|       |  // Update code if kNumLevels changes
 1107|      7|  static_assert(config::kNumLevels == 7, "");
 1108|      7|  std::snprintf(
 1109|      7|      scratch->buffer, sizeof(scratch->buffer), "files[ %d %d %d %d %d %d %d ]",
 1110|      7|      int(current_->files_[0].size()), int(current_->files_[1].size()),
 1111|      7|      int(current_->files_[2].size()), int(current_->files_[3].size()),
 1112|      7|      int(current_->files_[4].size()), int(current_->files_[5].size()),
 1113|      7|      int(current_->files_[6].size()));
 1114|      7|  return scratch->buffer;
 1115|      7|}
_ZN7leveldb10VersionSet12AddLiveFilesEPNSt3__13setImNS1_4lessImEENS1_9allocatorImEEEE:
 1149|    224|void VersionSet::AddLiveFiles(std::set<uint64_t>* live) {
 1150|    448|  for (Version* v = dummy_versions_.next_; v != &dummy_versions_;
  ------------------
  |  Branch (1150:44): [True: 224, False: 224]
  ------------------
 1151|    224|       v = v->next_) {
 1152|  1.79k|    for (int level = 0; level < config::kNumLevels; level++) {
  ------------------
  |  Branch (1152:25): [True: 1.56k, False: 224]
  ------------------
 1153|  1.56k|      const std::vector<FileMetaData*>& files = v->files_[level];
 1154|  1.79k|      for (size_t i = 0; i < files.size(); i++) {
  ------------------
  |  Branch (1154:26): [True: 227, False: 1.56k]
  ------------------
 1155|    227|        live->insert(files[i]->number);
 1156|    227|      }
 1157|  1.56k|    }
 1158|    224|  }
 1159|    224|}
_ZN7leveldb10VersionSet8GetRangeERKNSt3__16vectorIPNS_12FileMetaDataENS1_9allocatorIS4_EEEEPNS_11InternalKeyESB_:
 1188|     18|                          InternalKey* smallest, InternalKey* largest) {
 1189|     18|  assert(!inputs.empty());
 1190|     18|  smallest->Clear();
 1191|     18|  largest->Clear();
 1192|     62|  for (size_t i = 0; i < inputs.size(); i++) {
  ------------------
  |  Branch (1192:22): [True: 44, False: 18]
  ------------------
 1193|     44|    FileMetaData* f = inputs[i];
 1194|     44|    if (i == 0) {
  ------------------
  |  Branch (1194:9): [True: 18, False: 26]
  ------------------
 1195|     18|      *smallest = f->smallest;
 1196|     18|      *largest = f->largest;
 1197|     26|    } else {
 1198|     26|      if (icmp_.Compare(f->smallest, *smallest) < 0) {
  ------------------
  |  Branch (1198:11): [True: 0, False: 26]
  ------------------
 1199|      0|        *smallest = f->smallest;
 1200|      0|      }
 1201|     26|      if (icmp_.Compare(f->largest, *largest) > 0) {
  ------------------
  |  Branch (1201:11): [True: 10, False: 16]
  ------------------
 1202|     10|        *largest = f->largest;
 1203|     10|      }
 1204|     26|    }
 1205|     44|  }
 1206|     18|}
_ZN7leveldb10VersionSet9GetRange2ERKNSt3__16vectorIPNS_12FileMetaDataENS1_9allocatorIS4_EEEES9_PNS_11InternalKeyESB_:
 1213|      7|                           InternalKey* smallest, InternalKey* largest) {
 1214|      7|  std::vector<FileMetaData*> all = inputs1;
 1215|      7|  all.insert(all.end(), inputs2.begin(), inputs2.end());
 1216|      7|  GetRange(all, smallest, largest);
 1217|      7|}
_ZN7leveldb10VersionSet17MakeInputIteratorEPNS_10CompactionE:
 1219|      6|Iterator* VersionSet::MakeInputIterator(Compaction* c) {
 1220|      6|  ReadOptions options;
 1221|      6|  options.verify_checksums = options_->paranoid_checks;
 1222|      6|  options.fill_cache = false;
 1223|       |
 1224|       |  // Level-0 files have to be merged together.  For other levels,
 1225|       |  // we will make a concatenating iterator per level.
 1226|       |  // TODO(opt): use concatenating iterator for level-0 if there is no overlap
 1227|      6|  const int space = (c->level() == 0 ? c->inputs_[0].size() + 1 : 2);
  ------------------
  |  Branch (1227:22): [True: 6, False: 0]
  ------------------
 1228|      6|  Iterator** list = new Iterator*[space];
 1229|      6|  int num = 0;
 1230|     18|  for (int which = 0; which < 2; which++) {
  ------------------
  |  Branch (1230:23): [True: 12, False: 6]
  ------------------
 1231|     12|    if (!c->inputs_[which].empty()) {
  ------------------
  |  Branch (1231:9): [True: 8, False: 4]
  ------------------
 1232|      8|      if (c->level() + which == 0) {
  ------------------
  |  Branch (1232:11): [True: 6, False: 2]
  ------------------
 1233|      6|        const std::vector<FileMetaData*>& files = c->inputs_[which];
 1234|     24|        for (size_t i = 0; i < files.size(); i++) {
  ------------------
  |  Branch (1234:28): [True: 18, False: 6]
  ------------------
 1235|     18|          list[num++] = table_cache_->NewIterator(options, files[i]->number,
 1236|     18|                                                  files[i]->file_size);
 1237|     18|        }
 1238|      6|      } else {
 1239|       |        // Create concatenating iterator for the files from this level
 1240|      2|        list[num++] = NewTwoLevelIterator(
 1241|      2|            new Version::LevelFileNumIterator(icmp_, &c->inputs_[which]),
 1242|      2|            &GetFileIterator, table_cache_, options);
 1243|      2|      }
 1244|      8|    }
 1245|     12|  }
 1246|       |  assert(num <= space);
 1247|      6|  Iterator* result = NewMergingIterator(&icmp_, list, num);
 1248|      6|  delete[] list;
 1249|      6|  return result;
 1250|      6|}
_ZN7leveldb10VersionSet14PickCompactionEv:
 1252|      4|Compaction* VersionSet::PickCompaction() {
 1253|      4|  Compaction* c;
 1254|      4|  int level;
 1255|       |
 1256|       |  // We prefer compactions triggered by too much data in a level over
 1257|       |  // the compactions triggered by seeks.
 1258|      4|  const bool size_compaction = (current_->compaction_score_ >= 1);
 1259|      4|  const bool seek_compaction = (current_->file_to_compact_ != nullptr);
 1260|      4|  if (size_compaction) {
  ------------------
  |  Branch (1260:7): [True: 4, False: 0]
  ------------------
 1261|      4|    level = current_->compaction_level_;
 1262|      4|    assert(level >= 0);
 1263|      4|    assert(level + 1 < config::kNumLevels);
 1264|      4|    c = new Compaction(options_, level);
 1265|       |
 1266|       |    // Pick the first file that comes after compact_pointer_[level]
 1267|     12|    for (size_t i = 0; i < current_->files_[level].size(); i++) {
  ------------------
  |  Branch (1267:24): [True: 10, False: 2]
  ------------------
 1268|     10|      FileMetaData* f = current_->files_[level][i];
 1269|     10|      if (compact_pointer_[level].empty() ||
  ------------------
  |  Branch (1269:11): [True: 1, False: 9]
  |  Branch (1269:11): [True: 2, False: 8]
  ------------------
 1270|      9|          icmp_.Compare(f->largest.Encode(), compact_pointer_[level]) > 0) {
  ------------------
  |  Branch (1270:11): [True: 1, False: 8]
  ------------------
 1271|      2|        c->inputs_[0].push_back(f);
 1272|      2|        break;
 1273|      2|      }
 1274|     10|    }
 1275|      4|    if (c->inputs_[0].empty()) {
  ------------------
  |  Branch (1275:9): [True: 2, False: 2]
  ------------------
 1276|       |      // Wrap-around to the beginning of the key space
 1277|      2|      c->inputs_[0].push_back(current_->files_[level][0]);
 1278|      2|    }
 1279|      4|  } else if (seek_compaction) {
  ------------------
  |  Branch (1279:14): [True: 0, False: 0]
  ------------------
 1280|      0|    level = current_->file_to_compact_level_;
 1281|      0|    c = new Compaction(options_, level);
 1282|      0|    c->inputs_[0].push_back(current_->file_to_compact_);
 1283|      0|  } else {
 1284|      0|    return nullptr;
 1285|      0|  }
 1286|       |
 1287|      4|  c->input_version_ = current_;
 1288|      4|  c->input_version_->Ref();
 1289|       |
 1290|       |  // Files in level 0 may overlap each other, so pick up all overlapping ones
 1291|      4|  if (level == 0) {
  ------------------
  |  Branch (1291:7): [True: 4, False: 0]
  ------------------
 1292|      4|    InternalKey smallest, largest;
 1293|      4|    GetRange(c->inputs_[0], &smallest, &largest);
 1294|       |    // Note that the next call will discard the file we placed in
 1295|       |    // c->inputs_[0] earlier and replace it with an overlapping set
 1296|       |    // which will include the picked file.
 1297|      4|    current_->GetOverlappingInputs(0, &smallest, &largest, &c->inputs_[0]);
 1298|      4|    assert(!c->inputs_[0].empty());
 1299|      4|  }
 1300|       |
 1301|      4|  SetupOtherInputs(c);
 1302|       |
 1303|      4|  return c;
 1304|      4|}
_ZN7leveldb14FindLargestKeyERKNS_21InternalKeyComparatorERKNSt3__16vectorIPNS_12FileMetaDataENS3_9allocatorIS6_EEEEPNS_11InternalKeyE:
 1310|     16|                    InternalKey* largest_key) {
 1311|     16|  if (files.empty()) {
  ------------------
  |  Branch (1311:7): [True: 5, False: 11]
  ------------------
 1312|      5|    return false;
 1313|      5|  }
 1314|     11|  *largest_key = files[0]->largest;
 1315|     29|  for (size_t i = 1; i < files.size(); ++i) {
  ------------------
  |  Branch (1315:22): [True: 18, False: 11]
  ------------------
 1316|     18|    FileMetaData* f = files[i];
 1317|     18|    if (icmp.Compare(f->largest, *largest_key) > 0) {
  ------------------
  |  Branch (1317:9): [True: 8, False: 10]
  ------------------
 1318|      8|      *largest_key = f->largest;
 1319|      8|    }
 1320|     18|  }
 1321|     11|  return true;
 1322|     16|}
_ZN7leveldb24FindSmallestBoundaryFileERKNS_21InternalKeyComparatorERKNSt3__16vectorIPNS_12FileMetaDataENS3_9allocatorIS6_EEEERKNS_11InternalKeyE:
 1329|     11|    const InternalKey& largest_key) {
 1330|     11|  const Comparator* user_cmp = icmp.user_comparator();
 1331|     11|  FileMetaData* smallest_boundary_file = nullptr;
 1332|     49|  for (size_t i = 0; i < level_files.size(); ++i) {
  ------------------
  |  Branch (1332:22): [True: 38, False: 11]
  ------------------
 1333|     38|    FileMetaData* f = level_files[i];
 1334|     38|    if (icmp.Compare(f->smallest, largest_key) > 0 &&
  ------------------
  |  Branch (1334:9): [True: 8, False: 30]
  |  Branch (1334:9): [True: 0, False: 38]
  ------------------
 1335|      8|        user_cmp->Compare(f->smallest.user_key(), largest_key.user_key()) ==
  ------------------
  |  Branch (1335:9): [True: 0, False: 8]
  ------------------
 1336|      8|            0) {
 1337|      0|      if (smallest_boundary_file == nullptr ||
  ------------------
  |  Branch (1337:11): [True: 0, False: 0]
  ------------------
 1338|      0|          icmp.Compare(f->smallest, smallest_boundary_file->smallest) < 0) {
  ------------------
  |  Branch (1338:11): [True: 0, False: 0]
  ------------------
 1339|      0|        smallest_boundary_file = f;
 1340|      0|      }
 1341|      0|    }
 1342|     38|  }
 1343|     11|  return smallest_boundary_file;
 1344|     11|}
_ZN7leveldb17AddBoundaryInputsERKNS_21InternalKeyComparatorERKNSt3__16vectorIPNS_12FileMetaDataENS3_9allocatorIS6_EEEEPS9_:
 1362|     16|                       std::vector<FileMetaData*>* compaction_files) {
 1363|     16|  InternalKey largest_key;
 1364|       |
 1365|       |  // Quick return if compaction_files is empty.
 1366|     16|  if (!FindLargestKey(icmp, *compaction_files, &largest_key)) {
  ------------------
  |  Branch (1366:7): [True: 5, False: 11]
  ------------------
 1367|      5|    return;
 1368|      5|  }
 1369|       |
 1370|     11|  bool continue_searching = true;
 1371|     22|  while (continue_searching) {
  ------------------
  |  Branch (1371:10): [True: 11, False: 11]
  ------------------
 1372|     11|    FileMetaData* smallest_boundary_file =
 1373|     11|        FindSmallestBoundaryFile(icmp, level_files, largest_key);
 1374|       |
 1375|       |    // If a boundary file was found advance largest_key, otherwise we're done.
 1376|     11|    if (smallest_boundary_file != NULL) {
  ------------------
  |  Branch (1376:9): [True: 0, False: 11]
  ------------------
 1377|      0|      compaction_files->push_back(smallest_boundary_file);
 1378|      0|      largest_key = smallest_boundary_file->largest;
 1379|     11|    } else {
 1380|     11|      continue_searching = false;
 1381|     11|    }
 1382|     11|  }
 1383|     11|}
_ZN7leveldb10VersionSet16SetupOtherInputsEPNS_10CompactionE:
 1385|      7|void VersionSet::SetupOtherInputs(Compaction* c) {
 1386|      7|  const int level = c->level();
 1387|      7|  InternalKey smallest, largest;
 1388|       |
 1389|      7|  AddBoundaryInputs(icmp_, current_->files_[level], &c->inputs_[0]);
 1390|      7|  GetRange(c->inputs_[0], &smallest, &largest);
 1391|       |
 1392|      7|  current_->GetOverlappingInputs(level + 1, &smallest, &largest,
 1393|      7|                                 &c->inputs_[1]);
 1394|      7|  AddBoundaryInputs(icmp_, current_->files_[level + 1], &c->inputs_[1]);
 1395|       |
 1396|       |  // Get entire range covered by compaction
 1397|      7|  InternalKey all_start, all_limit;
 1398|      7|  GetRange2(c->inputs_[0], c->inputs_[1], &all_start, &all_limit);
 1399|       |
 1400|       |  // See if we can grow the number of inputs in "level" without
 1401|       |  // changing the number of "level+1" files we pick up.
 1402|      7|  if (!c->inputs_[1].empty()) {
  ------------------
  |  Branch (1402:7): [True: 2, False: 5]
  ------------------
 1403|      2|    std::vector<FileMetaData*> expanded0;
 1404|      2|    current_->GetOverlappingInputs(level, &all_start, &all_limit, &expanded0);
 1405|      2|    AddBoundaryInputs(icmp_, current_->files_[level], &expanded0);
 1406|      2|    const int64_t inputs0_size = TotalFileSize(c->inputs_[0]);
 1407|      2|    const int64_t inputs1_size = TotalFileSize(c->inputs_[1]);
 1408|      2|    const int64_t expanded0_size = TotalFileSize(expanded0);
 1409|      2|    if (expanded0.size() > c->inputs_[0].size() &&
  ------------------
  |  Branch (1409:9): [True: 0, False: 2]
  ------------------
 1410|      0|        inputs1_size + expanded0_size <
  ------------------
  |  Branch (1410:9): [True: 0, False: 0]
  ------------------
 1411|      0|            ExpandedCompactionByteSizeLimit(options_)) {
 1412|      0|      InternalKey new_start, new_limit;
 1413|      0|      GetRange(expanded0, &new_start, &new_limit);
 1414|      0|      std::vector<FileMetaData*> expanded1;
 1415|      0|      current_->GetOverlappingInputs(level + 1, &new_start, &new_limit,
 1416|      0|                                     &expanded1);
 1417|      0|      AddBoundaryInputs(icmp_, current_->files_[level + 1], &expanded1);
 1418|      0|      if (expanded1.size() == c->inputs_[1].size()) {
  ------------------
  |  Branch (1418:11): [True: 0, False: 0]
  ------------------
 1419|      0|        Log(options_->info_log,
 1420|      0|            "Expanding@%d %d+%d (%ld+%ld bytes) to %d+%d (%ld+%ld bytes)\n",
 1421|      0|            level, int(c->inputs_[0].size()), int(c->inputs_[1].size()),
 1422|      0|            long(inputs0_size), long(inputs1_size), int(expanded0.size()),
 1423|      0|            int(expanded1.size()), long(expanded0_size), long(inputs1_size));
 1424|      0|        smallest = new_start;
 1425|      0|        largest = new_limit;
 1426|      0|        c->inputs_[0] = expanded0;
 1427|      0|        c->inputs_[1] = expanded1;
 1428|      0|        GetRange2(c->inputs_[0], c->inputs_[1], &all_start, &all_limit);
 1429|      0|      }
 1430|      0|    }
 1431|      2|  }
 1432|       |
 1433|       |  // Compute the set of grandparent files that overlap this compaction
 1434|       |  // (parent == level+1; grandparent == level+2)
 1435|      7|  if (level + 2 < config::kNumLevels) {
  ------------------
  |  Branch (1435:7): [True: 7, False: 0]
  ------------------
 1436|      7|    current_->GetOverlappingInputs(level + 2, &all_start, &all_limit,
 1437|      7|                                   &c->grandparents_);
 1438|      7|  }
 1439|       |
 1440|       |  // Update the place where we will do the next compaction for this level.
 1441|       |  // We update this immediately instead of waiting for the VersionEdit
 1442|       |  // to be applied so that if the compaction fails, we will try a different
 1443|       |  // key range next time.
 1444|      7|  compact_pointer_[level] = largest.Encode().ToString();
 1445|      7|  c->edit_.SetCompactPointer(level, largest);
 1446|      7|}
_ZN7leveldb10VersionSet12CompactRangeEiPKNS_11InternalKeyES3_:
 1449|     21|                                     const InternalKey* end) {
 1450|     21|  std::vector<FileMetaData*> inputs;
 1451|     21|  current_->GetOverlappingInputs(level, begin, end, &inputs);
 1452|     21|  if (inputs.empty()) {
  ------------------
  |  Branch (1452:7): [True: 18, False: 3]
  ------------------
 1453|     18|    return nullptr;
 1454|     18|  }
 1455|       |
 1456|       |  // Avoid compacting too much in one shot in case the range is large.
 1457|       |  // But we cannot do this for level-0 since level-0 files can overlap
 1458|       |  // and we must not pick one file and drop another older file if the
 1459|       |  // two files overlap.
 1460|      3|  if (level > 0) {
  ------------------
  |  Branch (1460:7): [True: 0, False: 3]
  ------------------
 1461|      0|    const uint64_t limit = MaxFileSizeForLevel(options_, level);
 1462|      0|    uint64_t total = 0;
 1463|      0|    for (size_t i = 0; i < inputs.size(); i++) {
  ------------------
  |  Branch (1463:24): [True: 0, False: 0]
  ------------------
 1464|      0|      uint64_t s = inputs[i]->file_size;
 1465|      0|      total += s;
 1466|      0|      if (total >= limit) {
  ------------------
  |  Branch (1466:11): [True: 0, False: 0]
  ------------------
 1467|      0|        inputs.resize(i + 1);
 1468|      0|        break;
 1469|      0|      }
 1470|      0|    }
 1471|      0|  }
 1472|       |
 1473|      3|  Compaction* c = new Compaction(options_, level);
 1474|      3|  c->input_version_ = current_;
 1475|      3|  c->input_version_->Ref();
 1476|      3|  c->inputs_[0] = inputs;
 1477|      3|  SetupOtherInputs(c);
 1478|      3|  return c;
 1479|     21|}
_ZN7leveldb10CompactionC2EPKNS_7OptionsEi:
 1482|      7|    : level_(level),
 1483|      7|      max_output_file_size_(MaxFileSizeForLevel(options, level)),
 1484|      7|      input_version_(nullptr),
 1485|      7|      grandparent_index_(0),
 1486|      7|      seen_key_(false),
 1487|      7|      overlapped_bytes_(0) {
 1488|     56|  for (int i = 0; i < config::kNumLevels; i++) {
  ------------------
  |  Branch (1488:19): [True: 49, False: 7]
  ------------------
 1489|     49|    level_ptrs_[i] = 0;
 1490|     49|  }
 1491|      7|}
_ZN7leveldb10CompactionD2Ev:
 1493|      7|Compaction::~Compaction() {
 1494|      7|  if (input_version_ != nullptr) {
  ------------------
  |  Branch (1494:7): [True: 1, False: 6]
  ------------------
 1495|      1|    input_version_->Unref();
 1496|      1|  }
 1497|      7|}
_ZNK7leveldb10Compaction13IsTrivialMoveEv:
 1499|      4|bool Compaction::IsTrivialMove() const {
 1500|      4|  const VersionSet* vset = input_version_->vset_;
 1501|       |  // Avoid a move if there is lots of overlapping grandparent data.
 1502|       |  // Otherwise, the move could create a parent file that will require
 1503|       |  // a very expensive merge later on.
 1504|      4|  return (num_input_files(0) == 1 && num_input_files(1) == 0 &&
  ------------------
  |  Branch (1504:11): [True: 1, False: 3]
  |  Branch (1504:38): [True: 1, False: 0]
  ------------------
 1505|      1|          TotalFileSize(grandparents_) <=
  ------------------
  |  Branch (1505:11): [True: 1, False: 0]
  ------------------
 1506|      1|              MaxGrandParentOverlapBytes(vset->options_));
 1507|      4|}
_ZN7leveldb10Compaction17AddInputDeletionsEPNS_11VersionEditE:
 1509|      6|void Compaction::AddInputDeletions(VersionEdit* edit) {
 1510|     18|  for (int which = 0; which < 2; which++) {
  ------------------
  |  Branch (1510:23): [True: 12, False: 6]
  ------------------
 1511|     32|    for (size_t i = 0; i < inputs_[which].size(); i++) {
  ------------------
  |  Branch (1511:24): [True: 20, False: 12]
  ------------------
 1512|     20|      edit->RemoveFile(level_ + which, inputs_[which][i]->number);
 1513|     20|    }
 1514|     12|  }
 1515|      6|}
_ZN7leveldb10Compaction17IsBaseLevelForKeyERKNS_5SliceE:
 1517|      6|bool Compaction::IsBaseLevelForKey(const Slice& user_key) {
 1518|       |  // Maybe use binary search to find right entry instead of linear search?
 1519|      6|  const Comparator* user_cmp = input_version_->vset_->icmp_.user_comparator();
 1520|     36|  for (int lvl = level_ + 2; lvl < config::kNumLevels; lvl++) {
  ------------------
  |  Branch (1520:30): [True: 30, False: 6]
  ------------------
 1521|     30|    const std::vector<FileMetaData*>& files = input_version_->files_[lvl];
 1522|     30|    while (level_ptrs_[lvl] < files.size()) {
  ------------------
  |  Branch (1522:12): [True: 0, False: 30]
  ------------------
 1523|      0|      FileMetaData* f = files[level_ptrs_[lvl]];
 1524|      0|      if (user_cmp->Compare(user_key, f->largest.user_key()) <= 0) {
  ------------------
  |  Branch (1524:11): [True: 0, False: 0]
  ------------------
 1525|       |        // We've advanced far enough
 1526|      0|        if (user_cmp->Compare(user_key, f->smallest.user_key()) >= 0) {
  ------------------
  |  Branch (1526:13): [True: 0, False: 0]
  ------------------
 1527|       |          // Key falls in this file's range, so definitely not base level
 1528|      0|          return false;
 1529|      0|        }
 1530|      0|        break;
 1531|      0|      }
 1532|      0|      level_ptrs_[lvl]++;
 1533|      0|    }
 1534|     30|  }
 1535|      6|  return true;
 1536|      6|}
_ZN7leveldb10Compaction16ShouldStopBeforeERKNS_5SliceE:
 1538|    320|bool Compaction::ShouldStopBefore(const Slice& internal_key) {
 1539|    320|  const VersionSet* vset = input_version_->vset_;
 1540|       |  // Scan to find earliest grandparent file that contains key.
 1541|    320|  const InternalKeyComparator* icmp = &vset->icmp_;
 1542|    320|  while (grandparent_index_ < grandparents_.size() &&
  ------------------
  |  Branch (1542:10): [True: 0, False: 320]
  |  Branch (1542:10): [True: 0, False: 320]
  ------------------
 1543|      0|         icmp->Compare(internal_key,
  ------------------
  |  Branch (1543:10): [True: 0, False: 0]
  ------------------
 1544|      0|                       grandparents_[grandparent_index_]->largest.Encode()) >
 1545|      0|             0) {
 1546|      0|    if (seen_key_) {
  ------------------
  |  Branch (1546:9): [True: 0, False: 0]
  ------------------
 1547|      0|      overlapped_bytes_ += grandparents_[grandparent_index_]->file_size;
 1548|      0|    }
 1549|      0|    grandparent_index_++;
 1550|      0|  }
 1551|    320|  seen_key_ = true;
 1552|       |
 1553|    320|  if (overlapped_bytes_ > MaxGrandParentOverlapBytes(vset->options_)) {
  ------------------
  |  Branch (1553:7): [True: 0, False: 320]
  ------------------
 1554|       |    // Too much overlap for current output; start new output
 1555|      0|    overlapped_bytes_ = 0;
 1556|      0|    return true;
 1557|    320|  } else {
 1558|    320|    return false;
 1559|    320|  }
 1560|    320|}
_ZN7leveldb10Compaction13ReleaseInputsEv:
 1562|      6|void Compaction::ReleaseInputs() {
 1563|      6|  if (input_version_ != nullptr) {
  ------------------
  |  Branch (1563:7): [True: 6, False: 0]
  ------------------
 1564|      6|    input_version_->Unref();
 1565|      6|    input_version_ = nullptr;
 1566|      6|  }
 1567|      6|}
version_set.cc:_ZN7leveldbL9AfterFileEPKNS_10ComparatorEPKNS_5SliceEPKNS_12FileMetaDataE:
  108|      4|                      const FileMetaData* f) {
  109|       |  // null user_key occurs before all keys and is therefore never after *f
  110|      4|  return (user_key != nullptr &&
  ------------------
  |  Branch (110:11): [True: 4, False: 0]
  ------------------
  111|      4|          ucmp->Compare(*user_key, f->largest.user_key()) > 0);
  ------------------
  |  Branch (111:11): [True: 0, False: 4]
  ------------------
  112|      4|}
version_set.cc:_ZN7leveldbL10BeforeFileEPKNS_10ComparatorEPKNS_5SliceEPKNS_12FileMetaDataE:
  115|      6|                       const FileMetaData* f) {
  116|       |  // null user_key occurs after all keys and is therefore never before *f
  117|      6|  return (user_key != nullptr &&
  ------------------
  |  Branch (117:11): [True: 6, False: 0]
  ------------------
  118|      6|          ucmp->Compare(*user_key, f->smallest.user_key()) < 0);
  ------------------
  |  Branch (118:11): [True: 0, False: 6]
  ------------------
  119|      6|}
_ZN7leveldb7Version20LevelFileNumIteratorC2ERKNS_21InternalKeyComparatorEPKNSt3__16vectorIPNS_12FileMetaDataENS5_9allocatorIS8_EEEE:
  167|     18|      : icmp_(icmp), flist_(flist), index_(flist->size()) {  // Marks as invalid
  168|     18|  }
_ZNK7leveldb7Version20LevelFileNumIterator5ValidEv:
  169|     34|  bool Valid() const override { return index_ < flist_->size(); }
_ZN7leveldb7Version20LevelFileNumIterator11SeekToFirstEv:
  173|      8|  void SeekToFirst() override { index_ = 0; }
_ZN7leveldb7Version20LevelFileNumIterator4NextEv:
  177|      8|  void Next() override {
  178|       |    assert(Valid());
  179|      8|    index_++;
  180|      8|  }
_ZNK7leveldb7Version20LevelFileNumIterator3keyEv:
  189|      8|  Slice key() const override {
  190|       |    assert(Valid());
  191|      8|    return (*flist_)[index_]->largest.Encode();
  192|      8|  }
_ZNK7leveldb7Version20LevelFileNumIterator5valueEv:
  193|      8|  Slice value() const override {
  194|       |    assert(Valid());
  195|      8|    EncodeFixed64(value_buf_, (*flist_)[index_]->number);
  196|      8|    EncodeFixed64(value_buf_ + 8, (*flist_)[index_]->file_size);
  197|      8|    return Slice(value_buf_, sizeof(value_buf_));
  198|      8|  }
_ZNK7leveldb7Version20LevelFileNumIterator6statusEv:
  199|      4|  Status status() const override { return Status::OK(); }
version_set.cc:_ZN7leveldbL15GetFileIteratorEPvRKNS_11ReadOptionsERKNS_5SliceE:
  211|      8|                                 const Slice& file_value) {
  212|      8|  TableCache* cache = reinterpret_cast<TableCache*>(arg);
  213|      8|  if (file_value.size() != 16) {
  ------------------
  |  Branch (213:7): [True: 0, False: 8]
  ------------------
  214|      0|    return NewErrorIterator(
  215|      0|        Status::Corruption("FileReader invoked with unexpected value"));
  216|      8|  } else {
  217|      8|    return cache->NewIterator(options, DecodeFixed64(file_value.data()),
  218|      8|                              DecodeFixed64(file_value.data() + 8));
  219|      8|  }
  220|      8|}
version_set.cc:_ZN7leveldbL11NewestFirstEPNS_12FileMetaDataES1_:
  277|      6|static bool NewestFirst(FileMetaData* a, FileMetaData* b) {
  278|      6|  return a->number > b->number;
  279|      6|}
version_set.cc:_ZZN7leveldb7Version3GetERKNS_11ReadOptionsERKNS_9LookupKeyEPNSt3__112basic_stringIcNS7_11char_traitsIcEENS7_9allocatorIcEEEEPNS0_8GetStatsEEN5State5MatchEPviPNS_12FileMetaDataE:
  341|     10|    static bool Match(void* arg, int level, FileMetaData* f) {
  342|     10|      State* state = reinterpret_cast<State*>(arg);
  343|       |
  344|     10|      if (state->stats->seek_file == nullptr &&
  ------------------
  |  Branch (344:11): [True: 6, False: 4]
  ------------------
  345|      6|          state->last_file_read != nullptr) {
  ------------------
  |  Branch (345:11): [True: 2, False: 4]
  ------------------
  346|       |        // We have had more than one seek for this read.  Charge the 1st file.
  347|      2|        state->stats->seek_file = state->last_file_read;
  348|      2|        state->stats->seek_file_level = state->last_file_read_level;
  349|      2|      }
  350|       |
  351|     10|      state->last_file_read = f;
  352|     10|      state->last_file_read_level = level;
  353|       |
  354|     10|      state->s = state->vset->table_cache_->Get(*state->options, f->number,
  355|     10|                                                f->file_size, state->ikey,
  356|     10|                                                &state->saver, SaveValue);
  357|     10|      if (!state->s.ok()) {
  ------------------
  |  Branch (357:11): [True: 0, False: 10]
  ------------------
  358|      0|        state->found = true;
  359|      0|        return false;
  360|      0|      }
  361|     10|      switch (state->saver.state) {
  ------------------
  |  Branch (361:15): [True: 10, False: 0]
  ------------------
  362|     10|        case kNotFound:
  ------------------
  |  Branch (362:9): [True: 10, False: 0]
  ------------------
  363|     10|          return true;  // Keep searching in other files
  364|      0|        case kFound:
  ------------------
  |  Branch (364:9): [True: 0, False: 10]
  ------------------
  365|      0|          state->found = true;
  366|      0|          return false;
  367|      0|        case kDeleted:
  ------------------
  |  Branch (367:9): [True: 0, False: 10]
  ------------------
  368|      0|          return false;
  369|      0|        case kCorrupt:
  ------------------
  |  Branch (369:9): [True: 0, False: 10]
  ------------------
  370|      0|          state->s =
  371|      0|              Status::Corruption("corrupted key for ", state->saver.user_key);
  372|      0|          state->found = true;
  373|      0|          return false;
  374|     10|      }
  375|       |
  376|       |      // Not reached. Added to avoid false compilation warnings of
  377|       |      // "control reaches end of non-void function".
  378|      0|      return false;
  379|     10|    }
version_set.cc:_ZN7leveldbL9SaveValueEPvRKNS_5SliceES3_:
  262|     10|static void SaveValue(void* arg, const Slice& ikey, const Slice& v) {
  263|     10|  Saver* s = reinterpret_cast<Saver*>(arg);
  264|     10|  ParsedInternalKey parsed_key;
  265|     10|  if (!ParseInternalKey(ikey, &parsed_key)) {
  ------------------
  |  Branch (265:7): [True: 0, False: 10]
  ------------------
  266|      0|    s->state = kCorrupt;
  267|     10|  } else {
  268|     10|    if (s->ucmp->Compare(parsed_key.user_key, s->user_key) == 0) {
  ------------------
  |  Branch (268:9): [True: 0, False: 10]
  ------------------
  269|      0|      s->state = (parsed_key.type == kTypeValue) ? kFound : kDeleted;
  ------------------
  |  Branch (269:18): [True: 0, False: 0]
  ------------------
  270|      0|      if (s->state == kFound) {
  ------------------
  |  Branch (270:11): [True: 0, False: 0]
  ------------------
  271|      0|        s->value->assign(v.data(), v.size());
  272|      0|      }
  273|      0|    }
  274|     10|  }
  275|     10|}
version_set.cc:_ZZN7leveldb7Version16RecordReadSampleENS_5SliceEEN5State5MatchEPviPNS_12FileMetaDataE:
  425|     10|    static bool Match(void* arg, int level, FileMetaData* f) {
  426|     10|      State* state = reinterpret_cast<State*>(arg);
  427|     10|      state->matches++;
  428|     10|      if (state->matches == 1) {
  ------------------
  |  Branch (428:11): [True: 8, False: 2]
  ------------------
  429|       |        // Remember first match.
  430|      8|        state->stats.seek_file = f;
  431|      8|        state->stats.seek_file_level = level;
  432|      8|      }
  433|       |      // We can stop iterating once we have a second match.
  434|     10|      return state->matches < 2;
  435|     10|    }
version_set.cc:_ZN7leveldbL13TotalFileSizeERKNSt3__16vectorIPNS_12FileMetaDataENS0_9allocatorIS3_EEEE:
   59|  1.13k|static int64_t TotalFileSize(const std::vector<FileMetaData*>& files) {
   60|  1.13k|  int64_t sum = 0;
   61|  1.22k|  for (size_t i = 0; i < files.size(); i++) {
  ------------------
  |  Branch (61:22): [True: 89, False: 1.13k]
  ------------------
   62|     89|    sum += files[i]->file_size;
   63|     89|  }
   64|  1.13k|  return sum;
   65|  1.13k|}
version_set.cc:_ZN7leveldbL26MaxGrandParentOverlapBytesEPKNS_7OptionsE:
   30|    325|static int64_t MaxGrandParentOverlapBytes(const Options* options) {
   31|    325|  return 10 * TargetFileSize(options);
   32|    325|}
_ZN7leveldb10VersionSet7BuilderC2EPS0_PNS_7VersionE:
  598|    225|  Builder(VersionSet* vset, Version* base) : vset_(vset), base_(base) {
  599|    225|    base_->Ref();
  600|    225|    BySmallestKey cmp;
  601|    225|    cmp.internal_comparator = &vset_->icmp_;
  602|  1.80k|    for (int level = 0; level < config::kNumLevels; level++) {
  ------------------
  |  Branch (602:25): [True: 1.57k, False: 225]
  ------------------
  603|  1.57k|      levels_[level].added_files = new FileSet(cmp);
  604|  1.57k|    }
  605|    225|  }
_ZN7leveldb10VersionSet7Builder5ApplyEPKNS_11VersionEditE:
  629|    295|  void Apply(const VersionEdit* edit) {
  630|       |    // Update compaction pointers
  631|    320|    for (size_t i = 0; i < edit->compact_pointers_.size(); i++) {
  ------------------
  |  Branch (631:24): [True: 25, False: 295]
  ------------------
  632|     25|      const int level = edit->compact_pointers_[i].first;
  633|     25|      vset_->compact_pointer_[level] =
  634|     25|          edit->compact_pointers_[i].second.Encode().ToString();
  635|     25|    }
  636|       |
  637|       |    // Delete files
  638|    295|    for (const auto& deleted_file_set_kvp : edit->deleted_files_) {
  ------------------
  |  Branch (638:43): [True: 42, False: 295]
  ------------------
  639|     42|      const int level = deleted_file_set_kvp.first;
  640|     42|      const uint64_t number = deleted_file_set_kvp.second;
  641|     42|      levels_[level].deleted_files.insert(number);
  642|     42|    }
  643|       |
  644|       |    // Add new files
  645|    434|    for (size_t i = 0; i < edit->new_files_.size(); i++) {
  ------------------
  |  Branch (645:24): [True: 139, False: 295]
  ------------------
  646|    139|      const int level = edit->new_files_[i].first;
  647|    139|      FileMetaData* f = new FileMetaData(edit->new_files_[i].second);
  648|    139|      f->refs = 1;
  649|       |
  650|       |      // We arrange to automatically compact this file after
  651|       |      // a certain number of seeks.  Let's assume:
  652|       |      //   (1) One seek costs 10ms
  653|       |      //   (2) Writing or reading 1MB costs 10ms (100MB/s)
  654|       |      //   (3) A compaction of 1MB does 25MB of IO:
  655|       |      //         1MB read from this level
  656|       |      //         10-12MB read from next level (boundaries may be misaligned)
  657|       |      //         10-12MB written to next level
  658|       |      // This implies that 25 seeks cost the same as the compaction
  659|       |      // of 1MB of data.  I.e., one seek costs approximately the
  660|       |      // same as the compaction of 40KB of data.  We are a little
  661|       |      // conservative and allow approximately one seek for every 16KB
  662|       |      // of data before triggering a compaction.
  663|    139|      f->allowed_seeks = static_cast<int>((f->file_size / 16384U));
  664|    139|      if (f->allowed_seeks < 100) f->allowed_seeks = 100;
  ------------------
  |  Branch (664:11): [True: 139, False: 0]
  ------------------
  665|       |
  666|    139|      levels_[level].deleted_files.erase(f->number);
  667|    139|      levels_[level].added_files->insert(f);
  668|    139|    }
  669|    295|  }
_ZNK7leveldb10VersionSet7Builder13BySmallestKeyclEPNS_12FileMetaDataES4_:
  575|    133|    bool operator()(FileMetaData* f1, FileMetaData* f2) const {
  576|    133|      int r = internal_comparator->Compare(f1->smallest, f2->smallest);
  577|    133|      if (r != 0) {
  ------------------
  |  Branch (577:11): [True: 133, False: 0]
  ------------------
  578|    133|        return (r < 0);
  579|    133|      } else {
  580|       |        // Break ties by file number
  581|      0|        return (f1->number < f2->number);
  582|      0|      }
  583|    133|    }
_ZN7leveldb10VersionSet7Builder6SaveToEPNS_7VersionE:
  672|    225|  void SaveTo(Version* v) {
  673|    225|    BySmallestKey cmp;
  674|    225|    cmp.internal_comparator = &vset_->icmp_;
  675|  1.80k|    for (int level = 0; level < config::kNumLevels; level++) {
  ------------------
  |  Branch (675:25): [True: 1.57k, False: 225]
  ------------------
  676|       |      // Merge the set of added files with the set of pre-existing files.
  677|       |      // Drop any deleted files.  Store the result in *v.
  678|  1.57k|      const std::vector<FileMetaData*>& base_files = base_->files_[level];
  679|  1.57k|      std::vector<FileMetaData*>::const_iterator base_iter = base_files.begin();
  680|  1.57k|      std::vector<FileMetaData*>::const_iterator base_end = base_files.end();
  681|  1.57k|      const FileSet* added_files = levels_[level].added_files;
  682|  1.57k|      v->files_[level].reserve(base_files.size() + added_files->size());
  683|  1.57k|      for (const auto& added_file : *added_files) {
  ------------------
  |  Branch (683:35): [True: 139, False: 1.57k]
  ------------------
  684|       |        // Add all smaller files listed in base_
  685|    139|        for (std::vector<FileMetaData*>::const_iterator bpos =
  686|    139|                 std::upper_bound(base_iter, base_end, added_file, cmp);
  687|    163|             base_iter != bpos; ++base_iter) {
  ------------------
  |  Branch (687:14): [True: 24, False: 139]
  ------------------
  688|     24|          MaybeAddFile(v, level, *base_iter);
  689|     24|        }
  690|       |
  691|    139|        MaybeAddFile(v, level, added_file);
  692|    139|      }
  693|       |
  694|       |      // Add remaining base files
  695|  1.68k|      for (; base_iter != base_end; ++base_iter) {
  ------------------
  |  Branch (695:14): [True: 112, False: 1.57k]
  ------------------
  696|    112|        MaybeAddFile(v, level, *base_iter);
  697|    112|      }
  698|       |
  699|       |#ifndef NDEBUG
  700|       |      // Make sure there is no overlap in levels > 0
  701|       |      if (level > 0) {
  702|       |        for (uint32_t i = 1; i < v->files_[level].size(); i++) {
  703|       |          const InternalKey& prev_end = v->files_[level][i - 1]->largest;
  704|       |          const InternalKey& this_begin = v->files_[level][i]->smallest;
  705|       |          if (vset_->icmp_.Compare(prev_end, this_begin) >= 0) {
  706|       |            std::fprintf(stderr, "overlapping ranges in same level %s vs. %s\n",
  707|       |                         prev_end.DebugString().c_str(),
  708|       |                         this_begin.DebugString().c_str());
  709|       |            std::abort();
  710|       |          }
  711|       |        }
  712|       |      }
  713|       |#endif
  714|  1.57k|    }
  715|    225|  }
_ZN7leveldb10VersionSet7Builder12MaybeAddFileEPNS_7VersionEiPNS_12FileMetaDataE:
  717|    275|  void MaybeAddFile(Version* v, int level, FileMetaData* f) {
  718|    275|    if (levels_[level].deleted_files.count(f->number) > 0) {
  ------------------
  |  Branch (718:9): [True: 42, False: 233]
  ------------------
  719|       |      // File is deleted: do nothing
  720|    233|    } else {
  721|    233|      std::vector<FileMetaData*>* files = &v->files_[level];
  722|    233|      if (level > 0 && !files->empty()) {
  ------------------
  |  Branch (722:11): [True: 71, False: 162]
  |  Branch (722:24): [True: 3, False: 68]
  ------------------
  723|       |        // Must not overlap
  724|       |        assert(vset_->icmp_.Compare((*files)[files->size() - 1]->largest,
  725|      3|                                    f->smallest) < 0);
  726|      3|      }
  727|    233|      f->refs++;
  728|    233|      files->push_back(f);
  729|    233|    }
  730|    275|  }
_ZN7leveldb10VersionSet7BuilderD2Ev:
  607|    225|  ~Builder() {
  608|  1.80k|    for (int level = 0; level < config::kNumLevels; level++) {
  ------------------
  |  Branch (608:25): [True: 1.57k, False: 225]
  ------------------
  609|  1.57k|      const FileSet* added = levels_[level].added_files;
  610|  1.57k|      std::vector<FileMetaData*> to_unref;
  611|  1.57k|      to_unref.reserve(added->size());
  612|  1.71k|      for (FileSet::const_iterator it = added->begin(); it != added->end();
  ------------------
  |  Branch (612:57): [True: 139, False: 1.57k]
  ------------------
  613|  1.57k|           ++it) {
  614|    139|        to_unref.push_back(*it);
  615|    139|      }
  616|  1.57k|      delete added;
  617|  1.71k|      for (uint32_t i = 0; i < to_unref.size(); i++) {
  ------------------
  |  Branch (617:28): [True: 139, False: 1.57k]
  ------------------
  618|    139|        FileMetaData* f = to_unref[i];
  619|    139|        f->refs--;
  620|    139|        if (f->refs <= 0) {
  ------------------
  |  Branch (620:13): [True: 21, False: 118]
  ------------------
  621|     21|          delete f;
  622|     21|        }
  623|    139|      }
  624|  1.57k|    }
  625|    225|    base_->Unref();
  626|    225|  }
version_set.cc:_ZN7leveldbL14TargetFileSizeEPKNS_7OptionsE:
   24|    332|static size_t TargetFileSize(const Options* options) {
   25|    332|  return options->max_file_size;
   26|    332|}
version_set.cc:_ZN7leveldbL16MaxBytesForLevelEPKNS_7OptionsEi:
   41|  1.12k|static double MaxBytesForLevel(const Options* options, int level) {
   42|       |  // Note: the result for level zero is not really used since we set
   43|       |  // the level-0 compaction threshold based on number of files.
   44|       |
   45|       |  // Result for both level-0 and level-1
   46|  1.12k|  double result = 10. * 1048576.0;
   47|  3.37k|  while (level > 1) {
  ------------------
  |  Branch (47:10): [True: 2.25k, False: 1.12k]
  ------------------
   48|  2.25k|    result *= 10;
   49|  2.25k|    level--;
   50|  2.25k|  }
   51|  1.12k|  return result;
   52|  1.12k|}
version_set.cc:_ZN7leveldbL19MaxFileSizeForLevelEPKNS_7OptionsEi:
   54|      7|static uint64_t MaxFileSizeForLevel(const Options* options, int level) {
   55|       |  // We could vary per level to reduce number of files?
   56|      7|  return TargetFileSize(options);
   57|      7|}

_ZNK7leveldb10VersionSet9LogNumberEv:
  224|    296|  uint64_t LogNumber() const { return log_number_; }
_ZNK7leveldb10VersionSet13PrevLogNumberEv:
  228|    172|  uint64_t PrevLogNumber() const { return prev_log_number_; }
_ZNK7leveldb10VersionSet18ManifestFileNumberEv:
  191|    224|  uint64_t ManifestFileNumber() const { return manifest_file_number_; }
_ZNK7leveldb10VersionSet12LastSequenceEv:
  212|    638|  uint64_t LastSequence() const { return last_sequence_; }
_ZN7leveldb10VersionSet15SetLastSequenceEm:
  215|    464|  void SetLastSequence(uint64_t s) {
  216|       |    assert(s >= last_sequence_);
  217|    464|    last_sequence_ = s;
  218|    464|  }
_ZN7leveldb10VersionSet13NewFileNumberEv:
  194|    172|  uint64_t NewFileNumber() { return next_file_number_++; }
_ZNK7leveldb10VersionSet7currentEv:
  188|    168|  Version* current() const { return current_; }
_ZNK7leveldb10VersionSet15NeedsCompactionEv:
  252|    140|  bool NeedsCompaction() const {
  253|    140|    Version* v = current_;
  254|    140|    return (v->compaction_score_ >= 1) || (v->file_to_compact_ != nullptr);
  ------------------
  |  Branch (254:12): [True: 7, False: 133]
  |  Branch (254:43): [True: 0, False: 133]
  ------------------
  255|    140|  }
_ZNK7leveldb10Compaction5inputEii:
  335|     24|  FileMetaData* input(int which, int i) const { return inputs_[which][i]; }
_ZNK7leveldb10Compaction15num_input_filesEi:
  332|     64|  int num_input_files(int which) const { return inputs_[which].size(); }
_ZN7leveldb10Compaction4editEv:
  329|     21|  VersionEdit* edit() { return &edit_; }
_ZNK7leveldb10Compaction5levelEv:
  325|     66|  int level() const { return level_; }
_ZNK7leveldb10Compaction17MaxOutputFileSizeEv:
  338|    314|  uint64_t MaxOutputFileSize() const { return max_output_file_size_; }
_ZN7leveldb7VersionC2EPNS_10VersionSetE:
  124|    425|      : vset_(vset),
  125|    425|        next_(this),
  126|    425|        prev_(this),
  127|    425|        refs_(0),
  128|    425|        file_to_compact_(nullptr),
  129|    425|        file_to_compact_level_(-1),
  130|    425|        compaction_score_(-1),
  131|    425|        compaction_level_(-1) {}

_ZN7leveldb10WriteBatchC2Ev:
   29|    588|WriteBatch::WriteBatch() { Clear(); }
_ZN7leveldb10WriteBatchD2Ev:
   31|    588|WriteBatch::~WriteBatch() = default;
_ZN7leveldb10WriteBatch7HandlerD2Ev:
   33|    539|WriteBatch::Handler::~Handler() = default;
_ZN7leveldb10WriteBatch5ClearEv:
   35|    588|void WriteBatch::Clear() {
   36|    588|  rep_.clear();
   37|    588|  rep_.resize(kHeader);
   38|    588|}
_ZNK7leveldb10WriteBatch7IterateEPNS0_7HandlerE:
   42|    539|Status WriteBatch::Iterate(Handler* handler) const {
   43|    539|  Slice input(rep_);
   44|    539|  if (input.size() < kHeader) {
  ------------------
  |  Branch (44:7): [True: 0, False: 539]
  ------------------
   45|      0|    return Status::Corruption("malformed WriteBatch (too small)");
   46|      0|  }
   47|       |
   48|    539|  input.remove_prefix(kHeader);
   49|    539|  Slice key, value;
   50|    539|  int found = 0;
   51|  1.07k|  while (!input.empty()) {
  ------------------
  |  Branch (51:10): [True: 539, False: 539]
  ------------------
   52|    539|    found++;
   53|    539|    char tag = input[0];
   54|    539|    input.remove_prefix(1);
   55|    539|    switch (tag) {
   56|    518|      case kTypeValue:
  ------------------
  |  Branch (56:7): [True: 518, False: 21]
  ------------------
   57|    518|        if (GetLengthPrefixedSlice(&input, &key) &&
  ------------------
  |  Branch (57:13): [True: 518, False: 0]
  ------------------
   58|    518|            GetLengthPrefixedSlice(&input, &value)) {
  ------------------
  |  Branch (58:13): [True: 518, False: 0]
  ------------------
   59|    518|          handler->Put(key, value);
   60|    518|        } else {
   61|      0|          return Status::Corruption("bad WriteBatch Put");
   62|      0|        }
   63|    518|        break;
   64|    518|      case kTypeDeletion:
  ------------------
  |  Branch (64:7): [True: 21, False: 518]
  ------------------
   65|     21|        if (GetLengthPrefixedSlice(&input, &key)) {
  ------------------
  |  Branch (65:13): [True: 21, False: 0]
  ------------------
   66|     21|          handler->Delete(key);
   67|     21|        } else {
   68|      0|          return Status::Corruption("bad WriteBatch Delete");
   69|      0|        }
   70|     21|        break;
   71|     21|      default:
  ------------------
  |  Branch (71:7): [True: 0, False: 539]
  ------------------
   72|      0|        return Status::Corruption("unknown WriteBatch tag");
   73|    539|    }
   74|    539|  }
   75|    539|  if (found != WriteBatchInternal::Count(this)) {
  ------------------
  |  Branch (75:7): [True: 0, False: 539]
  ------------------
   76|      0|    return Status::Corruption("WriteBatch has wrong count");
   77|    539|  } else {
   78|    539|    return Status::OK();
   79|    539|  }
   80|    539|}
_ZN7leveldb18WriteBatchInternal5CountEPKNS_10WriteBatchE:
   82|  1.51k|int WriteBatchInternal::Count(const WriteBatch* b) {
   83|  1.51k|  return DecodeFixed32(b->rep_.data() + 8);
   84|  1.51k|}
_ZN7leveldb18WriteBatchInternal8SetCountEPNS_10WriteBatchEi:
   86|    434|void WriteBatchInternal::SetCount(WriteBatch* b, int n) {
   87|    434|  EncodeFixed32(&b->rep_[8], n);
   88|    434|}
_ZN7leveldb18WriteBatchInternal8SequenceEPKNS_10WriteBatchE:
   90|    644|SequenceNumber WriteBatchInternal::Sequence(const WriteBatch* b) {
   91|    644|  return SequenceNumber(DecodeFixed64(b->rep_.data()));
   92|    644|}
_ZN7leveldb18WriteBatchInternal11SetSequenceEPNS_10WriteBatchEm:
   94|    434|void WriteBatchInternal::SetSequence(WriteBatch* b, SequenceNumber seq) {
   95|    434|  EncodeFixed64(&b->rep_[0], seq);
   96|    434|}
_ZN7leveldb10WriteBatch3PutERKNS_5SliceES3_:
   98|    418|void WriteBatch::Put(const Slice& key, const Slice& value) {
   99|    418|  WriteBatchInternal::SetCount(this, WriteBatchInternal::Count(this) + 1);
  100|    418|  rep_.push_back(static_cast<char>(kTypeValue));
  101|    418|  PutLengthPrefixedSlice(&rep_, key);
  102|    418|  PutLengthPrefixedSlice(&rep_, value);
  103|    418|}
_ZN7leveldb10WriteBatch6DeleteERKNS_5SliceE:
  105|     16|void WriteBatch::Delete(const Slice& key) {
  106|     16|  WriteBatchInternal::SetCount(this, WriteBatchInternal::Count(this) + 1);
  107|     16|  rep_.push_back(static_cast<char>(kTypeDeletion));
  108|     16|  PutLengthPrefixedSlice(&rep_, key);
  109|     16|}
_ZN7leveldb18WriteBatchInternal10InsertIntoEPKNS_10WriteBatchEPNS_8MemTableE:
  132|    539|Status WriteBatchInternal::InsertInto(const WriteBatch* b, MemTable* memtable) {
  133|    539|  MemTableInserter inserter;
  134|    539|  inserter.sequence_ = WriteBatchInternal::Sequence(b);
  135|    539|  inserter.mem_ = memtable;
  136|    539|  return b->Iterate(&inserter);
  137|    539|}
_ZN7leveldb18WriteBatchInternal11SetContentsEPNS_10WriteBatchERKNS_5SliceE:
  139|    105|void WriteBatchInternal::SetContents(WriteBatch* b, const Slice& contents) {
  140|       |  assert(contents.size() >= kHeader);
  141|    105|  b->rep_.assign(contents.data(), contents.size());
  142|    105|}
write_batch.cc:_ZN7leveldb12_GLOBAL__N_116MemTableInserter3PutERKNS_5SliceES4_:
  121|    518|  void Put(const Slice& key, const Slice& value) override {
  122|    518|    mem_->Add(sequence_, kTypeValue, key, value);
  123|    518|    sequence_++;
  124|    518|  }
write_batch.cc:_ZN7leveldb12_GLOBAL__N_116MemTableInserter6DeleteERKNS_5SliceE:
  125|     21|  void Delete(const Slice& key) override {
  126|     21|    mem_->Add(sequence_, kTypeDeletion, key, Slice());
  127|     21|    sequence_++;
  128|     21|  }

_ZN7leveldb18WriteBatchInternal8ContentsEPKNS_10WriteBatchE:
   32|    434|  static Slice Contents(const WriteBatch* batch) { return Slice(batch->rep_); }
_ZN7leveldb18WriteBatchInternal8ByteSizeEPKNS_10WriteBatchE:
   34|    434|  static size_t ByteSize(const WriteBatch* batch) { return batch->rep_.size(); }

LLVMFuzzerTestOneInput:
   81|     48|extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
   82|       |  // Must occur before `db` so the deletion doesn't happen while the DB is open.
   83|     48|  AutoDbDeleter db_deleter;
   84|       |
   85|     48|  std::unique_ptr<leveldb::DB> db = OpenDB();
   86|     48|  if (!db.get())
  ------------------
  |  Branch (86:7): [True: 0, False: 48]
  ------------------
   87|      0|    return 0;
   88|       |
   89|       |  // Perform a sequence of operations on the database.
   90|     48|  FuzzedDataProvider fuzzed_data(data, size);
   91|    588|  while (fuzzed_data.remaining_bytes() != 0) {
  ------------------
  |  Branch (91:10): [True: 540, False: 48]
  ------------------
   92|    540|    FuzzOp fuzz_op = fuzzed_data.ConsumeEnum<FuzzOp>();
   93|       |
   94|    540|    switch (fuzz_op) {
  ------------------
  |  Branch (94:13): [True: 540, False: 0]
  ------------------
   95|    418|    case FuzzOp::kPut: {
  ------------------
  |  Branch (95:5): [True: 418, False: 122]
  ------------------
   96|    418|      std::string key = fuzzed_data.ConsumeRandomLengthString();
   97|    418|      std::string value = fuzzed_data.ConsumeRandomLengthString();
   98|    418|      db->Put(leveldb::WriteOptions(), key, value);
   99|    418|      break;
  100|      0|    }
  101|     22|    case FuzzOp::kGet: {
  ------------------
  |  Branch (101:5): [True: 22, False: 518]
  ------------------
  102|     22|      std::string key = fuzzed_data.ConsumeRandomLengthString();
  103|     22|      std::string value;
  104|     22|      db->Get(leveldb::ReadOptions(), key, &value);
  105|     22|      break;
  106|      0|    }
  107|     16|    case FuzzOp::kDelete: {
  ------------------
  |  Branch (107:5): [True: 16, False: 524]
  ------------------
  108|     16|      std::string key = fuzzed_data.ConsumeRandomLengthString();
  109|     16|      db->Delete(leveldb::WriteOptions(), key);
  110|     16|      break;
  111|      0|    }
  112|     14|    case FuzzOp::kGetProperty: {
  ------------------
  |  Branch (112:5): [True: 14, False: 526]
  ------------------
  113|     14|      std::string name = fuzzed_data.ConsumeRandomLengthString();
  114|     14|      std::string value;
  115|     14|      db->GetProperty(name, &value);
  116|     14|      break;
  117|      0|    }
  118|     10|    case FuzzOp::kIterate: {
  ------------------
  |  Branch (118:5): [True: 10, False: 530]
  ------------------
  119|     10|      std::unique_ptr<leveldb::Iterator> it(
  120|     10|          db->NewIterator(leveldb::ReadOptions()));
  121|    184|      for (it->SeekToFirst(); it->Valid(); it->Next())
  ------------------
  |  Branch (121:31): [True: 174, False: 10]
  ------------------
  122|    174|        continue;
  123|     10|    }
  124|     24|    case FuzzOp::kGetReleaseSnapshot: {
  ------------------
  |  Branch (124:5): [True: 14, False: 526]
  ------------------
  125|     24|      leveldb::ReadOptions snapshot_options;
  126|     24|      snapshot_options.snapshot = db->GetSnapshot();
  127|     24|      std::unique_ptr<leveldb::Iterator> it(db->NewIterator(snapshot_options));
  128|     24|      db->ReleaseSnapshot(snapshot_options.snapshot);
  129|     24|    }
  130|     52|    case FuzzOp::kReopenDb: {
  ------------------
  |  Branch (130:5): [True: 28, False: 512]
  ------------------
  131|       |      // The database must be closed before attempting to reopen it. Otherwise,
  132|       |      // the open will fail due to exclusive locking.
  133|     52|      db.reset();
  134|     52|      db = OpenDB();
  135|     52|      if (!db)
  ------------------
  |  Branch (135:11): [True: 0, False: 52]
  ------------------
  136|      0|        return 0;  // Reopening the database failed.
  137|     52|      break;
  138|     52|    }
  139|     52|    case FuzzOp::kCompactRange: {
  ------------------
  |  Branch (139:5): [True: 18, False: 522]
  ------------------
  140|     18|      std::string begin_key = fuzzed_data.ConsumeRandomLengthString();
  141|     18|      std::string end_key =  fuzzed_data.ConsumeRandomLengthString();
  142|     18|      leveldb::Slice begin_slice(begin_key);
  143|     18|      leveldb::Slice end_slice(end_key);
  144|     18|      db->CompactRange(&begin_slice, &end_slice);
  145|     18|      break;
  146|     52|    }
  147|    540|    }
  148|    540|  }
  149|       |
  150|     48|  return 0;
  151|     48|}
fuzz_db.cc:_ZN12_GLOBAL__N_16OpenDBEv:
   51|    100|std::unique_ptr<leveldb::DB> OpenDB() {
   52|    100|  leveldb::Options options;
   53|    100|  options.create_if_missing = true;
   54|       |
   55|    100|  leveldb::DB* db_ptr;
   56|    100|  leveldb::Status status =
   57|    100|      leveldb::DB::Open(options, AutoDbDeleter::kDbPath, &db_ptr);
   58|    100|  if (!status.ok())
  ------------------
  |  Branch (58:7): [True: 0, False: 100]
  ------------------
   59|      0|    return nullptr;
   60|       |
   61|    100|  return std::unique_ptr<leveldb::DB>(db_ptr);
   62|    100|}
fuzz_db.cc:_ZN12_GLOBAL__N_113AutoDbDeleterD2Ev:
   42|     48|  ~AutoDbDeleter() {
   43|     48|    std::filesystem::remove_all(kDbPath);
   44|     48|  }

_ZN7leveldb5CacheC2Ev:
   36|    200|  Cache() = default;

_ZN7leveldb2DBC2Ev:
   56|    100|  DB() = default;

_ZN7leveldb14SequentialFileC2Ev:
  224|    254|  SequentialFile() = default;
_ZN7leveldb16RandomAccessFileC2Ev:
  254|     72|  RandomAccessFile() = default;
_ZN7leveldb12WritableFileC2Ev:
  279|    454|  WritableFile() = default;
_ZN7leveldb8FileLockC2Ev:
  309|    100|  FileLock() = default;
_ZN7leveldb6LoggerC2Ev:
  295|    100|  Logger() = default;

_ZNK7leveldb8Iterator11CleanupNode7IsEmptyEv:
   88|  1.13k|    bool IsEmpty() const { return function == nullptr; }
_ZN7leveldb8Iterator11CleanupNode3RunEv:
   90|    438|    void Run() {
   91|       |      assert(function != nullptr);
   92|    438|      (*function)(arg1, arg2);
   93|    438|    }

_ZN7leveldb12WriteOptionsC2Ev:
  169|    452|  WriteOptions() = default;

_ZN7leveldb5SliceC2ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
   36|  10.6k|  Slice(const std::string& s) : data_(s.data()), size_(s.size()) {}
_ZN7leveldb5SliceC2Ev:
   30|  5.25k|  Slice() : data_(""), size_(0) {}
_ZN7leveldb5SliceC2EPKcm:
   33|  31.5k|  Slice(const char* d, size_t n) : data_(d), size_(n) {}
_ZN7leveldb5SliceC2EPKc:
   39|  10.0k|  Slice(const char* s) : data_(s), size_(strlen(s)) {}
_ZNK7leveldb5Slice4dataEv:
   46|  42.0k|  const char* data() const { return data_; }
_ZNK7leveldb5Slice4sizeEv:
   49|  4.43M|  size_t size() const { return size_; }
_ZNK7leveldb5Slice5emptyEv:
   52|  1.80k|  bool empty() const { return size_ == 0; }
_ZNK7leveldb5SliceixEm:
   59|  4.37M|  char operator[](size_t n) const {
   60|       |    assert(n < size());
   61|  4.37M|    return data_[n];
   62|  4.37M|  }
_ZN7leveldb5Slice5clearEv:
   65|  1.54k|  void clear() {
   66|  1.54k|    data_ = "";
   67|  1.54k|    size_ = 0;
   68|  1.54k|  }
_ZN7leveldb5Slice13remove_prefixEm:
   71|  5.26k|  void remove_prefix(size_t n) {
   72|       |    assert(n <= size());
   73|  5.26k|    data_ += n;
   74|  5.26k|    size_ -= n;
   75|  5.26k|  }
_ZNK7leveldb5Slice8ToStringEv:
   78|    471|  std::string ToString() const { return std::string(data_, size_); }
_ZNK7leveldb5Slice11starts_withERKS0_:
   87|  1.73k|  bool starts_with(const Slice& x) const {
   88|  1.73k|    return ((size_ >= x.size_) && (memcmp(data_, x.data_, x.size_) == 0));
  ------------------
  |  Branch (88:13): [True: 1.28k, False: 451]
  |  Branch (88:35): [True: 472, False: 815]
  ------------------
   89|  1.73k|  }
_ZN7leveldbeqERKNS_5SliceES2_:
   96|  7.97k|inline bool operator==(const Slice& x, const Slice& y) {
   97|  7.97k|  return ((x.size() == y.size()) &&
  ------------------
  |  Branch (97:11): [True: 1.97k, False: 6.00k]
  ------------------
   98|  1.97k|          (memcmp(x.data(), y.data(), x.size()) == 0));
  ------------------
  |  Branch (98:11): [True: 1.35k, False: 619]
  ------------------
   99|  7.97k|}
_ZN7leveldbneERKNS_5SliceES2_:
  101|     58|inline bool operator!=(const Slice& x, const Slice& y) { return !(x == y); }
_ZNK7leveldb5Slice7compareERKS0_:
  103|  5.28k|inline int Slice::compare(const Slice& b) const {
  104|  5.28k|  const size_t min_len = (size_ < b.size_) ? size_ : b.size_;
  ------------------
  |  Branch (104:26): [True: 2.17k, False: 3.10k]
  ------------------
  105|  5.28k|  int r = memcmp(data_, b.data_, min_len);
  106|  5.28k|  if (r == 0) {
  ------------------
  |  Branch (106:7): [True: 111, False: 5.16k]
  ------------------
  107|    111|    if (size_ < b.size_)
  ------------------
  |  Branch (107:9): [True: 10, False: 101]
  ------------------
  108|     10|      r = -1;
  109|    101|    else if (size_ > b.size_)
  ------------------
  |  Branch (109:14): [True: 8, False: 93]
  ------------------
  110|      8|      r = +1;
  111|    111|  }
  112|  5.28k|  return r;
  113|  5.28k|}

_ZNK7leveldb6Status2okEv:
   57|  22.0k|  bool ok() const { return (state_ == nullptr); }
_ZN7leveldb6StatusD2Ev:
   28|  21.4k|  ~Status() { delete[] state_; }
_ZN7leveldb6StatusC2Ev:
   27|  19.1k|  Status() noexcept : state_(nullptr) {}
_ZN7leveldb6StatusC2EOS0_:
   33|    100|  Status(Status&& rhs) noexcept : state_(rhs.state_) { rhs.state_ = nullptr; }
_ZN7leveldb6Status2OKEv:
   37|  14.6k|  static Status OK() { return Status(); }
_ZN7leveldb6Status8NotFoundERKNS_5SliceES3_:
   40|     81|  static Status NotFound(const Slice& msg, const Slice& msg2 = Slice()) {
   41|     81|    return Status(kNotFound, msg, msg2);
   42|     81|  }
_ZN7leveldb6Status7IOErrorERKNS_5SliceES3_:
   52|    153|  static Status IOError(const Slice& msg, const Slice& msg2 = Slice()) {
   53|    153|    return Status(kIOError, msg, msg2);
   54|    153|  }
_ZN7leveldb6StatusaSEOS0_:
  115|  14.3k|inline Status& Status::operator=(Status&& rhs) noexcept {
  116|  14.3k|  std::swap(state_, rhs.state_);
  117|  14.3k|  return *this;
  118|  14.3k|}
_ZN7leveldb6StatusC2ERKS0_:
  103|  1.98k|inline Status::Status(const Status& rhs) {
  104|  1.98k|  state_ = (rhs.state_ == nullptr) ? nullptr : CopyState(rhs.state_);
  ------------------
  |  Branch (104:12): [True: 1.98k, False: 0]
  ------------------
  105|  1.98k|}

_ZN7leveldb5TableC2EPNS0_3RepE:
   67|     72|  explicit Table(Rep* rep) : rep_(rep) {}

_ZNK7leveldb12TableBuilder2okEv:
   83|  1.45k|  bool ok() const { return status().ok(); }

_ZN7leveldb4port5MutexC2Ev:
   53|  3.50k|  Mutex() = default;
_ZN7leveldb4port7CondVarC2EPNS0_5MutexE:
   71|    553|  explicit CondVar(Mutex* mu) : mu_(mu) { assert(mu != nullptr); }
_ZN7leveldb4port5Mutex4LockEv:
   59|  2.65k|  void Lock() EXCLUSIVE_LOCK_FUNCTION() { mu_.lock(); }
_ZN7leveldb4port7CondVar4WaitEv:
   77|     80|  void Wait() {
   78|     80|    std::unique_lock<std::mutex> lock(mu_->mu_, std::adopt_lock);
   79|     80|    cv_.wait(lock);
   80|     80|    lock.release();
   81|     80|  }
_ZN7leveldb4port5Mutex6UnlockEv:
   60|  2.65k|  void Unlock() UNLOCK_FUNCTION() { mu_.unlock(); }
_ZN7leveldb4port7CondVarD2Ev:
   72|    552|  ~CondVar() = default;
_ZN7leveldb4port5Mutex10AssertHeldEv:
   61|  1.46k|  void AssertHeld() ASSERT_EXCLUSIVE_LOCK() {}
_ZN7leveldb4port7CondVar9SignalAllEv:
   83|     45|  void SignalAll() { cv_.notify_all(); }
_ZN7leveldb4port7CondVar6SignalEv:
   82|     45|  void Signal() { cv_.notify_one(); }
_ZN7leveldb4port15Snappy_CompressEPKcmPNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEE:
   91|    438|                            std::string* output) {
   92|       |#if HAVE_SNAPPY
   93|       |  output->resize(snappy::MaxCompressedLength(length));
   94|       |  size_t outlen;
   95|       |  snappy::RawCompress(input, length, &(*output)[0], &outlen);
   96|       |  output->resize(outlen);
   97|       |  return true;
   98|       |#else
   99|       |  // Silence compiler warnings about unused arguments.
  100|    438|  (void)input;
  101|    438|  (void)length;
  102|    438|  (void)output;
  103|    438|#endif  // HAVE_SNAPPY
  104|       |
  105|    438|  return false;
  106|    438|}
_ZN7leveldb4port17AcceleratedCRC32CEjPKcm:
  208|      1|inline uint32_t AcceleratedCRC32C(uint32_t crc, const char* buf, size_t size) {
  209|       |#if HAVE_CRC32C
  210|       |  return ::crc32c::Extend(crc, reinterpret_cast<const uint8_t*>(buf), size);
  211|       |#else
  212|       |  // Silence compiler warnings about unused arguments.
  213|      1|  (void)crc;
  214|      1|  (void)buf;
  215|      1|  (void)size;
  216|      1|  return 0;
  217|      1|#endif  // HAVE_CRC32C
  218|      1|}

_ZN7leveldb5BlockC2ERKNS_13BlockContentsE:
   26|    376|    : data_(contents.data.data()),
   27|    376|      size_(contents.data.size()),
   28|    376|      owned_(contents.heap_allocated) {
   29|    376|  if (size_ < sizeof(uint32_t)) {
  ------------------
  |  Branch (29:7): [True: 0, False: 376]
  ------------------
   30|      0|    size_ = 0;  // Error marker
   31|    376|  } else {
   32|    376|    size_t max_restarts_allowed = (size_ - sizeof(uint32_t)) / sizeof(uint32_t);
   33|    376|    if (NumRestarts() > max_restarts_allowed) {
  ------------------
  |  Branch (33:9): [True: 0, False: 376]
  ------------------
   34|       |      // The size is too small for NumRestarts()
   35|      0|      size_ = 0;
   36|    376|    } else {
   37|    376|      restart_offset_ = size_ - (1 + NumRestarts()) * sizeof(uint32_t);
   38|    376|    }
   39|    376|  }
   40|    376|}
_ZN7leveldb5BlockD2Ev:
   42|    376|Block::~Block() {
   43|    376|  if (owned_) {
  ------------------
  |  Branch (43:7): [True: 0, False: 376]
  ------------------
   44|      0|    delete[] data_;
   45|      0|  }
   46|    376|}
_ZN7leveldb5Block11NewIteratorEPKNS_10ComparatorE:
  280|    414|Iterator* Block::NewIterator(const Comparator* comparator) {
  281|    414|  if (size_ < sizeof(uint32_t)) {
  ------------------
  |  Branch (281:7): [True: 0, False: 414]
  ------------------
  282|      0|    return NewErrorIterator(Status::Corruption("bad block contents"));
  283|      0|  }
  284|    414|  const uint32_t num_restarts = NumRestarts();
  285|    414|  if (num_restarts == 0) {
  ------------------
  |  Branch (285:7): [True: 0, False: 414]
  ------------------
  286|      0|    return NewEmptyIterator();
  287|    414|  } else {
  288|    414|    return new Iter(comparator, data_, restart_offset_, num_restarts);
  289|    414|  }
  290|    414|}
_ZNK7leveldb5Block11NumRestartsEv:
   20|  1.16k|inline uint32_t Block::NumRestarts() const {
   21|       |  assert(size_ >= sizeof(uint32_t));
   22|  1.16k|  return DecodeFixed32(data_ + size_ - sizeof(uint32_t));
   23|  1.16k|}
_ZN7leveldb5Block4IterC2EPKNS_10ComparatorEPKcjj:
  118|    414|      : comparator_(comparator),
  119|    414|        data_(data),
  120|    414|        restarts_(restarts),
  121|    414|        num_restarts_(num_restarts),
  122|    414|        current_(restarts_),
  123|    414|        restart_index_(num_restarts_) {
  124|       |    assert(num_restarts_ > 0);
  125|    414|  }
_ZNK7leveldb5Block4Iter5ValidEv:
  127|  1.52k|  bool Valid() const override { return current_ < restarts_; }
_ZN7leveldb5Block4Iter11SeekToFirstEv:
  229|    330|  void SeekToFirst() override {
  230|    330|    SeekToRestartPoint(0);
  231|    330|    ParseNextKey();
  232|    330|  }
_ZN7leveldb5Block4Iter18SeekToRestartPointEj:
  105|    350|  void SeekToRestartPoint(uint32_t index) {
  106|    350|    key_.clear();
  107|    350|    restart_index_ = index;
  108|       |    // current_ will be fixed by ParseNextKey();
  109|       |
  110|       |    // ParseNextKey() starts at the end of value_, so set value_ accordingly
  111|    350|    uint32_t offset = GetRestartPoint(index);
  112|    350|    value_ = Slice(data_ + offset, 0);
  113|    350|  }
_ZN7leveldb5Block4Iter15GetRestartPointEj:
  100|    910|  uint32_t GetRestartPoint(uint32_t index) {
  101|       |    assert(index < num_restarts_);
  102|    910|    return DecodeFixed32(data_ + restarts_ + index * sizeof(uint32_t));
  103|    910|  }
_ZN7leveldb5Block4Iter12ParseNextKeyEv:
  250|  1.12k|  bool ParseNextKey() {
  251|  1.12k|    current_ = NextEntryOffset();
  252|  1.12k|    const char* p = data_ + current_;
  253|  1.12k|    const char* limit = data_ + restarts_;  // Restarts come right after data
  254|  1.12k|    if (p >= limit) {
  ------------------
  |  Branch (254:9): [True: 330, False: 796]
  ------------------
  255|       |      // No more entries to return.  Mark as invalid.
  256|    330|      current_ = restarts_;
  257|    330|      restart_index_ = num_restarts_;
  258|    330|      return false;
  259|    330|    }
  260|       |
  261|       |    // Decode next entry
  262|    796|    uint32_t shared, non_shared, value_length;
  263|    796|    p = DecodeEntry(p, limit, &shared, &non_shared, &value_length);
  264|    796|    if (p == nullptr || key_.size() < shared) {
  ------------------
  |  Branch (264:9): [True: 0, False: 796]
  |  Branch (264:25): [True: 0, False: 796]
  ------------------
  265|      0|      CorruptionError();
  266|      0|      return false;
  267|    796|    } else {
  268|    796|      key_.resize(shared);
  269|    796|      key_.append(p, non_shared);
  270|    796|      value_ = Slice(p + non_shared, value_length);
  271|  1.03k|      while (restart_index_ + 1 < num_restarts_ &&
  ------------------
  |  Branch (271:14): [True: 536, False: 494]
  ------------------
  272|    536|             GetRestartPoint(restart_index_ + 1) < current_) {
  ------------------
  |  Branch (272:14): [True: 234, False: 302]
  ------------------
  273|    234|        ++restart_index_;
  274|    234|      }
  275|    796|      return true;
  276|    796|    }
  277|    796|  }
_ZNK7leveldb5Block4Iter15NextEntryOffsetEv:
   96|  1.12k|  inline uint32_t NextEntryOffset() const {
   97|  1.12k|    return (value_.data() + value_.size()) - data_;
   98|  1.12k|  }
block.cc:_ZN7leveldbL11DecodeEntryEPKcS1_PjS2_S2_:
   57|    820|                                      uint32_t* value_length) {
   58|    820|  if (limit - p < 3) return nullptr;
  ------------------
  |  Branch (58:7): [True: 0, False: 820]
  ------------------
   59|    820|  *shared = reinterpret_cast<const uint8_t*>(p)[0];
   60|    820|  *non_shared = reinterpret_cast<const uint8_t*>(p)[1];
   61|    820|  *value_length = reinterpret_cast<const uint8_t*>(p)[2];
   62|    820|  if ((*shared | *non_shared | *value_length) < 128) {
  ------------------
  |  Branch (62:7): [True: 352, False: 468]
  ------------------
   63|       |    // Fast path: all three values are encoded in one byte each
   64|    352|    p += 3;
   65|    468|  } else {
   66|    468|    if ((p = GetVarint32Ptr(p, limit, shared)) == nullptr) return nullptr;
  ------------------
  |  Branch (66:9): [True: 0, False: 468]
  ------------------
   67|    468|    if ((p = GetVarint32Ptr(p, limit, non_shared)) == nullptr) return nullptr;
  ------------------
  |  Branch (67:9): [True: 0, False: 468]
  ------------------
   68|    468|    if ((p = GetVarint32Ptr(p, limit, value_length)) == nullptr) return nullptr;
  ------------------
  |  Branch (68:9): [True: 0, False: 468]
  ------------------
   69|    468|  }
   70|       |
   71|    820|  if (static_cast<uint32_t>(limit - p) < (*non_shared + *value_length)) {
  ------------------
  |  Branch (71:7): [True: 0, False: 820]
  ------------------
   72|      0|    return nullptr;
   73|      0|  }
   74|    820|  return p;
   75|    820|}
_ZN7leveldb5Block4Iter4SeekERKNS_5SliceE:
  164|     20|  void Seek(const Slice& target) override {
  165|       |    // Binary search in restart array to find the last restart point
  166|       |    // with a key < target
  167|     20|    uint32_t left = 0;
  168|     20|    uint32_t right = num_restarts_ - 1;
  169|     20|    int current_key_compare = 0;
  170|       |
  171|     20|    if (Valid()) {
  ------------------
  |  Branch (171:9): [True: 0, False: 20]
  ------------------
  172|       |      // If we're already scanning, use the current position as a starting
  173|       |      // point. This is beneficial if the key we're seeking to is ahead of the
  174|       |      // current position.
  175|      0|      current_key_compare = Compare(key_, target);
  176|      0|      if (current_key_compare < 0) {
  ------------------
  |  Branch (176:11): [True: 0, False: 0]
  ------------------
  177|       |        // key_ is smaller than target
  178|      0|        left = restart_index_;
  179|      0|      } else if (current_key_compare > 0) {
  ------------------
  |  Branch (179:18): [True: 0, False: 0]
  ------------------
  180|      0|        right = restart_index_;
  181|      0|      } else {
  182|       |        // We're seeking to the key we're already at.
  183|      0|        return;
  184|      0|      }
  185|      0|    }
  186|       |
  187|     44|    while (left < right) {
  ------------------
  |  Branch (187:12): [True: 24, False: 20]
  ------------------
  188|     24|      uint32_t mid = (left + right + 1) / 2;
  189|     24|      uint32_t region_offset = GetRestartPoint(mid);
  190|     24|      uint32_t shared, non_shared, value_length;
  191|     24|      const char* key_ptr =
  192|     24|          DecodeEntry(data_ + region_offset, data_ + restarts_, &shared,
  193|     24|                      &non_shared, &value_length);
  194|     24|      if (key_ptr == nullptr || (shared != 0)) {
  ------------------
  |  Branch (194:11): [True: 0, False: 24]
  |  Branch (194:33): [True: 0, False: 24]
  ------------------
  195|      0|        CorruptionError();
  196|      0|        return;
  197|      0|      }
  198|     24|      Slice mid_key(key_ptr, non_shared);
  199|     24|      if (Compare(mid_key, target) < 0) {
  ------------------
  |  Branch (199:11): [True: 10, False: 14]
  ------------------
  200|       |        // Key at "mid" is smaller than "target".  Therefore all
  201|       |        // blocks before "mid" are uninteresting.
  202|     10|        left = mid;
  203|     14|      } else {
  204|       |        // Key at "mid" is >= "target".  Therefore all blocks at or
  205|       |        // after "mid" are uninteresting.
  206|     14|        right = mid - 1;
  207|     14|      }
  208|     24|    }
  209|       |
  210|       |    // We might be able to use our current position within the restart block.
  211|       |    // This is true if we determined the key we desire is in the current block
  212|       |    // and is after than the current key.
  213|     20|    assert(current_key_compare == 0 || Valid());
  214|     20|    bool skip_seek = left == restart_index_ && current_key_compare < 0;
  ------------------
  |  Branch (214:22): [True: 0, False: 20]
  |  Branch (214:48): [True: 0, False: 0]
  ------------------
  215|     20|    if (!skip_seek) {
  ------------------
  |  Branch (215:9): [True: 20, False: 0]
  ------------------
  216|     20|      SeekToRestartPoint(left);
  217|     20|    }
  218|       |    // Linear search (within restart block) for first key >= target
  219|     34|    while (true) {
  ------------------
  |  Branch (219:12): [True: 34, Folded]
  ------------------
  220|     34|      if (!ParseNextKey()) {
  ------------------
  |  Branch (220:11): [True: 0, False: 34]
  ------------------
  221|      0|        return;
  222|      0|      }
  223|     34|      if (Compare(key_, target) >= 0) {
  ------------------
  |  Branch (223:11): [True: 20, False: 14]
  ------------------
  224|     20|        return;
  225|     20|      }
  226|     34|    }
  227|     20|  }
_ZNK7leveldb5Block4Iter7CompareERKNS_5SliceES4_:
   91|     58|  inline int Compare(const Slice& a, const Slice& b) const {
   92|     58|    return comparator_->Compare(a, b);
   93|     58|  }
_ZN7leveldb5Block4Iter4NextEv:
  138|    762|  void Next() override {
  139|       |    assert(Valid());
  140|    762|    ParseNextKey();
  141|    762|  }
_ZNK7leveldb5Block4Iter3keyEv:
  129|    772|  Slice key() const override {
  130|       |    assert(Valid());
  131|    772|    return key_;
  132|    772|  }
_ZNK7leveldb5Block4Iter5valueEv:
  133|    786|  Slice value() const override {
  134|       |    assert(Valid());
  135|    786|    return value_;
  136|    786|  }
_ZNK7leveldb5Block4Iter6statusEv:
  128|    400|  Status status() const override { return status_; }

_ZN7leveldb12BlockBuilderC2EPKNS_7OptionsE:
   41|    126|    : options_(options), restarts_(), counter_(0), finished_(false) {
   42|       |  assert(options->block_restart_interval >= 1);
   43|    126|  restarts_.push_back(0);  // First restart point is at offset 0
   44|    126|}
_ZN7leveldb12BlockBuilder5ResetEv:
   46|    438|void BlockBuilder::Reset() {
   47|    438|  buffer_.clear();
   48|    438|  restarts_.clear();
   49|    438|  restarts_.push_back(0);  // First restart point is at offset 0
   50|    438|  counter_ = 0;
   51|    438|  finished_ = false;
   52|    438|  last_key_.clear();
   53|    438|}
_ZNK7leveldb12BlockBuilder19CurrentSizeEstimateEv:
   55|    569|size_t BlockBuilder::CurrentSizeEstimate() const {
   56|    569|  return (buffer_.size() +                       // Raw data buffer
   57|    569|          restarts_.size() * sizeof(uint32_t) +  // Restart array
   58|    569|          sizeof(uint32_t));                     // Restart array length
   59|    569|}
_ZN7leveldb12BlockBuilder6FinishEv:
   61|    438|Slice BlockBuilder::Finish() {
   62|       |  // Append restart array
   63|  1.18k|  for (size_t i = 0; i < restarts_.size(); i++) {
  ------------------
  |  Branch (63:22): [True: 750, False: 438]
  ------------------
   64|    750|    PutFixed32(&buffer_, restarts_[i]);
   65|    750|  }
   66|    438|  PutFixed32(&buffer_, restarts_.size());
   67|    438|  finished_ = true;
   68|    438|  return Slice(buffer_);
   69|    438|}
_ZN7leveldb12BlockBuilder3AddERKNS_5SliceES3_:
   71|    923|void BlockBuilder::Add(const Slice& key, const Slice& value) {
   72|    923|  Slice last_key_piece(last_key_);
   73|    923|  assert(!finished_);
   74|    923|  assert(counter_ <= options_->block_restart_interval);
   75|    923|  assert(buffer_.empty()  // No values yet?
   76|    923|         || options_->comparator->Compare(key, last_key_piece) > 0);
   77|    923|  size_t shared = 0;
   78|    923|  if (counter_ < options_->block_restart_interval) {
  ------------------
  |  Branch (78:7): [True: 611, False: 312]
  ------------------
   79|       |    // See how much sharing to do with previous string
   80|    611|    const size_t min_length = std::min(last_key_piece.size(), key.size());
   81|  1.86k|    while ((shared < min_length) && (last_key_piece[shared] == key[shared])) {
  ------------------
  |  Branch (81:12): [True: 1.46k, False: 396]
  |  Branch (81:37): [True: 1.25k, False: 215]
  ------------------
   82|  1.25k|      shared++;
   83|  1.25k|    }
   84|    611|  } else {
   85|       |    // Restart compression
   86|    312|    restarts_.push_back(buffer_.size());
   87|    312|    counter_ = 0;
   88|    312|  }
   89|    923|  const size_t non_shared = key.size() - shared;
   90|       |
   91|       |  // Add "<shared><non_shared><value_size>" to buffer_
   92|    923|  PutVarint32(&buffer_, shared);
   93|    923|  PutVarint32(&buffer_, non_shared);
   94|    923|  PutVarint32(&buffer_, value.size());
   95|       |
   96|       |  // Add string delta to buffer_ followed by value
   97|    923|  buffer_.append(key.data() + shared, non_shared);
   98|    923|  buffer_.append(value.data(), value.size());
   99|       |
  100|       |  // Update state
  101|    923|  last_key_.resize(shared);
  102|    923|  last_key_.append(key.data() + shared, non_shared);
  103|       |  assert(Slice(last_key_) == key);
  104|    923|  counter_++;
  105|    923|}

_ZNK7leveldb12BlockBuilder5emptyEv:
   41|    360|  bool empty() const { return buffer_.empty(); }

_ZNK7leveldb11BlockHandle8EncodeToEPNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
   16|    438|void BlockHandle::EncodeTo(std::string* dst) const {
   17|       |  // Sanity check that all fields have been set
   18|    438|  assert(offset_ != ~static_cast<uint64_t>(0));
   19|       |  assert(size_ != ~static_cast<uint64_t>(0));
   20|    438|  PutVarint64(dst, offset_);
   21|    438|  PutVarint64(dst, size_);
   22|    438|}
_ZN7leveldb11BlockHandle10DecodeFromEPNS_5SliceE:
   24|    448|Status BlockHandle::DecodeFrom(Slice* input) {
   25|    448|  if (GetVarint64(input, &offset_) && GetVarint64(input, &size_)) {
  ------------------
  |  Branch (25:7): [True: 448, False: 0]
  |  Branch (25:39): [True: 448, False: 0]
  ------------------
   26|    448|    return Status::OK();
   27|    448|  } else {
   28|      0|    return Status::Corruption("bad block handle");
   29|      0|  }
   30|    448|}
_ZNK7leveldb6Footer8EncodeToEPNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
   32|     42|void Footer::EncodeTo(std::string* dst) const {
   33|     42|  const size_t original_size = dst->size();
   34|     42|  metaindex_handle_.EncodeTo(dst);
   35|     42|  index_handle_.EncodeTo(dst);
   36|     42|  dst->resize(2 * BlockHandle::kMaxEncodedLength);  // Padding
   37|     42|  PutFixed32(dst, static_cast<uint32_t>(kTableMagicNumber & 0xffffffffu));
   38|     42|  PutFixed32(dst, static_cast<uint32_t>(kTableMagicNumber >> 32));
   39|       |  assert(dst->size() == original_size + kEncodedLength);
   40|     42|  (void)original_size;  // Disable unused variable warning.
   41|     42|}
_ZN7leveldb6Footer10DecodeFromEPNS_5SliceE:
   43|     72|Status Footer::DecodeFrom(Slice* input) {
   44|     72|  if (input->size() < kEncodedLength) {
  ------------------
  |  Branch (44:7): [True: 0, False: 72]
  ------------------
   45|      0|    return Status::Corruption("not an sstable (footer too short)");
   46|      0|  }
   47|       |
   48|     72|  const char* magic_ptr = input->data() + kEncodedLength - 8;
   49|     72|  const uint32_t magic_lo = DecodeFixed32(magic_ptr);
   50|     72|  const uint32_t magic_hi = DecodeFixed32(magic_ptr + 4);
   51|     72|  const uint64_t magic = ((static_cast<uint64_t>(magic_hi) << 32) |
   52|     72|                          (static_cast<uint64_t>(magic_lo)));
   53|     72|  if (magic != kTableMagicNumber) {
  ------------------
  |  Branch (53:7): [True: 0, False: 72]
  ------------------
   54|      0|    return Status::Corruption("not an sstable (bad magic number)");
   55|      0|  }
   56|       |
   57|     72|  Status result = metaindex_handle_.DecodeFrom(input);
   58|     72|  if (result.ok()) {
  ------------------
  |  Branch (58:7): [True: 72, False: 0]
  ------------------
   59|     72|    result = index_handle_.DecodeFrom(input);
   60|     72|  }
   61|     72|  if (result.ok()) {
  ------------------
  |  Branch (61:7): [True: 72, False: 0]
  ------------------
   62|       |    // We skip over any leftover data (just padding for now) in "input"
   63|     72|    const char* end = magic_ptr + 8;
   64|     72|    *input = Slice(end, input->data() + input->size() - end);
   65|     72|  }
   66|     72|  return result;
   67|     72|}
_ZN7leveldb9ReadBlockEPNS_16RandomAccessFileERKNS_11ReadOptionsERKNS_11BlockHandleEPNS_13BlockContentsE:
   70|    376|                 const BlockHandle& handle, BlockContents* result) {
   71|    376|  result->data = Slice();
   72|    376|  result->cachable = false;
   73|    376|  result->heap_allocated = false;
   74|       |
   75|       |  // Read the block contents as well as the type/crc footer.
   76|       |  // See table_builder.cc for the code that built this structure.
   77|    376|  size_t n = static_cast<size_t>(handle.size());
   78|    376|  char* buf = new char[n + kBlockTrailerSize];
   79|    376|  Slice contents;
   80|    376|  Status s = file->Read(handle.offset(), n + kBlockTrailerSize, &contents, buf);
   81|    376|  if (!s.ok()) {
  ------------------
  |  Branch (81:7): [True: 0, False: 376]
  ------------------
   82|      0|    delete[] buf;
   83|      0|    return s;
   84|      0|  }
   85|    376|  if (contents.size() != n + kBlockTrailerSize) {
  ------------------
  |  Branch (85:7): [True: 0, False: 376]
  ------------------
   86|      0|    delete[] buf;
   87|      0|    return Status::Corruption("truncated block read");
   88|      0|  }
   89|       |
   90|       |  // Check the crc of the type and the block contents
   91|    376|  const char* data = contents.data();  // Pointer to where Read put the data
   92|    376|  if (options.verify_checksums) {
  ------------------
  |  Branch (92:7): [True: 0, False: 376]
  ------------------
   93|      0|    const uint32_t crc = crc32c::Unmask(DecodeFixed32(data + n + 1));
   94|      0|    const uint32_t actual = crc32c::Value(data, n + 1);
   95|      0|    if (actual != crc) {
  ------------------
  |  Branch (95:9): [True: 0, False: 0]
  ------------------
   96|      0|      delete[] buf;
   97|      0|      s = Status::Corruption("block checksum mismatch");
   98|      0|      return s;
   99|      0|    }
  100|      0|  }
  101|       |
  102|    376|  switch (data[n]) {
  103|    376|    case kNoCompression:
  ------------------
  |  Branch (103:5): [True: 376, False: 0]
  ------------------
  104|    376|      if (data != buf) {
  ------------------
  |  Branch (104:11): [True: 376, False: 0]
  ------------------
  105|       |        // File implementation gave us pointer to some other data.
  106|       |        // Use it directly under the assumption that it will be live
  107|       |        // while the file is open.
  108|    376|        delete[] buf;
  109|    376|        result->data = Slice(data, n);
  110|    376|        result->heap_allocated = false;
  111|    376|        result->cachable = false;  // Do not double-cache
  112|    376|      } else {
  113|      0|        result->data = Slice(buf, n);
  114|      0|        result->heap_allocated = true;
  115|      0|        result->cachable = true;
  116|      0|      }
  117|       |
  118|       |      // Ok
  119|    376|      break;
  120|      0|    case kSnappyCompression: {
  ------------------
  |  Branch (120:5): [True: 0, False: 376]
  ------------------
  121|      0|      size_t ulength = 0;
  122|      0|      if (!port::Snappy_GetUncompressedLength(data, n, &ulength)) {
  ------------------
  |  Branch (122:11): [True: 0, False: 0]
  ------------------
  123|      0|        delete[] buf;
  124|      0|        return Status::Corruption("corrupted snappy compressed block length");
  125|      0|      }
  126|      0|      char* ubuf = new char[ulength];
  127|      0|      if (!port::Snappy_Uncompress(data, n, ubuf)) {
  ------------------
  |  Branch (127:11): [True: 0, False: 0]
  ------------------
  128|      0|        delete[] buf;
  129|      0|        delete[] ubuf;
  130|      0|        return Status::Corruption("corrupted snappy compressed block contents");
  131|      0|      }
  132|      0|      delete[] buf;
  133|      0|      result->data = Slice(ubuf, ulength);
  134|      0|      result->heap_allocated = true;
  135|      0|      result->cachable = true;
  136|      0|      break;
  137|      0|    }
  138|      0|    case kZstdCompression: {
  ------------------
  |  Branch (138:5): [True: 0, False: 376]
  ------------------
  139|      0|      size_t ulength = 0;
  140|      0|      if (!port::Zstd_GetUncompressedLength(data, n, &ulength)) {
  ------------------
  |  Branch (140:11): [True: 0, False: 0]
  ------------------
  141|      0|        delete[] buf;
  142|      0|        return Status::Corruption("corrupted zstd compressed block length");
  143|      0|      }
  144|      0|      char* ubuf = new char[ulength];
  145|      0|      if (!port::Zstd_Uncompress(data, n, ubuf)) {
  ------------------
  |  Branch (145:11): [True: 0, False: 0]
  ------------------
  146|      0|        delete[] buf;
  147|      0|        delete[] ubuf;
  148|      0|        return Status::Corruption("corrupted zstd compressed block contents");
  149|      0|      }
  150|      0|      delete[] buf;
  151|      0|      result->data = Slice(ubuf, ulength);
  152|      0|      result->heap_allocated = true;
  153|      0|      result->cachable = true;
  154|      0|      break;
  155|      0|    }
  156|      0|    default:
  ------------------
  |  Branch (156:5): [True: 0, False: 376]
  ------------------
  157|      0|      delete[] buf;
  158|      0|      return Status::Corruption("bad block type");
  159|    376|  }
  160|       |
  161|    376|  return Status::OK();
  162|    376|}

_ZN7leveldb11BlockHandle10set_offsetEm:
   32|    438|  void set_offset(uint64_t offset) { offset_ = offset; }
_ZN7leveldb11BlockHandle8set_sizeEm:
   36|    438|  void set_size(uint64_t size) { size_ = size; }
_ZN7leveldb11BlockHandleC2Ev:
   95|    782|    : offset_(~static_cast<uint64_t>(0)), size_(~static_cast<uint64_t>(0)) {}
_ZN7leveldb6FooterC2Ev:
   55|    114|  Footer() = default;
_ZN7leveldb6Footer20set_metaindex_handleERKNS_11BlockHandleE:
   59|     42|  void set_metaindex_handle(const BlockHandle& h) { metaindex_handle_ = h; }
_ZN7leveldb6Footer16set_index_handleERKNS_11BlockHandleE:
   63|     42|  void set_index_handle(const BlockHandle& h) { index_handle_ = h; }
_ZNK7leveldb11BlockHandle6offsetEv:
   31|    680|  uint64_t offset() const { return offset_; }
_ZNK7leveldb11BlockHandle4sizeEv:
   35|    376|  uint64_t size() const { return size_; }
_ZNK7leveldb6Footer16metaindex_handleEv:
   58|     72|  const BlockHandle& metaindex_handle() const { return metaindex_handle_; }
_ZNK7leveldb6Footer12index_handleEv:
   62|     72|  const BlockHandle& index_handle() const { return index_handle_; }

_ZN7leveldb8IteratorC2Ev:
    9|    698|Iterator::Iterator() {
   10|    698|  cleanup_head_.function = nullptr;
   11|    698|  cleanup_head_.next = nullptr;
   12|    698|}
_ZN7leveldb8IteratorD2Ev:
   14|    698|Iterator::~Iterator() {
   15|    698|  if (!cleanup_head_.IsEmpty()) {
  ------------------
  |  Branch (15:7): [True: 438, False: 260]
  ------------------
   16|    438|    cleanup_head_.Run();
   17|    438|    for (CleanupNode* node = cleanup_head_.next; node != nullptr;) {
  ------------------
  |  Branch (17:50): [True: 0, False: 438]
  ------------------
   18|      0|      node->Run();
   19|      0|      CleanupNode* next_node = node->next;
   20|      0|      delete node;
   21|      0|      node = next_node;
   22|      0|    }
   23|    438|  }
   24|    698|}
_ZN7leveldb8Iterator15RegisterCleanupEPFvPvS1_ES1_S1_:
   26|    438|void Iterator::RegisterCleanup(CleanupFunction func, void* arg1, void* arg2) {
   27|    438|  assert(func != nullptr);
   28|    438|  CleanupNode* node;
   29|    438|  if (cleanup_head_.IsEmpty()) {
  ------------------
  |  Branch (29:7): [True: 438, False: 0]
  ------------------
   30|    438|    node = &cleanup_head_;
   31|    438|  } else {
   32|      0|    node = new CleanupNode();
   33|      0|    node->next = cleanup_head_.next;
   34|      0|    cleanup_head_.next = node;
   35|      0|  }
   36|    438|  node->function = func;
   37|    438|  node->arg1 = arg1;
   38|    438|  node->arg2 = arg2;
   39|    438|}

_ZN7leveldb15IteratorWrapperC2Ev:
   19|     94|  IteratorWrapper() : iter_(nullptr), valid_(false) {}
_ZN7leveldb15IteratorWrapper3SetEPNS_8IteratorE:
   26|    720|  void Set(Iterator* iter) {
   27|    720|    delete iter_;
   28|    720|    iter_ = iter;
   29|    720|    if (iter_ == nullptr) {
  ------------------
  |  Branch (29:9): [True: 206, False: 514]
  ------------------
   30|    206|      valid_ = false;
   31|    514|    } else {
   32|    514|      Update();
   33|    514|    }
   34|    720|  }
_ZN7leveldb15IteratorWrapper6UpdateEv:
   78|  2.37k|  void Update() {
   79|  2.37k|    valid_ = iter_->Valid();
   80|  2.37k|    if (valid_) {
  ------------------
  |  Branch (80:9): [True: 1.47k, False: 906]
  ------------------
   81|  1.47k|      key_ = iter_->key();
   82|  1.47k|    }
   83|  2.37k|  }
_ZN7leveldb15IteratorWrapperD2Ev:
   21|    330|  ~IteratorWrapper() { delete iter_; }
_ZN7leveldb15IteratorWrapper11SeekToFirstEv:
   66|    392|  void SeekToFirst() {
   67|       |    assert(iter_);
   68|    392|    iter_->SeekToFirst();
   69|    392|    Update();
   70|    392|  }
_ZNK7leveldb15IteratorWrapper5ValidEv:
   37|  4.52k|  bool Valid() const { return valid_; }
_ZNK7leveldb15IteratorWrapper3keyEv:
   38|  3.97k|  Slice key() const {
   39|       |    assert(Valid());
   40|  3.97k|    return key_;
   41|  3.97k|  }
_ZN7leveldb15IteratorWrapper4NextEv:
   51|  1.47k|  void Next() {
   52|       |    assert(iter_);
   53|  1.47k|    iter_->Next();
   54|  1.47k|    Update();
   55|  1.47k|  }
_ZNK7leveldb15IteratorWrapper5valueEv:
   42|  1.45k|  Slice value() const {
   43|       |    assert(Valid());
   44|  1.45k|    return iter_->value();
   45|  1.45k|  }
_ZNK7leveldb15IteratorWrapper6statusEv:
   47|    432|  Status status() const {
   48|       |    assert(iter_);
   49|    432|    return iter_->status();
   50|    432|  }
_ZN7leveldb15IteratorWrapperC2EPNS_8IteratorE:
   20|    236|  explicit IteratorWrapper(Iterator* iter) : iter_(nullptr) { Set(iter); }
_ZNK7leveldb15IteratorWrapper4iterEv:
   22|  2.14k|  Iterator* iter() const { return iter_; }

_ZN7leveldb18NewMergingIteratorEPKNS_10ComparatorEPPNS_8IteratorEi:
  180|     40|                             int n) {
  181|     40|  assert(n >= 0);
  182|     40|  if (n == 0) {
  ------------------
  |  Branch (182:7): [True: 0, False: 40]
  ------------------
  183|      0|    return NewEmptyIterator();
  184|     40|  } else if (n == 1) {
  ------------------
  |  Branch (184:14): [True: 8, False: 32]
  ------------------
  185|      8|    return children[0];
  186|     32|  } else {
  187|     32|    return new MergingIterator(comparator, children, n);
  188|     32|  }
  189|     40|}
merger.cc:_ZN7leveldb12_GLOBAL__N_115MergingIteratorC2EPKNS_10ComparatorEPPNS_8IteratorEi:
   17|     32|      : comparator_(comparator),
   18|     32|        children_(new IteratorWrapper[n]),
   19|     32|        n_(n),
   20|     32|        current_(nullptr),
   21|     32|        direction_(kForward) {
   22|    126|    for (int i = 0; i < n; i++) {
  ------------------
  |  Branch (22:21): [True: 94, False: 32]
  ------------------
   23|     94|      children_[i].Set(children[i]);
   24|     94|    }
   25|     32|  }
merger.cc:_ZN7leveldb12_GLOBAL__N_115MergingIteratorD2Ev:
   27|     32|  ~MergingIterator() override { delete[] children_; }
merger.cc:_ZNK7leveldb12_GLOBAL__N_115MergingIterator5ValidEv:
   29|    514|  bool Valid() const override { return (current_ != nullptr); }
merger.cc:_ZN7leveldb12_GLOBAL__N_115MergingIterator11SeekToFirstEv:
   31|     16|  void SeekToFirst() override {
   32|     62|    for (int i = 0; i < n_; i++) {
  ------------------
  |  Branch (32:21): [True: 46, False: 16]
  ------------------
   33|     46|      children_[i].SeekToFirst();
   34|     46|    }
   35|     16|    FindSmallest();
   36|     16|    direction_ = kForward;
   37|     16|  }
merger.cc:_ZN7leveldb12_GLOBAL__N_115MergingIterator12FindSmallestEv:
  148|    514|void MergingIterator::FindSmallest() {
  149|    514|  IteratorWrapper* smallest = nullptr;
  150|  2.58k|  for (int i = 0; i < n_; i++) {
  ------------------
  |  Branch (150:19): [True: 2.07k, False: 514]
  ------------------
  151|  2.07k|    IteratorWrapper* child = &children_[i];
  152|  2.07k|    if (child->Valid()) {
  ------------------
  |  Branch (152:9): [True: 1.81k, False: 257]
  ------------------
  153|  1.81k|      if (smallest == nullptr) {
  ------------------
  |  Branch (153:11): [True: 498, False: 1.31k]
  ------------------
  154|    498|        smallest = child;
  155|  1.31k|      } else if (comparator_->Compare(child->key(), smallest->key()) < 0) {
  ------------------
  |  Branch (155:18): [True: 399, False: 916]
  ------------------
  156|    399|        smallest = child;
  157|    399|      }
  158|  1.81k|    }
  159|  2.07k|  }
  160|    514|  current_ = smallest;
  161|    514|}
merger.cc:_ZN7leveldb12_GLOBAL__N_115MergingIterator4NextEv:
   55|    498|  void Next() override {
   56|    498|    assert(Valid());
   57|       |
   58|       |    // Ensure that all children are positioned after key().
   59|       |    // If we are moving in the forward direction, it is already
   60|       |    // true for all of the non-current_ children since current_ is
   61|       |    // the smallest child and key() == current_->key().  Otherwise,
   62|       |    // we explicitly position the non-current_ children.
   63|    498|    if (direction_ != kForward) {
  ------------------
  |  Branch (63:9): [True: 0, False: 498]
  ------------------
   64|      0|      for (int i = 0; i < n_; i++) {
  ------------------
  |  Branch (64:23): [True: 0, False: 0]
  ------------------
   65|      0|        IteratorWrapper* child = &children_[i];
   66|      0|        if (child != current_) {
  ------------------
  |  Branch (66:13): [True: 0, False: 0]
  ------------------
   67|      0|          child->Seek(key());
   68|      0|          if (child->Valid() &&
  ------------------
  |  Branch (68:15): [True: 0, False: 0]
  |  Branch (68:15): [True: 0, False: 0]
  ------------------
   69|      0|              comparator_->Compare(key(), child->key()) == 0) {
  ------------------
  |  Branch (69:15): [True: 0, False: 0]
  ------------------
   70|      0|            child->Next();
   71|      0|          }
   72|      0|        }
   73|      0|      }
   74|      0|      direction_ = kForward;
   75|      0|    }
   76|       |
   77|    498|    current_->Next();
   78|    498|    FindSmallest();
   79|    498|  }
merger.cc:_ZNK7leveldb12_GLOBAL__N_115MergingIterator3keyEv:
  110|    672|  Slice key() const override {
  111|       |    assert(Valid());
  112|    672|    return current_->key();
  113|    672|  }
merger.cc:_ZNK7leveldb12_GLOBAL__N_115MergingIterator5valueEv:
  115|    492|  Slice value() const override {
  116|       |    assert(Valid());
  117|    492|    return current_->value();
  118|    492|  }
merger.cc:_ZNK7leveldb12_GLOBAL__N_115MergingIterator6statusEv:
  120|     12|  Status status() const override {
  121|     12|    Status status;
  122|     52|    for (int i = 0; i < n_; i++) {
  ------------------
  |  Branch (122:21): [True: 40, False: 12]
  ------------------
  123|     40|      status = children_[i].status();
  124|     40|      if (!status.ok()) {
  ------------------
  |  Branch (124:11): [True: 0, False: 40]
  ------------------
  125|      0|        break;
  126|      0|      }
  127|     40|    }
  128|     12|    return status;
  129|     12|  }

_ZN7leveldb5Table4OpenERKNS_7OptionsEPNS_16RandomAccessFileEmPPS0_:
   39|     72|                   uint64_t size, Table** table) {
   40|     72|  *table = nullptr;
   41|     72|  if (size < Footer::kEncodedLength) {
  ------------------
  |  Branch (41:7): [True: 0, False: 72]
  ------------------
   42|      0|    return Status::Corruption("file is too short to be an sstable");
   43|      0|  }
   44|       |
   45|     72|  char footer_space[Footer::kEncodedLength];
   46|     72|  Slice footer_input;
   47|     72|  Status s = file->Read(size - Footer::kEncodedLength, Footer::kEncodedLength,
   48|     72|                        &footer_input, footer_space);
   49|     72|  if (!s.ok()) return s;
  ------------------
  |  Branch (49:7): [True: 0, False: 72]
  ------------------
   50|       |
   51|     72|  Footer footer;
   52|     72|  s = footer.DecodeFrom(&footer_input);
   53|     72|  if (!s.ok()) return s;
  ------------------
  |  Branch (53:7): [True: 0, False: 72]
  ------------------
   54|       |
   55|       |  // Read the index block
   56|     72|  BlockContents index_block_contents;
   57|     72|  ReadOptions opt;
   58|     72|  if (options.paranoid_checks) {
  ------------------
  |  Branch (58:7): [True: 0, False: 72]
  ------------------
   59|      0|    opt.verify_checksums = true;
   60|      0|  }
   61|     72|  s = ReadBlock(file, opt, footer.index_handle(), &index_block_contents);
   62|       |
   63|     72|  if (s.ok()) {
  ------------------
  |  Branch (63:7): [True: 72, False: 0]
  ------------------
   64|       |    // We've successfully read the footer and the index block: we're
   65|       |    // ready to serve requests.
   66|     72|    Block* index_block = new Block(index_block_contents);
   67|     72|    Rep* rep = new Table::Rep;
   68|     72|    rep->options = options;
   69|     72|    rep->file = file;
   70|     72|    rep->metaindex_handle = footer.metaindex_handle();
   71|     72|    rep->index_block = index_block;
   72|     72|    rep->cache_id = (options.block_cache ? options.block_cache->NewId() : 0);
  ------------------
  |  Branch (72:22): [True: 72, False: 0]
  ------------------
   73|     72|    rep->filter_data = nullptr;
   74|     72|    rep->filter = nullptr;
   75|     72|    *table = new Table(rep);
   76|     72|    (*table)->ReadMeta(footer);
   77|     72|  }
   78|       |
   79|     72|  return s;
   80|     72|}
_ZN7leveldb5Table8ReadMetaERKNS_6FooterE:
   82|     72|void Table::ReadMeta(const Footer& footer) {
   83|     72|  if (rep_->options.filter_policy == nullptr) {
  ------------------
  |  Branch (83:7): [True: 72, False: 0]
  ------------------
   84|     72|    return;  // Do not need any metadata
   85|     72|  }
   86|       |
   87|       |  // TODO(sanjay): Skip this if footer.metaindex_handle() size indicates
   88|       |  // it is an empty block.
   89|      0|  ReadOptions opt;
   90|      0|  if (rep_->options.paranoid_checks) {
  ------------------
  |  Branch (90:7): [True: 0, False: 0]
  ------------------
   91|      0|    opt.verify_checksums = true;
   92|      0|  }
   93|      0|  BlockContents contents;
   94|      0|  if (!ReadBlock(rep_->file, opt, footer.metaindex_handle(), &contents).ok()) {
  ------------------
  |  Branch (94:7): [True: 0, False: 0]
  ------------------
   95|       |    // Do not propagate errors since meta info is not needed for operation
   96|      0|    return;
   97|      0|  }
   98|      0|  Block* meta = new Block(contents);
   99|       |
  100|      0|  Iterator* iter = meta->NewIterator(BytewiseComparator());
  101|      0|  std::string key = "filter.";
  102|      0|  key.append(rep_->options.filter_policy->Name());
  103|      0|  iter->Seek(key);
  104|      0|  if (iter->Valid() && iter->key() == Slice(key)) {
  ------------------
  |  Branch (104:7): [True: 0, False: 0]
  |  Branch (104:7): [True: 0, False: 0]
  |  Branch (104:24): [True: 0, False: 0]
  ------------------
  105|      0|    ReadFilter(iter->value());
  106|      0|  }
  107|      0|  delete iter;
  108|      0|  delete meta;
  109|      0|}
_ZN7leveldb5TableD2Ev:
  134|     72|Table::~Table() { delete rep_; }
_ZN7leveldb5Table11BlockReaderEPvRKNS_11ReadOptionsERKNS_5SliceE:
  154|    304|                             const Slice& index_value) {
  155|    304|  Table* table = reinterpret_cast<Table*>(arg);
  156|    304|  Cache* block_cache = table->rep_->options.block_cache;
  157|    304|  Block* block = nullptr;
  158|    304|  Cache::Handle* cache_handle = nullptr;
  159|       |
  160|    304|  BlockHandle handle;
  161|    304|  Slice input = index_value;
  162|    304|  Status s = handle.DecodeFrom(&input);
  163|       |  // We intentionally allow extra stuff in index_value so that we
  164|       |  // can add more features in the future.
  165|       |
  166|    304|  if (s.ok()) {
  ------------------
  |  Branch (166:7): [True: 304, False: 0]
  ------------------
  167|    304|    BlockContents contents;
  168|    304|    if (block_cache != nullptr) {
  ------------------
  |  Branch (168:9): [True: 304, False: 0]
  ------------------
  169|    304|      char cache_key_buffer[16];
  170|    304|      EncodeFixed64(cache_key_buffer, table->rep_->cache_id);
  171|    304|      EncodeFixed64(cache_key_buffer + 8, handle.offset());
  172|    304|      Slice key(cache_key_buffer, sizeof(cache_key_buffer));
  173|    304|      cache_handle = block_cache->Lookup(key);
  174|    304|      if (cache_handle != nullptr) {
  ------------------
  |  Branch (174:11): [True: 0, False: 304]
  ------------------
  175|      0|        block = reinterpret_cast<Block*>(block_cache->Value(cache_handle));
  176|    304|      } else {
  177|    304|        s = ReadBlock(table->rep_->file, options, handle, &contents);
  178|    304|        if (s.ok()) {
  ------------------
  |  Branch (178:13): [True: 304, False: 0]
  ------------------
  179|    304|          block = new Block(contents);
  180|    304|          if (contents.cachable && options.fill_cache) {
  ------------------
  |  Branch (180:15): [True: 0, False: 304]
  |  Branch (180:36): [True: 0, False: 0]
  ------------------
  181|      0|            cache_handle = block_cache->Insert(key, block, block->size(),
  182|      0|                                               &DeleteCachedBlock);
  183|      0|          }
  184|    304|        }
  185|    304|      }
  186|    304|    } else {
  187|      0|      s = ReadBlock(table->rep_->file, options, handle, &contents);
  188|      0|      if (s.ok()) {
  ------------------
  |  Branch (188:11): [True: 0, False: 0]
  ------------------
  189|      0|        block = new Block(contents);
  190|      0|      }
  191|      0|    }
  192|    304|  }
  193|       |
  194|    304|  Iterator* iter;
  195|    304|  if (block != nullptr) {
  ------------------
  |  Branch (195:7): [True: 304, False: 0]
  ------------------
  196|    304|    iter = block->NewIterator(table->rep_->options.comparator);
  197|    304|    if (cache_handle == nullptr) {
  ------------------
  |  Branch (197:9): [True: 304, False: 0]
  ------------------
  198|    304|      iter->RegisterCleanup(&DeleteBlock, block, nullptr);
  199|    304|    } else {
  200|      0|      iter->RegisterCleanup(&ReleaseBlock, block_cache, cache_handle);
  201|      0|    }
  202|    304|  } else {
  203|      0|    iter = NewErrorIterator(s);
  204|      0|  }
  205|    304|  return iter;
  206|    304|}
_ZNK7leveldb5Table11NewIteratorERKNS_11ReadOptionsE:
  208|    100|Iterator* Table::NewIterator(const ReadOptions& options) const {
  209|    100|  return NewTwoLevelIterator(
  210|    100|      rep_->index_block->NewIterator(rep_->options.comparator),
  211|    100|      &Table::BlockReader, const_cast<Table*>(this), options);
  212|    100|}
_ZN7leveldb5Table11InternalGetERKNS_11ReadOptionsERKNS_5SliceEPvPFvS7_S6_S6_E:
  216|     10|                                                const Slice&)) {
  217|     10|  Status s;
  218|     10|  Iterator* iiter = rep_->index_block->NewIterator(rep_->options.comparator);
  219|     10|  iiter->Seek(k);
  220|     10|  if (iiter->Valid()) {
  ------------------
  |  Branch (220:7): [True: 10, False: 0]
  ------------------
  221|     10|    Slice handle_value = iiter->value();
  222|     10|    FilterBlockReader* filter = rep_->filter;
  223|     10|    BlockHandle handle;
  224|     10|    if (filter != nullptr && handle.DecodeFrom(&handle_value).ok() &&
  ------------------
  |  Branch (224:9): [True: 0, False: 10]
  |  Branch (224:9): [True: 0, False: 10]
  |  Branch (224:30): [True: 0, False: 0]
  ------------------
  225|      0|        !filter->KeyMayMatch(handle.offset(), k)) {
  ------------------
  |  Branch (225:9): [True: 0, False: 0]
  ------------------
  226|       |      // Not found
  227|     10|    } else {
  228|     10|      Iterator* block_iter = BlockReader(this, options, iiter->value());
  229|     10|      block_iter->Seek(k);
  230|     10|      if (block_iter->Valid()) {
  ------------------
  |  Branch (230:11): [True: 10, False: 0]
  ------------------
  231|     10|        (*handle_result)(arg, block_iter->key(), block_iter->value());
  232|     10|      }
  233|     10|      s = block_iter->status();
  234|     10|      delete block_iter;
  235|     10|    }
  236|     10|  }
  237|     10|  if (s.ok()) {
  ------------------
  |  Branch (237:7): [True: 10, False: 0]
  ------------------
  238|     10|    s = iiter->status();
  239|     10|  }
  240|     10|  delete iiter;
  241|     10|  return s;
  242|     10|}
_ZN7leveldb5Table3RepD2Ev:
   21|     72|  ~Rep() {
   22|     72|    delete filter;
   23|     72|    delete[] filter_data;
   24|     72|    delete index_block;
   25|     72|  }
table.cc:_ZN7leveldbL11DeleteBlockEPvS0_:
  136|    304|static void DeleteBlock(void* arg, void* ignored) {
  137|    304|  delete reinterpret_cast<Block*>(arg);
  138|    304|}

_ZN7leveldb12TableBuilderC2ERKNS_7OptionsEPNS_12WritableFileE:
   66|     42|    : rep_(new Rep(options, file)) {
   67|     42|  if (rep_->filter_block != nullptr) {
  ------------------
  |  Branch (67:7): [True: 0, False: 42]
  ------------------
   68|      0|    rep_->filter_block->StartBlock(0);
   69|      0|  }
   70|     42|}
_ZN7leveldb12TableBuilderD2Ev:
   72|     42|TableBuilder::~TableBuilder() {
   73|       |  assert(rep_->closed);  // Catch errors where caller forgot to call Finish()
   74|     42|  delete rep_->filter_block;
   75|     42|  delete rep_;
   76|     42|}
_ZN7leveldb12TableBuilder3AddERKNS_5SliceES3_:
   94|    569|void TableBuilder::Add(const Slice& key, const Slice& value) {
   95|    569|  Rep* r = rep_;
   96|    569|  assert(!r->closed);
   97|    569|  if (!ok()) return;
  ------------------
  |  Branch (97:7): [True: 0, False: 569]
  ------------------
   98|    569|  if (r->num_entries > 0) {
  ------------------
  |  Branch (98:7): [True: 527, False: 42]
  ------------------
   99|    527|    assert(r->options.comparator->Compare(key, Slice(r->last_key)) > 0);
  100|    527|  }
  101|       |
  102|    569|  if (r->pending_index_entry) {
  ------------------
  |  Branch (102:7): [True: 312, False: 257]
  ------------------
  103|    312|    assert(r->data_block.empty());
  104|    312|    r->options.comparator->FindShortestSeparator(&r->last_key, key);
  105|    312|    std::string handle_encoding;
  106|    312|    r->pending_handle.EncodeTo(&handle_encoding);
  107|    312|    r->index_block.Add(r->last_key, Slice(handle_encoding));
  108|    312|    r->pending_index_entry = false;
  109|    312|  }
  110|       |
  111|    569|  if (r->filter_block != nullptr) {
  ------------------
  |  Branch (111:7): [True: 0, False: 569]
  ------------------
  112|      0|    r->filter_block->AddKey(key);
  113|      0|  }
  114|       |
  115|    569|  r->last_key.assign(key.data(), key.size());
  116|    569|  r->num_entries++;
  117|    569|  r->data_block.Add(key, value);
  118|       |
  119|    569|  const size_t estimated_block_size = r->data_block.CurrentSizeEstimate();
  120|    569|  if (estimated_block_size >= r->options.block_size) {
  ------------------
  |  Branch (120:7): [True: 318, False: 251]
  ------------------
  121|    318|    Flush();
  122|    318|  }
  123|    569|}
_ZN7leveldb12TableBuilder5FlushEv:
  125|    360|void TableBuilder::Flush() {
  126|    360|  Rep* r = rep_;
  127|    360|  assert(!r->closed);
  128|    360|  if (!ok()) return;
  ------------------
  |  Branch (128:7): [True: 0, False: 360]
  ------------------
  129|    360|  if (r->data_block.empty()) return;
  ------------------
  |  Branch (129:7): [True: 6, False: 354]
  ------------------
  130|    360|  assert(!r->pending_index_entry);
  131|    354|  WriteBlock(&r->data_block, &r->pending_handle);
  132|    354|  if (ok()) {
  ------------------
  |  Branch (132:7): [True: 354, False: 0]
  ------------------
  133|    354|    r->pending_index_entry = true;
  134|    354|    r->status = r->file->Flush();
  135|    354|  }
  136|    354|  if (r->filter_block != nullptr) {
  ------------------
  |  Branch (136:7): [True: 0, False: 354]
  ------------------
  137|      0|    r->filter_block->StartBlock(r->offset);
  138|      0|  }
  139|    354|}
_ZN7leveldb12TableBuilder10WriteBlockEPNS_12BlockBuilderEPNS_11BlockHandleE:
  141|    438|void TableBuilder::WriteBlock(BlockBuilder* block, BlockHandle* handle) {
  142|       |  // File format contains a sequence of blocks where each block has:
  143|       |  //    block_data: uint8[n]
  144|       |  //    type: uint8
  145|       |  //    crc: uint32
  146|    438|  assert(ok());
  147|    438|  Rep* r = rep_;
  148|    438|  Slice raw = block->Finish();
  149|       |
  150|    438|  Slice block_contents;
  151|    438|  CompressionType type = r->options.compression;
  152|       |  // TODO(postrelease): Support more compression options: zlib?
  153|    438|  switch (type) {
  ------------------
  |  Branch (153:11): [True: 438, False: 0]
  ------------------
  154|      0|    case kNoCompression:
  ------------------
  |  Branch (154:5): [True: 0, False: 438]
  ------------------
  155|      0|      block_contents = raw;
  156|      0|      break;
  157|       |
  158|    438|    case kSnappyCompression: {
  ------------------
  |  Branch (158:5): [True: 438, False: 0]
  ------------------
  159|    438|      std::string* compressed = &r->compressed_output;
  160|    438|      if (port::Snappy_Compress(raw.data(), raw.size(), compressed) &&
  ------------------
  |  Branch (160:11): [True: 0, False: 438]
  ------------------
  161|      0|          compressed->size() < raw.size() - (raw.size() / 8u)) {
  ------------------
  |  Branch (161:11): [True: 0, False: 0]
  ------------------
  162|      0|        block_contents = *compressed;
  163|    438|      } else {
  164|       |        // Snappy not supported, or compressed less than 12.5%, so just
  165|       |        // store uncompressed form
  166|    438|        block_contents = raw;
  167|    438|        type = kNoCompression;
  168|    438|      }
  169|    438|      break;
  170|      0|    }
  171|       |
  172|      0|    case kZstdCompression: {
  ------------------
  |  Branch (172:5): [True: 0, False: 438]
  ------------------
  173|      0|      std::string* compressed = &r->compressed_output;
  174|      0|      if (port::Zstd_Compress(r->options.zstd_compression_level, raw.data(),
  ------------------
  |  Branch (174:11): [True: 0, False: 0]
  ------------------
  175|      0|                              raw.size(), compressed) &&
  176|      0|          compressed->size() < raw.size() - (raw.size() / 8u)) {
  ------------------
  |  Branch (176:11): [True: 0, False: 0]
  ------------------
  177|      0|        block_contents = *compressed;
  178|      0|      } else {
  179|       |        // Zstd not supported, or compressed less than 12.5%, so just
  180|       |        // store uncompressed form
  181|      0|        block_contents = raw;
  182|      0|        type = kNoCompression;
  183|      0|      }
  184|      0|      break;
  185|      0|    }
  186|    438|  }
  187|    438|  WriteRawBlock(block_contents, type, handle);
  188|    438|  r->compressed_output.clear();
  189|    438|  block->Reset();
  190|    438|}
_ZN7leveldb12TableBuilder13WriteRawBlockERKNS_5SliceENS_15CompressionTypeEPNS_11BlockHandleE:
  193|    438|                                 CompressionType type, BlockHandle* handle) {
  194|    438|  Rep* r = rep_;
  195|    438|  handle->set_offset(r->offset);
  196|    438|  handle->set_size(block_contents.size());
  197|    438|  r->status = r->file->Append(block_contents);
  198|    438|  if (r->status.ok()) {
  ------------------
  |  Branch (198:7): [True: 438, False: 0]
  ------------------
  199|    438|    char trailer[kBlockTrailerSize];
  200|    438|    trailer[0] = type;
  201|    438|    uint32_t crc = crc32c::Value(block_contents.data(), block_contents.size());
  202|    438|    crc = crc32c::Extend(crc, trailer, 1);  // Extend crc to cover block type
  203|    438|    EncodeFixed32(trailer + 1, crc32c::Mask(crc));
  204|    438|    r->status = r->file->Append(Slice(trailer, kBlockTrailerSize));
  205|    438|    if (r->status.ok()) {
  ------------------
  |  Branch (205:9): [True: 438, False: 0]
  ------------------
  206|    438|      r->offset += block_contents.size() + kBlockTrailerSize;
  207|    438|    }
  208|    438|  }
  209|    438|}
_ZNK7leveldb12TableBuilder6statusEv:
  211|  1.45k|Status TableBuilder::status() const { return rep_->status; }
_ZN7leveldb12TableBuilder6FinishEv:
  213|     42|Status TableBuilder::Finish() {
  214|     42|  Rep* r = rep_;
  215|     42|  Flush();
  216|     42|  assert(!r->closed);
  217|     42|  r->closed = true;
  218|       |
  219|     42|  BlockHandle filter_block_handle, metaindex_block_handle, index_block_handle;
  220|       |
  221|       |  // Write filter block
  222|     42|  if (ok() && r->filter_block != nullptr) {
  ------------------
  |  Branch (222:7): [True: 42, False: 0]
  |  Branch (222:15): [True: 0, False: 42]
  ------------------
  223|      0|    WriteRawBlock(r->filter_block->Finish(), kNoCompression,
  224|      0|                  &filter_block_handle);
  225|      0|  }
  226|       |
  227|       |  // Write metaindex block
  228|     42|  if (ok()) {
  ------------------
  |  Branch (228:7): [True: 42, False: 0]
  ------------------
  229|     42|    BlockBuilder meta_index_block(&r->options);
  230|     42|    if (r->filter_block != nullptr) {
  ------------------
  |  Branch (230:9): [True: 0, False: 42]
  ------------------
  231|       |      // Add mapping from "filter.Name" to location of filter data
  232|      0|      std::string key = "filter.";
  233|      0|      key.append(r->options.filter_policy->Name());
  234|      0|      std::string handle_encoding;
  235|      0|      filter_block_handle.EncodeTo(&handle_encoding);
  236|      0|      meta_index_block.Add(key, handle_encoding);
  237|      0|    }
  238|       |
  239|       |    // TODO(postrelease): Add stats and other meta blocks
  240|     42|    WriteBlock(&meta_index_block, &metaindex_block_handle);
  241|     42|  }
  242|       |
  243|       |  // Write index block
  244|     42|  if (ok()) {
  ------------------
  |  Branch (244:7): [True: 42, False: 0]
  ------------------
  245|     42|    if (r->pending_index_entry) {
  ------------------
  |  Branch (245:9): [True: 42, False: 0]
  ------------------
  246|     42|      r->options.comparator->FindShortSuccessor(&r->last_key);
  247|     42|      std::string handle_encoding;
  248|     42|      r->pending_handle.EncodeTo(&handle_encoding);
  249|     42|      r->index_block.Add(r->last_key, Slice(handle_encoding));
  250|     42|      r->pending_index_entry = false;
  251|     42|    }
  252|     42|    WriteBlock(&r->index_block, &index_block_handle);
  253|     42|  }
  254|       |
  255|       |  // Write footer
  256|     42|  if (ok()) {
  ------------------
  |  Branch (256:7): [True: 42, False: 0]
  ------------------
  257|     42|    Footer footer;
  258|     42|    footer.set_metaindex_handle(metaindex_block_handle);
  259|     42|    footer.set_index_handle(index_block_handle);
  260|     42|    std::string footer_encoding;
  261|     42|    footer.EncodeTo(&footer_encoding);
  262|     42|    r->status = r->file->Append(footer_encoding);
  263|     42|    if (r->status.ok()) {
  ------------------
  |  Branch (263:9): [True: 42, False: 0]
  ------------------
  264|     42|      r->offset += footer_encoding.size();
  265|     42|    }
  266|     42|  }
  267|     42|  return r->status;
  268|     42|}
_ZNK7leveldb12TableBuilder10NumEntriesEv:
  276|    320|uint64_t TableBuilder::NumEntries() const { return rep_->num_entries; }
_ZNK7leveldb12TableBuilder8FileSizeEv:
  278|    356|uint64_t TableBuilder::FileSize() const { return rep_->offset; }
_ZN7leveldb12TableBuilder3RepC2ERKNS_7OptionsEPNS_12WritableFileE:
   23|     42|      : options(opt),
   24|     42|        index_block_options(opt),
   25|     42|        file(f),
   26|     42|        offset(0),
   27|     42|        data_block(&options),
   28|     42|        index_block(&index_block_options),
   29|     42|        num_entries(0),
   30|     42|        closed(false),
   31|     42|        filter_block(opt.filter_policy == nullptr
  ------------------
  |  Branch (31:22): [True: 42, False: 0]
  ------------------
   32|     42|                         ? nullptr
   33|     42|                         : new FilterBlockBuilder(opt.filter_policy)),
   34|     42|        pending_index_entry(false) {
   35|     42|    index_block_options.block_restart_interval = 1;
   36|     42|  }

_ZN7leveldb19NewTwoLevelIteratorEPNS_8IteratorEPFS1_PvRKNS_11ReadOptionsERKNS_5SliceEES2_S5_:
  167|    118|                              const ReadOptions& options) {
  168|    118|  return new TwoLevelIterator(index_iter, block_function, arg, options);
  169|    118|}
two_level_iterator.cc:_ZN7leveldb12_GLOBAL__N_116TwoLevelIteratorC2EPNS_8IteratorEPFS3_PvRKNS_11ReadOptionsERKNS_5SliceEES4_S7_:
   74|    118|    : block_function_(block_function),
   75|    118|      arg_(arg),
   76|    118|      options_(options),
   77|    118|      index_iter_(index_iter),
   78|    118|      data_iter_(nullptr) {}
two_level_iterator.cc:_ZN7leveldb12_GLOBAL__N_116TwoLevelIteratorD2Ev:
   80|    118|TwoLevelIterator::~TwoLevelIterator() = default;
two_level_iterator.cc:_ZNK7leveldb12_GLOBAL__N_116TwoLevelIterator5ValidEv:
   31|    790|  bool Valid() const override { return data_iter_.Valid(); }
two_level_iterator.cc:_ZN7leveldb12_GLOBAL__N_116TwoLevelIterator11SeekToFirstEv:
   89|     44|void TwoLevelIterator::SeekToFirst() {
   90|     44|  index_iter_.SeekToFirst();
   91|     44|  InitDataBlock();
   92|     44|  if (data_iter_.iter() != nullptr) data_iter_.SeekToFirst();
  ------------------
  |  Branch (92:7): [True: 44, False: 0]
  ------------------
   93|     44|  SkipEmptyDataBlocksForward();
   94|     44|}
two_level_iterator.cc:_ZN7leveldb12_GLOBAL__N_116TwoLevelIterator13InitDataBlockEv:
  146|    346|void TwoLevelIterator::InitDataBlock() {
  147|    346|  if (!index_iter_.Valid()) {
  ------------------
  |  Branch (147:7): [True: 44, False: 302]
  ------------------
  148|     44|    SetDataIterator(nullptr);
  149|    302|  } else {
  150|    302|    Slice handle = index_iter_.value();
  151|    302|    if (data_iter_.iter() != nullptr &&
  ------------------
  |  Branch (151:9): [True: 258, False: 44]
  |  Branch (151:9): [True: 0, False: 302]
  ------------------
  152|    258|        handle.compare(data_block_handle_) == 0) {
  ------------------
  |  Branch (152:9): [True: 0, False: 258]
  ------------------
  153|       |      // data_iter_ is already constructed with this iterator, so
  154|       |      // no need to change anything
  155|    302|    } else {
  156|    302|      Iterator* iter = (*block_function_)(arg_, options_, handle);
  157|    302|      data_block_handle_.assign(handle.data(), handle.size());
  158|    302|      SetDataIterator(iter);
  159|    302|    }
  160|    302|  }
  161|    346|}
two_level_iterator.cc:_ZN7leveldb12_GLOBAL__N_116TwoLevelIterator15SetDataIteratorEPNS_8IteratorE:
  141|    390|void TwoLevelIterator::SetDataIterator(Iterator* data_iter) {
  142|    390|  if (data_iter_.iter() != nullptr) SaveError(data_iter_.status());
  ------------------
  |  Branch (142:7): [True: 302, False: 88]
  ------------------
  143|    390|  data_iter_.Set(data_iter);
  144|    390|}
two_level_iterator.cc:_ZN7leveldb12_GLOBAL__N_116TwoLevelIterator9SaveErrorERKNS_6StatusE:
   52|    302|  void SaveError(const Status& s) {
   53|    302|    if (status_.ok() && !s.ok()) status_ = s;
  ------------------
  |  Branch (53:9): [True: 302, False: 0]
  |  Branch (53:25): [True: 0, False: 302]
  ------------------
   54|    302|  }
two_level_iterator.cc:_ZN7leveldb12_GLOBAL__N_116TwoLevelIterator26SkipEmptyDataBlocksForwardEv:
  115|    714|void TwoLevelIterator::SkipEmptyDataBlocksForward() {
  116|  1.01k|  while (data_iter_.iter() == nullptr || !data_iter_.Valid()) {
  ------------------
  |  Branch (116:10): [True: 44, False: 972]
  |  Branch (116:42): [True: 302, False: 670]
  ------------------
  117|       |    // Move to next block
  118|    346|    if (!index_iter_.Valid()) {
  ------------------
  |  Branch (118:9): [True: 44, False: 302]
  ------------------
  119|     44|      SetDataIterator(nullptr);
  120|     44|      return;
  121|     44|    }
  122|    302|    index_iter_.Next();
  123|    302|    InitDataBlock();
  124|    302|    if (data_iter_.iter() != nullptr) data_iter_.SeekToFirst();
  ------------------
  |  Branch (124:9): [True: 258, False: 44]
  ------------------
  125|    302|  }
  126|    714|}
two_level_iterator.cc:_ZN7leveldb12_GLOBAL__N_116TwoLevelIterator4NextEv:
  103|    670|void TwoLevelIterator::Next() {
  104|       |  assert(Valid());
  105|    670|  data_iter_.Next();
  106|    670|  SkipEmptyDataBlocksForward();
  107|    670|}
two_level_iterator.cc:_ZNK7leveldb12_GLOBAL__N_116TwoLevelIterator3keyEv:
   32|    670|  Slice key() const override {
   33|       |    assert(Valid());
   34|    670|    return data_iter_.key();
   35|    670|  }
two_level_iterator.cc:_ZNK7leveldb12_GLOBAL__N_116TwoLevelIterator5valueEv:
   36|    664|  Slice value() const override {
   37|       |    assert(Valid());
   38|    664|    return data_iter_.value();
   39|    664|  }
two_level_iterator.cc:_ZNK7leveldb12_GLOBAL__N_116TwoLevelIterator6statusEv:
   40|     90|  Status status() const override {
   41|       |    // It'd be nice if status() returned a const Status& instead of a Status
   42|     90|    if (!index_iter_.status().ok()) {
  ------------------
  |  Branch (42:9): [True: 0, False: 90]
  ------------------
   43|      0|      return index_iter_.status();
   44|     90|    } else if (data_iter_.iter() != nullptr && !data_iter_.status().ok()) {
  ------------------
  |  Branch (44:16): [True: 0, False: 90]
  |  Branch (44:16): [True: 0, False: 90]
  |  Branch (44:48): [True: 0, False: 0]
  ------------------
   45|      0|      return data_iter_.status();
   46|     90|    } else {
   47|     90|      return status_;
   48|     90|    }
   49|     90|  }

_ZN7leveldb5ArenaC2Ev:
   12|    148|    : alloc_ptr_(nullptr), alloc_bytes_remaining_(0), memory_usage_(0) {}
_ZN7leveldb5ArenaD2Ev:
   14|    148|Arena::~Arena() {
   15|    613|  for (size_t i = 0; i < blocks_.size(); i++) {
  ------------------
  |  Branch (15:22): [True: 465, False: 148]
  ------------------
   16|    465|    delete[] blocks_[i];
   17|    465|  }
   18|    148|}
_ZN7leveldb5Arena16AllocateFallbackEm:
   20|    465|char* Arena::AllocateFallback(size_t bytes) {
   21|    465|  if (bytes > kBlockSize / 4) {
  ------------------
  |  Branch (21:7): [True: 300, False: 165]
  ------------------
   22|       |    // Object is more than a quarter of our block size.  Allocate it separately
   23|       |    // to avoid wasting too much space in leftover bytes.
   24|    300|    char* result = AllocateNewBlock(bytes);
   25|    300|    return result;
   26|    300|  }
   27|       |
   28|       |  // We waste the remaining space in the current block.
   29|    165|  alloc_ptr_ = AllocateNewBlock(kBlockSize);
   30|    165|  alloc_bytes_remaining_ = kBlockSize;
   31|       |
   32|    165|  char* result = alloc_ptr_;
   33|    165|  alloc_ptr_ += bytes;
   34|    165|  alloc_bytes_remaining_ -= bytes;
   35|    165|  return result;
   36|    465|}
_ZN7leveldb5Arena15AllocateAlignedEm:
   38|    687|char* Arena::AllocateAligned(size_t bytes) {
   39|    687|  const int align = (sizeof(void*) > 8) ? sizeof(void*) : 8;
  ------------------
  |  Branch (39:21): [Folded, False: 687]
  ------------------
   40|    687|  static_assert((align & (align - 1)) == 0,
   41|    687|                "Pointer size should be a power of 2");
   42|    687|  size_t current_mod = reinterpret_cast<uintptr_t>(alloc_ptr_) & (align - 1);
   43|    687|  size_t slop = (current_mod == 0 ? 0 : align - current_mod);
  ------------------
  |  Branch (43:18): [True: 477, False: 210]
  ------------------
   44|    687|  size_t needed = bytes + slop;
   45|    687|  char* result;
   46|    687|  if (needed <= alloc_bytes_remaining_) {
  ------------------
  |  Branch (46:7): [True: 535, False: 152]
  ------------------
   47|    535|    result = alloc_ptr_ + slop;
   48|    535|    alloc_ptr_ += needed;
   49|    535|    alloc_bytes_remaining_ -= needed;
   50|    535|  } else {
   51|       |    // AllocateFallback always returned aligned memory
   52|    152|    result = AllocateFallback(bytes);
   53|    152|  }
   54|       |  assert((reinterpret_cast<uintptr_t>(result) & (align - 1)) == 0);
   55|    687|  return result;
   56|    687|}
_ZN7leveldb5Arena16AllocateNewBlockEm:
   58|    465|char* Arena::AllocateNewBlock(size_t block_bytes) {
   59|    465|  char* result = new char[block_bytes];
   60|    465|  blocks_.push_back(result);
   61|    465|  memory_usage_.fetch_add(block_bytes + sizeof(char*),
   62|    465|                          std::memory_order_relaxed);
   63|    465|  return result;
   64|    465|}

_ZNK7leveldb5Arena11MemoryUsageEv:
   33|    557|  size_t MemoryUsage() const {
   34|    557|    return memory_usage_.load(std::memory_order_relaxed);
   35|    557|  }
_ZN7leveldb5Arena8AllocateEm:
   55|    539|inline char* Arena::Allocate(size_t bytes) {
   56|       |  // The semantics of what to return are a bit messy if we allow
   57|       |  // 0-byte allocations, so we disallow them here (we don't need
   58|       |  // them for our internal use).
   59|    539|  assert(bytes > 0);
   60|    539|  if (bytes <= alloc_bytes_remaining_) {
  ------------------
  |  Branch (60:7): [True: 226, False: 313]
  ------------------
   61|    226|    char* result = alloc_ptr_;
   62|    226|    alloc_ptr_ += bytes;
   63|    226|    alloc_bytes_remaining_ -= bytes;
   64|    226|    return result;
   65|    226|  }
   66|    313|  return AllocateFallback(bytes);
   67|    539|}

_ZN7leveldb5CacheD2Ev:
   18|    200|Cache::~Cache() {}
_ZN7leveldb11NewLRUCacheEm:
  399|    200|Cache* NewLRUCache(size_t capacity) { return new ShardedLRUCache(capacity); }
cache.cc:_ZN7leveldb12_GLOBAL__N_115ShardedLRUCacheC2Em:
  352|    200|  explicit ShardedLRUCache(size_t capacity) : last_id_(0) {
  353|    200|    const size_t per_shard = (capacity + (kNumShards - 1)) / kNumShards;
  354|  3.40k|    for (int s = 0; s < kNumShards; s++) {
  ------------------
  |  Branch (354:21): [True: 3.20k, False: 200]
  ------------------
  355|  3.20k|      shard_[s].SetCapacity(per_shard);
  356|  3.20k|    }
  357|    200|  }
cache.cc:_ZN7leveldb12_GLOBAL__N_18LRUCacheC2Ev:
  198|  3.20k|LRUCache::LRUCache() : capacity_(0), usage_(0) {
  199|       |  // Make empty circular linked lists.
  200|  3.20k|  lru_.next = &lru_;
  201|  3.20k|  lru_.prev = &lru_;
  202|  3.20k|  in_use_.next = &in_use_;
  203|  3.20k|  in_use_.prev = &in_use_;
  204|  3.20k|}
cache.cc:_ZN7leveldb12_GLOBAL__N_111HandleTableC2Ev:
   72|  3.20k|  HandleTable() : length_(0), elems_(0), list_(nullptr) { Resize(); }
cache.cc:_ZN7leveldb12_GLOBAL__N_111HandleTable6ResizeEv:
  123|  3.20k|  void Resize() {
  124|  3.20k|    uint32_t new_length = 4;
  125|  3.20k|    while (new_length < elems_) {
  ------------------
  |  Branch (125:12): [True: 0, False: 3.20k]
  ------------------
  126|      0|      new_length *= 2;
  127|      0|    }
  128|  3.20k|    LRUHandle** new_list = new LRUHandle*[new_length];
  129|  3.20k|    memset(new_list, 0, sizeof(new_list[0]) * new_length);
  130|  3.20k|    uint32_t count = 0;
  131|  3.20k|    for (uint32_t i = 0; i < length_; i++) {
  ------------------
  |  Branch (131:26): [True: 0, False: 3.20k]
  ------------------
  132|      0|      LRUHandle* h = list_[i];
  133|      0|      while (h != nullptr) {
  ------------------
  |  Branch (133:14): [True: 0, False: 0]
  ------------------
  134|      0|        LRUHandle* next = h->next_hash;
  135|      0|        uint32_t hash = h->hash;
  136|      0|        LRUHandle** ptr = &new_list[hash & (new_length - 1)];
  137|      0|        h->next_hash = *ptr;
  138|      0|        *ptr = h;
  139|      0|        h = next;
  140|      0|        count++;
  141|      0|      }
  142|      0|    }
  143|       |    assert(elems_ == count);
  144|  3.20k|    delete[] list_;
  145|  3.20k|    list_ = new_list;
  146|  3.20k|    length_ = new_length;
  147|  3.20k|  }
cache.cc:_ZN7leveldb12_GLOBAL__N_18LRUCache11SetCapacityEm:
  157|  3.20k|  void SetCapacity(size_t capacity) { capacity_ = capacity; }
cache.cc:_ZN7leveldb12_GLOBAL__N_115ShardedLRUCacheD2Ev:
  358|    200|  ~ShardedLRUCache() override {}
cache.cc:_ZN7leveldb12_GLOBAL__N_18LRUCacheD2Ev:
  206|  3.20k|LRUCache::~LRUCache() {
  207|  3.20k|  assert(in_use_.next == &in_use_);  // Error if caller has an unreleased handle
  208|  3.25k|  for (LRUHandle* e = lru_.next; e != &lru_;) {
  ------------------
  |  Branch (208:34): [True: 52, False: 3.20k]
  ------------------
  209|     52|    LRUHandle* next = e->next;
  210|     52|    assert(e->in_cache);
  211|     52|    e->in_cache = false;
  212|       |    assert(e->refs == 1);  // Invariant of lru_ list.
  213|     52|    Unref(e);
  214|     52|    e = next;
  215|     52|  }
  216|  3.20k|}
cache.cc:_ZN7leveldb12_GLOBAL__N_18LRUCache5UnrefEPNS0_9LRUHandleE:
  226|    182|void LRUCache::Unref(LRUHandle* e) {
  227|    182|  assert(e->refs > 0);
  228|    182|  e->refs--;
  229|    182|  if (e->refs == 0) {  // Deallocate.
  ------------------
  |  Branch (229:7): [True: 72, False: 110]
  ------------------
  230|     72|    assert(!e->in_cache);
  231|     72|    (*e->deleter)(e->key(), e->value);
  232|     72|    free(e);
  233|    110|  } else if (e->in_cache && e->refs == 1) {
  ------------------
  |  Branch (233:14): [True: 110, False: 0]
  |  Branch (233:29): [True: 110, False: 0]
  ------------------
  234|       |    // No longer in use; move to lru_ list.
  235|    110|    LRU_Remove(e);
  236|    110|    LRU_Append(&lru_, e);
  237|    110|  }
  238|    182|}
cache.cc:_ZNK7leveldb12_GLOBAL__N_19LRUHandle3keyEv:
   56|    202|  Slice key() const {
   57|       |    // next is only equal to this if the LRU handle is the list head of an
   58|       |    // empty list. List heads never have meaningful keys.
   59|    202|    assert(next != this);
   60|       |
   61|    202|    return Slice(key_data, key_length);
   62|    202|  }
cache.cc:_ZN7leveldb12_GLOBAL__N_18LRUCache10LRU_RemoveEPNS0_9LRUHandleE:
  240|    168|void LRUCache::LRU_Remove(LRUHandle* e) {
  241|    168|  e->next->prev = e->prev;
  242|    168|  e->prev->next = e->next;
  243|    168|}
cache.cc:_ZN7leveldb12_GLOBAL__N_18LRUCache10LRU_AppendEPNS0_9LRUHandleES3_:
  245|    220|void LRUCache::LRU_Append(LRUHandle* list, LRUHandle* e) {
  246|       |  // Make "e" newest entry by inserting just before *list
  247|    220|  e->next = list;
  248|    220|  e->prev = list->prev;
  249|    220|  e->prev->next = e;
  250|    220|  e->next->prev = e;
  251|    220|}
cache.cc:_ZN7leveldb12_GLOBAL__N_111HandleTableD2Ev:
   73|  3.20k|  ~HandleTable() { delete[] list_; }
cache.cc:_ZN7leveldb12_GLOBAL__N_115ShardedLRUCache6InsertERKNS_5SliceEPvmPFvS4_S5_E:
  360|     72|                 void (*deleter)(const Slice& key, void* value)) override {
  361|     72|    const uint32_t hash = HashSlice(key);
  362|     72|    return shard_[Shard(hash)].Insert(key, hash, value, charge, deleter);
  363|     72|  }
cache.cc:_ZN7leveldb12_GLOBAL__N_115ShardedLRUCache9HashSliceERKNS_5SliceE:
  345|    506|  static inline uint32_t HashSlice(const Slice& s) {
  346|    506|    return Hash(s.data(), s.size(), 0);
  347|    506|  }
cache.cc:_ZN7leveldb12_GLOBAL__N_115ShardedLRUCache5ShardEj:
  349|    616|  static uint32_t Shard(uint32_t hash) { return hash >> (32 - kNumShardBits); }
cache.cc:_ZN7leveldb12_GLOBAL__N_18LRUCache6InsertERKNS_5SliceEjPvmPFvS4_S5_E:
  270|     72|                                                void* value)) {
  271|     72|  MutexLock l(&mutex_);
  272|       |
  273|     72|  LRUHandle* e =
  274|     72|      reinterpret_cast<LRUHandle*>(malloc(sizeof(LRUHandle) - 1 + key.size()));
  275|     72|  e->value = value;
  276|     72|  e->deleter = deleter;
  277|     72|  e->charge = charge;
  278|     72|  e->key_length = key.size();
  279|     72|  e->hash = hash;
  280|     72|  e->in_cache = false;
  281|     72|  e->refs = 1;  // for the returned handle.
  282|     72|  std::memcpy(e->key_data, key.data(), key.size());
  283|       |
  284|     72|  if (capacity_ > 0) {
  ------------------
  |  Branch (284:7): [True: 72, False: 0]
  ------------------
  285|     72|    e->refs++;  // for the cache's reference.
  286|     72|    e->in_cache = true;
  287|     72|    LRU_Append(&in_use_, e);
  288|     72|    usage_ += charge;
  289|     72|    FinishErase(table_.Insert(e));
  290|     72|  } else {  // don't cache. (capacity_==0 is supported and turns off caching.)
  291|       |    // next is read by key() in an assert, so it must be initialized
  292|      0|    e->next = nullptr;
  293|      0|  }
  294|     72|  while (usage_ > capacity_ && lru_.next != &lru_) {
  ------------------
  |  Branch (294:10): [True: 0, False: 72]
  |  Branch (294:32): [True: 0, False: 0]
  ------------------
  295|      0|    LRUHandle* old = lru_.next;
  296|      0|    assert(old->refs == 1);
  297|      0|    bool erased = FinishErase(table_.Remove(old->key(), old->hash));
  298|      0|    if (!erased) {  // to avoid unused variable when compiled NDEBUG
  ------------------
  |  Branch (298:9): [True: 0, False: 0]
  ------------------
  299|      0|      assert(erased);
  300|      0|    }
  301|      0|  }
  302|       |
  303|     72|  return reinterpret_cast<Cache::Handle*>(e);
  304|     72|}
cache.cc:_ZN7leveldb12_GLOBAL__N_18LRUCache11FinishEraseEPNS0_9LRUHandleE:
  308|     92|bool LRUCache::FinishErase(LRUHandle* e) {
  309|     92|  if (e != nullptr) {
  ------------------
  |  Branch (309:7): [True: 20, False: 72]
  ------------------
  310|       |    assert(e->in_cache);
  311|     20|    LRU_Remove(e);
  312|     20|    e->in_cache = false;
  313|     20|    usage_ -= e->charge;
  314|     20|    Unref(e);
  315|     20|  }
  316|     92|  return e != nullptr;
  317|     92|}
cache.cc:_ZN7leveldb12_GLOBAL__N_111HandleTable6InsertEPNS0_9LRUHandleE:
   79|     72|  LRUHandle* Insert(LRUHandle* h) {
   80|     72|    LRUHandle** ptr = FindPointer(h->key(), h->hash);
   81|     72|    LRUHandle* old = *ptr;
   82|     72|    h->next_hash = (old == nullptr ? nullptr : old->next_hash);
  ------------------
  |  Branch (82:21): [True: 72, False: 0]
  ------------------
   83|     72|    *ptr = h;
   84|     72|    if (old == nullptr) {
  ------------------
  |  Branch (84:9): [True: 72, False: 0]
  ------------------
   85|     72|      ++elems_;
   86|     72|      if (elems_ > length_) {
  ------------------
  |  Branch (86:11): [True: 0, False: 72]
  ------------------
   87|       |        // Since each cache entry is fairly large, we aim for a small
   88|       |        // average linked list length (<= 1).
   89|      0|        Resize();
   90|      0|      }
   91|     72|    }
   92|     72|    return old;
   93|     72|  }
cache.cc:_ZN7leveldb12_GLOBAL__N_111HandleTable11FindPointerERKNS_5SliceEj:
  115|    506|  LRUHandle** FindPointer(const Slice& key, uint32_t hash) {
  116|    506|    LRUHandle** ptr = &list_[hash & (length_ - 1)];
  117|    509|    while (*ptr != nullptr && ((*ptr)->hash != hash || key != (*ptr)->key())) {
  ------------------
  |  Branch (117:12): [True: 61, False: 448]
  |  Branch (117:12): [True: 3, False: 506]
  |  Branch (117:32): [True: 3, False: 58]
  |  Branch (117:56): [True: 0, False: 58]
  ------------------
  118|      3|      ptr = &(*ptr)->next_hash;
  119|      3|    }
  120|    506|    return ptr;
  121|    506|  }
cache.cc:_ZN7leveldb12_GLOBAL__N_111HandleTable6RemoveERKNS_5SliceEj:
   95|     20|  LRUHandle* Remove(const Slice& key, uint32_t hash) {
   96|     20|    LRUHandle** ptr = FindPointer(key, hash);
   97|     20|    LRUHandle* result = *ptr;
   98|     20|    if (result != nullptr) {
  ------------------
  |  Branch (98:9): [True: 20, False: 0]
  ------------------
   99|     20|      *ptr = result->next_hash;
  100|     20|      --elems_;
  101|     20|    }
  102|     20|    return result;
  103|     20|  }
cache.cc:_ZN7leveldb12_GLOBAL__N_115ShardedLRUCache6LookupERKNS_5SliceE:
  364|    414|  Handle* Lookup(const Slice& key) override {
  365|    414|    const uint32_t hash = HashSlice(key);
  366|    414|    return shard_[Shard(hash)].Lookup(key, hash);
  367|    414|  }
cache.cc:_ZN7leveldb12_GLOBAL__N_18LRUCache6LookupERKNS_5SliceEj:
  253|    414|Cache::Handle* LRUCache::Lookup(const Slice& key, uint32_t hash) {
  254|    414|  MutexLock l(&mutex_);
  255|    414|  LRUHandle* e = table_.Lookup(key, hash);
  256|    414|  if (e != nullptr) {
  ------------------
  |  Branch (256:7): [True: 38, False: 376]
  ------------------
  257|     38|    Ref(e);
  258|     38|  }
  259|    414|  return reinterpret_cast<Cache::Handle*>(e);
  260|    414|}
cache.cc:_ZN7leveldb12_GLOBAL__N_111HandleTable6LookupERKNS_5SliceEj:
   75|    414|  LRUHandle* Lookup(const Slice& key, uint32_t hash) {
   76|    414|    return *FindPointer(key, hash);
   77|    414|  }
cache.cc:_ZN7leveldb12_GLOBAL__N_18LRUCache3RefEPNS0_9LRUHandleE:
  218|     38|void LRUCache::Ref(LRUHandle* e) {
  219|     38|  if (e->refs == 1 && e->in_cache) {  // If on lru_ list, move to in_use_ list.
  ------------------
  |  Branch (219:7): [True: 38, False: 0]
  |  Branch (219:23): [True: 38, False: 0]
  ------------------
  220|     38|    LRU_Remove(e);
  221|     38|    LRU_Append(&in_use_, e);
  222|     38|  }
  223|     38|  e->refs++;
  224|     38|}
cache.cc:_ZN7leveldb12_GLOBAL__N_115ShardedLRUCache7ReleaseEPNS_5Cache6HandleE:
  368|    110|  void Release(Handle* handle) override {
  369|    110|    LRUHandle* h = reinterpret_cast<LRUHandle*>(handle);
  370|    110|    shard_[Shard(h->hash)].Release(handle);
  371|    110|  }
cache.cc:_ZN7leveldb12_GLOBAL__N_18LRUCache7ReleaseEPNS_5Cache6HandleE:
  262|    110|void LRUCache::Release(Cache::Handle* handle) {
  263|    110|  MutexLock l(&mutex_);
  264|    110|  Unref(reinterpret_cast<LRUHandle*>(handle));
  265|    110|}
cache.cc:_ZN7leveldb12_GLOBAL__N_115ShardedLRUCache5ValueEPNS_5Cache6HandleE:
  376|    110|  void* Value(Handle* handle) override {
  377|    110|    return reinterpret_cast<LRUHandle*>(handle)->value;
  378|    110|  }
cache.cc:_ZN7leveldb12_GLOBAL__N_115ShardedLRUCache5EraseERKNS_5SliceE:
  372|     20|  void Erase(const Slice& key) override {
  373|     20|    const uint32_t hash = HashSlice(key);
  374|     20|    shard_[Shard(hash)].Erase(key, hash);
  375|     20|  }
cache.cc:_ZN7leveldb12_GLOBAL__N_18LRUCache5EraseERKNS_5SliceEj:
  319|     20|void LRUCache::Erase(const Slice& key, uint32_t hash) {
  320|     20|  MutexLock l(&mutex_);
  321|     20|  FinishErase(table_.Remove(key, hash));
  322|     20|}
cache.cc:_ZN7leveldb12_GLOBAL__N_115ShardedLRUCache5NewIdEv:
  379|     72|  uint64_t NewId() override {
  380|     72|    MutexLock l(&id_mutex_);
  381|     72|    return ++(last_id_);
  382|     72|  }

_ZN7leveldb10PutFixed32EPNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEj:
    9|  1.27k|void PutFixed32(std::string* dst, uint32_t value) {
   10|  1.27k|  char buf[sizeof(value)];
   11|  1.27k|  EncodeFixed32(buf, value);
   12|  1.27k|  dst->append(buf, sizeof(buf));
   13|  1.27k|}
_ZN7leveldb10PutFixed64EPNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEm:
   15|    463|void PutFixed64(std::string* dst, uint64_t value) {
   16|    463|  char buf[sizeof(value)];
   17|    463|  EncodeFixed64(buf, value);
   18|    463|  dst->append(buf, sizeof(buf));
   19|    463|}
_ZN7leveldb14EncodeVarint32EPcj:
   21|  6.23k|char* EncodeVarint32(char* dst, uint32_t v) {
   22|       |  // Operate on characters as unsigneds
   23|  6.23k|  uint8_t* ptr = reinterpret_cast<uint8_t*>(dst);
   24|  6.23k|  static const int B = 128;
   25|  6.23k|  if (v < (1 << 7)) {
  ------------------
  |  Branch (25:7): [True: 3.82k, False: 2.41k]
  ------------------
   26|  3.82k|    *(ptr++) = v;
   27|  3.82k|  } else if (v < (1 << 14)) {
  ------------------
  |  Branch (27:14): [True: 2.17k, False: 238]
  ------------------
   28|  2.17k|    *(ptr++) = v | B;
   29|  2.17k|    *(ptr++) = v >> 7;
   30|  2.17k|  } else if (v < (1 << 21)) {
  ------------------
  |  Branch (30:14): [True: 238, False: 0]
  ------------------
   31|    238|    *(ptr++) = v | B;
   32|    238|    *(ptr++) = (v >> 7) | B;
   33|    238|    *(ptr++) = v >> 14;
   34|    238|  } else if (v < (1 << 28)) {
  ------------------
  |  Branch (34:14): [True: 0, False: 0]
  ------------------
   35|      0|    *(ptr++) = v | B;
   36|      0|    *(ptr++) = (v >> 7) | B;
   37|      0|    *(ptr++) = (v >> 14) | B;
   38|      0|    *(ptr++) = v >> 21;
   39|      0|  } else {
   40|      0|    *(ptr++) = v | B;
   41|      0|    *(ptr++) = (v >> 7) | B;
   42|      0|    *(ptr++) = (v >> 14) | B;
   43|      0|    *(ptr++) = (v >> 21) | B;
   44|      0|    *(ptr++) = v >> 28;
   45|      0|  }
   46|  6.23k|  return reinterpret_cast<char*>(ptr);
   47|  6.23k|}
_ZN7leveldb11PutVarint32EPNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEj:
   49|  5.13k|void PutVarint32(std::string* dst, uint32_t v) {
   50|  5.13k|  char buf[5];
   51|  5.13k|  char* ptr = EncodeVarint32(buf, v);
   52|  5.13k|  dst->append(buf, ptr - buf);
   53|  5.13k|}
_ZN7leveldb14EncodeVarint64EPcm:
   55|  1.77k|char* EncodeVarint64(char* dst, uint64_t v) {
   56|  1.77k|  static const int B = 128;
   57|  1.77k|  uint8_t* ptr = reinterpret_cast<uint8_t*>(dst);
   58|  3.02k|  while (v >= B) {
  ------------------
  |  Branch (58:10): [True: 1.24k, False: 1.77k]
  ------------------
   59|  1.24k|    *(ptr++) = v | B;
   60|  1.24k|    v >>= 7;
   61|  1.24k|  }
   62|  1.77k|  *(ptr++) = static_cast<uint8_t>(v);
   63|  1.77k|  return reinterpret_cast<char*>(ptr);
   64|  1.77k|}
_ZN7leveldb11PutVarint64EPNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEm:
   66|  1.77k|void PutVarint64(std::string* dst, uint64_t v) {
   67|  1.77k|  char buf[10];
   68|  1.77k|  char* ptr = EncodeVarint64(buf, v);
   69|  1.77k|  dst->append(buf, ptr - buf);
   70|  1.77k|}
_ZN7leveldb22PutLengthPrefixedSliceEPNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEERKNS_5SliceE:
   72|  1.25k|void PutLengthPrefixedSlice(std::string* dst, const Slice& value) {
   73|  1.25k|  PutVarint32(dst, value.size());
   74|  1.25k|  dst->append(value.data(), value.size());
   75|  1.25k|}
_ZN7leveldb12VarintLengthEm:
   77|  1.07k|int VarintLength(uint64_t v) {
   78|  1.07k|  int len = 1;
   79|  1.87k|  while (v >= 128) {
  ------------------
  |  Branch (79:10): [True: 793, False: 1.07k]
  ------------------
   80|    793|    v >>= 7;
   81|    793|    len++;
   82|    793|  }
   83|  1.07k|  return len;
   84|  1.07k|}
_ZN7leveldb22GetVarint32PtrFallbackEPKcS1_Pj:
   87|  5.44k|                                   uint32_t* value) {
   88|  5.44k|  uint32_t result = 0;
   89|  11.1k|  for (uint32_t shift = 0; shift <= 28 && p < limit; shift += 7) {
  ------------------
  |  Branch (89:28): [True: 11.1k, False: 0]
  |  Branch (89:43): [True: 11.0k, False: 170]
  ------------------
   90|  11.0k|    uint32_t byte = *(reinterpret_cast<const uint8_t*>(p));
   91|  11.0k|    p++;
   92|  11.0k|    if (byte & 128) {
  ------------------
  |  Branch (92:9): [True: 5.74k, False: 5.27k]
  ------------------
   93|       |      // More bytes are present
   94|  5.74k|      result |= ((byte & 127) << shift);
   95|  5.74k|    } else {
   96|  5.27k|      result |= (byte << shift);
   97|  5.27k|      *value = result;
   98|  5.27k|      return reinterpret_cast<const char*>(p);
   99|  5.27k|    }
  100|  11.0k|  }
  101|    170|  return nullptr;
  102|  5.44k|}
_ZN7leveldb11GetVarint32EPNS_5SliceEPj:
  104|  2.32k|bool GetVarint32(Slice* input, uint32_t* value) {
  105|  2.32k|  const char* p = input->data();
  106|  2.32k|  const char* limit = p + input->size();
  107|  2.32k|  const char* q = GetVarint32Ptr(p, limit, value);
  108|  2.32k|  if (q == nullptr) {
  ------------------
  |  Branch (108:7): [True: 170, False: 2.15k]
  ------------------
  109|    170|    return false;
  110|  2.15k|  } else {
  111|  2.15k|    *input = Slice(q, limit - q);
  112|  2.15k|    return true;
  113|  2.15k|  }
  114|  2.32k|}
_ZN7leveldb14GetVarint64PtrEPKcS1_Pm:
  116|  1.53k|const char* GetVarint64Ptr(const char* p, const char* limit, uint64_t* value) {
  117|  1.53k|  uint64_t result = 0;
  118|  2.69k|  for (uint32_t shift = 0; shift <= 63 && p < limit; shift += 7) {
  ------------------
  |  Branch (118:28): [True: 2.69k, False: 0]
  |  Branch (118:43): [True: 2.69k, False: 0]
  ------------------
  119|  2.69k|    uint64_t byte = *(reinterpret_cast<const uint8_t*>(p));
  120|  2.69k|    p++;
  121|  2.69k|    if (byte & 128) {
  ------------------
  |  Branch (121:9): [True: 1.16k, False: 1.53k]
  ------------------
  122|       |      // More bytes are present
  123|  1.16k|      result |= ((byte & 127) << shift);
  124|  1.53k|    } else {
  125|  1.53k|      result |= (byte << shift);
  126|  1.53k|      *value = result;
  127|  1.53k|      return reinterpret_cast<const char*>(p);
  128|  1.53k|    }
  129|  2.69k|  }
  130|      0|  return nullptr;
  131|  1.53k|}
_ZN7leveldb11GetVarint64EPNS_5SliceEPm:
  133|  1.53k|bool GetVarint64(Slice* input, uint64_t* value) {
  134|  1.53k|  const char* p = input->data();
  135|  1.53k|  const char* limit = p + input->size();
  136|  1.53k|  const char* q = GetVarint64Ptr(p, limit, value);
  137|  1.53k|  if (q == nullptr) {
  ------------------
  |  Branch (137:7): [True: 0, False: 1.53k]
  ------------------
  138|      0|    return false;
  139|  1.53k|  } else {
  140|  1.53k|    *input = Slice(q, limit - q);
  141|  1.53k|    return true;
  142|  1.53k|  }
  143|  1.53k|}
_ZN7leveldb22GetLengthPrefixedSliceEPNS_5SliceES1_:
  145|  1.36k|bool GetLengthPrefixedSlice(Slice* input, Slice* result) {
  146|  1.36k|  uint32_t len;
  147|  1.36k|  if (GetVarint32(input, &len) && input->size() >= len) {
  ------------------
  |  Branch (147:7): [True: 1.36k, False: 0]
  |  Branch (147:35): [True: 1.36k, False: 0]
  ------------------
  148|  1.36k|    *result = Slice(input->data(), len);
  149|  1.36k|    input->remove_prefix(len);
  150|  1.36k|    return true;
  151|  1.36k|  } else {
  152|      0|    return false;
  153|      0|  }
  154|  1.36k|}

_ZN7leveldb13DecodeFixed64EPKc:
   91|  1.33k|inline uint64_t DecodeFixed64(const char* ptr) {
   92|  1.33k|  const uint8_t* const buffer = reinterpret_cast<const uint8_t*>(ptr);
   93|       |
   94|       |  // Recent clang and gcc optimize this to a single mov / ldr instruction.
   95|  1.33k|  return (static_cast<uint64_t>(buffer[0])) |
   96|  1.33k|         (static_cast<uint64_t>(buffer[1]) << 8) |
   97|  1.33k|         (static_cast<uint64_t>(buffer[2]) << 16) |
   98|  1.33k|         (static_cast<uint64_t>(buffer[3]) << 24) |
   99|  1.33k|         (static_cast<uint64_t>(buffer[4]) << 32) |
  100|  1.33k|         (static_cast<uint64_t>(buffer[5]) << 40) |
  101|  1.33k|         (static_cast<uint64_t>(buffer[6]) << 48) |
  102|  1.33k|         (static_cast<uint64_t>(buffer[7]) << 56);
  103|  1.33k|}
_ZN7leveldb13EncodeFixed32EPcj:
   54|  4.86k|inline void EncodeFixed32(char* dst, uint32_t value) {
   55|  4.86k|  uint8_t* const buffer = reinterpret_cast<uint8_t*>(dst);
   56|       |
   57|       |  // Recent clang and gcc optimize this to a single mov / str instruction.
   58|  4.86k|  buffer[0] = static_cast<uint8_t>(value);
   59|  4.86k|  buffer[1] = static_cast<uint8_t>(value >> 8);
   60|  4.86k|  buffer[2] = static_cast<uint8_t>(value >> 16);
   61|  4.86k|  buffer[3] = static_cast<uint8_t>(value >> 24);
   62|  4.86k|}
_ZN7leveldb13EncodeFixed64EPcm:
   64|  2.21k|inline void EncodeFixed64(char* dst, uint64_t value) {
   65|  2.21k|  uint8_t* const buffer = reinterpret_cast<uint8_t*>(dst);
   66|       |
   67|       |  // Recent clang and gcc optimize this to a single mov / str instruction.
   68|  2.21k|  buffer[0] = static_cast<uint8_t>(value);
   69|  2.21k|  buffer[1] = static_cast<uint8_t>(value >> 8);
   70|  2.21k|  buffer[2] = static_cast<uint8_t>(value >> 16);
   71|  2.21k|  buffer[3] = static_cast<uint8_t>(value >> 24);
   72|  2.21k|  buffer[4] = static_cast<uint8_t>(value >> 32);
   73|  2.21k|  buffer[5] = static_cast<uint8_t>(value >> 40);
   74|  2.21k|  buffer[6] = static_cast<uint8_t>(value >> 48);
   75|  2.21k|  buffer[7] = static_cast<uint8_t>(value >> 56);
   76|  2.21k|}
_ZN7leveldb13DecodeFixed32EPKc:
   81|  24.9M|inline uint32_t DecodeFixed32(const char* ptr) {
   82|  24.9M|  const uint8_t* const buffer = reinterpret_cast<const uint8_t*>(ptr);
   83|       |
   84|       |  // Recent clang and gcc optimize this to a single mov / ldr instruction.
   85|  24.9M|  return (static_cast<uint32_t>(buffer[0])) |
   86|  24.9M|         (static_cast<uint32_t>(buffer[1]) << 8) |
   87|  24.9M|         (static_cast<uint32_t>(buffer[2]) << 16) |
   88|  24.9M|         (static_cast<uint32_t>(buffer[3]) << 24);
   89|  24.9M|}
_ZN7leveldb14GetVarint32PtrEPKcS1_Pj:
  109|  9.22k|                                  uint32_t* value) {
  110|  9.22k|  if (p < limit) {
  ------------------
  |  Branch (110:7): [True: 9.05k, False: 170]
  ------------------
  111|  9.05k|    uint32_t result = *(reinterpret_cast<const uint8_t*>(p));
  112|  9.05k|    if ((result & 128) == 0) {
  ------------------
  |  Branch (112:9): [True: 3.77k, False: 5.27k]
  ------------------
  113|  3.77k|      *value = result;
  114|  3.77k|      return p + 1;
  115|  3.77k|    }
  116|  9.05k|  }
  117|  5.44k|  return GetVarint32PtrFallback(p, limit, value);
  118|  9.22k|}

_ZN7leveldb10ComparatorD2Ev:
   18|    662|Comparator::~Comparator() = default;
_ZN7leveldb18BytewiseComparatorEv:
   70|    172|const Comparator* BytewiseComparator() {
   71|    172|  static NoDestructor<BytewiseComparatorImpl> singleton;
   72|    172|  return singleton.get();
   73|    172|}
comparator.cc:_ZN7leveldb12_GLOBAL__N_122BytewiseComparatorImplC2Ev:
   23|      1|  BytewiseComparatorImpl() = default;
comparator.cc:_ZNK7leveldb12_GLOBAL__N_122BytewiseComparatorImpl7CompareERKNS_5SliceES4_:
   27|  5.02k|  int Compare(const Slice& a, const Slice& b) const override {
   28|  5.02k|    return a.compare(b);
   29|  5.02k|  }
comparator.cc:_ZNK7leveldb12_GLOBAL__N_122BytewiseComparatorImpl4NameEv:
   25|    247|  const char* Name() const override { return "leveldb.BytewiseComparator"; }
comparator.cc:_ZNK7leveldb12_GLOBAL__N_122BytewiseComparatorImpl21FindShortestSeparatorEPNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_5SliceE:
   32|    312|                             const Slice& limit) const override {
   33|       |    // Find length of common prefix
   34|    312|    size_t min_length = std::min(start->size(), limit.size());
   35|    312|    size_t diff_index = 0;
   36|  2.63k|    while ((diff_index < min_length) &&
  ------------------
  |  Branch (36:12): [True: 2.63k, False: 0]
  ------------------
   37|  2.63k|           ((*start)[diff_index] == limit[diff_index])) {
  ------------------
  |  Branch (37:12): [True: 2.32k, False: 312]
  ------------------
   38|  2.32k|      diff_index++;
   39|  2.32k|    }
   40|       |
   41|    312|    if (diff_index >= min_length) {
  ------------------
  |  Branch (41:9): [True: 0, False: 312]
  ------------------
   42|       |      // Do not shorten if one string is a prefix of the other
   43|    312|    } else {
   44|    312|      uint8_t diff_byte = static_cast<uint8_t>((*start)[diff_index]);
   45|    312|      if (diff_byte < static_cast<uint8_t>(0xff) &&
  ------------------
  |  Branch (45:11): [True: 312, False: 0]
  ------------------
   46|    312|          diff_byte + 1 < static_cast<uint8_t>(limit[diff_index])) {
  ------------------
  |  Branch (46:11): [True: 270, False: 42]
  ------------------
   47|    270|        (*start)[diff_index]++;
   48|    270|        start->resize(diff_index + 1);
   49|       |        assert(Compare(*start, limit) < 0);
   50|    270|      }
   51|    312|    }
   52|    312|  }
comparator.cc:_ZNK7leveldb12_GLOBAL__N_122BytewiseComparatorImpl18FindShortSuccessorEPNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
   54|     42|  void FindShortSuccessor(std::string* key) const override {
   55|       |    // Find first character that can be incremented
   56|     42|    size_t n = key->size();
   57|     58|    for (size_t i = 0; i < n; i++) {
  ------------------
  |  Branch (57:24): [True: 57, False: 1]
  ------------------
   58|     57|      const uint8_t byte = (*key)[i];
   59|     57|      if (byte != static_cast<uint8_t>(0xff)) {
  ------------------
  |  Branch (59:11): [True: 41, False: 16]
  ------------------
   60|     41|        (*key)[i] = byte + 1;
   61|     41|        key->resize(i + 1);
   62|     41|        return;
   63|     41|      }
   64|     57|    }
   65|       |    // *key is a run of 0xffs.  Leave it alone.
   66|     42|  }

_ZN7leveldb6crc32c6ExtendEjPKcm:
  276|  6.00k|uint32_t Extend(uint32_t crc, const char* data, size_t n) {
  277|  6.00k|  static bool accelerate = CanAccelerateCRC32C();
  278|  6.00k|  if (accelerate) {
  ------------------
  |  Branch (278:7): [True: 0, False: 6.00k]
  ------------------
  279|      0|    return port::AcceleratedCRC32C(crc, data, n);
  280|      0|  }
  281|       |
  282|  6.00k|  const uint8_t* p = reinterpret_cast<const uint8_t*>(data);
  283|  6.00k|  const uint8_t* e = p + n;
  284|  6.00k|  uint32_t l = crc ^ kCRC32Xor;
  285|       |
  286|       |// Process one byte at a time.
  287|  6.00k|#define STEP1                              \
  288|  6.00k|  do {                                     \
  289|  6.00k|    int c = (l & 0xff) ^ *p++;             \
  290|  6.00k|    l = kByteExtensionTable[c] ^ (l >> 8); \
  291|  6.00k|  } while (0)
  292|       |
  293|       |// Process one of the 4 strides of 4-byte data.
  294|  6.00k|#define STEP4(s)                                                               \
  295|  6.00k|  do {                                                                         \
  296|  6.00k|    crc##s = ReadUint32LE(p + s * 4) ^ kStrideExtensionTable3[crc##s & 0xff] ^ \
  297|  6.00k|             kStrideExtensionTable2[(crc##s >> 8) & 0xff] ^                    \
  298|  6.00k|             kStrideExtensionTable1[(crc##s >> 16) & 0xff] ^                   \
  299|  6.00k|             kStrideExtensionTable0[crc##s >> 24];                             \
  300|  6.00k|  } while (0)
  301|       |
  302|       |// Process a 16-byte swath of 4 strides, each of which has 4 bytes of data.
  303|  6.00k|#define STEP16 \
  304|  6.00k|  do {         \
  305|  6.00k|    STEP4(0);  \
  306|  6.00k|    STEP4(1);  \
  307|  6.00k|    STEP4(2);  \
  308|  6.00k|    STEP4(3);  \
  309|  6.00k|    p += 16;   \
  310|  6.00k|  } while (0)
  311|       |
  312|       |// Process 4 bytes that were already loaded into a word.
  313|  6.00k|#define STEP4W(w)                                   \
  314|  6.00k|  do {                                              \
  315|  6.00k|    w ^= l;                                         \
  316|  6.00k|    for (size_t i = 0; i < 4; ++i) {                \
  317|  6.00k|      w = (w >> 8) ^ kByteExtensionTable[w & 0xff]; \
  318|  6.00k|    }                                               \
  319|  6.00k|    l = w;                                          \
  320|  6.00k|  } while (0)
  321|       |
  322|       |  // Point x at first 4-byte aligned byte in the buffer. This might be past the
  323|       |  // end of the buffer.
  324|  6.00k|  const uint8_t* x = RoundUp<4>(p);
  325|  6.00k|  if (x <= e) {
  ------------------
  |  Branch (325:7): [True: 6.00k, False: 0]
  ------------------
  326|       |    // Process bytes p is 4-byte aligned.
  327|  13.4k|    while (p != x) {
  ------------------
  |  Branch (327:12): [True: 7.45k, False: 6.00k]
  ------------------
  328|  7.45k|      STEP1;
  ------------------
  |  |  288|  7.45k|  do {                                     \
  |  |  289|  7.45k|    int c = (l & 0xff) ^ *p++;             \
  |  |  290|  7.45k|    l = kByteExtensionTable[c] ^ (l >> 8); \
  |  |  291|  7.45k|  } while (0)
  |  |  ------------------
  |  |  |  Branch (291:12): [Folded, False: 7.45k]
  |  |  ------------------
  ------------------
  329|  7.45k|    }
  330|  6.00k|  }
  331|       |
  332|  6.00k|  if ((e - p) >= 16) {
  ------------------
  |  Branch (332:7): [True: 4.07k, False: 1.92k]
  ------------------
  333|       |    // Load a 16-byte swath into the stride partial results.
  334|  4.07k|    uint32_t crc0 = ReadUint32LE(p + 0 * 4) ^ l;
  335|  4.07k|    uint32_t crc1 = ReadUint32LE(p + 1 * 4);
  336|  4.07k|    uint32_t crc2 = ReadUint32LE(p + 2 * 4);
  337|  4.07k|    uint32_t crc3 = ReadUint32LE(p + 3 * 4);
  338|  4.07k|    p += 16;
  339|       |
  340|       |    // It is possible to get better speeds (at least on x86) by interleaving
  341|       |    // prefetching 256 bytes ahead with processing 64 bytes at a time. See the
  342|       |    // portable implementation in https://github.com/google/crc32c/.
  343|       |
  344|       |    // Process one 16-byte swath at a time.
  345|  6.23M|    while ((e - p) >= 16) {
  ------------------
  |  Branch (345:12): [True: 6.23M, False: 4.07k]
  ------------------
  346|  6.23M|      STEP16;
  ------------------
  |  |  304|  6.23M|  do {         \
  |  |  305|  6.23M|    STEP4(0);  \
  |  |  ------------------
  |  |  |  |  295|  6.23M|  do {                                                                         \
  |  |  |  |  296|  6.23M|    crc##s = ReadUint32LE(p + s * 4) ^ kStrideExtensionTable3[crc##s & 0xff] ^ \
  |  |  |  |  297|  6.23M|             kStrideExtensionTable2[(crc##s >> 8) & 0xff] ^                    \
  |  |  |  |  298|  6.23M|             kStrideExtensionTable1[(crc##s >> 16) & 0xff] ^                   \
  |  |  |  |  299|  6.23M|             kStrideExtensionTable0[crc##s >> 24];                             \
  |  |  |  |  300|  6.23M|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (300:12): [Folded, False: 6.23M]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  306|  6.23M|    STEP4(1);  \
  |  |  ------------------
  |  |  |  |  295|  6.23M|  do {                                                                         \
  |  |  |  |  296|  6.23M|    crc##s = ReadUint32LE(p + s * 4) ^ kStrideExtensionTable3[crc##s & 0xff] ^ \
  |  |  |  |  297|  6.23M|             kStrideExtensionTable2[(crc##s >> 8) & 0xff] ^                    \
  |  |  |  |  298|  6.23M|             kStrideExtensionTable1[(crc##s >> 16) & 0xff] ^                   \
  |  |  |  |  299|  6.23M|             kStrideExtensionTable0[crc##s >> 24];                             \
  |  |  |  |  300|  6.23M|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (300:12): [Folded, False: 6.23M]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  307|  6.23M|    STEP4(2);  \
  |  |  ------------------
  |  |  |  |  295|  6.23M|  do {                                                                         \
  |  |  |  |  296|  6.23M|    crc##s = ReadUint32LE(p + s * 4) ^ kStrideExtensionTable3[crc##s & 0xff] ^ \
  |  |  |  |  297|  6.23M|             kStrideExtensionTable2[(crc##s >> 8) & 0xff] ^                    \
  |  |  |  |  298|  6.23M|             kStrideExtensionTable1[(crc##s >> 16) & 0xff] ^                   \
  |  |  |  |  299|  6.23M|             kStrideExtensionTable0[crc##s >> 24];                             \
  |  |  |  |  300|  6.23M|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (300:12): [Folded, False: 6.23M]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  308|  6.23M|    STEP4(3);  \
  |  |  ------------------
  |  |  |  |  295|  6.23M|  do {                                                                         \
  |  |  |  |  296|  6.23M|    crc##s = ReadUint32LE(p + s * 4) ^ kStrideExtensionTable3[crc##s & 0xff] ^ \
  |  |  |  |  297|  6.23M|             kStrideExtensionTable2[(crc##s >> 8) & 0xff] ^                    \
  |  |  |  |  298|  6.23M|             kStrideExtensionTable1[(crc##s >> 16) & 0xff] ^                   \
  |  |  |  |  299|  6.23M|             kStrideExtensionTable0[crc##s >> 24];                             \
  |  |  |  |  300|  6.23M|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (300:12): [Folded, False: 6.23M]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  309|  6.23M|    p += 16;   \
  |  |  310|  6.23M|  } while (0)
  |  |  ------------------
  |  |  |  Branch (310:12): [Folded, False: 6.23M]
  |  |  ------------------
  ------------------
  347|  6.23M|    }
  348|       |
  349|       |    // Advance one word at a time as far as possible.
  350|  10.4k|    while ((e - p) >= 4) {
  ------------------
  |  Branch (350:12): [True: 6.39k, False: 4.07k]
  ------------------
  351|  6.39k|      STEP4(0);
  ------------------
  |  |  295|  6.39k|  do {                                                                         \
  |  |  296|  6.39k|    crc##s = ReadUint32LE(p + s * 4) ^ kStrideExtensionTable3[crc##s & 0xff] ^ \
  |  |  297|  6.39k|             kStrideExtensionTable2[(crc##s >> 8) & 0xff] ^                    \
  |  |  298|  6.39k|             kStrideExtensionTable1[(crc##s >> 16) & 0xff] ^                   \
  |  |  299|  6.39k|             kStrideExtensionTable0[crc##s >> 24];                             \
  |  |  300|  6.39k|  } while (0)
  |  |  ------------------
  |  |  |  Branch (300:12): [Folded, False: 6.39k]
  |  |  ------------------
  ------------------
  352|  6.39k|      uint32_t tmp = crc0;
  353|  6.39k|      crc0 = crc1;
  354|  6.39k|      crc1 = crc2;
  355|  6.39k|      crc2 = crc3;
  356|  6.39k|      crc3 = tmp;
  357|  6.39k|      p += 4;
  358|  6.39k|    }
  359|       |
  360|       |    // Combine the 4 partial stride results.
  361|  4.07k|    l = 0;
  362|  4.07k|    STEP4W(crc0);
  ------------------
  |  |  314|  4.07k|  do {                                              \
  |  |  315|  4.07k|    w ^= l;                                         \
  |  |  316|  20.3k|    for (size_t i = 0; i < 4; ++i) {                \
  |  |  ------------------
  |  |  |  Branch (316:24): [True: 16.3k, False: 4.07k]
  |  |  ------------------
  |  |  317|  16.3k|      w = (w >> 8) ^ kByteExtensionTable[w & 0xff]; \
  |  |  318|  16.3k|    }                                               \
  |  |  319|  4.07k|    l = w;                                          \
  |  |  320|  4.07k|  } while (0)
  |  |  ------------------
  |  |  |  Branch (320:12): [Folded, False: 4.07k]
  |  |  ------------------
  ------------------
  363|  4.07k|    STEP4W(crc1);
  ------------------
  |  |  314|  4.07k|  do {                                              \
  |  |  315|  4.07k|    w ^= l;                                         \
  |  |  316|  20.3k|    for (size_t i = 0; i < 4; ++i) {                \
  |  |  ------------------
  |  |  |  Branch (316:24): [True: 16.3k, False: 4.07k]
  |  |  ------------------
  |  |  317|  16.3k|      w = (w >> 8) ^ kByteExtensionTable[w & 0xff]; \
  |  |  318|  16.3k|    }                                               \
  |  |  319|  4.07k|    l = w;                                          \
  |  |  320|  4.07k|  } while (0)
  |  |  ------------------
  |  |  |  Branch (320:12): [Folded, False: 4.07k]
  |  |  ------------------
  ------------------
  364|  4.07k|    STEP4W(crc2);
  ------------------
  |  |  314|  4.07k|  do {                                              \
  |  |  315|  4.07k|    w ^= l;                                         \
  |  |  316|  20.3k|    for (size_t i = 0; i < 4; ++i) {                \
  |  |  ------------------
  |  |  |  Branch (316:24): [True: 16.3k, False: 4.07k]
  |  |  ------------------
  |  |  317|  16.3k|      w = (w >> 8) ^ kByteExtensionTable[w & 0xff]; \
  |  |  318|  16.3k|    }                                               \
  |  |  319|  4.07k|    l = w;                                          \
  |  |  320|  4.07k|  } while (0)
  |  |  ------------------
  |  |  |  Branch (320:12): [Folded, False: 4.07k]
  |  |  ------------------
  ------------------
  365|  4.07k|    STEP4W(crc3);
  ------------------
  |  |  314|  4.07k|  do {                                              \
  |  |  315|  4.07k|    w ^= l;                                         \
  |  |  316|  20.3k|    for (size_t i = 0; i < 4; ++i) {                \
  |  |  ------------------
  |  |  |  Branch (316:24): [True: 16.3k, False: 4.07k]
  |  |  ------------------
  |  |  317|  16.3k|      w = (w >> 8) ^ kByteExtensionTable[w & 0xff]; \
  |  |  318|  16.3k|    }                                               \
  |  |  319|  4.07k|    l = w;                                          \
  |  |  320|  4.07k|  } while (0)
  |  |  ------------------
  |  |  |  Branch (320:12): [Folded, False: 4.07k]
  |  |  ------------------
  ------------------
  366|  4.07k|  }
  367|       |
  368|       |  // Process the last few bytes.
  369|  11.7k|  while (p != e) {
  ------------------
  |  Branch (369:10): [True: 5.75k, False: 6.00k]
  ------------------
  370|  5.75k|    STEP1;
  ------------------
  |  |  288|  5.75k|  do {                                     \
  |  |  289|  5.75k|    int c = (l & 0xff) ^ *p++;             \
  |  |  290|  5.75k|    l = kByteExtensionTable[c] ^ (l >> 8); \
  |  |  291|  5.75k|  } while (0)
  |  |  ------------------
  |  |  |  Branch (291:12): [Folded, False: 5.75k]
  |  |  ------------------
  ------------------
  371|  5.75k|  }
  372|  6.00k|#undef STEP4W
  373|  6.00k|#undef STEP16
  374|  6.00k|#undef STEP4
  375|  6.00k|#undef STEP1
  376|  6.00k|  return l ^ kCRC32Xor;
  377|  6.00k|}
crc32c.cc:_ZN7leveldb6crc32cL19CanAccelerateCRC32CEv:
  267|      1|static bool CanAccelerateCRC32C() {
  268|       |  // port::AcceleretedCRC32C returns zero when unable to accelerate.
  269|      1|  static const char kTestCRCBuffer[] = "TestCRCBuffer";
  270|      1|  static const char kBufSize = sizeof(kTestCRCBuffer) - 1;
  271|      1|  static const uint32_t kTestCRCValue = 0xdcbc59fa;
  272|       |
  273|      1|  return port::AcceleratedCRC32C(0, kTestCRCBuffer, kBufSize) == kTestCRCValue;
  274|      1|}
crc32c.cc:_ZN7leveldb6crc32c12_GLOBAL__N_17RoundUpILi4EEEPKhS4_:
  257|  6.00k|constexpr inline const uint8_t* RoundUp(const uint8_t* pointer) {
  258|  6.00k|  return reinterpret_cast<uint8_t*>(
  259|  6.00k|      (reinterpret_cast<uintptr_t>(pointer) + (N - 1)) &
  260|  6.00k|      ~static_cast<uintptr_t>(N - 1));
  261|  6.00k|}
crc32c.cc:_ZN7leveldb6crc32c12_GLOBAL__N_112ReadUint32LEEPKh:
  249|  24.9M|inline uint32_t ReadUint32LE(const uint8_t* buffer) {
  250|  24.9M|  return DecodeFixed32(reinterpret_cast<const char*>(buffer));
  251|  24.9M|}

_ZN7leveldb6crc32c6UnmaskEj:
   35|  1.08k|inline uint32_t Unmask(uint32_t masked_crc) {
   36|  1.08k|  uint32_t rot = masked_crc - kMaskDelta;
   37|  1.08k|  return ((rot >> 17) | (rot << 15));
   38|  1.08k|}
_ZN7leveldb6crc32c5ValueEPKcm:
   20|  2.84k|inline uint32_t Value(const char* data, size_t n) { return Extend(0, data, n); }
_ZN7leveldb6crc32c4MaskEj:
   29|  3.15k|inline uint32_t Mask(uint32_t crc) {
   30|       |  // Rotate right by 15 bits and add a constant.
   31|  3.15k|  return ((crc >> 15) | (crc << 17)) + kMaskDelta;
   32|  3.15k|}

_ZN7leveldb3EnvC2Ev:
   17|      1|Env::Env() = default;
_ZN7leveldb14SequentialFileD2Ev:
   31|    254|SequentialFile::~SequentialFile() = default;
_ZN7leveldb16RandomAccessFileD2Ev:
   33|     72|RandomAccessFile::~RandomAccessFile() = default;
_ZN7leveldb12WritableFileD2Ev:
   35|    454|WritableFile::~WritableFile() = default;
_ZN7leveldb6LoggerD2Ev:
   37|    100|Logger::~Logger() = default;
_ZN7leveldb8FileLockD2Ev:
   39|    100|FileLock::~FileLock() = default;
_ZN7leveldb3LogEPNS_6LoggerEPKcz:
   41|    435|void Log(Logger* info_log, const char* format, ...) {
   42|    435|  if (info_log != nullptr) {
  ------------------
  |  Branch (42:7): [True: 435, False: 0]
  ------------------
   43|    435|    std::va_list ap;
   44|    435|    va_start(ap, format);
   45|    435|    info_log->Logv(format, ap);
   46|       |    va_end(ap);
   47|    435|  }
   48|    435|}
_ZN7leveldb21WriteStringToFileSyncEPNS_3EnvERKNS_5SliceERKNSt3__112basic_stringIcNS5_11char_traitsIcEENS5_9allocatorIcEEEE:
   77|    147|                             const std::string& fname) {
   78|    147|  return DoWriteStringToFile(env, data, fname, true);
   79|    147|}
_ZN7leveldb16ReadFileToStringEPNS_3EnvERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPS8_:
   81|    100|Status ReadFileToString(Env* env, const std::string& fname, std::string* data) {
   82|    100|  data->clear();
   83|    100|  SequentialFile* file;
   84|    100|  Status s = env->NewSequentialFile(fname, &file);
   85|    100|  if (!s.ok()) {
  ------------------
  |  Branch (85:7): [True: 0, False: 100]
  ------------------
   86|      0|    return s;
   87|      0|  }
   88|    100|  static const int kBufferSize = 8192;
   89|    100|  char* space = new char[kBufferSize];
   90|    200|  while (true) {
  ------------------
  |  Branch (90:10): [True: 200, Folded]
  ------------------
   91|    200|    Slice fragment;
   92|    200|    s = file->Read(kBufferSize, &fragment, space);
   93|    200|    if (!s.ok()) {
  ------------------
  |  Branch (93:9): [True: 0, False: 200]
  ------------------
   94|      0|      break;
   95|      0|    }
   96|    200|    data->append(fragment.data(), fragment.size());
   97|    200|    if (fragment.empty()) {
  ------------------
  |  Branch (97:9): [True: 100, False: 100]
  ------------------
   98|    100|      break;
   99|    100|    }
  100|    200|  }
  101|    100|  delete[] space;
  102|    100|  delete file;
  103|    100|  return s;
  104|    100|}
env.cc:_ZN7leveldbL19DoWriteStringToFileEPNS_3EnvERKNS_5SliceERKNSt3__112basic_stringIcNS5_11char_traitsIcEENS5_9allocatorIcEEEEb:
   51|    147|                                  const std::string& fname, bool should_sync) {
   52|    147|  WritableFile* file;
   53|    147|  Status s = env->NewWritableFile(fname, &file);
   54|    147|  if (!s.ok()) {
  ------------------
  |  Branch (54:7): [True: 0, False: 147]
  ------------------
   55|      0|    return s;
   56|      0|  }
   57|    147|  s = file->Append(data);
   58|    147|  if (s.ok() && should_sync) {
  ------------------
  |  Branch (58:7): [True: 147, False: 0]
  |  Branch (58:17): [True: 147, False: 0]
  ------------------
   59|    147|    s = file->Sync();
   60|    147|  }
   61|    147|  if (s.ok()) {
  ------------------
  |  Branch (61:7): [True: 147, False: 0]
  ------------------
   62|    147|    s = file->Close();
   63|    147|  }
   64|    147|  delete file;  // Will auto-close if we did not close above
   65|    147|  if (!s.ok()) {
  ------------------
  |  Branch (65:7): [True: 0, False: 147]
  ------------------
   66|      0|    env->RemoveFile(fname);
   67|      0|  }
   68|    147|  return s;
   69|    147|}

_ZN7leveldb3Env7DefaultEv:
  924|    172|Env* Env::Default() {
  925|    172|  static PosixDefaultEnv env_container;
  926|    172|  return env_container.env();
  927|    172|}
env_posix.cc:_ZN7leveldb12_GLOBAL__N_112SingletonEnvINS0_8PosixEnvEEC2Ev:
  871|      1|  SingletonEnv() {
  872|       |#if !defined(NDEBUG)
  873|       |    env_initialized_.store(true, std::memory_order_relaxed);
  874|       |#endif  // !defined(NDEBUG)
  875|      1|    static_assert(sizeof(env_storage_) >= sizeof(EnvType),
  876|      1|                  "env_storage_ will not fit the Env");
  877|      1|    static_assert(std::is_standard_layout_v<SingletonEnv<EnvType>>);
  878|      1|    static_assert(
  879|      1|        offsetof(SingletonEnv<EnvType>, env_storage_) % alignof(EnvType) == 0,
  880|      1|        "env_storage_ does not meet the Env's alignment needs");
  881|      1|    static_assert(alignof(SingletonEnv<EnvType>) % alignof(EnvType) == 0,
  882|      1|                  "env_storage_ does not meet the Env's alignment needs");
  883|      1|    new (env_storage_) EnvType();
  884|      1|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_18PosixEnvC2Ev:
  809|      1|    : background_work_cv_(&background_work_mutex_),
  810|      1|      started_background_thread_(false),
  811|      1|      mmap_limiter_(MaxMmaps()),
  812|      1|      fd_limiter_(MaxOpenFiles()) {}
env_posix.cc:_ZN7leveldb12_GLOBAL__N_18MaxMmapsEv:
  781|      1|int MaxMmaps() { return g_mmap_limit; }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_17LimiterC2Ei:
   81|      2|        acquires_allowed_(max_acquires) {
   82|       |    assert(max_acquires >= 0);
   83|      2|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_112MaxOpenFilesEv:
  784|      1|int MaxOpenFiles() {
  785|      1|  if (g_open_read_only_file_limit >= 0) {
  ------------------
  |  Branch (785:7): [True: 0, False: 1]
  ------------------
  786|      0|    return g_open_read_only_file_limit;
  787|      0|  }
  788|       |#ifdef __Fuchsia__
  789|       |  // Fuchsia doesn't implement getrlimit.
  790|       |  g_open_read_only_file_limit = 50;
  791|       |#else
  792|      1|  struct ::rlimit rlim;
  793|      1|  if (::getrlimit(RLIMIT_NOFILE, &rlim)) {
  ------------------
  |  Branch (793:7): [True: 0, False: 1]
  ------------------
  794|       |    // getrlimit failed, fallback to hard-coded default.
  795|      0|    g_open_read_only_file_limit = 50;
  796|      1|  } else if (rlim.rlim_cur == RLIM_INFINITY) {
  ------------------
  |  Branch (796:14): [True: 0, False: 1]
  ------------------
  797|      0|    g_open_read_only_file_limit = std::numeric_limits<int>::max();
  798|      1|  } else {
  799|       |    // Allow use of 20% of available file descriptors for read-only files.
  800|      1|    g_open_read_only_file_limit = rlim.rlim_cur / 5;
  801|      1|  }
  802|      1|#endif
  803|      1|  return g_open_read_only_file_limit;
  804|      1|}
env_posix.cc:_ZN7leveldb12_GLOBAL__N_18PosixEnv17NewSequentialFileERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPPNS_14SequentialFileE:
  529|    254|                           SequentialFile** result) override {
  530|    254|    int fd = ::open(filename.c_str(), O_RDONLY | kOpenBaseFlags);
  531|    254|    if (fd < 0) {
  ------------------
  |  Branch (531:9): [True: 0, False: 254]
  ------------------
  532|      0|      *result = nullptr;
  533|      0|      return PosixError(filename, errno);
  534|      0|    }
  535|       |
  536|    254|    *result = new PosixSequentialFile(filename, fd);
  537|    254|    return Status::OK();
  538|    254|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_110PosixErrorERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEi:
   61|    212|Status PosixError(const std::string& context, int error_number) {
   62|    212|  if (error_number == ENOENT) {
  ------------------
  |  Branch (62:7): [True: 59, False: 153]
  ------------------
   63|     59|    return Status::NotFound(context, std::strerror(error_number));
   64|    153|  } else {
   65|    153|    return Status::IOError(context, std::strerror(error_number));
   66|    153|  }
   67|    212|}
env_posix.cc:_ZN7leveldb12_GLOBAL__N_119PosixSequentialFileC2ENSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEi:
  139|    254|      : fd_(fd), filename_(std::move(filename)) {}
env_posix.cc:_ZN7leveldb12_GLOBAL__N_119PosixSequentialFileD2Ev:
  140|    254|  ~PosixSequentialFile() override { close(fd_); }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_119PosixSequentialFile4ReadEmPNS_5SliceEPc:
  142|  1.16k|  Status Read(size_t n, Slice* result, char* scratch) override {
  143|  1.16k|    Status status;
  144|  1.16k|    while (true) {
  ------------------
  |  Branch (144:12): [True: 1.16k, Folded]
  ------------------
  145|  1.16k|      ::ssize_t read_size = ::read(fd_, scratch, n);
  146|  1.16k|      if (read_size < 0) {  // Read error.
  ------------------
  |  Branch (146:11): [True: 0, False: 1.16k]
  ------------------
  147|      0|        if (errno == EINTR) {
  ------------------
  |  Branch (147:13): [True: 0, False: 0]
  ------------------
  148|      0|          continue;  // Retry
  149|      0|        }
  150|      0|        status = PosixError(filename_, errno);
  151|      0|        break;
  152|      0|      }
  153|  1.16k|      *result = Slice(scratch, read_size);
  154|  1.16k|      break;
  155|  1.16k|    }
  156|  1.16k|    return status;
  157|  1.16k|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_18PosixEnv19NewRandomAccessFileERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPPNS_16RandomAccessFileE:
  541|     72|                             RandomAccessFile** result) override {
  542|     72|    *result = nullptr;
  543|     72|    int fd = ::open(filename.c_str(), O_RDONLY | kOpenBaseFlags);
  544|     72|    if (fd < 0) {
  ------------------
  |  Branch (544:9): [True: 0, False: 72]
  ------------------
  545|      0|      return PosixError(filename, errno);
  546|      0|    }
  547|       |
  548|     72|    if (!mmap_limiter_.Acquire()) {
  ------------------
  |  Branch (548:9): [True: 0, False: 72]
  ------------------
  549|      0|      *result = new PosixRandomAccessFile(filename, fd, &fd_limiter_);
  550|      0|      return Status::OK();
  551|      0|    }
  552|       |
  553|     72|    uint64_t file_size;
  554|     72|    Status status = GetFileSize(filename, &file_size);
  555|     72|    if (status.ok()) {
  ------------------
  |  Branch (555:9): [True: 72, False: 0]
  ------------------
  556|     72|      void* mmap_base =
  557|     72|          ::mmap(/*addr=*/nullptr, file_size, PROT_READ, MAP_SHARED, fd, 0);
  558|     72|      if (mmap_base != MAP_FAILED) {
  ------------------
  |  Branch (558:11): [True: 72, False: 0]
  ------------------
  559|     72|        *result = new PosixMmapReadableFile(filename,
  560|     72|                                            reinterpret_cast<char*>(mmap_base),
  561|     72|                                            file_size, &mmap_limiter_);
  562|     72|      } else {
  563|      0|        status = PosixError(filename, errno);
  564|      0|      }
  565|     72|    }
  566|     72|    ::close(fd);
  567|     72|    if (!status.ok()) {
  ------------------
  |  Branch (567:9): [True: 0, False: 72]
  ------------------
  568|      0|      mmap_limiter_.Release();
  569|      0|    }
  570|     72|    return status;
  571|     72|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_17Limiter7AcquireEv:
   90|     72|  bool Acquire() {
   91|     72|    int old_acquires_allowed =
   92|     72|        acquires_allowed_.fetch_sub(1, std::memory_order_relaxed);
   93|       |
   94|     72|    if (old_acquires_allowed > 0) return true;
  ------------------
  |  Branch (94:9): [True: 72, False: 0]
  ------------------
   95|       |
   96|      0|    int pre_increment_acquires_allowed =
   97|      0|        acquires_allowed_.fetch_add(1, std::memory_order_relaxed);
   98|       |
   99|       |    // Silence compiler warnings about unused arguments when NDEBUG is defined.
  100|      0|    (void)pre_increment_acquires_allowed;
  101|       |    // If the check below fails, Release() was called more times than acquire.
  102|      0|    assert(pre_increment_acquires_allowed < max_acquires_);
  103|       |
  104|      0|    return false;
  105|     72|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_121PosixMmapReadableFileC2ENSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPcmPNS0_7LimiterE:
  249|     72|      : mmap_base_(mmap_base),
  250|     72|        length_(length),
  251|     72|        mmap_limiter_(mmap_limiter),
  252|     72|        filename_(std::move(filename)) {}
env_posix.cc:_ZN7leveldb12_GLOBAL__N_121PosixMmapReadableFileD2Ev:
  254|     72|  ~PosixMmapReadableFile() override {
  255|     72|    ::munmap(static_cast<void*>(mmap_base_), length_);
  256|     72|    mmap_limiter_->Release();
  257|     72|  }
env_posix.cc:_ZNK7leveldb12_GLOBAL__N_121PosixMmapReadableFile4ReadEmmPNS_5SliceEPc:
  260|    448|              char* scratch) const override {
  261|    448|    if (offset + n > length_) {
  ------------------
  |  Branch (261:9): [True: 0, False: 448]
  ------------------
  262|      0|      *result = Slice();
  263|      0|      return PosixError(filename_, EINVAL);
  264|      0|    }
  265|       |
  266|    448|    *result = Slice(mmap_base_ + offset, n);
  267|    448|    return Status::OK();
  268|    448|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_17Limiter7ReleaseEv:
  109|     72|  void Release() {
  110|     72|    int old_acquires_allowed =
  111|     72|        acquires_allowed_.fetch_add(1, std::memory_order_relaxed);
  112|       |
  113|       |    // Silence compiler warnings about unused arguments when NDEBUG is defined.
  114|     72|    (void)old_acquires_allowed;
  115|       |    // If the check below fails, Release() was called more times than acquire.
  116|       |    assert(old_acquires_allowed < max_acquires_);
  117|     72|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_18PosixEnv15NewWritableFileERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPPNS_12WritableFileE:
  574|    454|                         WritableFile** result) override {
  575|    454|    int fd = ::open(filename.c_str(),
  576|    454|                    O_TRUNC | O_WRONLY | O_CREAT | kOpenBaseFlags, 0644);
  577|    454|    if (fd < 0) {
  ------------------
  |  Branch (577:9): [True: 0, False: 454]
  ------------------
  578|      0|      *result = nullptr;
  579|      0|      return PosixError(filename, errno);
  580|      0|    }
  581|       |
  582|    454|    *result = new PosixWritableFile(filename, fd);
  583|    454|    return Status::OK();
  584|    454|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_117PosixWritableFileC2ENSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEi:
  280|    454|      : pos_(0),
  281|    454|        fd_(fd),
  282|    454|        is_manifest_(IsManifest(filename)),
  283|    454|        filename_(std::move(filename)),
  284|    454|        dirname_(Dirname(filename_)) {}
env_posix.cc:_ZN7leveldb12_GLOBAL__N_117PosixWritableFile10IsManifestERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  453|    454|  static bool IsManifest(const std::string& filename) {
  454|    454|    return Basename(filename).starts_with("MANIFEST");
  455|    454|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_117PosixWritableFile8BasenameERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  439|    454|  static Slice Basename(const std::string& filename) {
  440|    454|    std::string::size_type separator_pos = filename.rfind('/');
  441|    454|    if (separator_pos == std::string::npos) {
  ------------------
  |  Branch (441:9): [True: 0, False: 454]
  ------------------
  442|      0|      return Slice(filename);
  443|      0|    }
  444|       |    // The filename component should not contain a path separator. If it does,
  445|       |    // the splitting was done incorrectly.
  446|    454|    assert(filename.find('/', separator_pos + 1) == std::string::npos);
  447|       |
  448|    454|    return Slice(filename.data() + separator_pos + 1,
  449|    454|                 filename.length() - separator_pos - 1);
  450|    454|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_117PosixWritableFile7DirnameERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  423|    454|  static std::string Dirname(const std::string& filename) {
  424|    454|    std::string::size_type separator_pos = filename.rfind('/');
  425|    454|    if (separator_pos == std::string::npos) {
  ------------------
  |  Branch (425:9): [True: 0, False: 454]
  ------------------
  426|      0|      return std::string(".");
  427|      0|    }
  428|       |    // The filename component should not contain a path separator. If it does,
  429|       |    // the splitting was done incorrectly.
  430|    454|    assert(filename.find('/', separator_pos + 1) == std::string::npos);
  431|       |
  432|    454|    return filename.substr(0, separator_pos);
  433|    454|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_117PosixWritableFileD2Ev:
  286|    454|  ~PosixWritableFile() override {
  287|    454|    if (fd_ >= 0) {
  ------------------
  |  Branch (287:9): [True: 200, False: 254]
  ------------------
  288|       |      // Ignoring any potential errors
  289|    200|      Close();
  290|    200|    }
  291|    454|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_117PosixWritableFile6AppendERKNS_5SliceE:
  293|  6.50k|  Status Append(const Slice& data) override {
  294|  6.50k|    size_t write_size = data.size();
  295|  6.50k|    const char* write_data = data.data();
  296|       |
  297|       |    // Fit as much as possible into buffer.
  298|  6.50k|    size_t copy_size = std::min(write_size, kWritableFileBufferSize - pos_);
  299|  6.50k|    std::memcpy(buf_ + pos_, write_data, copy_size);
  300|  6.50k|    write_data += copy_size;
  301|  6.50k|    write_size -= copy_size;
  302|  6.50k|    pos_ += copy_size;
  303|  6.50k|    if (write_size == 0) {
  ------------------
  |  Branch (303:9): [True: 6.49k, False: 6]
  ------------------
  304|  6.49k|      return Status::OK();
  305|  6.49k|    }
  306|       |
  307|       |    // Can't fit in buffer, so need to do at least one write.
  308|      6|    Status status = FlushBuffer();
  309|      6|    if (!status.ok()) {
  ------------------
  |  Branch (309:9): [True: 0, False: 6]
  ------------------
  310|      0|      return status;
  311|      0|    }
  312|       |
  313|       |    // Small writes go to buffer, large writes are written directly.
  314|      6|    if (write_size < kWritableFileBufferSize) {
  ------------------
  |  Branch (314:9): [True: 0, False: 6]
  ------------------
  315|      0|      std::memcpy(buf_, write_data, write_size);
  316|      0|      pos_ = write_size;
  317|      0|      return Status::OK();
  318|      0|    }
  319|      6|    return WriteUnbuffered(write_data, write_size);
  320|      6|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_117PosixWritableFile11FlushBufferEv:
  354|  3.89k|  Status FlushBuffer() {
  355|  3.89k|    Status status = WriteUnbuffered(buf_, pos_);
  356|  3.89k|    pos_ = 0;
  357|  3.89k|    return status;
  358|  3.89k|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_117PosixWritableFile15WriteUnbufferedEPKcm:
  360|  3.90k|  Status WriteUnbuffered(const char* data, size_t size) {
  361|  7.17k|    while (size > 0) {
  ------------------
  |  Branch (361:12): [True: 3.27k, False: 3.90k]
  ------------------
  362|  3.27k|      ssize_t write_result = ::write(fd_, data, size);
  363|  3.27k|      if (write_result < 0) {
  ------------------
  |  Branch (363:11): [True: 0, False: 3.27k]
  ------------------
  364|      0|        if (errno == EINTR) {
  ------------------
  |  Branch (364:13): [True: 0, False: 0]
  ------------------
  365|      0|          continue;  // Retry
  366|      0|        }
  367|      0|        return PosixError(filename_, errno);
  368|      0|      }
  369|  3.27k|      data += write_result;
  370|  3.27k|      size -= write_result;
  371|  3.27k|    }
  372|  3.90k|    return Status::OK();
  373|  3.90k|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_117PosixWritableFile5CloseEv:
  322|    454|  Status Close() override {
  323|    454|    Status status = FlushBuffer();
  324|    454|    const int close_result = ::close(fd_);
  325|    454|    if (close_result < 0 && status.ok()) {
  ------------------
  |  Branch (325:9): [True: 0, False: 454]
  |  Branch (325:29): [True: 0, False: 0]
  ------------------
  326|       |      status = PosixError(filename_, errno);
  327|      0|    }
  328|    454|    fd_ = -1;
  329|    454|    return status;
  330|    454|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_117PosixWritableFile5FlushEv:
  332|  3.07k|  Status Flush() override { return FlushBuffer(); }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_117PosixWritableFile4SyncEv:
  334|    361|  Status Sync() override {
  335|       |    // Ensure new files referred to by the manifest are in the filesystem.
  336|       |    //
  337|       |    // This needs to happen before the manifest file is flushed to disk, to
  338|       |    // avoid crashing in a state where the manifest refers to files that are not
  339|       |    // yet on disk.
  340|    361|    Status status = SyncDirIfManifest();
  341|    361|    if (!status.ok()) {
  ------------------
  |  Branch (341:9): [True: 0, False: 361]
  ------------------
  342|      0|      return status;
  343|      0|    }
  344|       |
  345|    361|    status = FlushBuffer();
  346|    361|    if (!status.ok()) {
  ------------------
  |  Branch (346:9): [True: 0, False: 361]
  ------------------
  347|      0|      return status;
  348|      0|    }
  349|       |
  350|    361|    return SyncFd(fd_, filename_);
  351|    361|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_117PosixWritableFile17SyncDirIfManifestEv:
  375|    361|  Status SyncDirIfManifest() {
  376|    361|    Status status;
  377|    361|    if (!is_manifest_) {
  ------------------
  |  Branch (377:9): [True: 189, False: 172]
  ------------------
  378|    189|      return status;
  379|    189|    }
  380|       |
  381|    172|    int fd = ::open(dirname_.c_str(), O_RDONLY | kOpenBaseFlags);
  382|    172|    if (fd < 0) {
  ------------------
  |  Branch (382:9): [True: 0, False: 172]
  ------------------
  383|      0|      status = PosixError(dirname_, errno);
  384|    172|    } else {
  385|    172|      status = SyncFd(fd, dirname_);
  386|    172|      ::close(fd);
  387|    172|    }
  388|    172|    return status;
  389|    361|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_117PosixWritableFile6SyncFdEiRKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  397|    533|  static Status SyncFd(int fd, const std::string& fd_path) {
  398|       |#if HAVE_FULLFSYNC
  399|       |    // On macOS and iOS, fsync() doesn't guarantee durability past power
  400|       |    // failures. fcntl(F_FULLFSYNC) is required for that purpose. Some
  401|       |    // filesystems don't support fcntl(F_FULLFSYNC), and require a fallback to
  402|       |    // fsync().
  403|       |    if (::fcntl(fd, F_FULLFSYNC) == 0) {
  404|       |      return Status::OK();
  405|       |    }
  406|       |#endif  // HAVE_FULLFSYNC
  407|       |
  408|    533|#if HAVE_FDATASYNC
  409|    533|    bool sync_success = ::fdatasync(fd) == 0;
  410|       |#else
  411|       |    bool sync_success = ::fsync(fd) == 0;
  412|       |#endif  // HAVE_FDATASYNC
  413|       |
  414|    533|    if (sync_success) {
  ------------------
  |  Branch (414:9): [True: 533, False: 0]
  ------------------
  415|    533|      return Status::OK();
  416|    533|    }
  417|      0|    return PosixError(fd_path, errno);
  418|    533|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_18PosixEnv10FileExistsERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  599|    100|  bool FileExists(const std::string& filename) override {
  600|       |    return ::access(filename.c_str(), F_OK) == 0;
  601|    100|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_18PosixEnv11GetChildrenERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPNS2_6vectorIS8_NS6_IS8_EEEE:
  604|    224|                     std::vector<std::string>* result) override {
  605|    224|    result->clear();
  606|    224|    ::DIR* dir = ::opendir(directory_path.c_str());
  607|    224|    if (dir == nullptr) {
  ------------------
  |  Branch (607:9): [True: 0, False: 224]
  ------------------
  608|      0|      return PosixError(directory_path, errno);
  609|      0|    }
  610|    224|    struct ::dirent* entry;
  611|  2.29k|    while ((entry = ::readdir(dir)) != nullptr) {
  ------------------
  |  Branch (611:12): [True: 2.06k, False: 224]
  ------------------
  612|  2.06k|      result->emplace_back(entry->d_name);
  613|  2.06k|    }
  614|    224|    ::closedir(dir);
  615|    224|    return Status::OK();
  616|    224|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_18PosixEnv10RemoveFileERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  618|    204|  Status RemoveFile(const std::string& filename) override {
  619|    204|    if (::unlink(filename.c_str()) != 0) {
  ------------------
  |  Branch (619:9): [True: 12, False: 192]
  ------------------
  620|     12|      return PosixError(filename, errno);
  621|     12|    }
  622|    192|    return Status::OK();
  623|    204|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_18PosixEnv9CreateDirERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  625|    200|  Status CreateDir(const std::string& dirname) override {
  626|    200|    if (::mkdir(dirname.c_str(), 0755) != 0) {
  ------------------
  |  Branch (626:9): [True: 153, False: 47]
  ------------------
  627|    153|      return PosixError(dirname, errno);
  628|    153|    }
  629|     47|    return Status::OK();
  630|    200|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_18PosixEnv11GetFileSizeERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPm:
  639|     72|  Status GetFileSize(const std::string& filename, uint64_t* size) override {
  640|     72|    struct ::stat file_stat;
  641|     72|    if (::stat(filename.c_str(), &file_stat) != 0) {
  ------------------
  |  Branch (641:9): [True: 0, False: 72]
  ------------------
  642|      0|      *size = 0;
  643|      0|      return PosixError(filename, errno);
  644|      0|    }
  645|     72|    *size = file_stat.st_size;
  646|     72|    return Status::OK();
  647|     72|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_18PosixEnv10RenameFileERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEESA_:
  649|    247|  Status RenameFile(const std::string& from, const std::string& to) override {
  650|    247|    if (std::rename(from.c_str(), to.c_str()) != 0) {
  ------------------
  |  Branch (650:9): [True: 47, False: 200]
  ------------------
  651|     47|      return PosixError(from, errno);
  652|     47|    }
  653|    200|    return Status::OK();
  654|    247|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_18PosixEnv8LockFileERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPPNS_8FileLockE:
  656|    100|  Status LockFile(const std::string& filename, FileLock** lock) override {
  657|    100|    *lock = nullptr;
  658|       |
  659|    100|    int fd = ::open(filename.c_str(), O_RDWR | O_CREAT | kOpenBaseFlags, 0644);
  660|    100|    if (fd < 0) {
  ------------------
  |  Branch (660:9): [True: 0, False: 100]
  ------------------
  661|      0|      return PosixError(filename, errno);
  662|      0|    }
  663|       |
  664|    100|    if (!locks_.Insert(filename)) {
  ------------------
  |  Branch (664:9): [True: 0, False: 100]
  ------------------
  665|      0|      ::close(fd);
  666|      0|      return Status::IOError("lock " + filename, "already held by process");
  667|      0|    }
  668|       |
  669|    100|    if (LockOrUnlock(fd, true) == -1) {
  ------------------
  |  Branch (669:9): [True: 0, False: 100]
  ------------------
  670|      0|      int lock_errno = errno;
  671|      0|      ::close(fd);
  672|      0|      locks_.Remove(filename);
  673|      0|      return PosixError("lock " + filename, lock_errno);
  674|      0|    }
  675|       |
  676|    100|    *lock = new PosixFileLock(fd, filename);
  677|    100|    return Status::OK();
  678|    100|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_114PosixLockTable6InsertERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  501|    100|  bool Insert(const std::string& fname) LOCKS_EXCLUDED(mu_) {
  502|    100|    mu_.Lock();
  503|    100|    bool succeeded = locked_files_.insert(fname).second;
  504|    100|    mu_.Unlock();
  505|    100|    return succeeded;
  506|    100|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_112LockOrUnlockEib:
  467|    200|int LockOrUnlock(int fd, bool lock) {
  468|    200|  errno = 0;
  469|    200|  struct ::flock file_lock_info;
  470|    200|  std::memset(&file_lock_info, 0, sizeof(file_lock_info));
  471|    200|  file_lock_info.l_type = (lock ? F_WRLCK : F_UNLCK);
  ------------------
  |  Branch (471:28): [True: 100, False: 100]
  ------------------
  472|    200|  file_lock_info.l_whence = SEEK_SET;
  473|    200|  file_lock_info.l_start = 0;
  474|    200|  file_lock_info.l_len = 0;  // Lock/unlock entire file.
  475|       |  return ::fcntl(fd, F_SETLK, &file_lock_info);
  476|    200|}
env_posix.cc:_ZN7leveldb12_GLOBAL__N_114PosixLockTable6RemoveERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  507|    100|  void Remove(const std::string& fname) LOCKS_EXCLUDED(mu_) {
  508|    100|    mu_.Lock();
  509|    100|    locked_files_.erase(fname);
  510|    100|    mu_.Unlock();
  511|    100|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_113PosixFileLockC2EiNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  482|    100|      : fd_(fd), filename_(std::move(filename)) {}
env_posix.cc:_ZN7leveldb12_GLOBAL__N_18PosixEnv10UnlockFileEPNS_8FileLockE:
  680|    100|  Status UnlockFile(FileLock* lock) override {
  681|    100|    PosixFileLock* posix_file_lock = static_cast<PosixFileLock*>(lock);
  682|    100|    if (LockOrUnlock(posix_file_lock->fd(), false) == -1) {
  ------------------
  |  Branch (682:9): [True: 0, False: 100]
  ------------------
  683|      0|      return PosixError("unlock " + posix_file_lock->filename(), errno);
  684|      0|    }
  685|    100|    locks_.Remove(posix_file_lock->filename());
  686|    100|    ::close(posix_file_lock->fd());
  687|    100|    delete posix_file_lock;
  688|    100|    return Status::OK();
  689|    100|  }
env_posix.cc:_ZNK7leveldb12_GLOBAL__N_113PosixFileLock2fdEv:
  484|    200|  int fd() const { return fd_; }
env_posix.cc:_ZNK7leveldb12_GLOBAL__N_113PosixFileLock8filenameEv:
  485|    100|  const std::string& filename() const { return filename_; }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_18PosixEnv8ScheduleEPFvPvES2_:
  816|     45|    void* background_work_arg) {
  817|     45|  background_work_mutex_.Lock();
  818|       |
  819|       |  // Start the background thread, if we haven't done so already.
  820|     45|  if (!started_background_thread_) {
  ------------------
  |  Branch (820:7): [True: 1, False: 44]
  ------------------
  821|      1|    started_background_thread_ = true;
  822|      1|    std::thread background_thread(PosixEnv::BackgroundThreadEntryPoint, this);
  823|      1|    background_thread.detach();
  824|      1|  }
  825|       |
  826|       |  // If the queue is empty, the background thread may be waiting for work.
  827|     45|  if (background_work_queue_.empty()) {
  ------------------
  |  Branch (827:7): [True: 45, False: 0]
  ------------------
  828|     45|    background_work_cv_.Signal();
  829|     45|  }
  830|       |
  831|     45|  background_work_queue_.emplace(background_work_function, background_work_arg);
  832|     45|  background_work_mutex_.Unlock();
  833|     45|}
env_posix.cc:_ZN7leveldb12_GLOBAL__N_18PosixEnv26BackgroundThreadEntryPointEPS1_:
  750|      1|  static void BackgroundThreadEntryPoint(PosixEnv* env) {
  751|      1|    env->BackgroundThreadMain();
  752|      1|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_18PosixEnv20BackgroundThreadMainEv:
  835|      1|void PosixEnv::BackgroundThreadMain() {
  836|     47|  while (true) {
  ------------------
  |  Branch (836:10): [True: 46, Folded]
  ------------------
  837|     46|    background_work_mutex_.Lock();
  838|       |
  839|       |    // Wait until there is work to be done.
  840|     84|    while (background_work_queue_.empty()) {
  ------------------
  |  Branch (840:12): [True: 38, False: 46]
  ------------------
  841|     38|      background_work_cv_.Wait();
  842|     38|    }
  843|       |
  844|     46|    assert(!background_work_queue_.empty());
  845|     46|    auto background_work_function = background_work_queue_.front().function;
  846|     46|    void* background_work_arg = background_work_queue_.front().arg;
  847|     46|    background_work_queue_.pop();
  848|       |
  849|     46|    background_work_mutex_.Unlock();
  850|     46|    background_work_function(background_work_arg);
  851|     46|  }
  852|      1|}
env_posix.cc:_ZN7leveldb12_GLOBAL__N_18PosixEnv18BackgroundWorkItemC2EPFvPvES3_:
  762|     45|        : function(function), arg(arg) {}
env_posix.cc:_ZN7leveldb12_GLOBAL__N_18PosixEnv9NewLoggerERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPPNS_6LoggerE:
  717|    100|  Status NewLogger(const std::string& filename, Logger** result) override {
  718|    100|    int fd = ::open(filename.c_str(),
  719|    100|                    O_APPEND | O_WRONLY | O_CREAT | kOpenBaseFlags, 0644);
  720|    100|    if (fd < 0) {
  ------------------
  |  Branch (720:9): [True: 0, False: 100]
  ------------------
  721|      0|      *result = nullptr;
  722|      0|      return PosixError(filename, errno);
  723|      0|    }
  724|       |
  725|    100|    std::FILE* fp = ::fdopen(fd, "w");
  726|    100|    if (fp == nullptr) {
  ------------------
  |  Branch (726:9): [True: 0, False: 100]
  ------------------
  727|      0|      ::close(fd);
  728|      0|      *result = nullptr;
  729|      0|      return PosixError(filename, errno);
  730|    100|    } else {
  731|    100|      *result = new PosixLogger(fp);
  732|    100|      return Status::OK();
  733|    100|    }
  734|    100|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_18PosixEnv9NowMicrosEv:
  736|    108|  uint64_t NowMicros() override {
  737|    108|    static constexpr uint64_t kUsecondsPerSecond = 1000000;
  738|    108|    struct ::timeval tv;
  739|    108|    ::gettimeofday(&tv, nullptr);
  740|    108|    return static_cast<uint64_t>(tv.tv_sec) * kUsecondsPerSecond + tv.tv_usec;
  741|    108|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_112SingletonEnvINS0_8PosixEnvEE3envEv:
  890|    172|  Env* env() { return reinterpret_cast<Env*>(&env_storage_); }

_ZN7leveldb12FilterPolicyD2Ev:
    9|    100|FilterPolicy::~FilterPolicy() {}

_ZN7leveldb4HashEPKcmj:
   22|    506|uint32_t Hash(const char* data, size_t n, uint32_t seed) {
   23|       |  // Similar to murmur hash
   24|    506|  const uint32_t m = 0xc6a4a793;
   25|    506|  const uint32_t r = 24;
   26|    506|  const char* limit = data + n;
   27|    506|  uint32_t h = seed ^ (n * m);
   28|       |
   29|       |  // Pick up four bytes at a time
   30|  2.12k|  while (limit - data >= 4) {
  ------------------
  |  Branch (30:10): [True: 1.62k, False: 506]
  ------------------
   31|  1.62k|    uint32_t w = DecodeFixed32(data);
   32|  1.62k|    data += 4;
   33|  1.62k|    h += w;
   34|  1.62k|    h *= m;
   35|  1.62k|    h ^= (h >> 16);
   36|  1.62k|  }
   37|       |
   38|       |  // Pick up remaining bytes
   39|    506|  switch (limit - data) {
  ------------------
  |  Branch (39:11): [True: 0, False: 506]
  ------------------
   40|      0|    case 3:
  ------------------
  |  Branch (40:5): [True: 0, False: 506]
  ------------------
   41|      0|      h += static_cast<uint8_t>(data[2]) << 16;
   42|      0|      FALLTHROUGH_INTENDED;
  ------------------
  |  |   16|      0|  do {                       \
  |  |   17|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (17:12): [Folded, False: 0]
  |  |  ------------------
  ------------------
   43|      0|    case 2:
  ------------------
  |  Branch (43:5): [True: 0, False: 506]
  ------------------
   44|      0|      h += static_cast<uint8_t>(data[1]) << 8;
   45|      0|      FALLTHROUGH_INTENDED;
  ------------------
  |  |   16|      0|  do {                       \
  |  |   17|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (17:12): [Folded, False: 0]
  |  |  ------------------
  ------------------
   46|      0|    case 1:
  ------------------
  |  Branch (46:5): [True: 0, False: 506]
  ------------------
   47|      0|      h += static_cast<uint8_t>(data[0]);
   48|      0|      h *= m;
   49|      0|      h ^= (h >> r);
   50|      0|      break;
   51|    506|  }
   52|    506|  return h;
   53|    506|}

_ZN7leveldb21AppendEscapedStringToEPNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEERKNS_5SliceE:
   23|     45|void AppendEscapedStringTo(std::string* str, const Slice& value) {
   24|  4.37M|  for (size_t i = 0; i < value.size(); i++) {
  ------------------
  |  Branch (24:22): [True: 4.37M, False: 45]
  ------------------
   25|  4.37M|    char c = value[i];
   26|  4.37M|    if (c >= ' ' && c <= '~') {
  ------------------
  |  Branch (26:9): [True: 3.29M, False: 1.07M]
  |  Branch (26:21): [True: 3.29M, False: 132]
  ------------------
   27|  3.29M|      str->push_back(c);
   28|  3.29M|    } else {
   29|  1.07M|      char buf[10];
   30|  1.07M|      std::snprintf(buf, sizeof(buf), "\\x%02x",
   31|  1.07M|                    static_cast<unsigned int>(c) & 0xff);
   32|  1.07M|      str->append(buf);
   33|  1.07M|    }
   34|  4.37M|  }
   35|     45|}
_ZN7leveldb12EscapeStringERKNS_5SliceE:
   43|     45|std::string EscapeString(const Slice& value) {
   44|     45|  std::string r;
   45|     45|  AppendEscapedStringTo(&r, value);
   46|     45|  return r;
   47|     45|}
_ZN7leveldb20ConsumeDecimalNumberEPNS_5SliceEPm:
   49|  1.27k|bool ConsumeDecimalNumber(Slice* in, uint64_t* val) {
   50|       |  // Constants that will be optimized away.
   51|  1.27k|  constexpr const uint64_t kMaxUint64 = std::numeric_limits<uint64_t>::max();
   52|  1.27k|  constexpr const char kLastDigitOfMaxUint64 =
   53|  1.27k|      '0' + static_cast<char>(kMaxUint64 % 10);
   54|       |
   55|  1.27k|  uint64_t value = 0;
   56|       |
   57|       |  // reinterpret_cast-ing from char* to uint8_t* to avoid signedness.
   58|  1.27k|  const uint8_t* start = reinterpret_cast<const uint8_t*>(in->data());
   59|       |
   60|  1.27k|  const uint8_t* end = start + in->size();
   61|  1.27k|  const uint8_t* current = start;
   62|  6.20k|  for (; current != end; ++current) {
  ------------------
  |  Branch (62:10): [True: 5.87k, False: 325]
  ------------------
   63|  5.87k|    const uint8_t ch = *current;
   64|  5.87k|    if (ch < '0' || ch > '9') break;
  ------------------
  |  Branch (64:9): [True: 945, False: 4.93k]
  |  Branch (64:21): [True: 0, False: 4.93k]
  ------------------
   65|       |
   66|       |    // Overflow check.
   67|       |    // kMaxUint64 / 10 is also constant and will be optimized away.
   68|  4.93k|    if (value > kMaxUint64 / 10 ||
  ------------------
  |  Branch (68:9): [True: 0, False: 4.93k]
  ------------------
   69|  4.93k|        (value == kMaxUint64 / 10 && ch > kLastDigitOfMaxUint64)) {
  ------------------
  |  Branch (69:10): [True: 0, False: 4.93k]
  |  Branch (69:38): [True: 0, False: 0]
  ------------------
   70|      0|      return false;
   71|      0|    }
   72|       |
   73|  4.93k|    value = (value * 10) + (ch - '0');
   74|  4.93k|  }
   75|       |
   76|  1.27k|  *val = value;
   77|  1.27k|  const size_t digits_consumed = current - start;
   78|  1.27k|  in->remove_prefix(digits_consumed);
   79|  1.27k|  return digits_consumed != 0;
   80|  1.27k|}

_ZN7leveldb9MutexLockC2EPNS_4port5MutexE:
   25|  1.33k|  explicit MutexLock(port::Mutex* mu) EXCLUSIVE_LOCK_FUNCTION(mu) : mu_(mu) {
   26|  1.33k|    this->mu_->Lock();
   27|  1.33k|  }
_ZN7leveldb9MutexLockD2Ev:
   28|  1.33k|  ~MutexLock() UNLOCK_FUNCTION() { this->mu_->Unlock(); }

comparator.cc:_ZN7leveldb12NoDestructorINS_12_GLOBAL__N_122BytewiseComparatorImplEEC2IJEEEDpOT_:
   21|      1|  explicit NoDestructor(ConstructorArgTypes&&... constructor_args) {
   22|      1|    static_assert(sizeof(instance_storage_) >= sizeof(InstanceType),
   23|      1|                  "instance_storage_ is not large enough to hold the instance");
   24|      1|    static_assert(std::is_standard_layout_v<NoDestructor<InstanceType>>);
   25|      1|    static_assert(
   26|      1|        offsetof(NoDestructor, instance_storage_) % alignof(InstanceType) == 0,
   27|      1|        "instance_storage_ does not meet the instance's alignment requirement");
   28|      1|    static_assert(
   29|      1|        alignof(NoDestructor<InstanceType>) % alignof(InstanceType) == 0,
   30|      1|        "instance_storage_ does not meet the instance's alignment requirement");
   31|      1|    new (instance_storage_)
   32|      1|        InstanceType(std::forward<ConstructorArgTypes>(constructor_args)...);
   33|      1|  }
comparator.cc:_ZN7leveldb12NoDestructorINS_12_GLOBAL__N_122BytewiseComparatorImplEE3getEv:
   40|    172|  InstanceType* get() {
   41|    172|    return reinterpret_cast<InstanceType*>(&instance_storage_);
   42|    172|  }

_ZN7leveldb7OptionsC2Ev:
   12|    172|Options::Options() : comparator(BytewiseComparator()), env(Env::Default()) {}

_ZN7leveldb11PosixLoggerC2EP8_IO_FILE:
   29|    100|  explicit PosixLogger(std::FILE* fp) : fp_(fp) { assert(fp != nullptr); }
_ZN7leveldb11PosixLoggerD2Ev:
   31|    100|  ~PosixLogger() override { std::fclose(fp_); }
_ZN7leveldb11PosixLogger4LogvEPKcP13__va_list_tag:
   33|    435|  void Logv(const char* format, std::va_list arguments) override {
   34|       |    // Record the time as close to the Logv() call as possible.
   35|    435|    struct ::timeval now_timeval;
   36|    435|    ::gettimeofday(&now_timeval, nullptr);
   37|    435|    const std::time_t now_seconds = now_timeval.tv_sec;
   38|    435|    struct std::tm now_components;
   39|    435|    ::localtime_r(&now_seconds, &now_components);
   40|       |
   41|       |    // Record the thread ID.
   42|    435|    constexpr const int kMaxThreadIdSize = 32;
   43|    435|    std::ostringstream thread_stream;
   44|    435|    thread_stream << std::this_thread::get_id();
   45|    435|    std::string thread_id = thread_stream.str();
   46|    435|    if (thread_id.size() > kMaxThreadIdSize) {
  ------------------
  |  Branch (46:9): [True: 0, False: 435]
  ------------------
   47|      0|      thread_id.resize(kMaxThreadIdSize);
   48|      0|    }
   49|       |
   50|       |    // We first attempt to print into a stack-allocated buffer. If this attempt
   51|       |    // fails, we make a second attempt with a dynamically allocated buffer.
   52|    435|    constexpr const int kStackBufferSize = 512;
   53|    435|    char stack_buffer[kStackBufferSize];
   54|    435|    static_assert(sizeof(stack_buffer) == static_cast<size_t>(kStackBufferSize),
   55|    435|                  "sizeof(char) is expected to be 1 in C++");
   56|       |
   57|    435|    int dynamic_buffer_size = 0;  // Computed in the first iteration.
   58|    447|    for (int iteration = 0; iteration < 2; ++iteration) {
  ------------------
  |  Branch (58:29): [True: 447, False: 0]
  ------------------
   59|    447|      const int buffer_size =
   60|    447|          (iteration == 0) ? kStackBufferSize : dynamic_buffer_size;
  ------------------
  |  Branch (60:11): [True: 435, False: 12]
  ------------------
   61|    447|      char* const buffer =
   62|    447|          (iteration == 0) ? stack_buffer : new char[dynamic_buffer_size];
  ------------------
  |  Branch (62:11): [True: 435, False: 12]
  ------------------
   63|       |
   64|       |      // Print the header into the buffer.
   65|    447|      int buffer_offset = std::snprintf(
   66|    447|          buffer, buffer_size, "%04d/%02d/%02d-%02d:%02d:%02d.%06d %s ",
   67|    447|          now_components.tm_year + 1900, now_components.tm_mon + 1,
   68|    447|          now_components.tm_mday, now_components.tm_hour, now_components.tm_min,
   69|    447|          now_components.tm_sec, static_cast<int>(now_timeval.tv_usec),
   70|    447|          thread_id.c_str());
   71|       |
   72|       |      // The header can be at most 28 characters (10 date + 15 time +
   73|       |      // 3 delimiters) plus the thread ID, which should fit comfortably into the
   74|       |      // static buffer.
   75|    447|      assert(buffer_offset <= 28 + kMaxThreadIdSize);
   76|    447|      static_assert(28 + kMaxThreadIdSize < kStackBufferSize,
   77|    447|                    "stack-allocated buffer may not fit the message header");
   78|    447|      assert(buffer_offset < buffer_size);
   79|       |
   80|       |      // Print the message into the buffer.
   81|    447|      std::va_list arguments_copy;
   82|    447|      va_copy(arguments_copy, arguments);
   83|    447|      buffer_offset +=
   84|    447|          std::vsnprintf(buffer + buffer_offset, buffer_size - buffer_offset,
   85|    447|                         format, arguments_copy);
   86|    447|      va_end(arguments_copy);
   87|       |
   88|       |      // The code below may append a newline at the end of the buffer, which
   89|       |      // requires an extra character.
   90|    447|      if (buffer_offset >= buffer_size - 1) {
  ------------------
  |  Branch (90:11): [True: 12, False: 435]
  ------------------
   91|       |        // The message did not fit into the buffer.
   92|     12|        if (iteration == 0) {
  ------------------
  |  Branch (92:13): [True: 12, False: 0]
  ------------------
   93|       |          // Re-run the loop and use a dynamically-allocated buffer. The buffer
   94|       |          // will be large enough for the log message, an extra newline and a
   95|       |          // null terminator.
   96|     12|          dynamic_buffer_size = buffer_offset + 2;
   97|     12|          continue;
   98|     12|        }
   99|       |
  100|       |        // The dynamically-allocated buffer was incorrectly sized. This should
  101|       |        // not happen, assuming a correct implementation of std::(v)snprintf.
  102|       |        // Fail in tests, recover by truncating the log message in production.
  103|     12|        assert(false);
  104|      0|        buffer_offset = buffer_size - 1;
  105|      0|      }
  106|       |
  107|       |      // Add a newline if necessary.
  108|    435|      if (buffer[buffer_offset - 1] != '\n') {
  ------------------
  |  Branch (108:11): [True: 221, False: 214]
  ------------------
  109|    221|        buffer[buffer_offset] = '\n';
  110|    221|        ++buffer_offset;
  111|    221|      }
  112|       |
  113|    435|      assert(buffer_offset <= buffer_size);
  114|    435|      std::fwrite(buffer, 1, buffer_offset, fp_);
  115|    435|      std::fflush(fp_);
  116|       |
  117|    435|      if (iteration != 0) {
  ------------------
  |  Branch (117:11): [True: 12, False: 423]
  ------------------
  118|     12|        delete[] buffer;
  119|     12|      }
  120|    435|      break;
  121|    447|    }
  122|    435|  }

_ZN7leveldb6RandomC2Ej:
   20|    182|  explicit Random(uint32_t s) : seed_(s & 0x7fffffffu) {
   21|       |    // Avoid bad seeds.
   22|    182|    if (seed_ == 0 || seed_ == 2147483647L) {
  ------------------
  |  Branch (22:9): [True: 0, False: 182]
  |  Branch (22:23): [True: 0, False: 182]
  ------------------
   23|      0|      seed_ = 1;
   24|      0|    }
   25|    182|  }
_ZN7leveldb6Random4NextEv:
   26|    737|  uint32_t Next() {
   27|    737|    static const uint32_t M = 2147483647L;  // 2^31-1
   28|    737|    static const uint64_t A = 16807;        // bits 14, 8, 7, 5, 2, 1, 0
   29|       |    // We are computing
   30|       |    //       seed_ = (seed_ * A) % M,    where M = 2^31-1
   31|       |    //
   32|       |    // seed_ must not be zero or M, or else all subsequent computed values
   33|       |    // will be zero or M respectively.  For all other values, seed_ will end
   34|       |    // up cycling through every number in [1,M-1]
   35|    737|    uint64_t product = seed_ * A;
   36|       |
   37|       |    // Compute (product % M) using the fact that ((x << 31) % M) == x.
   38|    737|    seed_ = static_cast<uint32_t>((product >> 31) + (product & M));
   39|       |    // The first reduction may overflow by 1 bit, so we may need to
   40|       |    // repeat.  mod == M is not possible; using > allows the faster
   41|       |    // sign-bit-based test.
   42|    737|    if (seed_ > M) {
  ------------------
  |  Branch (42:9): [True: 0, False: 737]
  ------------------
   43|      0|      seed_ -= M;
   44|      0|    }
   45|    737|    return seed_;
   46|    737|  }
_ZN7leveldb6Random7UniformEi:
   49|     42|  uint32_t Uniform(int n) { return Next() % n; }
_ZN7leveldb6Random5OneInEi:
   53|    695|  bool OneIn(int n) { return (Next() % n) == 0; }

_ZN7leveldb6StatusC2ENS0_4CodeERKNS_5SliceES4_:
   21|    234|Status::Status(Code code, const Slice& msg, const Slice& msg2) {
   22|    234|  assert(code != kOk);
   23|    234|  const uint32_t len1 = static_cast<uint32_t>(msg.size());
   24|    234|  const uint32_t len2 = static_cast<uint32_t>(msg2.size());
   25|    234|  const uint32_t size = len1 + (len2 ? (2 + len2) : 0);
  ------------------
  |  Branch (25:33): [True: 212, False: 22]
  ------------------
   26|    234|  char* result = new char[size + 5];
   27|    234|  std::memcpy(result, &size, sizeof(size));
   28|    234|  result[4] = static_cast<char>(code);
   29|    234|  std::memcpy(result + 5, msg.data(), len1);
   30|    234|  if (len2) {
  ------------------
  |  Branch (30:7): [True: 212, False: 22]
  ------------------
   31|    212|    result[5 + len1] = ':';
   32|    212|    result[6 + len1] = ' ';
   33|    212|    std::memcpy(result + 7 + len1, msg2.data(), len2);
   34|    212|  }
   35|    234|  state_ = result;
   36|    234|}
_ZNK7leveldb6Status8ToStringEv:
   38|     49|std::string Status::ToString() const {
   39|     49|  if (state_ == nullptr) {
  ------------------
  |  Branch (39:7): [True: 49, False: 0]
  ------------------
   40|     49|    return "OK";
   41|     49|  } else {
   42|      0|    char tmp[30];
   43|      0|    const char* type;
   44|      0|    switch (code()) {
   45|      0|      case kOk:
  ------------------
  |  Branch (45:7): [True: 0, False: 0]
  ------------------
   46|      0|        type = "OK";
   47|      0|        break;
   48|      0|      case kNotFound:
  ------------------
  |  Branch (48:7): [True: 0, False: 0]
  ------------------
   49|      0|        type = "NotFound: ";
   50|      0|        break;
   51|      0|      case kCorruption:
  ------------------
  |  Branch (51:7): [True: 0, False: 0]
  ------------------
   52|      0|        type = "Corruption: ";
   53|      0|        break;
   54|      0|      case kNotSupported:
  ------------------
  |  Branch (54:7): [True: 0, False: 0]
  ------------------
   55|      0|        type = "Not implemented: ";
   56|      0|        break;
   57|      0|      case kInvalidArgument:
  ------------------
  |  Branch (57:7): [True: 0, False: 0]
  ------------------
   58|      0|        type = "Invalid argument: ";
   59|      0|        break;
   60|      0|      case kIOError:
  ------------------
  |  Branch (60:7): [True: 0, False: 0]
  ------------------
   61|      0|        type = "IO error: ";
   62|      0|        break;
   63|      0|      default:
  ------------------
  |  Branch (63:7): [True: 0, False: 0]
  ------------------
   64|      0|        std::snprintf(tmp, sizeof(tmp),
   65|      0|                      "Unknown code(%d): ", static_cast<int>(code()));
   66|      0|        type = tmp;
   67|      0|        break;
   68|      0|    }
   69|      0|    std::string result(type);
   70|      0|    uint32_t length;
   71|      0|    std::memcpy(&length, state_, sizeof(length));
   72|      0|    result.append(state_ + 5, length);
   73|      0|    return result;
   74|      0|  }
   75|     49|}

