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

_ZN7leveldb15SanitizeOptionsERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEPKNS_21InternalKeyComparatorEPKNS_20InternalFilterPolicyERKNS_7OptionsE:
   97|    108|                        const Options& src) {
   98|    108|  Options result = src;
   99|    108|  result.comparator = icmp;
  100|    108|  result.filter_policy = (src.filter_policy != nullptr) ? ipolicy : nullptr;
  ------------------
  |  Branch (100:26): [True: 0, False: 108]
  ------------------
  101|    108|  ClipToRange(&result.max_open_files, 64 + kNumNonTableCacheFiles, 50000);
  102|    108|  ClipToRange(&result.write_buffer_size, 64 << 10, 1 << 30);
  103|    108|  ClipToRange(&result.max_file_size, 1 << 20, 1 << 30);
  104|    108|  ClipToRange(&result.block_size, 1 << 10, 4 << 20);
  105|    108|  if (result.info_log == nullptr) {
  ------------------
  |  Branch (105:7): [True: 108, False: 0]
  ------------------
  106|       |    // Open a log file in the same directory as the db
  107|    108|    src.env->CreateDir(dbname);  // In case it does not exist
  108|    108|    src.env->RenameFile(InfoLogFileName(dbname), OldInfoLogFileName(dbname));
  109|    108|    Status s = src.env->NewLogger(InfoLogFileName(dbname), &result.info_log);
  110|    108|    if (!s.ok()) {
  ------------------
  |  Branch (110:9): [True: 0, False: 108]
  ------------------
  111|       |      // No place suitable for logging
  112|      0|      result.info_log = nullptr;
  113|      0|    }
  114|    108|  }
  115|    108|  if (result.block_cache == nullptr) {
  ------------------
  |  Branch (115:7): [True: 108, False: 0]
  ------------------
  116|    108|    result.block_cache = NewLRUCache(8 << 20);
  117|    108|  }
  118|    108|  return result;
  119|    108|}
_ZN7leveldb6DBImplC2ERKNS_7OptionsERKNSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEE:
  127|    108|    : env_(raw_options.env),
  128|    108|      internal_comparator_(raw_options.comparator),
  129|    108|      internal_filter_policy_(raw_options.filter_policy),
  130|    108|      options_(SanitizeOptions(dbname, &internal_comparator_,
  131|    108|                               &internal_filter_policy_, raw_options)),
  132|    108|      owns_info_log_(options_.info_log != raw_options.info_log),
  133|    108|      owns_cache_(options_.block_cache != raw_options.block_cache),
  134|    108|      dbname_(dbname),
  135|    108|      table_cache_(new TableCache(dbname_, options_, TableCacheSize(options_))),
  136|    108|      db_lock_(nullptr),
  137|    108|      shutting_down_(false),
  138|    108|      background_work_finished_signal_(&mutex_),
  139|    108|      mem_(nullptr),
  140|    108|      imm_(nullptr),
  141|    108|      has_imm_(false),
  142|    108|      logfile_(nullptr),
  143|    108|      logfile_number_(0),
  144|    108|      log_(nullptr),
  145|    108|      seed_(0),
  146|    108|      tmp_batch_(new WriteBatch),
  147|    108|      background_compaction_scheduled_(false),
  148|    108|      manual_compaction_(nullptr),
  149|    108|      versions_(new VersionSet(dbname_, &options_, table_cache_,
  150|    108|                               &internal_comparator_)) {}
_ZN7leveldb6DBImplD2Ev:
  152|    108|DBImpl::~DBImpl() {
  153|       |  // Wait for background work to finish.
  154|    108|  mutex_.Lock();
  155|    108|  shutting_down_.store(true, std::memory_order_release);
  156|    110|  while (background_compaction_scheduled_) {
  ------------------
  |  Branch (156:10): [True: 2, False: 108]
  ------------------
  157|      2|    background_work_finished_signal_.Wait();
  158|      2|  }
  159|    108|  mutex_.Unlock();
  160|       |
  161|    108|  if (db_lock_ != nullptr) {
  ------------------
  |  Branch (161:7): [True: 108, False: 0]
  ------------------
  162|    108|    env_->UnlockFile(db_lock_);
  163|    108|  }
  164|       |
  165|    108|  delete versions_;
  166|    108|  if (mem_ != nullptr) mem_->Unref();
  ------------------
  |  Branch (166:7): [True: 108, False: 0]
  ------------------
  167|    108|  if (imm_ != nullptr) imm_->Unref();
  ------------------
  |  Branch (167:7): [True: 0, False: 108]
  ------------------
  168|    108|  delete tmp_batch_;
  169|    108|  delete log_;
  170|    108|  delete logfile_;
  171|    108|  delete table_cache_;
  172|       |
  173|    108|  if (owns_info_log_) {
  ------------------
  |  Branch (173:7): [True: 108, False: 0]
  ------------------
  174|    108|    delete options_.info_log;
  175|    108|  }
  176|    108|  if (owns_cache_) {
  ------------------
  |  Branch (176:7): [True: 108, False: 0]
  ------------------
  177|    108|    delete options_.block_cache;
  178|    108|  }
  179|    108|}
_ZN7leveldb6DBImpl5NewDBEv:
  181|     49|Status DBImpl::NewDB() {
  182|     49|  VersionEdit new_db;
  183|     49|  new_db.SetComparatorName(user_comparator()->Name());
  184|     49|  new_db.SetLogNumber(0);
  185|     49|  new_db.SetNextFile(2);
  186|     49|  new_db.SetLastSequence(0);
  187|       |
  188|     49|  const std::string manifest = DescriptorFileName(dbname_, 1);
  189|     49|  WritableFile* file;
  190|     49|  Status s = env_->NewWritableFile(manifest, &file);
  191|     49|  if (!s.ok()) {
  ------------------
  |  Branch (191:7): [True: 0, False: 49]
  ------------------
  192|      0|    return s;
  193|      0|  }
  194|     49|  {
  195|     49|    log::Writer log(file);
  196|     49|    std::string record;
  197|     49|    new_db.EncodeTo(&record);
  198|     49|    s = log.AddRecord(record);
  199|     49|    if (s.ok()) {
  ------------------
  |  Branch (199:9): [True: 49, False: 0]
  ------------------
  200|     49|      s = file->Sync();
  201|     49|    }
  202|     49|    if (s.ok()) {
  ------------------
  |  Branch (202:9): [True: 49, False: 0]
  ------------------
  203|     49|      s = file->Close();
  204|     49|    }
  205|     49|  }
  206|     49|  delete file;
  207|     49|  if (s.ok()) {
  ------------------
  |  Branch (207:7): [True: 49, False: 0]
  ------------------
  208|       |    // Make "CURRENT" file that points to the new manifest file.
  209|     49|    s = SetCurrentFile(env_, dbname_, 1);
  210|     49|  } else {
  211|      0|    env_->RemoveFile(manifest);
  212|      0|  }
  213|     49|  return s;
  214|     49|}
_ZNK7leveldb6DBImpl16MaybeIgnoreErrorEPNS_6StatusE:
  216|    146|void DBImpl::MaybeIgnoreError(Status* s) const {
  217|    146|  if (s->ok() || options_.paranoid_checks) {
  ------------------
  |  Branch (217:7): [True: 146, False: 0]
  |  Branch (217:18): [True: 0, False: 0]
  ------------------
  218|       |    // No change needed
  219|    146|  } else {
  220|      0|    Log(options_.info_log, "Ignoring error %s", s->ToString().c_str());
  221|      0|    *s = Status::OK();
  222|      0|  }
  223|    146|}
_ZN7leveldb6DBImpl19RemoveObsoleteFilesEv:
  225|    136|void DBImpl::RemoveObsoleteFiles() {
  226|    136|  mutex_.AssertHeld();
  227|       |
  228|    136|  if (!bg_error_.ok()) {
  ------------------
  |  Branch (228:7): [True: 0, False: 136]
  ------------------
  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|    136|  std::set<uint64_t> live = pending_outputs_;
  236|    136|  versions_->AddLiveFiles(&live);
  237|       |
  238|    136|  std::vector<std::string> filenames;
  239|    136|  env_->GetChildren(dbname_, &filenames);  // Ignoring errors on purpose
  240|    136|  uint64_t number;
  241|    136|  FileType type;
  242|    136|  std::vector<std::string> files_to_delete;
  243|  1.42k|  for (std::string& filename : filenames) {
  ------------------
  |  Branch (243:30): [True: 1.42k, False: 136]
  ------------------
  244|  1.42k|    if (ParseFileName(filename, &number, &type)) {
  ------------------
  |  Branch (244:9): [True: 1.15k, False: 272]
  ------------------
  245|  1.15k|      bool keep = true;
  246|  1.15k|      switch (type) {
  ------------------
  |  Branch (246:15): [True: 1.15k, False: 0]
  ------------------
  247|    216|        case kLogFile:
  ------------------
  |  Branch (247:9): [True: 216, False: 938]
  ------------------
  248|    216|          keep = ((number >= versions_->LogNumber()) ||
  ------------------
  |  Branch (248:19): [True: 136, False: 80]
  ------------------
  249|     80|                  (number == versions_->PrevLogNumber()));
  ------------------
  |  Branch (249:19): [True: 0, False: 80]
  ------------------
  250|    216|          break;
  251|    244|        case kDescriptorFile:
  ------------------
  |  Branch (251:9): [True: 244, False: 910]
  ------------------
  252|       |          // Keep my manifest file, and any newer incarnations'
  253|       |          // (in case there is a race that allows other incarnations)
  254|    244|          keep = (number >= versions_->ManifestFileNumber());
  255|    244|          break;
  256|    204|        case kTableFile:
  ------------------
  |  Branch (256:9): [True: 204, False: 950]
  ------------------
  257|    204|          keep = (live.find(number) != live.end());
  258|    204|          break;
  259|      0|        case kTempFile:
  ------------------
  |  Branch (259:9): [True: 0, False: 1.15k]
  ------------------
  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|    136|        case kCurrentFile:
  ------------------
  |  Branch (264:9): [True: 136, False: 1.01k]
  ------------------
  265|    272|        case kDBLockFile:
  ------------------
  |  Branch (265:9): [True: 136, False: 1.01k]
  ------------------
  266|    490|        case kInfoLogFile:
  ------------------
  |  Branch (266:9): [True: 218, False: 936]
  ------------------
  267|    490|          keep = true;
  268|    490|          break;
  269|  1.15k|      }
  270|       |
  271|  1.15k|      if (!keep) {
  ------------------
  |  Branch (271:11): [True: 216, False: 938]
  ------------------
  272|    216|        files_to_delete.push_back(std::move(filename));
  273|    216|        if (type == kTableFile) {
  ------------------
  |  Branch (273:13): [True: 28, False: 188]
  ------------------
  274|     28|          table_cache_->Evict(number);
  275|     28|        }
  276|    216|        Log(options_.info_log, "Delete type=%d #%lld\n", static_cast<int>(type),
  277|    216|            static_cast<unsigned long long>(number));
  278|    216|      }
  279|  1.15k|    }
  280|  1.42k|  }
  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|    136|  mutex_.Unlock();
  286|    216|  for (const std::string& filename : files_to_delete) {
  ------------------
  |  Branch (286:36): [True: 216, False: 136]
  ------------------
  287|    216|    env_->RemoveFile(dbname_ + "/" + filename);
  288|    216|  }
  289|    136|  mutex_.Lock();
  290|    136|}
_ZN7leveldb6DBImpl7RecoverEPNS_11VersionEditEPb:
  292|    108|Status DBImpl::Recover(VersionEdit* edit, bool* save_manifest) {
  293|    108|  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|    108|  env_->CreateDir(dbname_);
  299|    108|  assert(db_lock_ == nullptr);
  300|    108|  Status s = env_->LockFile(LockFileName(dbname_), &db_lock_);
  301|    108|  if (!s.ok()) {
  ------------------
  |  Branch (301:7): [True: 0, False: 108]
  ------------------
  302|      0|    return s;
  303|      0|  }
  304|       |
  305|    108|  if (!env_->FileExists(CurrentFileName(dbname_))) {
  ------------------
  |  Branch (305:7): [True: 49, False: 59]
  ------------------
  306|     49|    if (options_.create_if_missing) {
  ------------------
  |  Branch (306:9): [True: 49, False: 0]
  ------------------
  307|     49|      Log(options_.info_log, "Creating DB %s since it was missing.",
  308|     49|          dbname_.c_str());
  309|     49|      s = NewDB();
  310|     49|      if (!s.ok()) {
  ------------------
  |  Branch (310:11): [True: 0, False: 49]
  ------------------
  311|      0|        return s;
  312|      0|      }
  313|     49|    } else {
  314|      0|      return Status::InvalidArgument(
  315|      0|          dbname_, "does not exist (create_if_missing is false)");
  316|      0|    }
  317|     59|  } else {
  318|     59|    if (options_.error_if_exists) {
  ------------------
  |  Branch (318:9): [True: 0, False: 59]
  ------------------
  319|      0|      return Status::InvalidArgument(dbname_,
  320|      0|                                     "exists (error_if_exists is true)");
  321|      0|    }
  322|     59|  }
  323|       |
  324|    108|  s = versions_->Recover(save_manifest);
  325|    108|  if (!s.ok()) {
  ------------------
  |  Branch (325:7): [True: 0, False: 108]
  ------------------
  326|      0|    return s;
  327|      0|  }
  328|    108|  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|    108|  const uint64_t min_log = versions_->LogNumber();
  338|    108|  const uint64_t prev_log = versions_->PrevLogNumber();
  339|    108|  std::vector<std::string> filenames;
  340|    108|  s = env_->GetChildren(dbname_, &filenames);
  341|    108|  if (!s.ok()) {
  ------------------
  |  Branch (341:7): [True: 0, False: 108]
  ------------------
  342|      0|    return s;
  343|      0|  }
  344|    108|  std::set<uint64_t> expected;
  345|    108|  versions_->AddLiveFiles(&expected);
  346|    108|  uint64_t number;
  347|    108|  FileType type;
  348|    108|  std::vector<uint64_t> logs;
  349|    959|  for (size_t i = 0; i < filenames.size(); i++) {
  ------------------
  |  Branch (349:22): [True: 851, False: 108]
  ------------------
  350|    851|    if (ParseFileName(filenames[i], &number, &type)) {
  ------------------
  |  Branch (350:9): [True: 635, False: 216]
  ------------------
  351|    635|      expected.erase(number);
  352|    635|      if (type == kLogFile && ((number >= min_log) || (number == prev_log)))
  ------------------
  |  Branch (352:11): [True: 60, False: 575]
  |  Branch (352:32): [True: 60, False: 0]
  |  Branch (352:55): [True: 0, False: 0]
  ------------------
  353|     60|        logs.push_back(number);
  354|    635|    }
  355|    851|  }
  356|    108|  if (!expected.empty()) {
  ------------------
  |  Branch (356:7): [True: 0, False: 108]
  ------------------
  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|    108|  std::sort(logs.begin(), logs.end());
  365|    168|  for (size_t i = 0; i < logs.size(); i++) {
  ------------------
  |  Branch (365:22): [True: 60, False: 108]
  ------------------
  366|     60|    s = RecoverLogFile(logs[i], (i == logs.size() - 1), save_manifest, edit,
  367|     60|                       &max_sequence);
  368|     60|    if (!s.ok()) {
  ------------------
  |  Branch (368:9): [True: 0, False: 60]
  ------------------
  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|     60|    versions_->MarkFileNumberUsed(logs[i]);
  376|     60|  }
  377|       |
  378|    108|  if (versions_->LastSequence() < max_sequence) {
  ------------------
  |  Branch (378:7): [True: 36, False: 72]
  ------------------
  379|     36|    versions_->SetLastSequence(max_sequence);
  380|     36|  }
  381|       |
  382|    108|  return Status::OK();
  383|    108|}
_ZN7leveldb6DBImpl14RecoverLogFileEmbPbPNS_11VersionEditEPm:
  387|     60|                              SequenceNumber* max_sequence) {
  388|     60|  struct LogReporter : public log::Reader::Reporter {
  389|     60|    Env* env;
  390|     60|    Logger* info_log;
  391|     60|    const char* fname;
  392|     60|    Status* status;  // null if options_.paranoid_checks==false
  393|     60|    void Corruption(size_t bytes, const Status& s) override {
  394|     60|      Log(info_log, "%s%s: dropping %d bytes; %s",
  395|     60|          (this->status == nullptr ? "(ignoring error) " : ""), fname,
  396|     60|          static_cast<int>(bytes), s.ToString().c_str());
  397|     60|      if (this->status != nullptr && this->status->ok()) *this->status = s;
  398|     60|    }
  399|     60|  };
  400|       |
  401|     60|  mutex_.AssertHeld();
  402|       |
  403|       |  // Open the log file
  404|     60|  std::string fname = LogFileName(dbname_, log_number);
  405|     60|  SequentialFile* file;
  406|     60|  Status status = env_->NewSequentialFile(fname, &file);
  407|     60|  if (!status.ok()) {
  ------------------
  |  Branch (407:7): [True: 0, False: 60]
  ------------------
  408|      0|    MaybeIgnoreError(&status);
  409|      0|    return status;
  410|      0|  }
  411|       |
  412|       |  // Create the log reader.
  413|     60|  LogReporter reporter;
  414|     60|  reporter.env = env_;
  415|     60|  reporter.info_log = options_.info_log;
  416|     60|  reporter.fname = fname.c_str();
  417|     60|  reporter.status = (options_.paranoid_checks ? &status : nullptr);
  ------------------
  |  Branch (417:22): [True: 0, False: 60]
  ------------------
  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|     60|  log::Reader reader(file, &reporter, true /*checksum*/, 0 /*initial_offset*/);
  423|     60|  Log(options_.info_log, "Recovering log #%llu",
  424|     60|      (unsigned long long)log_number);
  425|       |
  426|       |  // Read all the records and add to a memtable
  427|     60|  std::string scratch;
  428|     60|  Slice record;
  429|     60|  WriteBatch batch;
  430|     60|  int compactions = 0;
  431|     60|  MemTable* mem = nullptr;
  432|    206|  while (reader.ReadRecord(&record, &scratch) && status.ok()) {
  ------------------
  |  Branch (432:10): [True: 146, False: 60]
  |  Branch (432:50): [True: 146, False: 0]
  ------------------
  433|    146|    if (record.size() < 12) {
  ------------------
  |  Branch (433:9): [True: 0, False: 146]
  ------------------
  434|      0|      reporter.Corruption(record.size(),
  435|      0|                          Status::Corruption("log record too small"));
  436|      0|      continue;
  437|      0|    }
  438|    146|    WriteBatchInternal::SetContents(&batch, record);
  439|       |
  440|    146|    if (mem == nullptr) {
  ------------------
  |  Branch (440:9): [True: 36, False: 110]
  ------------------
  441|     36|      mem = new MemTable(internal_comparator_);
  442|     36|      mem->Ref();
  443|     36|    }
  444|    146|    status = WriteBatchInternal::InsertInto(&batch, mem);
  445|    146|    MaybeIgnoreError(&status);
  446|    146|    if (!status.ok()) {
  ------------------
  |  Branch (446:9): [True: 0, False: 146]
  ------------------
  447|      0|      break;
  448|      0|    }
  449|    146|    const SequenceNumber last_seq = WriteBatchInternal::Sequence(&batch) +
  450|    146|                                    WriteBatchInternal::Count(&batch) - 1;
  451|    146|    if (last_seq > *max_sequence) {
  ------------------
  |  Branch (451:9): [True: 146, False: 0]
  ------------------
  452|    146|      *max_sequence = last_seq;
  453|    146|    }
  454|       |
  455|    146|    if (mem->ApproximateMemoryUsage() > options_.write_buffer_size) {
  ------------------
  |  Branch (455:9): [True: 0, False: 146]
  ------------------
  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|    146|  }
  468|       |
  469|     60|  delete file;
  470|       |
  471|       |  // See if we should keep reusing the last log file.
  472|     60|  if (status.ok() && options_.reuse_logs && last_log && compactions == 0) {
  ------------------
  |  Branch (472:7): [True: 60, False: 0]
  |  Branch (472:22): [True: 0, False: 60]
  |  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|     60|  if (mem != nullptr) {
  ------------------
  |  Branch (493:7): [True: 36, False: 24]
  ------------------
  494|       |    // mem did not get reused; compact it.
  495|     36|    if (status.ok()) {
  ------------------
  |  Branch (495:9): [True: 36, False: 0]
  ------------------
  496|     36|      *save_manifest = true;
  497|     36|      status = WriteLevel0Table(mem, edit, nullptr);
  498|     36|    }
  499|     36|    mem->Unref();
  500|     36|  }
  501|       |
  502|     60|  return status;
  503|     60|}
_ZN7leveldb6DBImpl16WriteLevel0TableEPNS_8MemTableEPNS_11VersionEditEPNS_7VersionE:
  506|     56|                                Version* base) {
  507|     56|  mutex_.AssertHeld();
  508|     56|  const uint64_t start_micros = env_->NowMicros();
  509|     56|  FileMetaData meta;
  510|     56|  meta.number = versions_->NewFileNumber();
  511|     56|  pending_outputs_.insert(meta.number);
  512|     56|  Iterator* iter = mem->NewIterator();
  513|     56|  Log(options_.info_log, "Level-0 table #%llu: started",
  514|     56|      (unsigned long long)meta.number);
  515|       |
  516|     56|  Status s;
  517|     56|  {
  518|     56|    mutex_.Unlock();
  519|     56|    s = BuildTable(dbname_, env_, options_, table_cache_, iter, &meta);
  520|     56|    mutex_.Lock();
  521|     56|  }
  522|       |
  523|     56|  Log(options_.info_log, "Level-0 table #%llu: %lld bytes %s",
  524|     56|      (unsigned long long)meta.number, (unsigned long long)meta.file_size,
  525|     56|      s.ToString().c_str());
  526|     56|  delete iter;
  527|     56|  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|     56|  int level = 0;
  532|     56|  if (s.ok() && meta.file_size > 0) {
  ------------------
  |  Branch (532:7): [True: 56, False: 0]
  |  Branch (532:17): [True: 44, False: 12]
  ------------------
  533|     44|    const Slice min_user_key = meta.smallest.user_key();
  534|     44|    const Slice max_user_key = meta.largest.user_key();
  535|     44|    if (base != nullptr) {
  ------------------
  |  Branch (535:9): [True: 8, False: 36]
  ------------------
  536|      8|      level = base->PickLevelForMemTableOutput(min_user_key, max_user_key);
  537|      8|    }
  538|     44|    edit->AddFile(level, meta.number, meta.file_size, meta.smallest,
  539|     44|                  meta.largest);
  540|     44|  }
  541|       |
  542|     56|  CompactionStats stats;
  543|     56|  stats.micros = env_->NowMicros() - start_micros;
  544|     56|  stats.bytes_written = meta.file_size;
  545|     56|  stats_[level].Add(stats);
  546|     56|  return s;
  547|     56|}
_ZN7leveldb6DBImpl15CompactMemTableEv:
  549|     20|void DBImpl::CompactMemTable() {
  550|     20|  mutex_.AssertHeld();
  551|     20|  assert(imm_ != nullptr);
  552|       |
  553|       |  // Save the contents of the memtable as a new Table
  554|     20|  VersionEdit edit;
  555|     20|  Version* base = versions_->current();
  556|     20|  base->Ref();
  557|     20|  Status s = WriteLevel0Table(imm_, &edit, base);
  558|     20|  base->Unref();
  559|       |
  560|     20|  if (s.ok() && shutting_down_.load(std::memory_order_acquire)) {
  ------------------
  |  Branch (560:7): [True: 20, False: 0]
  |  Branch (560:17): [True: 0, False: 20]
  ------------------
  561|      0|    s = Status::IOError("Deleting DB during memtable compaction");
  562|      0|  }
  563|       |
  564|       |  // Replace immutable memtable with the generated Table
  565|     20|  if (s.ok()) {
  ------------------
  |  Branch (565:7): [True: 20, False: 0]
  ------------------
  566|     20|    edit.SetPrevLogNumber(0);
  567|     20|    edit.SetLogNumber(logfile_number_);  // Earlier logs no longer needed
  568|     20|    s = versions_->LogAndApply(&edit, &mutex_);
  569|     20|  }
  570|       |
  571|     20|  if (s.ok()) {
  ------------------
  |  Branch (571:7): [True: 20, False: 0]
  ------------------
  572|       |    // Commit to the new state
  573|     20|    imm_->Unref();
  574|     20|    imm_ = nullptr;
  575|     20|    has_imm_.store(false, std::memory_order_release);
  576|     20|    RemoveObsoleteFiles();
  577|     20|  } else {
  578|      0|    RecordBackgroundError(s);
  579|      0|  }
  580|     20|}
_ZN7leveldb6DBImpl12CompactRangeEPKNS_5SliceES3_:
  582|     20|void DBImpl::CompactRange(const Slice* begin, const Slice* end) {
  583|     20|  int max_level_with_files = 1;
  584|     20|  {
  585|     20|    MutexLock l(&mutex_);
  586|     20|    Version* base = versions_->current();
  587|    140|    for (int level = 1; level < config::kNumLevels; level++) {
  ------------------
  |  Branch (587:25): [True: 120, False: 20]
  ------------------
  588|    120|      if (base->OverlapInLevel(level, begin, end)) {
  ------------------
  |  Branch (588:11): [True: 3, False: 117]
  ------------------
  589|      3|        max_level_with_files = level;
  590|      3|      }
  591|    120|    }
  592|     20|  }
  593|     20|  TEST_CompactMemTable();  // TODO(sanjay): Skip if memtable does not overlap
  594|     40|  for (int level = 0; level < max_level_with_files; level++) {
  ------------------
  |  Branch (594:23): [True: 20, False: 20]
  ------------------
  595|     20|    TEST_CompactRange(level, begin, end);
  596|     20|  }
  597|     20|}
_ZN7leveldb6DBImpl17TEST_CompactRangeEiPKNS_5SliceES3_:
  600|     20|                               const Slice* end) {
  601|     20|  assert(level >= 0);
  602|     20|  assert(level + 1 < config::kNumLevels);
  603|       |
  604|     20|  InternalKey begin_storage, end_storage;
  605|       |
  606|     20|  ManualCompaction manual;
  607|     20|  manual.level = level;
  608|     20|  manual.done = false;
  609|     20|  if (begin == nullptr) {
  ------------------
  |  Branch (609:7): [True: 0, False: 20]
  ------------------
  610|      0|    manual.begin = nullptr;
  611|     20|  } else {
  612|     20|    begin_storage = InternalKey(*begin, kMaxSequenceNumber, kValueTypeForSeek);
  613|     20|    manual.begin = &begin_storage;
  614|     20|  }
  615|     20|  if (end == nullptr) {
  ------------------
  |  Branch (615:7): [True: 0, False: 20]
  ------------------
  616|      0|    manual.end = nullptr;
  617|     20|  } else {
  618|     20|    end_storage = InternalKey(*end, 0, static_cast<ValueType>(0));
  619|     20|    manual.end = &end_storage;
  620|     20|  }
  621|       |
  622|     20|  MutexLock l(&mutex_);
  623|     68|  while (!manual.done && !shutting_down_.load(std::memory_order_acquire) &&
  ------------------
  |  Branch (623:10): [True: 48, False: 20]
  |  Branch (623:26): [True: 48, False: 0]
  ------------------
  624|     48|         bg_error_.ok()) {
  ------------------
  |  Branch (624:10): [True: 48, False: 0]
  ------------------
  625|     48|    if (manual_compaction_ == nullptr) {  // Idle
  ------------------
  |  Branch (625:9): [True: 24, False: 24]
  ------------------
  626|     24|      manual_compaction_ = &manual;
  627|     24|      MaybeScheduleCompaction();
  628|     24|    } else {  // Running either my compaction or another compaction.
  629|     24|      background_work_finished_signal_.Wait();
  630|     24|    }
  631|     48|  }
  632|       |  // Finish current background compaction in the case where
  633|       |  // `background_work_finished_signal_` was signalled due to an error.
  634|     20|  while (background_compaction_scheduled_) {
  ------------------
  |  Branch (634:10): [True: 0, False: 20]
  ------------------
  635|      0|    background_work_finished_signal_.Wait();
  636|      0|  }
  637|     20|  if (manual_compaction_ == &manual) {
  ------------------
  |  Branch (637:7): [True: 0, False: 20]
  ------------------
  638|       |    // Cancel my manual compaction since we aborted early for some reason.
  639|      0|    manual_compaction_ = nullptr;
  640|      0|  }
  641|     20|}
_ZN7leveldb6DBImpl20TEST_CompactMemTableEv:
  643|     20|Status DBImpl::TEST_CompactMemTable() {
  644|       |  // nullptr batch means just wait for earlier writes to be done
  645|     20|  Status s = Write(WriteOptions(), nullptr);
  646|     20|  if (s.ok()) {
  ------------------
  |  Branch (646:7): [True: 20, False: 0]
  ------------------
  647|       |    // Wait until the compaction completes
  648|     20|    MutexLock l(&mutex_);
  649|     40|    while (imm_ != nullptr && bg_error_.ok() &&
  ------------------
  |  Branch (649:12): [True: 20, False: 20]
  |  Branch (649:31): [True: 20, False: 0]
  ------------------
  650|     20|           !shutting_down_.load(std::memory_order_acquire)) {
  ------------------
  |  Branch (650:12): [True: 20, False: 0]
  ------------------
  651|     20|      background_work_finished_signal_.Wait();
  652|     20|    }
  653|     20|    if (imm_ != nullptr) {
  ------------------
  |  Branch (653:9): [True: 0, False: 20]
  ------------------
  654|      0|      s = bg_error_;
  655|      0|    }
  656|     20|  }
  657|     20|  return s;
  658|     20|}
_ZN7leveldb6DBImpl23MaybeScheduleCompactionEv:
  668|    202|void DBImpl::MaybeScheduleCompaction() {
  669|    202|  mutex_.AssertHeld();
  670|    202|  if (background_compaction_scheduled_) {
  ------------------
  |  Branch (670:7): [True: 5, False: 197]
  ------------------
  671|       |    // Already scheduled
  672|    197|  } else if (shutting_down_.load(std::memory_order_acquire)) {
  ------------------
  |  Branch (672:14): [True: 2, False: 195]
  ------------------
  673|       |    // DB is being deleted; no more background compactions
  674|    195|  } else if (!bg_error_.ok()) {
  ------------------
  |  Branch (674:14): [True: 0, False: 195]
  ------------------
  675|       |    // Already got an error; no more changes
  676|    195|  } else if (imm_ == nullptr && manual_compaction_ == nullptr &&
  ------------------
  |  Branch (676:14): [True: 176, False: 19]
  |  Branch (676:33): [True: 152, False: 24]
  ------------------
  677|    152|             !versions_->NeedsCompaction()) {
  ------------------
  |  Branch (677:14): [True: 145, False: 7]
  ------------------
  678|       |    // No work to be done
  679|    145|  } else {
  680|     50|    background_compaction_scheduled_ = true;
  681|     50|    env_->Schedule(&DBImpl::BGWork, this);
  682|     50|  }
  683|    202|}
_ZN7leveldb6DBImpl6BGWorkEPv:
  685|     50|void DBImpl::BGWork(void* db) {
  686|     50|  reinterpret_cast<DBImpl*>(db)->BackgroundCall();
  687|     50|}
_ZN7leveldb6DBImpl14BackgroundCallEv:
  689|     50|void DBImpl::BackgroundCall() {
  690|     50|  MutexLock l(&mutex_);
  691|     50|  assert(background_compaction_scheduled_);
  692|     50|  if (shutting_down_.load(std::memory_order_acquire)) {
  ------------------
  |  Branch (692:7): [True: 1, False: 49]
  ------------------
  693|       |    // No more background work when shutting down.
  694|     49|  } else if (!bg_error_.ok()) {
  ------------------
  |  Branch (694:14): [True: 0, False: 49]
  ------------------
  695|       |    // No more background work after a background error.
  696|     49|  } else {
  697|     49|    BackgroundCompaction();
  698|     49|  }
  699|       |
  700|     50|  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|     50|  MaybeScheduleCompaction();
  705|     50|  background_work_finished_signal_.SignalAll();
  706|     50|}
_ZN7leveldb6DBImpl20BackgroundCompactionEv:
  708|     49|void DBImpl::BackgroundCompaction() {
  709|     49|  mutex_.AssertHeld();
  710|       |
  711|     49|  if (imm_ != nullptr) {
  ------------------
  |  Branch (711:7): [True: 20, False: 29]
  ------------------
  712|     20|    CompactMemTable();
  713|     20|    return;
  714|     20|  }
  715|       |
  716|     29|  Compaction* c;
  717|     29|  bool is_manual = (manual_compaction_ != nullptr);
  718|     29|  InternalKey manual_end;
  719|     29|  if (is_manual) {
  ------------------
  |  Branch (719:7): [True: 24, False: 5]
  ------------------
  720|     24|    ManualCompaction* m = manual_compaction_;
  721|     24|    c = versions_->CompactRange(m->level, m->begin, m->end);
  722|     24|    m->done = (c == nullptr);
  723|     24|    if (c != nullptr) {
  ------------------
  |  Branch (723:9): [True: 4, False: 20]
  ------------------
  724|      4|      manual_end = c->input(0, c->num_input_files(0) - 1)->largest;
  725|      4|    }
  726|     24|    Log(options_.info_log,
  727|     24|        "Manual compaction at level-%d from %s .. %s; will stop at %s\n",
  728|     24|        m->level, (m->begin ? m->begin->DebugString().c_str() : "(begin)"),
  ------------------
  |  Branch (728:20): [True: 24, False: 0]
  ------------------
  729|     24|        (m->end ? m->end->DebugString().c_str() : "(end)"),
  ------------------
  |  Branch (729:10): [True: 24, False: 0]
  ------------------
  730|     24|        (m->done ? "(end)" : manual_end.DebugString().c_str()));
  ------------------
  |  Branch (730:10): [True: 20, False: 4]
  ------------------
  731|     24|  } else {
  732|      5|    c = versions_->PickCompaction();
  733|      5|  }
  734|       |
  735|     29|  Status status;
  736|     29|  if (c == nullptr) {
  ------------------
  |  Branch (736:7): [True: 20, False: 9]
  ------------------
  737|       |    // Nothing to do
  738|     20|  } else if (!is_manual && c->IsTrivialMove()) {
  ------------------
  |  Branch (738:14): [True: 5, False: 4]
  |  Branch (738:28): [True: 1, False: 4]
  ------------------
  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|      8|  } else {
  755|      8|    CompactionState* compact = new CompactionState(c);
  756|      8|    status = DoCompactionWork(compact);
  757|      8|    if (!status.ok()) {
  ------------------
  |  Branch (757:9): [True: 0, False: 8]
  ------------------
  758|      0|      RecordBackgroundError(status);
  759|      0|    }
  760|      8|    CleanupCompaction(compact);
  761|      8|    c->ReleaseInputs();
  762|      8|    RemoveObsoleteFiles();
  763|      8|  }
  764|     29|  delete c;
  765|       |
  766|     29|  if (status.ok()) {
  ------------------
  |  Branch (766:7): [True: 29, False: 0]
  ------------------
  767|       |    // Done
  768|     29|  } 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|     29|  if (is_manual) {
  ------------------
  |  Branch (774:7): [True: 24, False: 5]
  ------------------
  775|     24|    ManualCompaction* m = manual_compaction_;
  776|     24|    if (!status.ok()) {
  ------------------
  |  Branch (776:9): [True: 0, False: 24]
  ------------------
  777|      0|      m->done = true;
  778|      0|    }
  779|     24|    if (!m->done) {
  ------------------
  |  Branch (779:9): [True: 4, False: 20]
  ------------------
  780|       |      // We only compacted part of the requested range.  Update *m
  781|       |      // to the range that is left to be compacted.
  782|      4|      m->tmp_storage = manual_end;
  783|      4|      m->begin = &m->tmp_storage;
  784|      4|    }
  785|     24|    manual_compaction_ = nullptr;
  786|     24|  }
  787|     29|}
_ZN7leveldb6DBImpl17CleanupCompactionEPNS0_15CompactionStateE:
  789|      8|void DBImpl::CleanupCompaction(CompactionState* compact) {
  790|      8|  mutex_.AssertHeld();
  791|      8|  if (compact->builder != nullptr) {
  ------------------
  |  Branch (791:7): [True: 0, False: 8]
  ------------------
  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|      8|  } else {
  796|      8|    assert(compact->outfile == nullptr);
  797|      8|  }
  798|      8|  delete compact->outfile;
  799|     16|  for (size_t i = 0; i < compact->outputs.size(); i++) {
  ------------------
  |  Branch (799:22): [True: 8, False: 8]
  ------------------
  800|      8|    const CompactionState::Output& out = compact->outputs[i];
  801|      8|    pending_outputs_.erase(out.number);
  802|      8|  }
  803|      8|  delete compact;
  804|      8|}
_ZN7leveldb6DBImpl24OpenCompactionOutputFileEPNS0_15CompactionStateE:
  806|      8|Status DBImpl::OpenCompactionOutputFile(CompactionState* compact) {
  807|      8|  assert(compact != nullptr);
  808|      8|  assert(compact->builder == nullptr);
  809|      8|  uint64_t file_number;
  810|      8|  {
  811|      8|    mutex_.Lock();
  812|      8|    file_number = versions_->NewFileNumber();
  813|      8|    pending_outputs_.insert(file_number);
  814|      8|    CompactionState::Output out;
  815|      8|    out.number = file_number;
  816|      8|    out.smallest.Clear();
  817|      8|    out.largest.Clear();
  818|      8|    compact->outputs.push_back(out);
  819|      8|    mutex_.Unlock();
  820|      8|  }
  821|       |
  822|       |  // Make the output file
  823|      8|  std::string fname = TableFileName(dbname_, file_number);
  824|      8|  Status s = env_->NewWritableFile(fname, &compact->outfile);
  825|      8|  if (s.ok()) {
  ------------------
  |  Branch (825:7): [True: 8, False: 0]
  ------------------
  826|      8|    compact->builder = new TableBuilder(options_, compact->outfile);
  827|      8|  }
  828|      8|  return s;
  829|      8|}
_ZN7leveldb6DBImpl26FinishCompactionOutputFileEPNS0_15CompactionStateEPNS_8IteratorE:
  832|      8|                                          Iterator* input) {
  833|      8|  assert(compact != nullptr);
  834|      8|  assert(compact->outfile != nullptr);
  835|      8|  assert(compact->builder != nullptr);
  836|       |
  837|      8|  const uint64_t output_number = compact->current_output()->number;
  838|      8|  assert(output_number != 0);
  839|       |
  840|       |  // Check for iterator errors
  841|      8|  Status s = input->status();
  842|      8|  const uint64_t current_entries = compact->builder->NumEntries();
  843|      8|  if (s.ok()) {
  ------------------
  |  Branch (843:7): [True: 8, False: 0]
  ------------------
  844|      8|    s = compact->builder->Finish();
  845|      8|  } else {
  846|      0|    compact->builder->Abandon();
  847|      0|  }
  848|      8|  const uint64_t current_bytes = compact->builder->FileSize();
  849|      8|  compact->current_output()->file_size = current_bytes;
  850|      8|  compact->total_bytes += current_bytes;
  851|      8|  delete compact->builder;
  852|      8|  compact->builder = nullptr;
  853|       |
  854|       |  // Finish and check for file errors
  855|      8|  if (s.ok()) {
  ------------------
  |  Branch (855:7): [True: 8, False: 0]
  ------------------
  856|      8|    s = compact->outfile->Sync();
  857|      8|  }
  858|      8|  if (s.ok()) {
  ------------------
  |  Branch (858:7): [True: 8, False: 0]
  ------------------
  859|      8|    s = compact->outfile->Close();
  860|      8|  }
  861|      8|  delete compact->outfile;
  862|      8|  compact->outfile = nullptr;
  863|       |
  864|      8|  if (s.ok() && current_entries > 0) {
  ------------------
  |  Branch (864:7): [True: 8, False: 0]
  |  Branch (864:17): [True: 8, False: 0]
  ------------------
  865|       |    // Verify that the table is usable
  866|      8|    Iterator* iter =
  867|      8|        table_cache_->NewIterator(ReadOptions(), output_number, current_bytes);
  868|      8|    s = iter->status();
  869|      8|    delete iter;
  870|      8|    if (s.ok()) {
  ------------------
  |  Branch (870:9): [True: 8, False: 0]
  ------------------
  871|      8|      Log(options_.info_log, "Generated table #%llu@%d: %lld keys, %lld bytes",
  872|      8|          (unsigned long long)output_number, compact->compaction->level(),
  873|      8|          (unsigned long long)current_entries,
  874|      8|          (unsigned long long)current_bytes);
  875|      8|    }
  876|      8|  }
  877|      8|  return s;
  878|      8|}
_ZN7leveldb6DBImpl24InstallCompactionResultsEPNS0_15CompactionStateE:
  880|      8|Status DBImpl::InstallCompactionResults(CompactionState* compact) {
  881|      8|  mutex_.AssertHeld();
  882|      8|  Log(options_.info_log, "Compacted %d@%d + %d@%d files => %lld bytes",
  883|      8|      compact->compaction->num_input_files(0), compact->compaction->level(),
  884|      8|      compact->compaction->num_input_files(1), compact->compaction->level() + 1,
  885|      8|      static_cast<long long>(compact->total_bytes));
  886|       |
  887|       |  // Add compaction outputs
  888|      8|  compact->compaction->AddInputDeletions(compact->compaction->edit());
  889|      8|  const int level = compact->compaction->level();
  890|     16|  for (size_t i = 0; i < compact->outputs.size(); i++) {
  ------------------
  |  Branch (890:22): [True: 8, False: 8]
  ------------------
  891|      8|    const CompactionState::Output& out = compact->outputs[i];
  892|      8|    compact->compaction->edit()->AddFile(level + 1, out.number, out.file_size,
  893|      8|                                         out.smallest, out.largest);
  894|      8|  }
  895|      8|  return versions_->LogAndApply(compact->compaction->edit(), &mutex_);
  896|      8|}
_ZN7leveldb6DBImpl16DoCompactionWorkEPNS0_15CompactionStateE:
  898|      8|Status DBImpl::DoCompactionWork(CompactionState* compact) {
  899|      8|  const uint64_t start_micros = env_->NowMicros();
  900|      8|  int64_t imm_micros = 0;  // Micros spent doing imm_ compactions
  901|       |
  902|      8|  Log(options_.info_log, "Compacting %d@%d + %d@%d files",
  903|      8|      compact->compaction->num_input_files(0), compact->compaction->level(),
  904|      8|      compact->compaction->num_input_files(1),
  905|      8|      compact->compaction->level() + 1);
  906|       |
  907|      8|  assert(versions_->NumLevelFiles(compact->compaction->level()) > 0);
  908|      8|  assert(compact->builder == nullptr);
  909|      8|  assert(compact->outfile == nullptr);
  910|      8|  if (snapshots_.empty()) {
  ------------------
  |  Branch (910:7): [True: 8, False: 0]
  ------------------
  911|      8|    compact->smallest_snapshot = versions_->LastSequence();
  912|      8|  } else {
  913|      0|    compact->smallest_snapshot = snapshots_.oldest()->sequence_number();
  914|      0|  }
  915|       |
  916|      8|  Iterator* input = versions_->MakeInputIterator(compact->compaction);
  917|       |
  918|       |  // Release mutex while we're actually doing the compaction work
  919|      8|  mutex_.Unlock();
  920|       |
  921|      8|  input->SeekToFirst();
  922|      8|  Status status;
  923|      8|  ParsedInternalKey ikey;
  924|      8|  std::string current_user_key;
  925|      8|  bool has_current_user_key = false;
  926|      8|  SequenceNumber last_sequence_for_key = kMaxSequenceNumber;
  927|    485|  while (input->Valid() && !shutting_down_.load(std::memory_order_acquire)) {
  ------------------
  |  Branch (927:10): [True: 477, False: 8]
  |  Branch (927:28): [True: 477, False: 0]
  ------------------
  928|       |    // Prioritize immutable compaction work
  929|    477|    if (has_imm_.load(std::memory_order_relaxed)) {
  ------------------
  |  Branch (929:9): [True: 0, False: 477]
  ------------------
  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|    477|    Slice key = input->key();
  942|    477|    if (compact->compaction->ShouldStopBefore(key) &&
  ------------------
  |  Branch (942:9): [True: 0, False: 477]
  ------------------
  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|    477|    bool drop = false;
  952|    477|    if (!ParseInternalKey(key, &ikey)) {
  ------------------
  |  Branch (952:9): [True: 0, False: 477]
  ------------------
  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|    477|    } else {
  958|    477|      if (!has_current_user_key ||
  ------------------
  |  Branch (958:11): [True: 8, False: 469]
  |  Branch (958:11): [True: 477, False: 0]
  ------------------
  959|    469|          user_comparator()->Compare(ikey.user_key, Slice(current_user_key)) !=
  ------------------
  |  Branch (959:11): [True: 469, False: 0]
  ------------------
  960|    477|              0) {
  961|       |        // First occurrence of this user key
  962|    477|        current_user_key.assign(ikey.user_key.data(), ikey.user_key.size());
  963|    477|        has_current_user_key = true;
  964|    477|        last_sequence_for_key = kMaxSequenceNumber;
  965|    477|      }
  966|       |
  967|    477|      if (last_sequence_for_key <= compact->smallest_snapshot) {
  ------------------
  |  Branch (967:11): [True: 0, False: 477]
  ------------------
  968|       |        // Hidden by an newer entry for same user key
  969|      0|        drop = true;  // (A)
  970|    477|      } else if (ikey.type == kTypeDeletion &&
  ------------------
  |  Branch (970:18): [True: 8, False: 469]
  ------------------
  971|      8|                 ikey.sequence <= compact->smallest_snapshot &&
  ------------------
  |  Branch (971:18): [True: 8, False: 0]
  ------------------
  972|      8|                 compact->compaction->IsBaseLevelForKey(ikey.user_key)) {
  ------------------
  |  Branch (972:18): [True: 8, 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|      8|        drop = true;
  981|      8|      }
  982|       |
  983|    477|      last_sequence_for_key = ikey.sequence;
  984|    477|    }
  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|    477|    if (!drop) {
  ------------------
  |  Branch (995:9): [True: 469, False: 8]
  ------------------
  996|       |      // Open output file if necessary
  997|    469|      if (compact->builder == nullptr) {
  ------------------
  |  Branch (997:11): [True: 8, False: 461]
  ------------------
  998|      8|        status = OpenCompactionOutputFile(compact);
  999|      8|        if (!status.ok()) {
  ------------------
  |  Branch (999:13): [True: 0, False: 8]
  ------------------
 1000|      0|          break;
 1001|      0|        }
 1002|      8|      }
 1003|    469|      if (compact->builder->NumEntries() == 0) {
  ------------------
  |  Branch (1003:11): [True: 8, False: 461]
  ------------------
 1004|      8|        compact->current_output()->smallest.DecodeFrom(key);
 1005|      8|      }
 1006|    469|      compact->current_output()->largest.DecodeFrom(key);
 1007|    469|      compact->builder->Add(key, input->value());
 1008|       |
 1009|       |      // Close output file if it is big enough
 1010|    469|      if (compact->builder->FileSize() >=
  ------------------
  |  Branch (1010:11): [True: 0, False: 469]
  ------------------
 1011|    469|          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|    469|    }
 1018|       |
 1019|    477|    input->Next();
 1020|    477|  }
 1021|       |
 1022|      8|  if (status.ok() && shutting_down_.load(std::memory_order_acquire)) {
  ------------------
  |  Branch (1022:7): [True: 8, False: 0]
  |  Branch (1022:22): [True: 0, False: 8]
  ------------------
 1023|      0|    status = Status::IOError("Deleting DB during compaction");
 1024|      0|  }
 1025|      8|  if (status.ok() && compact->builder != nullptr) {
  ------------------
  |  Branch (1025:7): [True: 8, False: 0]
  |  Branch (1025:22): [True: 8, False: 0]
  ------------------
 1026|      8|    status = FinishCompactionOutputFile(compact, input);
 1027|      8|  }
 1028|      8|  if (status.ok()) {
  ------------------
  |  Branch (1028:7): [True: 8, False: 0]
  ------------------
 1029|      8|    status = input->status();
 1030|      8|  }
 1031|      8|  delete input;
 1032|      8|  input = nullptr;
 1033|       |
 1034|      8|  CompactionStats stats;
 1035|      8|  stats.micros = env_->NowMicros() - start_micros - imm_micros;
 1036|     24|  for (int which = 0; which < 2; which++) {
  ------------------
  |  Branch (1036:23): [True: 16, False: 8]
  ------------------
 1037|     44|    for (int i = 0; i < compact->compaction->num_input_files(which); i++) {
  ------------------
  |  Branch (1037:21): [True: 28, False: 16]
  ------------------
 1038|     28|      stats.bytes_read += compact->compaction->input(which, i)->file_size;
 1039|     28|    }
 1040|     16|  }
 1041|     16|  for (size_t i = 0; i < compact->outputs.size(); i++) {
  ------------------
  |  Branch (1041:22): [True: 8, False: 8]
  ------------------
 1042|      8|    stats.bytes_written += compact->outputs[i].file_size;
 1043|      8|  }
 1044|       |
 1045|      8|  mutex_.Lock();
 1046|      8|  stats_[compact->compaction->level() + 1].Add(stats);
 1047|       |
 1048|      8|  if (status.ok()) {
  ------------------
  |  Branch (1048:7): [True: 8, False: 0]
  ------------------
 1049|      8|    status = InstallCompactionResults(compact);
 1050|      8|  }
 1051|      8|  if (!status.ok()) {
  ------------------
  |  Branch (1051:7): [True: 0, False: 8]
  ------------------
 1052|      0|    RecordBackgroundError(status);
 1053|      0|  }
 1054|      8|  VersionSet::LevelSummaryStorage tmp;
 1055|      8|  Log(options_.info_log, "compacted to: %s", versions_->LevelSummary(&tmp));
 1056|      8|  return status;
 1057|      8|}
_ZN7leveldb6DBImpl19NewInternalIteratorERKNS_11ReadOptionsEPmPj:
 1085|     40|                                      uint32_t* seed) {
 1086|     40|  mutex_.Lock();
 1087|     40|  *latest_snapshot = versions_->LastSequence();
 1088|       |
 1089|       |  // Collect together all needed child iterators
 1090|     40|  std::vector<Iterator*> list;
 1091|     40|  list.push_back(mem_->NewIterator());
 1092|     40|  mem_->Ref();
 1093|     40|  if (imm_ != nullptr) {
  ------------------
  |  Branch (1093:7): [True: 0, False: 40]
  ------------------
 1094|      0|    list.push_back(imm_->NewIterator());
 1095|      0|    imm_->Ref();
 1096|      0|  }
 1097|     40|  versions_->current()->AddIterators(options, &list);
 1098|     40|  Iterator* internal_iter =
 1099|     40|      NewMergingIterator(&internal_comparator_, &list[0], list.size());
 1100|     40|  versions_->current()->Ref();
 1101|       |
 1102|     40|  IterState* cleanup = new IterState(&mutex_, mem_, imm_, versions_->current());
 1103|     40|  internal_iter->RegisterCleanup(CleanupIteratorState, cleanup, nullptr);
 1104|       |
 1105|     40|  *seed = ++seed_;
 1106|     40|  mutex_.Unlock();
 1107|     40|  return internal_iter;
 1108|     40|}
_ZN7leveldb6DBImpl3GetERKNS_11ReadOptionsERKNS_5SliceEPNSt3__112basic_stringIcNS7_11char_traitsIcEENS7_9allocatorIcEEEE:
 1122|     24|                   std::string* value) {
 1123|     24|  Status s;
 1124|     24|  MutexLock l(&mutex_);
 1125|     24|  SequenceNumber snapshot;
 1126|     24|  if (options.snapshot != nullptr) {
  ------------------
  |  Branch (1126:7): [True: 0, False: 24]
  ------------------
 1127|      0|    snapshot =
 1128|      0|        static_cast<const SnapshotImpl*>(options.snapshot)->sequence_number();
 1129|     24|  } else {
 1130|     24|    snapshot = versions_->LastSequence();
 1131|     24|  }
 1132|       |
 1133|     24|  MemTable* mem = mem_;
 1134|     24|  MemTable* imm = imm_;
 1135|     24|  Version* current = versions_->current();
 1136|     24|  mem->Ref();
 1137|     24|  if (imm != nullptr) imm->Ref();
  ------------------
  |  Branch (1137:7): [True: 0, False: 24]
  ------------------
 1138|     24|  current->Ref();
 1139|       |
 1140|     24|  bool have_stat_update = false;
 1141|     24|  Version::GetStats stats;
 1142|       |
 1143|       |  // Unlock while reading from files and memtables
 1144|     24|  {
 1145|     24|    mutex_.Unlock();
 1146|       |    // First look in the memtable, then in the immutable memtable (if any).
 1147|     24|    LookupKey lkey(key, snapshot);
 1148|     24|    if (mem->Get(lkey, value, &s)) {
  ------------------
  |  Branch (1148:9): [True: 1, False: 23]
  ------------------
 1149|       |      // Done
 1150|     23|    } else if (imm != nullptr && imm->Get(lkey, value, &s)) {
  ------------------
  |  Branch (1150:16): [True: 0, False: 23]
  |  Branch (1150:34): [True: 0, False: 0]
  ------------------
 1151|       |      // Done
 1152|     23|    } else {
 1153|     23|      s = current->Get(options, lkey, value, &stats);
 1154|     23|      have_stat_update = true;
 1155|     23|    }
 1156|     24|    mutex_.Lock();
 1157|     24|  }
 1158|       |
 1159|     24|  if (have_stat_update && current->UpdateStats(stats)) {
  ------------------
  |  Branch (1159:7): [True: 23, False: 1]
  |  Branch (1159:27): [True: 0, False: 23]
  ------------------
 1160|      0|    MaybeScheduleCompaction();
 1161|      0|  }
 1162|     24|  mem->Unref();
 1163|     24|  if (imm != nullptr) imm->Unref();
  ------------------
  |  Branch (1163:7): [True: 0, False: 24]
  ------------------
 1164|     24|  current->Unref();
 1165|     24|  return s;
 1166|     24|}
_ZN7leveldb6DBImpl11NewIteratorERKNS_11ReadOptionsE:
 1168|     40|Iterator* DBImpl::NewIterator(const ReadOptions& options) {
 1169|     40|  SequenceNumber latest_snapshot;
 1170|     40|  uint32_t seed;
 1171|     40|  Iterator* iter = NewInternalIterator(options, &latest_snapshot, &seed);
 1172|     40|  return NewDBIterator(this, user_comparator(), iter,
 1173|     40|                       (options.snapshot != nullptr
  ------------------
  |  Branch (1173:25): [True: 28, False: 12]
  ------------------
 1174|     40|                            ? static_cast<const SnapshotImpl*>(options.snapshot)
 1175|     28|                                  ->sequence_number()
 1176|     40|                            : latest_snapshot),
 1177|     40|                       seed);
 1178|     40|}
_ZN7leveldb6DBImpl16RecordReadSampleENS_5SliceE:
 1180|     10|void DBImpl::RecordReadSample(Slice key) {
 1181|     10|  MutexLock l(&mutex_);
 1182|     10|  if (versions_->current()->RecordReadSample(key)) {
  ------------------
  |  Branch (1182:7): [True: 0, False: 10]
  ------------------
 1183|      0|    MaybeScheduleCompaction();
 1184|      0|  }
 1185|     10|}
_ZN7leveldb6DBImpl11GetSnapshotEv:
 1187|     28|const Snapshot* DBImpl::GetSnapshot() {
 1188|     28|  MutexLock l(&mutex_);
 1189|     28|  return snapshots_.New(versions_->LastSequence());
 1190|     28|}
_ZN7leveldb6DBImpl15ReleaseSnapshotEPKNS_8SnapshotE:
 1192|     28|void DBImpl::ReleaseSnapshot(const Snapshot* snapshot) {
 1193|     28|  MutexLock l(&mutex_);
 1194|     28|  snapshots_.Delete(static_cast<const SnapshotImpl*>(snapshot));
 1195|     28|}
_ZN7leveldb6DBImpl3PutERKNS_12WriteOptionsERKNS_5SliceES6_:
 1198|    534|Status DBImpl::Put(const WriteOptions& o, const Slice& key, const Slice& val) {
 1199|    534|  return DB::Put(o, key, val);
 1200|    534|}
_ZN7leveldb6DBImpl6DeleteERKNS_12WriteOptionsERKNS_5SliceE:
 1202|     18|Status DBImpl::Delete(const WriteOptions& options, const Slice& key) {
 1203|     18|  return DB::Delete(options, key);
 1204|     18|}
_ZN7leveldb6DBImpl5WriteERKNS_12WriteOptionsEPNS_10WriteBatchE:
 1206|    572|Status DBImpl::Write(const WriteOptions& options, WriteBatch* updates) {
 1207|    572|  Writer w(&mutex_);
 1208|    572|  w.batch = updates;
 1209|    572|  w.sync = options.sync;
 1210|    572|  w.done = false;
 1211|       |
 1212|    572|  MutexLock l(&mutex_);
 1213|    572|  writers_.push_back(&w);
 1214|    572|  while (!w.done && &w != writers_.front()) {
  ------------------
  |  Branch (1214:10): [True: 572, False: 0]
  |  Branch (1214:21): [True: 0, False: 572]
  ------------------
 1215|      0|    w.cv.Wait();
 1216|      0|  }
 1217|    572|  if (w.done) {
  ------------------
  |  Branch (1217:7): [True: 0, False: 572]
  ------------------
 1218|      0|    return w.status;
 1219|      0|  }
 1220|       |
 1221|       |  // May temporarily unlock and wait.
 1222|    572|  Status status = MakeRoomForWrite(updates == nullptr);
 1223|    572|  uint64_t last_sequence = versions_->LastSequence();
 1224|    572|  Writer* last_writer = &w;
 1225|    572|  if (status.ok() && updates != nullptr) {  // nullptr batch is for compactions
  ------------------
  |  Branch (1225:7): [True: 572, False: 0]
  |  Branch (1225:22): [True: 552, False: 20]
  ------------------
 1226|    552|    WriteBatch* write_batch = BuildBatchGroup(&last_writer);
 1227|    552|    WriteBatchInternal::SetSequence(write_batch, last_sequence + 1);
 1228|    552|    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|    552|    {
 1235|    552|      mutex_.Unlock();
 1236|    552|      status = log_->AddRecord(WriteBatchInternal::Contents(write_batch));
 1237|    552|      bool sync_error = false;
 1238|    552|      if (status.ok() && options.sync) {
  ------------------
  |  Branch (1238:11): [True: 552, False: 0]
  |  Branch (1238:26): [True: 0, False: 552]
  ------------------
 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|    552|      if (status.ok()) {
  ------------------
  |  Branch (1244:11): [True: 552, False: 0]
  ------------------
 1245|    552|        status = WriteBatchInternal::InsertInto(write_batch, mem_);
 1246|    552|      }
 1247|    552|      mutex_.Lock();
 1248|    552|      if (sync_error) {
  ------------------
  |  Branch (1248:11): [True: 0, False: 552]
  ------------------
 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|    552|    }
 1255|    552|    if (write_batch == tmp_batch_) tmp_batch_->Clear();
  ------------------
  |  Branch (1255:9): [True: 0, False: 552]
  ------------------
 1256|       |
 1257|    552|    versions_->SetLastSequence(last_sequence);
 1258|    552|  }
 1259|       |
 1260|    572|  while (true) {
  ------------------
  |  Branch (1260:10): [True: 572, Folded]
  ------------------
 1261|    572|    Writer* ready = writers_.front();
 1262|    572|    writers_.pop_front();
 1263|    572|    if (ready != &w) {
  ------------------
  |  Branch (1263:9): [True: 0, False: 572]
  ------------------
 1264|      0|      ready->status = status;
 1265|      0|      ready->done = true;
 1266|      0|      ready->cv.Signal();
 1267|      0|    }
 1268|    572|    if (ready == last_writer) break;
  ------------------
  |  Branch (1268:9): [True: 572, False: 0]
  ------------------
 1269|    572|  }
 1270|       |
 1271|       |  // Notify new head of write queue
 1272|    572|  if (!writers_.empty()) {
  ------------------
  |  Branch (1272:7): [True: 0, False: 572]
  ------------------
 1273|      0|    writers_.front()->cv.Signal();
 1274|      0|  }
 1275|       |
 1276|    572|  return status;
 1277|    572|}
_ZN7leveldb6DBImpl15BuildBatchGroupEPPNS0_6WriterE:
 1281|    552|WriteBatch* DBImpl::BuildBatchGroup(Writer** last_writer) {
 1282|    552|  mutex_.AssertHeld();
 1283|    552|  assert(!writers_.empty());
 1284|    552|  Writer* first = writers_.front();
 1285|    552|  WriteBatch* result = first->batch;
 1286|    552|  assert(result != nullptr);
 1287|       |
 1288|    552|  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|    552|  size_t max_size = 1 << 20;
 1294|    552|  if (size <= (128 << 10)) {
  ------------------
  |  Branch (1294:7): [True: 503, False: 49]
  ------------------
 1295|    503|    max_size = size + (128 << 10);
 1296|    503|  }
 1297|       |
 1298|    552|  *last_writer = first;
 1299|    552|  std::deque<Writer*>::iterator iter = writers_.begin();
 1300|    552|  ++iter;  // Advance past "first"
 1301|    552|  for (; iter != writers_.end(); ++iter) {
  ------------------
  |  Branch (1301:10): [True: 0, False: 552]
  ------------------
 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|    552|  return result;
 1327|    552|}
_ZN7leveldb6DBImpl16MakeRoomForWriteEb:
 1331|    572|Status DBImpl::MakeRoomForWrite(bool force) {
 1332|    572|  mutex_.AssertHeld();
 1333|    572|  assert(!writers_.empty());
 1334|    572|  bool allow_delay = !force;
 1335|    572|  Status s;
 1336|    592|  while (true) {
  ------------------
  |  Branch (1336:10): [True: 592, Folded]
  ------------------
 1337|    592|    if (!bg_error_.ok()) {
  ------------------
  |  Branch (1337:9): [True: 0, False: 592]
  ------------------
 1338|       |      // Yield previous error
 1339|      0|      s = bg_error_;
 1340|      0|      break;
 1341|    592|    } else if (allow_delay && versions_->NumLevelFiles(0) >=
  ------------------
  |  Branch (1341:16): [True: 552, False: 40]
  |  Branch (1341:31): [True: 0, False: 552]
  ------------------
 1342|    552|                                  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|    592|    } else if (!force &&
  ------------------
  |  Branch (1353:16): [True: 572, False: 20]
  ------------------
 1354|    572|               (mem_->ApproximateMemoryUsage() <= options_.write_buffer_size)) {
  ------------------
  |  Branch (1354:16): [True: 572, False: 0]
  ------------------
 1355|       |      // There is room in current memtable
 1356|    572|      break;
 1357|    572|    } else if (imm_ != nullptr) {
  ------------------
  |  Branch (1357:16): [True: 0, False: 20]
  ------------------
 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|     20|    } else if (versions_->NumLevelFiles(0) >= config::kL0_StopWritesTrigger) {
  ------------------
  |  Branch (1362:16): [True: 0, False: 20]
  ------------------
 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|     20|    } else {
 1367|       |      // Attempt to switch to a new memtable and trigger compaction of old
 1368|     20|      assert(versions_->PrevLogNumber() == 0);
 1369|     20|      uint64_t new_log_number = versions_->NewFileNumber();
 1370|     20|      WritableFile* lfile = nullptr;
 1371|     20|      s = env_->NewWritableFile(LogFileName(dbname_, new_log_number), &lfile);
 1372|     20|      if (!s.ok()) {
  ------------------
  |  Branch (1372:11): [True: 0, False: 20]
  ------------------
 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|     20|      delete log_;
 1379|       |
 1380|     20|      s = logfile_->Close();
 1381|     20|      if (!s.ok()) {
  ------------------
  |  Branch (1381:11): [True: 0, False: 20]
  ------------------
 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|     20|      delete logfile_;
 1392|       |
 1393|     20|      logfile_ = lfile;
 1394|     20|      logfile_number_ = new_log_number;
 1395|     20|      log_ = new log::Writer(lfile);
 1396|     20|      imm_ = mem_;
 1397|     20|      has_imm_.store(true, std::memory_order_release);
 1398|     20|      mem_ = new MemTable(internal_comparator_);
 1399|     20|      mem_->Ref();
 1400|     20|      force = false;  // Do not force another compaction if have room
 1401|     20|      MaybeScheduleCompaction();
 1402|     20|    }
 1403|    592|  }
 1404|    572|  return s;
 1405|    572|}
_ZN7leveldb6DBImpl11GetPropertyERKNS_5SliceEPNSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEE:
 1407|     16|bool DBImpl::GetProperty(const Slice& property, std::string* value) {
 1408|     16|  value->clear();
 1409|       |
 1410|     16|  MutexLock l(&mutex_);
 1411|     16|  Slice in = property;
 1412|     16|  Slice prefix("leveldb.");
 1413|     16|  if (!in.starts_with(prefix)) return false;
  ------------------
  |  Branch (1413:7): [True: 16, 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|    534|Status DB::Put(const WriteOptions& opt, const Slice& key, const Slice& value) {
 1490|    534|  WriteBatch batch;
 1491|    534|  batch.Put(key, value);
 1492|    534|  return Write(opt, &batch);
 1493|    534|}
_ZN7leveldb2DB6DeleteERKNS_12WriteOptionsERKNS_5SliceE:
 1495|     18|Status DB::Delete(const WriteOptions& opt, const Slice& key) {
 1496|     18|  WriteBatch batch;
 1497|     18|  batch.Delete(key);
 1498|     18|  return Write(opt, &batch);
 1499|     18|}
_ZN7leveldb2DBD2Ev:
 1501|    108|DB::~DB() = default;
_ZN7leveldb2DB4OpenERKNS_7OptionsERKNSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEPPS0_:
 1503|    108|Status DB::Open(const Options& options, const std::string& dbname, DB** dbptr) {
 1504|    108|  *dbptr = nullptr;
 1505|       |
 1506|    108|  DBImpl* impl = new DBImpl(options, dbname);
 1507|    108|  impl->mutex_.Lock();
 1508|    108|  VersionEdit edit;
 1509|       |  // Recover handles create_if_missing, error_if_exists
 1510|    108|  bool save_manifest = false;
 1511|    108|  Status s = impl->Recover(&edit, &save_manifest);
 1512|    108|  if (s.ok() && impl->mem_ == nullptr) {
  ------------------
  |  Branch (1512:7): [True: 108, False: 0]
  |  Branch (1512:17): [True: 108, False: 0]
  ------------------
 1513|       |    // Create new log and a corresponding memtable.
 1514|    108|    uint64_t new_log_number = impl->versions_->NewFileNumber();
 1515|    108|    WritableFile* lfile;
 1516|    108|    s = options.env->NewWritableFile(LogFileName(dbname, new_log_number),
 1517|    108|                                     &lfile);
 1518|    108|    if (s.ok()) {
  ------------------
  |  Branch (1518:9): [True: 108, False: 0]
  ------------------
 1519|    108|      edit.SetLogNumber(new_log_number);
 1520|    108|      impl->logfile_ = lfile;
 1521|    108|      impl->logfile_number_ = new_log_number;
 1522|    108|      impl->log_ = new log::Writer(lfile);
 1523|    108|      impl->mem_ = new MemTable(impl->internal_comparator_);
 1524|    108|      impl->mem_->Ref();
 1525|    108|    }
 1526|    108|  }
 1527|    108|  if (s.ok() && save_manifest) {
  ------------------
  |  Branch (1527:7): [True: 108, False: 0]
  |  Branch (1527:17): [True: 108, False: 0]
  ------------------
 1528|    108|    edit.SetPrevLogNumber(0);  // No older logs needed after recovery.
 1529|    108|    edit.SetLogNumber(impl->logfile_number_);
 1530|    108|    s = impl->versions_->LogAndApply(&edit, &impl->mutex_);
 1531|    108|  }
 1532|    108|  if (s.ok()) {
  ------------------
  |  Branch (1532:7): [True: 108, False: 0]
  ------------------
 1533|    108|    impl->RemoveObsoleteFiles();
 1534|    108|    impl->MaybeScheduleCompaction();
 1535|    108|  }
 1536|    108|  impl->mutex_.Unlock();
 1537|    108|  if (s.ok()) {
  ------------------
  |  Branch (1537:7): [True: 108, False: 0]
  ------------------
 1538|    108|    assert(impl->mem_ != nullptr);
 1539|    108|    *dbptr = impl;
 1540|    108|  } else {
 1541|      0|    delete impl;
 1542|      0|  }
 1543|    108|  return s;
 1544|    108|}
_ZN7leveldb8SnapshotD2Ev:
 1546|    136|Snapshot::~Snapshot() = default;
db_impl.cc:_ZN7leveldbL14TableCacheSizeERKNS_7OptionsE:
  121|    108|static int TableCacheSize(const Options& sanitized_options) {
  122|       |  // Reserve ten files or so for other uses and give the rest to TableCache.
  123|    108|  return sanitized_options.max_open_files - kNumNonTableCacheFiles;
  124|    108|}
_ZN7leveldb6DBImpl15CompactionStateC2EPNS_10CompactionE:
   65|      8|      : compaction(c),
   66|      8|        smallest_snapshot(0),
   67|      8|        outfile(nullptr),
   68|      8|        builder(nullptr),
   69|      8|        total_bytes(0) {}
_ZN7leveldb6DBImpl15CompactionState14current_outputEv:
   62|    493|  Output* current_output() { return &outputs[outputs.size() - 1]; }
db_impl.cc:_ZN7leveldb12_GLOBAL__N_19IterStateC2EPNS_4port5MutexEPNS_8MemTableES6_PNS_7VersionE:
 1068|     40|      : mu(mutex), version(version), mem(mem), imm(imm) {}
db_impl.cc:_ZN7leveldb12_GLOBAL__N_120CleanupIteratorStateEPvS1_:
 1071|     40|static void CleanupIteratorState(void* arg1, void* arg2) {
 1072|     40|  IterState* state = reinterpret_cast<IterState*>(arg1);
 1073|     40|  state->mu->Lock();
 1074|     40|  state->mem->Unref();
 1075|     40|  if (state->imm != nullptr) state->imm->Unref();
  ------------------
  |  Branch (1075:7): [True: 0, False: 40]
  ------------------
 1076|     40|  state->version->Unref();
 1077|     40|  state->mu->Unlock();
 1078|     40|  delete state;
 1079|     40|}
_ZN7leveldb6DBImpl6WriterC2EPNS_4port5MutexE:
   45|    572|      : batch(nullptr), sync(false), done(false), cv(mu) {}
db_impl.cc:_ZN7leveldbL11ClipToRangeIiiEEvPT_T0_S3_:
   90|    108|static void ClipToRange(T* ptr, V minvalue, V maxvalue) {
   91|    108|  if (static_cast<V>(*ptr) > maxvalue) *ptr = maxvalue;
  ------------------
  |  Branch (91:7): [True: 0, False: 108]
  ------------------
   92|    108|  if (static_cast<V>(*ptr) < minvalue) *ptr = minvalue;
  ------------------
  |  Branch (92:7): [True: 0, False: 108]
  ------------------
   93|    108|}
db_impl.cc:_ZN7leveldbL11ClipToRangeImiEEvPT_T0_S3_:
   90|    324|static void ClipToRange(T* ptr, V minvalue, V maxvalue) {
   91|    324|  if (static_cast<V>(*ptr) > maxvalue) *ptr = maxvalue;
  ------------------
  |  Branch (91:7): [True: 0, False: 324]
  ------------------
   92|    324|  if (static_cast<V>(*ptr) < minvalue) *ptr = minvalue;
  ------------------
  |  Branch (92:7): [True: 0, False: 324]
  ------------------
   93|    324|}

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

_ZN7leveldb13NewDBIteratorEPNS_6DBImplEPKNS_10ComparatorEPNS_8IteratorEmj:
  314|     40|                        uint32_t seed) {
  315|     40|  return new DBIter(db, user_key_comparator, internal_iter, sequence, seed);
  316|     40|}
db_iter.cc:_ZN7leveldb12_GLOBAL__N_16DBIterC2EPNS_6DBImplEPKNS_10ComparatorEPNS_8IteratorEmj:
   50|     40|      : db_(db),
   51|     40|        user_comparator_(cmp),
   52|     40|        iter_(iter),
   53|     40|        sequence_(s),
   54|     40|        direction_(kForward),
   55|     40|        valid_(false),
   56|     40|        rnd_(seed),
   57|     40|        bytes_until_read_sampling_(RandomCompactionPeriod()) {}
db_iter.cc:_ZN7leveldb12_GLOBAL__N_16DBIter22RandomCompactionPeriodEv:
  105|     50|  size_t RandomCompactionPeriod() {
  106|     50|    return rnd_.Uniform(2 * config::kReadBytesPeriod);
  107|     50|  }
db_iter.cc:_ZN7leveldb12_GLOBAL__N_16DBIterD2Ev:
   62|     40|  ~DBIter() override { delete iter_; }
db_iter.cc:_ZNK7leveldb12_GLOBAL__N_16DBIter5ValidEv:
   63|    269|  bool Valid() const override { return valid_; }
db_iter.cc:_ZN7leveldb12_GLOBAL__N_16DBIter11SeekToFirstEv:
  292|     12|void DBIter::SeekToFirst() {
  293|     12|  direction_ = kForward;
  294|     12|  ClearSavedValue();
  295|     12|  iter_->SeekToFirst();
  296|     12|  if (iter_->Valid()) {
  ------------------
  |  Branch (296:7): [True: 12, False: 0]
  ------------------
  297|     12|    FindNextUserEntry(false, &saved_key_ /* temporary storage */);
  298|     12|  } else {
  299|      0|    valid_ = false;
  300|      0|  }
  301|     12|}
db_iter.cc:_ZN7leveldb12_GLOBAL__N_16DBIter15ClearSavedValueEv:
   95|     12|  inline void ClearSavedValue() {
   96|     12|    if (saved_value_.capacity() > 1048576) {
  ------------------
  |  Branch (96:9): [True: 0, False: 12]
  ------------------
   97|      0|      std::string empty;
   98|      0|      swap(empty, saved_value_);
   99|     12|    } else {
  100|     12|      saved_value_.clear();
  101|     12|    }
  102|     12|  }
db_iter.cc:_ZN7leveldb12_GLOBAL__N_16DBIter17FindNextUserEntryEbPNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  177|    260|void DBIter::FindNextUserEntry(bool skipping, std::string* skip) {
  178|       |  // Loop until we hit an acceptable entry to yield
  179|    260|  assert(iter_->Valid());
  180|    260|  assert(direction_ == kForward);
  181|    261|  do {
  182|    261|    ParsedInternalKey ikey;
  183|    261|    if (ParseKey(&ikey) && ikey.sequence <= sequence_) {
  ------------------
  |  Branch (183:9): [True: 261, False: 0]
  |  Branch (183:28): [True: 261, False: 0]
  ------------------
  184|    261|      switch (ikey.type) {
  ------------------
  |  Branch (184:15): [True: 261, False: 0]
  ------------------
  185|      4|        case kTypeDeletion:
  ------------------
  |  Branch (185:9): [True: 4, False: 257]
  ------------------
  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|    257|        case kTypeValue:
  ------------------
  |  Branch (191:9): [True: 257, False: 4]
  ------------------
  192|    257|          if (skipping &&
  ------------------
  |  Branch (192:15): [True: 248, False: 9]
  |  Branch (192:15): [True: 0, False: 257]
  ------------------
  193|    248|              user_comparator_->Compare(ikey.user_key, *skip) <= 0) {
  ------------------
  |  Branch (193:15): [True: 0, False: 248]
  ------------------
  194|       |            // Entry hidden
  195|    257|          } else {
  196|    257|            valid_ = true;
  197|    257|            saved_key_.clear();
  198|    257|            return;
  199|    257|          }
  200|      0|          break;
  201|    261|      }
  202|    261|    }
  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|    261|inline bool DBIter::ParseKey(ParsedInternalKey* ikey) {
  123|    261|  Slice k = iter_->key();
  124|       |
  125|    261|  size_t bytes_read = k.size() + iter_->value().size();
  126|    271|  while (bytes_until_read_sampling_ < bytes_read) {
  ------------------
  |  Branch (126:10): [True: 10, False: 261]
  ------------------
  127|     10|    bytes_until_read_sampling_ += RandomCompactionPeriod();
  128|     10|    db_->RecordReadSample(k);
  129|     10|  }
  130|    261|  assert(bytes_until_read_sampling_ >= bytes_read);
  131|    261|  bytes_until_read_sampling_ -= bytes_read;
  132|       |
  133|    261|  if (!ParseInternalKey(k, ikey)) {
  ------------------
  |  Branch (133:7): [True: 0, False: 261]
  ------------------
  134|      0|    status_ = Status::Corruption("corrupted internal key in DBIter");
  135|      0|    return false;
  136|    261|  } else {
  137|    261|    return true;
  138|    261|  }
  139|    261|}
db_iter.cc:_ZN7leveldb12_GLOBAL__N_16DBIter7SaveKeyERKNS_5SliceEPNSt3__112basic_stringIcNS5_11char_traitsIcEENS5_9allocatorIcEEEE:
   91|    261|  inline void SaveKey(const Slice& k, std::string* dst) {
   92|    261|    dst->assign(k.data(), k.size());
   93|    261|  }
db_iter.cc:_ZN7leveldb12_GLOBAL__N_16DBIter4NextEv:
  141|    257|void DBIter::Next() {
  142|    257|  assert(valid_);
  143|       |
  144|    257|  if (direction_ == kReverse) {  // Switch directions?
  ------------------
  |  Branch (144:7): [True: 0, False: 257]
  ------------------
  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|    257|  } else {
  161|       |    // Store in saved_key_ the current key so we skip it below.
  162|    257|    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|    257|    iter_->Next();
  167|    257|    if (!iter_->Valid()) {
  ------------------
  |  Branch (167:9): [True: 9, False: 248]
  ------------------
  168|      9|      valid_ = false;
  169|      9|      saved_key_.clear();
  170|      9|      return;
  171|      9|    }
  172|    257|  }
  173|       |
  174|    248|  FindNextUserEntry(true, &saved_key_);
  175|    248|}

_ZN7leveldb17AppendInternalKeyEPNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEERKNS_17ParsedInternalKeyE:
   21|    168|void AppendInternalKey(std::string* result, const ParsedInternalKey& key) {
   22|    168|  result->append(key.user_key.data(), key.user_key.size());
   23|    168|  PutFixed64(result, PackSequenceAndType(key.sequence, key.type));
   24|    168|}
_ZNK7leveldb17ParsedInternalKey11DebugStringEv:
   26|     52|std::string ParsedInternalKey::DebugString() const {
   27|     52|  std::ostringstream ss;
   28|     52|  ss << '\'' << EscapeString(user_key.ToString()) << "' @ " << sequence << " : "
   29|     52|     << static_cast<int>(type);
   30|     52|  return ss.str();
   31|     52|}
_ZNK7leveldb11InternalKey11DebugStringEv:
   33|     52|std::string InternalKey::DebugString() const {
   34|     52|  ParsedInternalKey parsed;
   35|     52|  if (ParseInternalKey(rep_, &parsed)) {
  ------------------
  |  Branch (35:7): [True: 52, False: 0]
  ------------------
   36|     52|    return parsed.DebugString();
   37|     52|  }
   38|      0|  std::ostringstream ss;
   39|      0|  ss << "(bad)" << EscapeString(rep_);
   40|      0|  return ss.str();
   41|     52|}
_ZNK7leveldb21InternalKeyComparator7CompareERKNS_5SliceES3_:
   47|  5.33k|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|  5.33k|  int r = user_comparator_->Compare(ExtractUserKey(akey), ExtractUserKey(bkey));
   53|  5.33k|  if (r == 0) {
  ------------------
  |  Branch (53:7): [True: 57, False: 5.27k]
  ------------------
   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|  5.33k|  return r;
   63|  5.33k|}
_ZNK7leveldb21InternalKeyComparator21FindShortestSeparatorEPNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERKNS_5SliceE:
   66|    468|                                                  const Slice& limit) const {
   67|       |  // Attempt to shorten the user portion of the key
   68|    468|  Slice user_start = ExtractUserKey(*start);
   69|    468|  Slice user_limit = ExtractUserKey(limit);
   70|    468|  std::string tmp(user_start.data(), user_start.size());
   71|    468|  user_comparator_->FindShortestSeparator(&tmp, user_limit);
   72|    468|  if (tmp.size() < user_start.size() &&
  ------------------
  |  Branch (72:7): [True: 405, False: 63]
  |  Branch (72:7): [True: 405, False: 63]
  ------------------
   73|    405|      user_comparator_->Compare(user_start, tmp) < 0) {
  ------------------
  |  Branch (73:7): [True: 405, 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|    405|    PutFixed64(&tmp,
   77|    405|               PackSequenceAndType(kMaxSequenceNumber, kValueTypeForSeek));
   78|    405|    assert(this->Compare(*start, tmp) < 0);
   79|       |    assert(this->Compare(tmp, limit) < 0);
   80|    405|    start->swap(tmp);
   81|    405|  }
   82|    468|}
_ZNK7leveldb21InternalKeyComparator18FindShortSuccessorEPNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
   84|     52|void InternalKeyComparator::FindShortSuccessor(std::string* key) const {
   85|     52|  Slice user_key = ExtractUserKey(*key);
   86|     52|  std::string tmp(user_key.data(), user_key.size());
   87|     52|  user_comparator_->FindShortSuccessor(&tmp);
   88|     52|  if (tmp.size() < user_key.size() &&
  ------------------
  |  Branch (88:7): [True: 51, False: 1]
  |  Branch (88:7): [True: 51, False: 1]
  ------------------
   89|     51|      user_comparator_->Compare(user_key, tmp) < 0) {
  ------------------
  |  Branch (89:7): [True: 51, 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|     51|    PutFixed64(&tmp,
   93|     51|               PackSequenceAndType(kMaxSequenceNumber, kValueTypeForSeek));
   94|       |    assert(this->Compare(*key, tmp) < 0);
   95|     51|    key->swap(tmp);
   96|     51|  }
   97|     52|}
_ZN7leveldb9LookupKeyC2ERKNS_5SliceEm:
  117|     24|LookupKey::LookupKey(const Slice& user_key, SequenceNumber s) {
  118|     24|  size_t usize = user_key.size();
  119|     24|  size_t needed = usize + 13;  // A conservative estimate
  120|     24|  char* dst;
  121|     24|  if (needed <= sizeof(space_)) {
  ------------------
  |  Branch (121:7): [True: 15, False: 9]
  ------------------
  122|     15|    dst = space_;
  123|     15|  } else {
  124|      9|    dst = new char[needed];
  125|      9|  }
  126|     24|  start_ = dst;
  127|     24|  dst = EncodeVarint32(dst, usize + 8);
  128|     24|  kstart_ = dst;
  129|     24|  std::memcpy(dst, user_key.data(), usize);
  130|     24|  dst += usize;
  131|     24|  EncodeFixed64(dst, PackSequenceAndType(s, kValueTypeForSeek));
  132|     24|  dst += 8;
  133|     24|  end_ = dst;
  134|     24|}
dbformat.cc:_ZN7leveldbL19PackSequenceAndTypeEmNS_9ValueTypeE:
   15|    648|static uint64_t PackSequenceAndType(uint64_t seq, ValueType t) {
   16|    648|  assert(seq <= kMaxSequenceNumber);
   17|       |  assert(t <= kValueTypeForSeek);
   18|    648|  return (seq << 8) | t;
   19|    648|}

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

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

_ZN7leveldb3log6Reader8ReporterD2Ev:
   16|    168|Reader::Reporter::~Reporter() = default;
_ZN7leveldb3log6ReaderC2EPNS_14SequentialFileEPNS1_8ReporterEbm:
   20|    168|    : file_(file),
   21|    168|      reporter_(reporter),
   22|    168|      checksum_(checksum),
   23|    168|      backing_store_(new char[kBlockSize]),
   24|    168|      buffer_(),
   25|    168|      eof_(false),
   26|    168|      last_record_offset_(0),
   27|    168|      end_of_buffer_offset_(0),
   28|    168|      initial_offset_(initial_offset),
   29|    168|      resyncing_(initial_offset > 0) {}
_ZN7leveldb3log6ReaderD2Ev:
   31|    168|Reader::~Reader() { delete[] backing_store_; }
_ZN7leveldb3log6Reader10ReadRecordEPNS_5SliceEPNSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEE:
   56|    502|bool Reader::ReadRecord(Slice* record, std::string* scratch) {
   57|    502|  if (last_record_offset_ < initial_offset_) {
  ------------------
  |  Branch (57:7): [True: 0, False: 502]
  ------------------
   58|      0|    if (!SkipToInitialBlock()) {
  ------------------
  |  Branch (58:9): [True: 0, False: 0]
  ------------------
   59|      0|      return false;
   60|      0|    }
   61|      0|  }
   62|       |
   63|    502|  scratch->clear();
   64|    502|  record->clear();
   65|    502|  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|    502|  uint64_t prospective_record_offset = 0;
   69|       |
   70|    502|  Slice fragment;
   71|  1.33k|  while (true) {
  ------------------
  |  Branch (71:10): [True: 1.33k, Folded]
  ------------------
   72|  1.33k|    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.33k|    uint64_t physical_record_offset =
   78|  1.33k|        end_of_buffer_offset_ - buffer_.size() - kHeaderSize - fragment.size();
   79|       |
   80|  1.33k|    if (resyncing_) {
  ------------------
  |  Branch (80:9): [True: 0, False: 1.33k]
  ------------------
   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.33k|    switch (record_type) {
   92|    296|      case kFullType:
  ------------------
  |  Branch (92:7): [True: 296, False: 1.03k]
  ------------------
   93|    296|        if (in_fragmented_record) {
  ------------------
  |  Branch (93:13): [True: 0, False: 296]
  ------------------
   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|    296|        prospective_record_offset = physical_record_offset;
  103|    296|        scratch->clear();
  104|    296|        *record = fragment;
  105|    296|        last_record_offset_ = prospective_record_offset;
  106|    296|        return true;
  107|       |
  108|     38|      case kFirstType:
  ------------------
  |  Branch (108:7): [True: 38, False: 1.29k]
  ------------------
  109|     38|        if (in_fragmented_record) {
  ------------------
  |  Branch (109:13): [True: 0, False: 38]
  ------------------
  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|     38|        prospective_record_offset = physical_record_offset;
  119|     38|        scratch->assign(fragment.data(), fragment.size());
  120|     38|        in_fragmented_record = true;
  121|     38|        break;
  122|       |
  123|    790|      case kMiddleType:
  ------------------
  |  Branch (123:7): [True: 790, False: 540]
  ------------------
  124|    790|        if (!in_fragmented_record) {
  ------------------
  |  Branch (124:13): [True: 0, False: 790]
  ------------------
  125|      0|          ReportCorruption(fragment.size(),
  126|      0|                           "missing start of fragmented record(1)");
  127|    790|        } else {
  128|    790|          scratch->append(fragment.data(), fragment.size());
  129|    790|        }
  130|    790|        break;
  131|       |
  132|     38|      case kLastType:
  ------------------
  |  Branch (132:7): [True: 38, False: 1.29k]
  ------------------
  133|     38|        if (!in_fragmented_record) {
  ------------------
  |  Branch (133:13): [True: 0, False: 38]
  ------------------
  134|      0|          ReportCorruption(fragment.size(),
  135|      0|                           "missing start of fragmented record(2)");
  136|     38|        } else {
  137|     38|          scratch->append(fragment.data(), fragment.size());
  138|     38|          *record = Slice(*scratch);
  139|     38|          last_record_offset_ = prospective_record_offset;
  140|     38|          return true;
  141|     38|        }
  142|      0|        break;
  143|       |
  144|    168|      case kEof:
  ------------------
  |  Branch (144:7): [True: 168, False: 1.16k]
  ------------------
  145|    168|        if (in_fragmented_record) {
  ------------------
  |  Branch (145:13): [True: 0, False: 168]
  ------------------
  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|    168|        return false;
  152|       |
  153|      0|      case kBadRecord:
  ------------------
  |  Branch (153:7): [True: 0, False: 1.33k]
  ------------------
  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.33k]
  ------------------
  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|     38|      }
  171|  1.33k|    }
  172|  1.33k|  }
  173|      0|  return false;
  174|    502|}
_ZN7leveldb3log6Reader18ReadPhysicalRecordEPNS_5SliceE:
  189|  1.33k|unsigned int Reader::ReadPhysicalRecord(Slice* result) {
  190|  2.32k|  while (true) {
  ------------------
  |  Branch (190:10): [True: 2.32k, Folded]
  ------------------
  191|  2.32k|    if (buffer_.size() < kHeaderSize) {
  ------------------
  |  Branch (191:9): [True: 1.16k, False: 1.16k]
  ------------------
  192|  1.16k|      if (!eof_) {
  ------------------
  |  Branch (192:11): [True: 996, False: 168]
  ------------------
  193|       |        // Last read was a full read, so this is a trailer to skip
  194|    996|        buffer_.clear();
  195|    996|        Status status = file_->Read(kBlockSize, &buffer_, backing_store_);
  196|    996|        end_of_buffer_offset_ += buffer_.size();
  197|    996|        if (!status.ok()) {
  ------------------
  |  Branch (197:13): [True: 0, False: 996]
  ------------------
  198|      0|          buffer_.clear();
  199|      0|          ReportDrop(kBlockSize, status);
  200|      0|          eof_ = true;
  201|      0|          return kEof;
  202|    996|        } else if (buffer_.size() < kBlockSize) {
  ------------------
  |  Branch (202:20): [True: 168, False: 828]
  ------------------
  203|    168|          eof_ = true;
  204|    168|        }
  205|    996|        continue;
  206|    996|      } 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|    168|        buffer_.clear();
  212|    168|        return kEof;
  213|    168|      }
  214|  1.16k|    }
  215|       |
  216|       |    // Parse the header
  217|  1.16k|    const char* header = buffer_.data();
  218|  1.16k|    const uint32_t a = static_cast<uint32_t>(header[4]) & 0xff;
  219|  1.16k|    const uint32_t b = static_cast<uint32_t>(header[5]) & 0xff;
  220|  1.16k|    const unsigned int type = header[6];
  221|  1.16k|    const uint32_t length = a | (b << 8);
  222|  1.16k|    if (kHeaderSize + length > buffer_.size()) {
  ------------------
  |  Branch (222:9): [True: 0, False: 1.16k]
  ------------------
  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.16k|    if (type == kZeroType && length == 0) {
  ------------------
  |  Branch (235:9): [True: 0, False: 1.16k]
  |  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.16k|    if (checksum_) {
  ------------------
  |  Branch (244:9): [True: 1.16k, False: 0]
  ------------------
  245|  1.16k|      uint32_t expected_crc = crc32c::Unmask(DecodeFixed32(header));
  246|  1.16k|      uint32_t actual_crc = crc32c::Value(header + 6, 1 + length);
  247|  1.16k|      if (actual_crc != expected_crc) {
  ------------------
  |  Branch (247:11): [True: 0, False: 1.16k]
  ------------------
  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.16k|    }
  258|       |
  259|  1.16k|    buffer_.remove_prefix(kHeaderSize + length);
  260|       |
  261|       |    // Skip physical record that started before initial_offset_
  262|  1.16k|    if (end_of_buffer_offset_ - buffer_.size() - kHeaderSize - length <
  ------------------
  |  Branch (262:9): [True: 0, False: 1.16k]
  ------------------
  263|  1.16k|        initial_offset_) {
  264|      0|      result->clear();
  265|      0|      return kBadRecord;
  266|      0|    }
  267|       |
  268|  1.16k|    *result = Slice(header + kHeaderSize, length);
  269|  1.16k|    return type;
  270|  1.16k|  }
  271|  1.33k|}

_ZN7leveldb3log6WriterC2EPNS_12WritableFileE:
   23|    285|Writer::Writer(WritableFile* dest) : dest_(dest), block_offset_(0) {
   24|    285|  InitTypeCrc(type_crc_);
   25|    285|}
_ZN7leveldb3log6WriterD2Ev:
   32|    285|Writer::~Writer() = default;
_ZN7leveldb3log6Writer9AddRecordERKNS_5SliceE:
   34|    846|Status Writer::AddRecord(const Slice& slice) {
   35|    846|  const char* ptr = slice.data();
   36|    846|  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|    846|  Status s;
   42|    846|  bool begin = true;
   43|  2.93k|  do {
   44|  2.93k|    const int leftover = kBlockSize - block_offset_;
   45|  2.93k|    assert(leftover >= 0);
   46|  2.93k|    if (leftover < kHeaderSize) {
  ------------------
  |  Branch (46:9): [True: 2.09k, False: 846]
  ------------------
   47|       |      // Switch to a new block
   48|  2.09k|      if (leftover > 0) {
  ------------------
  |  Branch (48:11): [True: 0, False: 2.09k]
  ------------------
   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.09k|      block_offset_ = 0;
   54|  2.09k|    }
   55|       |
   56|       |    // Invariant: we never leave < kHeaderSize bytes in a block.
   57|  2.93k|    assert(kBlockSize - block_offset_ - kHeaderSize >= 0);
   58|       |
   59|  2.93k|    const size_t avail = kBlockSize - block_offset_ - kHeaderSize;
   60|  2.93k|    const size_t fragment_length = (left < avail) ? left : avail;
  ------------------
  |  Branch (60:36): [True: 846, False: 2.09k]
  ------------------
   61|       |
   62|  2.93k|    RecordType type;
   63|  2.93k|    const bool end = (left == fragment_length);
   64|  2.93k|    if (begin && end) {
  ------------------
  |  Branch (64:9): [True: 846, False: 2.09k]
  |  Branch (64:18): [True: 688, False: 158]
  ------------------
   65|    688|      type = kFullType;
   66|  2.25k|    } else if (begin) {
  ------------------
  |  Branch (66:16): [True: 158, False: 2.09k]
  ------------------
   67|    158|      type = kFirstType;
   68|  2.09k|    } else if (end) {
  ------------------
  |  Branch (68:16): [True: 158, False: 1.93k]
  ------------------
   69|    158|      type = kLastType;
   70|  1.93k|    } else {
   71|  1.93k|      type = kMiddleType;
   72|  1.93k|    }
   73|       |
   74|  2.93k|    s = EmitPhysicalRecord(type, ptr, fragment_length);
   75|  2.93k|    ptr += fragment_length;
   76|  2.93k|    left -= fragment_length;
   77|  2.93k|    begin = false;
   78|  2.93k|  } while (s.ok() && left > 0);
  ------------------
  |  Branch (78:12): [True: 2.93k, False: 0]
  |  Branch (78:22): [True: 2.09k, False: 846]
  ------------------
   79|    846|  return s;
   80|    846|}
_ZN7leveldb3log6Writer18EmitPhysicalRecordENS0_10RecordTypeEPKcm:
   83|  2.93k|                                  size_t length) {
   84|  2.93k|  assert(length <= 0xffff);  // Must fit in two bytes
   85|  2.93k|  assert(block_offset_ + kHeaderSize + length <= kBlockSize);
   86|       |
   87|       |  // Format the header
   88|  2.93k|  char buf[kHeaderSize];
   89|  2.93k|  buf[4] = static_cast<char>(length & 0xff);
   90|  2.93k|  buf[5] = static_cast<char>(length >> 8);
   91|  2.93k|  buf[6] = static_cast<char>(t);
   92|       |
   93|       |  // Compute the crc of the record type and the payload.
   94|  2.93k|  uint32_t crc = crc32c::Extend(type_crc_[t], ptr, length);
   95|  2.93k|  crc = crc32c::Mask(crc);  // Adjust for storage
   96|  2.93k|  EncodeFixed32(buf, crc);
   97|       |
   98|       |  // Write the header and the payload
   99|  2.93k|  Status s = dest_->Append(Slice(buf, kHeaderSize));
  100|  2.93k|  if (s.ok()) {
  ------------------
  |  Branch (100:7): [True: 2.93k, False: 0]
  ------------------
  101|  2.93k|    s = dest_->Append(Slice(ptr, length));
  102|  2.93k|    if (s.ok()) {
  ------------------
  |  Branch (102:9): [True: 2.93k, False: 0]
  ------------------
  103|  2.93k|      s = dest_->Flush();
  104|  2.93k|    }
  105|  2.93k|  }
  106|  2.93k|  block_offset_ += kHeaderSize + length;
  107|  2.93k|  return s;
  108|  2.93k|}
log_writer.cc:_ZN7leveldb3logL11InitTypeCrcEPj:
   16|    285|static void InitTypeCrc(uint32_t* type_crc) {
   17|  1.71k|  for (int i = 0; i <= kMaxRecordType; i++) {
  ------------------
  |  Branch (17:19): [True: 1.42k, False: 285]
  ------------------
   18|  1.42k|    char t = static_cast<char>(i);
   19|  1.42k|    type_crc[i] = crc32c::Value(&t, 1);
   20|  1.42k|  }
   21|    285|}

_ZN7leveldb8MemTableC2ERKNS_21InternalKeyComparatorE:
   22|    164|    : comparator_(comparator), refs_(0), table_(comparator_, &arena_) {}
_ZN7leveldb8MemTableD2Ev:
   24|    164|MemTable::~MemTable() { assert(refs_ == 0); }
_ZN7leveldb8MemTable22ApproximateMemoryUsageEv:
   26|    718|size_t MemTable::ApproximateMemoryUsage() { return arena_.MemoryUsage(); }
_ZNK7leveldb8MemTable13KeyComparatorclEPKcS3_:
   29|  2.94k|                                        const char* bptr) const {
   30|       |  // Internal keys are encoded as length-prefixed strings.
   31|  2.94k|  Slice a = GetLengthPrefixedSlice(aptr);
   32|  2.94k|  Slice b = GetLengthPrefixedSlice(bptr);
   33|  2.94k|  return comparator.Compare(a, b);
   34|  2.94k|}
_ZN7leveldb8MemTable11NewIteratorEv:
   74|     96|Iterator* MemTable::NewIterator() { return new MemTableIterator(&table_); }
_ZN7leveldb8MemTable3AddEmNS_9ValueTypeERKNS_5SliceES4_:
   77|    698|                   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|    698|  size_t key_size = key.size();
   85|    698|  size_t val_size = value.size();
   86|    698|  size_t internal_key_size = key_size + 8;
   87|    698|  const size_t encoded_len = VarintLength(internal_key_size) +
   88|    698|                             internal_key_size + VarintLength(val_size) +
   89|    698|                             val_size;
   90|    698|  char* buf = arena_.Allocate(encoded_len);
   91|    698|  char* p = EncodeVarint32(buf, internal_key_size);
   92|    698|  std::memcpy(p, key.data(), key_size);
   93|    698|  p += key_size;
   94|    698|  EncodeFixed64(p, (s << 8) | type);
   95|    698|  p += 8;
   96|    698|  p = EncodeVarint32(p, val_size);
   97|    698|  std::memcpy(p, value.data(), val_size);
   98|       |  assert(p + val_size == buf + encoded_len);
   99|    698|  table_.Insert(buf);
  100|    698|}
_ZN7leveldb8MemTable3GetERKNS_9LookupKeyEPNSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEPNS_6StatusE:
  102|     24|bool MemTable::Get(const LookupKey& key, std::string* value, Status* s) {
  103|     24|  Slice memkey = key.memtable_key();
  104|     24|  Table::Iterator iter(&table_);
  105|     24|  iter.Seek(memkey.data());
  106|     24|  if (iter.Valid()) {
  ------------------
  |  Branch (106:7): [True: 7, 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|      7|    const char* entry = iter.key();
  117|      7|    uint32_t key_length;
  118|      7|    const char* key_ptr = GetVarint32Ptr(entry, entry + 5, &key_length);
  119|      7|    if (comparator_.comparator.user_comparator()->Compare(
  ------------------
  |  Branch (119:9): [True: 1, False: 6]
  ------------------
  120|      7|            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|      7|  }
  135|     23|  return false;
  136|     24|}
memtable.cc:_ZN7leveldbL22GetLengthPrefixedSliceEPKc:
   14|  7.18k|static Slice GetLengthPrefixedSlice(const char* data) {
   15|  7.18k|  uint32_t len;
   16|  7.18k|  const char* p = data;
   17|  7.18k|  p = GetVarint32Ptr(p, p + 5, &len);  // +5: we assume "p" is not corrupted
   18|  7.18k|  return Slice(p, len);
   19|  7.18k|}
_ZN7leveldb16MemTableIteratorC2EPNS_8SkipListIPKcNS_8MemTable13KeyComparatorEEE:
   48|     96|  explicit MemTableIterator(MemTable::Table* table) : iter_(table) {}
_ZN7leveldb16MemTableIteratorD2Ev:
   53|     96|  ~MemTableIterator() override = default;
_ZNK7leveldb16MemTableIterator5ValidEv:
   55|    557|  bool Valid() const override { return iter_.Valid(); }
_ZN7leveldb16MemTableIterator11SeekToFirstEv:
   57|     68|  void SeekToFirst() override { iter_.SeekToFirst(); }
_ZN7leveldb16MemTableIterator4NextEv:
   59|    414|  void Next() override { iter_.Next(); }
_ZNK7leveldb16MemTableIterator3keyEv:
   61|    458|  Slice key() const override { return GetLengthPrefixedSlice(iter_.key()); }
_ZNK7leveldb16MemTableIterator5valueEv:
   62|    414|  Slice value() const override {
   63|    414|    Slice key_slice = GetLengthPrefixedSlice(iter_.key());
   64|    414|    return GetLengthPrefixedSlice(key_slice.data() + key_slice.size());
   65|    414|  }
_ZNK7leveldb16MemTableIterator6statusEv:
   67|     56|  Status status() const override { return Status::OK(); }

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

_ZN7leveldb8SkipListIPKcNS_8MemTable13KeyComparatorEE8Iterator11SeekToFirstEv:
  227|     68|inline void SkipList<Key, Comparator>::Iterator::SeekToFirst() {
  228|     68|  node_ = list_->head_->Next(0);
  229|     68|}
_ZN7leveldb8SkipListIPKcNS_8MemTable13KeyComparatorEE4Node4NextEi:
  151|  3.78k|  Node* Next(int n) {
  152|  3.78k|    assert(n >= 0);
  153|       |    // Use an 'acquire load' so that we observe a fully initialized
  154|       |    // version of the returned Node.
  155|  3.78k|    return next_[n].load(std::memory_order_acquire);
  156|  3.78k|  }
_ZNK7leveldb8SkipListIPKcNS_8MemTable13KeyComparatorEE12GetMaxHeightEv:
  102|  1.54k|  inline int GetMaxHeight() const {
  103|  1.54k|    return max_height_.load(std::memory_order_relaxed);
  104|  1.54k|  }
_ZN7leveldb8SkipListIPKcNS_8MemTable13KeyComparatorEE8Iterator4NextEv:
  205|    414|inline void SkipList<Key, Comparator>::Iterator::Next() {
  206|       |  assert(Valid());
  207|    414|  node_ = node_->Next(0);
  208|    414|}
_ZN7leveldb8SkipListIPKcNS_8MemTable13KeyComparatorEEC2ES4_PNS_5ArenaE:
  324|    164|    : compare_(cmp),
  325|    164|      arena_(arena),
  326|    164|      head_(NewNode(0 /* any key will do */, kMaxHeight)),
  327|    164|      max_height_(1),
  328|    164|      rnd_(0xdeadbeef) {
  329|  2.13k|  for (int i = 0; i < kMaxHeight; i++) {
  ------------------
  |  Branch (329:19): [True: 1.96k, False: 164]
  ------------------
  330|  1.96k|    head_->SetNext(i, nullptr);
  331|  1.96k|  }
  332|    164|}
_ZN7leveldb8SkipListIPKcNS_8MemTable13KeyComparatorEE7NewNodeERKS2_i:
  181|    862|    const Key& key, int height) {
  182|    862|  char* const node_memory = arena_->AllocateAligned(
  183|    862|      sizeof(Node) + sizeof(std::atomic<Node*>) * (height - 1));
  184|    862|  return new (node_memory) Node(key);
  185|    862|}
_ZN7leveldb8SkipListIPKcNS_8MemTable13KeyComparatorEE4NodeC2ERKS2_:
  145|    862|  explicit Node(const Key& k) : key(k) {}
_ZN7leveldb8SkipListIPKcNS_8MemTable13KeyComparatorEE4Node7SetNextEiPS6_:
  157|  2.85k|  void SetNext(int n, Node* x) {
  158|  2.85k|    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.85k|    next_[n].store(x, std::memory_order_release);
  162|  2.85k|  }
_ZN7leveldb8SkipListIPKcNS_8MemTable13KeyComparatorEE8IteratorC2EPKS5_:
  188|    120|inline SkipList<Key, Comparator>::Iterator::Iterator(const SkipList* list) {
  189|    120|  list_ = list;
  190|    120|  node_ = nullptr;
  191|    120|}
_ZNK7leveldb8SkipListIPKcNS_8MemTable13KeyComparatorEE8Iterator5ValidEv:
  194|    581|inline bool SkipList<Key, Comparator>::Iterator::Valid() const {
  195|    581|  return node_ != nullptr;
  196|    581|}
_ZN7leveldb8SkipListIPKcNS_8MemTable13KeyComparatorEE8Iterator4SeekERKS2_:
  222|     24|inline void SkipList<Key, Comparator>::Iterator::Seek(const Key& target) {
  223|     24|  node_ = list_->FindGreaterOrEqual(target, nullptr);
  224|     24|}
_ZNK7leveldb8SkipListIPKcNS_8MemTable13KeyComparatorEE18FindGreaterOrEqualERKS2_PPNS5_4NodeE:
  261|    722|                                              Node** prev) const {
  262|    722|  Node* x = head_;
  263|    722|  int level = GetMaxHeight() - 1;
  264|  3.30k|  while (true) {
  ------------------
  |  Branch (264:10): [True: 3.30k, Folded]
  ------------------
  265|  3.30k|    Node* next = x->Next(level);
  266|  3.30k|    if (KeyIsAfterNode(key, next)) {
  ------------------
  |  Branch (266:9): [True: 1.78k, False: 1.51k]
  ------------------
  267|       |      // Keep searching in this list
  268|  1.78k|      x = next;
  269|  1.78k|    } else {
  270|  1.51k|      if (prev != nullptr) prev[level] = x;
  ------------------
  |  Branch (270:11): [True: 1.48k, False: 37]
  ------------------
  271|  1.51k|      if (level == 0) {
  ------------------
  |  Branch (271:11): [True: 722, False: 797]
  ------------------
  272|    722|        return next;
  273|    797|      } else {
  274|       |        // Switch to next list
  275|    797|        level--;
  276|    797|      }
  277|  1.51k|    }
  278|  3.30k|  }
  279|    722|}
_ZNK7leveldb8SkipListIPKcNS_8MemTable13KeyComparatorEE14KeyIsAfterNodeERKS2_PNS5_4NodeE:
  253|  3.30k|bool SkipList<Key, Comparator>::KeyIsAfterNode(const Key& key, Node* n) const {
  254|       |  // null n is considered infinite
  255|  3.30k|  return (n != nullptr) && (compare_(n->key, key) < 0);
  ------------------
  |  Branch (255:10): [True: 2.94k, False: 359]
  |  Branch (255:28): [True: 1.78k, False: 1.16k]
  ------------------
  256|  3.30k|}
_ZNK7leveldb8SkipListIPKcNS_8MemTable13KeyComparatorEE8Iterator3keyEv:
  199|    879|inline const Key& SkipList<Key, Comparator>::Iterator::key() const {
  200|       |  assert(Valid());
  201|    879|  return node_->key;
  202|    879|}
_ZN7leveldb8SkipListIPKcNS_8MemTable13KeyComparatorEE6InsertERKS2_:
  335|    698|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|    698|  Node* prev[kMaxHeight];
  339|    698|  Node* x = FindGreaterOrEqual(key, prev);
  340|       |
  341|       |  // Our data structure does not allow duplicate insertion
  342|    698|  assert(x == nullptr || !Equal(key, x->key));
  343|       |
  344|    698|  int height = RandomHeight();
  345|    698|  if (height > GetMaxHeight()) {
  ------------------
  |  Branch (345:7): [True: 128, False: 570]
  ------------------
  346|    256|    for (int i = GetMaxHeight(); i < height; i++) {
  ------------------
  |  Branch (346:34): [True: 128, False: 128]
  ------------------
  347|    128|      prev[i] = head_;
  348|    128|    }
  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|    128|    max_height_.store(height, std::memory_order_relaxed);
  357|    128|  }
  358|       |
  359|    698|  x = NewNode(key, height);
  360|  1.58k|  for (int i = 0; i < height; i++) {
  ------------------
  |  Branch (360:19): [True: 882, False: 698]
  ------------------
  361|       |    // NoBarrier_SetNext() suffices since we will add a barrier when
  362|       |    // we publish a pointer to "x" in prev[i].
  363|    882|    x->NoBarrier_SetNext(i, prev[i]->NoBarrier_Next(i));
  364|    882|    prev[i]->SetNext(i, x);
  365|    882|  }
  366|    698|}
_ZN7leveldb8SkipListIPKcNS_8MemTable13KeyComparatorEE12RandomHeightEv:
  240|    698|int SkipList<Key, Comparator>::RandomHeight() {
  241|       |  // Increase height with probability 1 in kBranching
  242|    698|  static const unsigned int kBranching = 4;
  243|    698|  int height = 1;
  244|    882|  while (height < kMaxHeight && rnd_.OneIn(kBranching)) {
  ------------------
  |  Branch (244:10): [True: 882, False: 0]
  |  Branch (244:33): [True: 184, False: 698]
  ------------------
  245|    184|    height++;
  246|    184|  }
  247|    698|  assert(height > 0);
  248|       |  assert(height <= kMaxHeight);
  249|    698|  return height;
  250|    698|}
_ZN7leveldb8SkipListIPKcNS_8MemTable13KeyComparatorEE4Node17NoBarrier_SetNextEiPS6_:
  169|    882|  void NoBarrier_SetNext(int n, Node* x) {
  170|       |    assert(n >= 0);
  171|    882|    next_[n].store(x, std::memory_order_relaxed);
  172|    882|  }
_ZN7leveldb8SkipListIPKcNS_8MemTable13KeyComparatorEE4Node14NoBarrier_NextEi:
  165|    882|  Node* NoBarrier_Next(int n) {
  166|       |    assert(n >= 0);
  167|    882|    return next_[n].load(std::memory_order_relaxed);
  168|    882|  }

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

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

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

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

_ZN7leveldb7VersionD2Ev:
   67|    461|Version::~Version() {
   68|    461|  assert(refs_ == 0);
   69|       |
   70|       |  // Remove from linked list
   71|    461|  prev_->next_ = next_;
   72|    461|  next_->prev_ = prev_;
   73|       |
   74|       |  // Drop references to files
   75|  3.68k|  for (int level = 0; level < config::kNumLevels; level++) {
  ------------------
  |  Branch (75:23): [True: 3.22k, False: 461]
  ------------------
   76|  3.49k|    for (size_t i = 0; i < files_[level].size(); i++) {
  ------------------
  |  Branch (76:24): [True: 264, False: 3.22k]
  ------------------
   77|    264|      FileMetaData* f = files_[level][i];
   78|    264|      assert(f->refs > 0);
   79|    264|      f->refs--;
   80|    264|      if (f->refs <= 0) {
  ------------------
  |  Branch (80:11): [True: 136, False: 128]
  ------------------
   81|    136|        delete f;
   82|    136|      }
   83|    264|    }
   84|  3.22k|  }
   85|    461|}
_ZN7leveldb8FindFileERKNS_21InternalKeyComparatorERKNSt3__16vectorIPNS_12FileMetaDataENS3_9allocatorIS6_EEEERKNS_5SliceE:
   88|    140|             const std::vector<FileMetaData*>& files, const Slice& key) {
   89|    140|  uint32_t left = 0;
   90|    140|  uint32_t right = files.size();
   91|    163|  while (left < right) {
  ------------------
  |  Branch (91:10): [True: 23, False: 140]
  ------------------
   92|     23|    uint32_t mid = (left + right) / 2;
   93|     23|    const FileMetaData* f = files[mid];
   94|     23|    if (icmp.InternalKeyComparator::Compare(f->largest.Encode(), key) < 0) {
  ------------------
  |  Branch (94:9): [True: 10, False: 13]
  ------------------
   95|       |      // Key at "mid.largest" is < "target".  Therefore all
   96|       |      // files at or before "mid" are uninteresting.
   97|     10|      left = mid + 1;
   98|     13|    } else {
   99|       |      // Key at "mid.largest" is >= "target".  Therefore all files
  100|       |      // after "mid" are uninteresting.
  101|     13|      right = mid;
  102|     13|    }
  103|     23|  }
  104|    140|  return right;
  105|    140|}
_ZN7leveldb21SomeFileOverlapsRangeERKNS_21InternalKeyComparatorEbRKNSt3__16vectorIPNS_12FileMetaDataENS3_9allocatorIS6_EEEEPKNS_5SliceESE_:
  125|    132|                           const Slice* largest_user_key) {
  126|    132|  const Comparator* ucmp = icmp.user_comparator();
  127|    132|  if (!disjoint_sorted_files) {
  ------------------
  |  Branch (127:7): [True: 8, False: 124]
  ------------------
  128|       |    // Need to check against all files
  129|      8|    for (size_t i = 0; i < files.size(); i++) {
  ------------------
  |  Branch (129:24): [True: 6, False: 2]
  ------------------
  130|      6|      const FileMetaData* f = files[i];
  131|      6|      if (AfterFile(ucmp, smallest_user_key, f) ||
  ------------------
  |  Branch (131:11): [True: 0, False: 6]
  ------------------
  132|      6|          BeforeFile(ucmp, largest_user_key, f)) {
  ------------------
  |  Branch (132:11): [True: 0, False: 6]
  ------------------
  133|       |        // No overlap
  134|      6|      } else {
  135|      6|        return true;  // Overlap
  136|      6|      }
  137|      6|    }
  138|      2|    return false;
  139|      8|  }
  140|       |
  141|       |  // Binary search over file list
  142|    124|  uint32_t index = 0;
  143|    124|  if (smallest_user_key != nullptr) {
  ------------------
  |  Branch (143:7): [True: 124, False: 0]
  ------------------
  144|       |    // Find the earliest possible internal key for smallest_user_key
  145|    124|    InternalKey small_key(*smallest_user_key, kMaxSequenceNumber,
  146|    124|                          kValueTypeForSeek);
  147|    124|    index = FindFile(icmp, files, small_key.Encode());
  148|    124|  }
  149|       |
  150|    124|  if (index >= files.size()) {
  ------------------
  |  Branch (150:7): [True: 121, False: 3]
  ------------------
  151|       |    // beginning of range is after all files, so no overlap.
  152|    121|    return false;
  153|    121|  }
  154|       |
  155|      3|  return !BeforeFile(ucmp, largest_user_key, files[index]);
  156|    124|}
_ZNK7leveldb7Version24NewConcatenatingIteratorERKNS_11ReadOptionsEi:
  223|     19|                                            int level) const {
  224|     19|  return NewTwoLevelIterator(
  225|     19|      new LevelFileNumIterator(vset_->icmp_, &files_[level]), &GetFileIterator,
  226|     19|      vset_->table_cache_, options);
  227|     19|}
_ZN7leveldb7Version12AddIteratorsERKNS_11ReadOptionsEPNSt3__16vectorIPNS_8IteratorENS4_9allocatorIS7_EEEE:
  230|     40|                           std::vector<Iterator*>* iters) {
  231|       |  // Merge all level zero files together since they may overlap
  232|     79|  for (size_t i = 0; i < files_[0].size(); i++) {
  ------------------
  |  Branch (232:22): [True: 39, False: 40]
  ------------------
  233|     39|    iters->push_back(vset_->table_cache_->NewIterator(
  234|     39|        options, files_[0][i]->number, files_[0][i]->file_size));
  235|     39|  }
  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|    280|  for (int level = 1; level < config::kNumLevels; level++) {
  ------------------
  |  Branch (240:23): [True: 240, False: 40]
  ------------------
  241|    240|    if (!files_[level].empty()) {
  ------------------
  |  Branch (241:9): [True: 19, False: 221]
  ------------------
  242|     19|      iters->push_back(NewConcatenatingIterator(options, level));
  243|     19|    }
  244|    240|  }
  245|     40|}
_ZN7leveldb7Version18ForEachOverlappingENS_5SliceES1_PvPFbS2_iPNS_12FileMetaDataEE:
  282|     33|                                 bool (*func)(void*, int, FileMetaData*)) {
  283|     33|  const Comparator* ucmp = vset_->icmp_.user_comparator();
  284|       |
  285|       |  // Search level-0 in order from newest to oldest.
  286|     33|  std::vector<FileMetaData*> tmp;
  287|     33|  tmp.reserve(files_[0].size());
  288|     64|  for (uint32_t i = 0; i < files_[0].size(); i++) {
  ------------------
  |  Branch (288:24): [True: 31, False: 33]
  ------------------
  289|     31|    FileMetaData* f = files_[0][i];
  290|     31|    if (ucmp->Compare(user_key, f->smallest.user_key()) >= 0 &&
  ------------------
  |  Branch (290:9): [True: 27, False: 4]
  |  Branch (290:9): [True: 22, False: 9]
  ------------------
  291|     27|        ucmp->Compare(user_key, f->largest.user_key()) <= 0) {
  ------------------
  |  Branch (291:9): [True: 22, False: 5]
  ------------------
  292|     22|      tmp.push_back(f);
  293|     22|    }
  294|     31|  }
  295|     33|  if (!tmp.empty()) {
  ------------------
  |  Branch (295:7): [True: 16, False: 17]
  ------------------
  296|     16|    std::sort(tmp.begin(), tmp.end(), NewestFirst);
  297|     38|    for (uint32_t i = 0; i < tmp.size(); i++) {
  ------------------
  |  Branch (297:26): [True: 22, False: 16]
  ------------------
  298|     22|      if (!(*func)(arg, 0, tmp[i])) {
  ------------------
  |  Branch (298:11): [True: 0, False: 22]
  ------------------
  299|      0|        return;
  300|      0|      }
  301|     22|    }
  302|     16|  }
  303|       |
  304|       |  // Search other levels.
  305|    213|  for (int level = 1; level < config::kNumLevels; level++) {
  ------------------
  |  Branch (305:23): [True: 183, False: 30]
  ------------------
  306|    183|    size_t num_files = files_[level].size();
  307|    183|    if (num_files == 0) continue;
  ------------------
  |  Branch (307:9): [True: 167, False: 16]
  ------------------
  308|       |
  309|       |    // Binary search to find earliest index whose largest key >= internal_key.
  310|     16|    uint32_t index = FindFile(vset_->icmp_, files_[level], internal_key);
  311|     16|    if (index < num_files) {
  ------------------
  |  Branch (311:9): [True: 10, False: 6]
  ------------------
  312|     10|      FileMetaData* f = files_[level][index];
  313|     10|      if (ucmp->Compare(user_key, f->smallest.user_key()) < 0) {
  ------------------
  |  Branch (313:11): [True: 4, False: 6]
  ------------------
  314|       |        // All of "f" is past any data for user_key
  315|      6|      } else {
  316|      6|        if (!(*func)(arg, level, f)) {
  ------------------
  |  Branch (316:13): [True: 3, False: 3]
  ------------------
  317|      3|          return;
  318|      3|        }
  319|      6|      }
  320|     10|    }
  321|     16|  }
  322|     33|}
_ZN7leveldb7Version3GetERKNS_11ReadOptionsERKNS_9LookupKeyEPNSt3__112basic_stringIcNS7_11char_traitsIcEENS7_9allocatorIcEEEEPNS0_8GetStatsE:
  325|     23|                    std::string* value, GetStats* stats) {
  326|     23|  stats->seek_file = nullptr;
  327|     23|  stats->seek_file_level = -1;
  328|       |
  329|     23|  struct State {
  330|     23|    Saver saver;
  331|     23|    GetStats* stats;
  332|     23|    const ReadOptions* options;
  333|     23|    Slice ikey;
  334|     23|    FileMetaData* last_file_read;
  335|     23|    int last_file_read_level;
  336|       |
  337|     23|    VersionSet* vset;
  338|     23|    Status s;
  339|     23|    bool found;
  340|       |
  341|     23|    static bool Match(void* arg, int level, FileMetaData* f) {
  342|     23|      State* state = reinterpret_cast<State*>(arg);
  343|       |
  344|     23|      if (state->stats->seek_file == nullptr &&
  345|     23|          state->last_file_read != nullptr) {
  346|       |        // We have had more than one seek for this read.  Charge the 1st file.
  347|     23|        state->stats->seek_file = state->last_file_read;
  348|     23|        state->stats->seek_file_level = state->last_file_read_level;
  349|     23|      }
  350|       |
  351|     23|      state->last_file_read = f;
  352|     23|      state->last_file_read_level = level;
  353|       |
  354|     23|      state->s = state->vset->table_cache_->Get(*state->options, f->number,
  355|     23|                                                f->file_size, state->ikey,
  356|     23|                                                &state->saver, SaveValue);
  357|     23|      if (!state->s.ok()) {
  358|     23|        state->found = true;
  359|     23|        return false;
  360|     23|      }
  361|     23|      switch (state->saver.state) {
  362|     23|        case kNotFound:
  363|     23|          return true;  // Keep searching in other files
  364|     23|        case kFound:
  365|     23|          state->found = true;
  366|     23|          return false;
  367|     23|        case kDeleted:
  368|     23|          return false;
  369|     23|        case kCorrupt:
  370|     23|          state->s =
  371|     23|              Status::Corruption("corrupted key for ", state->saver.user_key);
  372|     23|          state->found = true;
  373|     23|          return false;
  374|     23|      }
  375|       |
  376|       |      // Not reached. Added to avoid false compilation warnings of
  377|       |      // "control reaches end of non-void function".
  378|     23|      return false;
  379|     23|    }
  380|     23|  };
  381|       |
  382|     23|  State state;
  383|     23|  state.found = false;
  384|     23|  state.stats = stats;
  385|     23|  state.last_file_read = nullptr;
  386|     23|  state.last_file_read_level = -1;
  387|       |
  388|     23|  state.options = &options;
  389|     23|  state.ikey = k.internal_key();
  390|     23|  state.vset = vset_;
  391|       |
  392|     23|  state.saver.state = kNotFound;
  393|     23|  state.saver.ucmp = vset_->icmp_.user_comparator();
  394|     23|  state.saver.user_key = k.user_key();
  395|     23|  state.saver.value = value;
  396|       |
  397|     23|  ForEachOverlapping(state.saver.user_key, state.ikey, &state, &State::Match);
  398|       |
  399|     23|  return state.found ? state.s : Status::NotFound(Slice());
  ------------------
  |  Branch (399:10): [True: 0, False: 23]
  ------------------
  400|     23|}
_ZN7leveldb7Version11UpdateStatsERKNS0_8GetStatsE:
  402|     26|bool Version::UpdateStats(const GetStats& stats) {
  403|     26|  FileMetaData* f = stats.seek_file;
  404|     26|  if (f != nullptr) {
  ------------------
  |  Branch (404:7): [True: 6, False: 20]
  ------------------
  405|      6|    f->allowed_seeks--;
  406|      6|    if (f->allowed_seeks <= 0 && file_to_compact_ == nullptr) {
  ------------------
  |  Branch (406:9): [True: 0, False: 6]
  |  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|      6|  }
  412|     26|  return false;
  413|     26|}
_ZN7leveldb7Version16RecordReadSampleENS_5SliceE:
  415|     10|bool Version::RecordReadSample(Slice internal_key) {
  416|     10|  ParsedInternalKey ikey;
  417|     10|  if (!ParseInternalKey(internal_key, &ikey)) {
  ------------------
  |  Branch (417:7): [True: 0, False: 10]
  ------------------
  418|      0|    return false;
  419|      0|  }
  420|       |
  421|     10|  struct State {
  422|     10|    GetStats stats;  // Holds first matching file
  423|     10|    int matches;
  424|       |
  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) {
  429|       |        // Remember first match.
  430|     10|        state->stats.seek_file = f;
  431|     10|        state->stats.seek_file_level = level;
  432|     10|      }
  433|       |      // We can stop iterating once we have a second match.
  434|     10|      return state->matches < 2;
  435|     10|    }
  436|     10|  };
  437|       |
  438|     10|  State state;
  439|     10|  state.matches = 0;
  440|     10|  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|     10|  if (state.matches >= 2) {
  ------------------
  |  Branch (446:7): [True: 3, False: 7]
  ------------------
  447|       |    // 1MB cost is about 1 seek (see comment in Builder::Apply).
  448|      3|    return UpdateStats(state.stats);
  449|      3|  }
  450|      7|  return false;
  451|     10|}
_ZN7leveldb7Version3RefEv:
  453|    691|void Version::Ref() { ++refs_; }
_ZN7leveldb7Version5UnrefEv:
  455|    691|void Version::Unref() {
  456|    691|  assert(this != &vset_->dummy_versions_);
  457|    691|  assert(refs_ >= 1);
  458|    691|  --refs_;
  459|    691|  if (refs_ == 0) {
  ------------------
  |  Branch (459:7): [True: 353, False: 338]
  ------------------
  460|    353|    delete this;
  461|    353|  }
  462|    691|}
_ZN7leveldb7Version14OverlapInLevelEiPKNS_5SliceES3_:
  465|    132|                             const Slice* largest_user_key) {
  466|    132|  return SomeFileOverlapsRange(vset_->icmp_, (level > 0), files_[level],
  467|    132|                               smallest_user_key, largest_user_key);
  468|    132|}
_ZN7leveldb7Version26PickLevelForMemTableOutputERKNS_5SliceES3_:
  471|      8|                                        const Slice& largest_user_key) {
  472|      8|  int level = 0;
  473|      8|  if (!OverlapInLevel(0, &smallest_user_key, &largest_user_key)) {
  ------------------
  |  Branch (473:7): [True: 2, False: 6]
  ------------------
  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|      8|  return level;
  495|      8|}
_ZN7leveldb7Version20GetOverlappingInputsEiPKNS_11InternalKeyES3_PNSt3__16vectorIPNS_12FileMetaDataENS4_9allocatorIS7_EEEE:
  500|     54|                                   std::vector<FileMetaData*>* inputs) {
  501|     54|  assert(level >= 0);
  502|     54|  assert(level < config::kNumLevels);
  503|     54|  inputs->clear();
  504|     54|  Slice user_begin, user_end;
  505|     54|  if (begin != nullptr) {
  ------------------
  |  Branch (505:7): [True: 54, False: 0]
  ------------------
  506|     54|    user_begin = begin->user_key();
  507|     54|  }
  508|     54|  if (end != nullptr) {
  ------------------
  |  Branch (508:7): [True: 54, False: 0]
  ------------------
  509|     54|    user_end = end->user_key();
  510|     54|  }
  511|     54|  const Comparator* user_cmp = vset_->icmp_.user_comparator();
  512|    138|  for (size_t i = 0; i < files_[level].size();) {
  ------------------
  |  Branch (512:22): [True: 84, False: 54]
  ------------------
  513|     84|    FileMetaData* f = files_[level][i++];
  514|     84|    const Slice file_start = f->smallest.user_key();
  515|     84|    const Slice file_limit = f->largest.user_key();
  516|     84|    if (begin != nullptr && user_cmp->Compare(file_limit, user_begin) < 0) {
  ------------------
  |  Branch (516:9): [True: 84, False: 0]
  |  Branch (516:29): [True: 10, False: 74]
  ------------------
  517|       |      // "f" is completely before specified range; skip it
  518|     74|    } else if (end != nullptr && user_cmp->Compare(file_start, user_end) > 0) {
  ------------------
  |  Branch (518:16): [True: 74, False: 0]
  |  Branch (518:34): [True: 9, False: 65]
  ------------------
  519|       |      // "f" is completely after specified range; skip it
  520|     65|    } else {
  521|     65|      inputs->push_back(f);
  522|     65|      if (level == 0) {
  ------------------
  |  Branch (522:11): [True: 62, False: 3]
  ------------------
  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|     62|        if (begin != nullptr && user_cmp->Compare(file_start, user_begin) < 0) {
  ------------------
  |  Branch (525:13): [True: 62, False: 0]
  |  Branch (525:33): [True: 3, False: 59]
  ------------------
  526|      3|          user_begin = file_start;
  527|      3|          inputs->clear();
  528|      3|          i = 0;
  529|     59|        } else if (end != nullptr &&
  ------------------
  |  Branch (529:20): [True: 59, False: 0]
  ------------------
  530|     59|                   user_cmp->Compare(file_limit, user_end) > 0) {
  ------------------
  |  Branch (530:20): [True: 9, False: 50]
  ------------------
  531|      9|          user_end = file_limit;
  532|      9|          inputs->clear();
  533|      9|          i = 0;
  534|      9|        }
  535|     62|      }
  536|     65|    }
  537|     84|  }
  538|     54|}
_ZN7leveldb10VersionSetC2ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEPKNS_7OptionsEPNS_10TableCacheEPKNS_21InternalKeyComparatorE:
  736|    108|    : env_(options->env),
  737|    108|      dbname_(dbname),
  738|    108|      options_(options),
  739|    108|      table_cache_(table_cache),
  740|    108|      icmp_(*cmp),
  741|    108|      next_file_number_(2),
  742|    108|      manifest_file_number_(0),  // Filled by Recover()
  743|    108|      last_sequence_(0),
  744|    108|      log_number_(0),
  745|    108|      prev_log_number_(0),
  746|    108|      descriptor_file_(nullptr),
  747|    108|      descriptor_log_(nullptr),
  748|    108|      dummy_versions_(this),
  749|    108|      current_(nullptr) {
  750|    108|  AppendVersion(new Version(this));
  751|    108|}
_ZN7leveldb10VersionSetD2Ev:
  753|    108|VersionSet::~VersionSet() {
  754|    108|  current_->Unref();
  755|       |  assert(dummy_versions_.next_ == &dummy_versions_);  // List must be empty
  756|    108|  delete descriptor_log_;
  757|    108|  delete descriptor_file_;
  758|    108|}
_ZN7leveldb10VersionSet13AppendVersionEPNS_7VersionE:
  760|    353|void VersionSet::AppendVersion(Version* v) {
  761|       |  // Make "v" current
  762|    353|  assert(v->refs_ == 0);
  763|    353|  assert(v != current_);
  764|    353|  if (current_ != nullptr) {
  ------------------
  |  Branch (764:7): [True: 245, False: 108]
  ------------------
  765|    245|    current_->Unref();
  766|    245|  }
  767|    353|  current_ = v;
  768|    353|  v->Ref();
  769|       |
  770|       |  // Append to linked list
  771|    353|  v->prev_ = dummy_versions_.prev_;
  772|    353|  v->next_ = &dummy_versions_;
  773|    353|  v->prev_->next_ = v;
  774|    353|  v->next_->prev_ = v;
  775|    353|}
_ZN7leveldb10VersionSet11LogAndApplyEPNS_11VersionEditEPNS_4port5MutexE:
  777|    137|Status VersionSet::LogAndApply(VersionEdit* edit, port::Mutex* mu) {
  778|    137|  if (edit->has_log_number_) {
  ------------------
  |  Branch (778:7): [True: 128, False: 9]
  ------------------
  779|    128|    assert(edit->log_number_ >= log_number_);
  780|    128|    assert(edit->log_number_ < next_file_number_);
  781|    128|  } else {
  782|      9|    edit->SetLogNumber(log_number_);
  783|      9|  }
  784|       |
  785|    137|  if (!edit->has_prev_log_number_) {
  ------------------
  |  Branch (785:7): [True: 9, False: 128]
  ------------------
  786|      9|    edit->SetPrevLogNumber(prev_log_number_);
  787|      9|  }
  788|       |
  789|    137|  edit->SetNextFile(next_file_number_);
  790|    137|  edit->SetLastSequence(last_sequence_);
  791|       |
  792|    137|  Version* v = new Version(this);
  793|    137|  {
  794|    137|    Builder builder(this, current_);
  795|    137|    builder.Apply(edit);
  796|    137|    builder.SaveTo(v);
  797|    137|  }
  798|    137|  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|    137|  std::string new_manifest_file;
  803|    137|  Status s;
  804|    137|  if (descriptor_log_ == nullptr) {
  ------------------
  |  Branch (804:7): [True: 108, False: 29]
  ------------------
  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|    108|    assert(descriptor_file_ == nullptr);
  808|    108|    new_manifest_file = DescriptorFileName(dbname_, manifest_file_number_);
  809|    108|    s = env_->NewWritableFile(new_manifest_file, &descriptor_file_);
  810|    108|    if (s.ok()) {
  ------------------
  |  Branch (810:9): [True: 108, False: 0]
  ------------------
  811|    108|      descriptor_log_ = new log::Writer(descriptor_file_);
  812|    108|      s = WriteSnapshot(descriptor_log_);
  813|    108|    }
  814|    108|  }
  815|       |
  816|       |  // Unlock during expensive MANIFEST log write
  817|    137|  {
  818|    137|    mu->Unlock();
  819|       |
  820|       |    // Write new record to MANIFEST log
  821|    137|    if (s.ok()) {
  ------------------
  |  Branch (821:9): [True: 137, False: 0]
  ------------------
  822|    137|      std::string record;
  823|    137|      edit->EncodeTo(&record);
  824|    137|      s = descriptor_log_->AddRecord(record);
  825|    137|      if (s.ok()) {
  ------------------
  |  Branch (825:11): [True: 137, False: 0]
  ------------------
  826|    137|        s = descriptor_file_->Sync();
  827|    137|      }
  828|    137|      if (!s.ok()) {
  ------------------
  |  Branch (828:11): [True: 0, False: 137]
  ------------------
  829|      0|        Log(options_->info_log, "MANIFEST write: %s\n", s.ToString().c_str());
  830|      0|      }
  831|    137|    }
  832|       |
  833|       |    // If we just created a new descriptor file, install it by writing a
  834|       |    // new CURRENT file that points to it.
  835|    137|    if (s.ok() && !new_manifest_file.empty()) {
  ------------------
  |  Branch (835:9): [True: 137, False: 0]
  |  Branch (835:19): [True: 108, False: 29]
  ------------------
  836|    108|      s = SetCurrentFile(env_, dbname_, manifest_file_number_);
  837|    108|    }
  838|       |
  839|    137|    mu->Lock();
  840|    137|  }
  841|       |
  842|       |  // Install the new version
  843|    137|  if (s.ok()) {
  ------------------
  |  Branch (843:7): [True: 137, False: 0]
  ------------------
  844|    137|    AppendVersion(v);
  845|    137|    log_number_ = edit->log_number_;
  846|    137|    prev_log_number_ = edit->prev_log_number_;
  847|    137|  } 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|    137|  return s;
  859|    137|}
_ZN7leveldb10VersionSet7RecoverEPb:
  861|    108|Status VersionSet::Recover(bool* save_manifest) {
  862|    108|  struct LogReporter : public log::Reader::Reporter {
  863|    108|    Status* status;
  864|    108|    void Corruption(size_t bytes, const Status& s) override {
  865|    108|      if (this->status->ok()) *this->status = s;
  866|    108|    }
  867|    108|  };
  868|       |
  869|       |  // Read "CURRENT" file, which contains a pointer to the current manifest file
  870|    108|  std::string current;
  871|    108|  Status s = ReadFileToString(env_, CurrentFileName(dbname_), &current);
  872|    108|  if (!s.ok()) {
  ------------------
  |  Branch (872:7): [True: 0, False: 108]
  ------------------
  873|      0|    return s;
  874|      0|  }
  875|    108|  if (current.empty() || current[current.size() - 1] != '\n') {
  ------------------
  |  Branch (875:7): [True: 0, False: 108]
  |  Branch (875:26): [True: 0, False: 108]
  ------------------
  876|      0|    return Status::Corruption("CURRENT file does not end with newline");
  877|      0|  }
  878|    108|  current.resize(current.size() - 1);
  879|       |
  880|    108|  std::string dscname = dbname_ + "/" + current;
  881|    108|  SequentialFile* file;
  882|    108|  s = env_->NewSequentialFile(dscname, &file);
  883|    108|  if (!s.ok()) {
  ------------------
  |  Branch (883:7): [True: 0, False: 108]
  ------------------
  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|    108|  bool have_log_number = false;
  892|    108|  bool have_prev_log_number = false;
  893|    108|  bool have_next_file = false;
  894|    108|  bool have_last_sequence = false;
  895|    108|  uint64_t next_file = 0;
  896|    108|  uint64_t last_sequence = 0;
  897|    108|  uint64_t log_number = 0;
  898|    108|  uint64_t prev_log_number = 0;
  899|    108|  Builder builder(this, current_);
  900|    108|  int read_records = 0;
  901|       |
  902|    108|  {
  903|    108|    LogReporter reporter;
  904|    108|    reporter.status = &s;
  905|    108|    log::Reader reader(file, &reporter, true /*checksum*/,
  906|    108|                       0 /*initial_offset*/);
  907|    108|    Slice record;
  908|    108|    std::string scratch;
  909|    296|    while (reader.ReadRecord(&record, &scratch) && s.ok()) {
  ------------------
  |  Branch (909:12): [True: 188, False: 108]
  |  Branch (909:52): [True: 188, False: 0]
  ------------------
  910|    188|      ++read_records;
  911|    188|      VersionEdit edit;
  912|    188|      s = edit.DecodeFrom(record);
  913|    188|      if (s.ok()) {
  ------------------
  |  Branch (913:11): [True: 188, False: 0]
  ------------------
  914|    188|        if (edit.has_comparator_ &&
  ------------------
  |  Branch (914:13): [True: 108, False: 80]
  ------------------
  915|    108|            edit.comparator_ != icmp_.user_comparator()->Name()) {
  ------------------
  |  Branch (915:13): [True: 0, False: 108]
  ------------------
  916|      0|          s = Status::InvalidArgument(
  917|      0|              edit.comparator_ + " does not match existing comparator ",
  918|      0|              icmp_.user_comparator()->Name());
  919|      0|        }
  920|    188|      }
  921|       |
  922|    188|      if (s.ok()) {
  ------------------
  |  Branch (922:11): [True: 188, False: 0]
  ------------------
  923|    188|        builder.Apply(&edit);
  924|    188|      }
  925|       |
  926|    188|      if (edit.has_log_number_) {
  ------------------
  |  Branch (926:11): [True: 129, False: 59]
  ------------------
  927|    129|        log_number = edit.log_number_;
  928|    129|        have_log_number = true;
  929|    129|      }
  930|       |
  931|    188|      if (edit.has_prev_log_number_) {
  ------------------
  |  Branch (931:11): [True: 80, False: 108]
  ------------------
  932|     80|        prev_log_number = edit.prev_log_number_;
  933|     80|        have_prev_log_number = true;
  934|     80|      }
  935|       |
  936|    188|      if (edit.has_next_file_number_) {
  ------------------
  |  Branch (936:11): [True: 129, False: 59]
  ------------------
  937|    129|        next_file = edit.next_file_number_;
  938|    129|        have_next_file = true;
  939|    129|      }
  940|       |
  941|    188|      if (edit.has_last_sequence_) {
  ------------------
  |  Branch (941:11): [True: 129, False: 59]
  ------------------
  942|    129|        last_sequence = edit.last_sequence_;
  943|    129|        have_last_sequence = true;
  944|    129|      }
  945|    188|    }
  946|    108|  }
  947|    108|  delete file;
  948|    108|  file = nullptr;
  949|       |
  950|    108|  if (s.ok()) {
  ------------------
  |  Branch (950:7): [True: 108, False: 0]
  ------------------
  951|    108|    if (!have_next_file) {
  ------------------
  |  Branch (951:9): [True: 0, False: 108]
  ------------------
  952|      0|      s = Status::Corruption("no meta-nextfile entry in descriptor");
  953|    108|    } else if (!have_log_number) {
  ------------------
  |  Branch (953:16): [True: 0, False: 108]
  ------------------
  954|      0|      s = Status::Corruption("no meta-lognumber entry in descriptor");
  955|    108|    } else if (!have_last_sequence) {
  ------------------
  |  Branch (955:16): [True: 0, False: 108]
  ------------------
  956|      0|      s = Status::Corruption("no last-sequence-number entry in descriptor");
  957|      0|    }
  958|       |
  959|    108|    if (!have_prev_log_number) {
  ------------------
  |  Branch (959:9): [True: 49, False: 59]
  ------------------
  960|     49|      prev_log_number = 0;
  961|     49|    }
  962|       |
  963|    108|    MarkFileNumberUsed(prev_log_number);
  964|    108|    MarkFileNumberUsed(log_number);
  965|    108|  }
  966|       |
  967|    108|  if (s.ok()) {
  ------------------
  |  Branch (967:7): [True: 108, False: 0]
  ------------------
  968|    108|    Version* v = new Version(this);
  969|    108|    builder.SaveTo(v);
  970|       |    // Install recovered version
  971|    108|    Finalize(v);
  972|    108|    AppendVersion(v);
  973|    108|    manifest_file_number_ = next_file;
  974|    108|    next_file_number_ = next_file + 1;
  975|    108|    last_sequence_ = last_sequence;
  976|    108|    log_number_ = log_number;
  977|    108|    prev_log_number_ = prev_log_number;
  978|       |
  979|       |    // See if we can reuse the existing MANIFEST file.
  980|    108|    if (ReuseManifest(dscname, current)) {
  ------------------
  |  Branch (980:9): [True: 0, False: 108]
  ------------------
  981|       |      // No need to save new manifest
  982|    108|    } else {
  983|    108|      *save_manifest = true;
  984|    108|    }
  985|    108|  } 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|    108|  return s;
  992|    108|}
_ZN7leveldb10VersionSet13ReuseManifestERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEES9_:
  995|    108|                               const std::string& dscbase) {
  996|    108|  if (!options_->reuse_logs) {
  ------------------
  |  Branch (996:7): [True: 108, False: 0]
  ------------------
  997|    108|    return false;
  998|    108|  }
  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|    276|void VersionSet::MarkFileNumberUsed(uint64_t number) {
 1026|    276|  if (next_file_number_ <= number) {
  ------------------
  |  Branch (1026:7): [True: 60, False: 216]
  ------------------
 1027|     60|    next_file_number_ = number + 1;
 1028|     60|  }
 1029|    276|}
_ZN7leveldb10VersionSet8FinalizeEPNS_7VersionE:
 1031|    245|void VersionSet::Finalize(Version* v) {
 1032|       |  // Precomputed best level for next compaction
 1033|    245|  int best_level = -1;
 1034|    245|  double best_score = -1;
 1035|       |
 1036|  1.71k|  for (int level = 0; level < config::kNumLevels - 1; level++) {
  ------------------
  |  Branch (1036:23): [True: 1.47k, False: 245]
  ------------------
 1037|  1.47k|    double score;
 1038|  1.47k|    if (level == 0) {
  ------------------
  |  Branch (1038:9): [True: 245, False: 1.22k]
  ------------------
 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|    245|      score = v->files_[level].size() /
 1051|    245|              static_cast<double>(config::kL0_CompactionTrigger);
 1052|  1.22k|    } else {
 1053|       |      // Compute the ratio of current size to size limit.
 1054|  1.22k|      const uint64_t level_bytes = TotalFileSize(v->files_[level]);
 1055|  1.22k|      score =
 1056|  1.22k|          static_cast<double>(level_bytes) / MaxBytesForLevel(options_, level);
 1057|  1.22k|    }
 1058|       |
 1059|  1.47k|    if (score > best_score) {
  ------------------
  |  Branch (1059:9): [True: 273, False: 1.19k]
  ------------------
 1060|    273|      best_level = level;
 1061|    273|      best_score = score;
 1062|    273|    }
 1063|  1.47k|  }
 1064|       |
 1065|    245|  v->compaction_level_ = best_level;
 1066|    245|  v->compaction_score_ = best_score;
 1067|    245|}
_ZN7leveldb10VersionSet13WriteSnapshotEPNS_3log6WriterE:
 1069|    108|Status VersionSet::WriteSnapshot(log::Writer* log) {
 1070|       |  // TODO: Break up into multiple records to reduce memory usage on recovery?
 1071|       |
 1072|       |  // Save metadata
 1073|    108|  VersionEdit edit;
 1074|    108|  edit.SetComparatorName(icmp_.user_comparator()->Name());
 1075|       |
 1076|       |  // Save compaction pointers
 1077|    864|  for (int level = 0; level < config::kNumLevels; level++) {
  ------------------
  |  Branch (1077:23): [True: 756, False: 108]
  ------------------
 1078|    756|    if (!compact_pointer_[level].empty()) {
  ------------------
  |  Branch (1078:9): [True: 20, False: 736]
  ------------------
 1079|     20|      InternalKey key;
 1080|     20|      key.DecodeFrom(compact_pointer_[level]);
 1081|     20|      edit.SetCompactPointer(level, key);
 1082|     20|    }
 1083|    756|  }
 1084|       |
 1085|       |  // Save files
 1086|    864|  for (int level = 0; level < config::kNumLevels; level++) {
  ------------------
  |  Branch (1086:23): [True: 756, False: 108]
  ------------------
 1087|    756|    const std::vector<FileMetaData*>& files = current_->files_[level];
 1088|    839|    for (size_t i = 0; i < files.size(); i++) {
  ------------------
  |  Branch (1088:24): [True: 83, False: 756]
  ------------------
 1089|     83|      const FileMetaData* f = files[i];
 1090|     83|      edit.AddFile(level, f->number, f->file_size, f->smallest, f->largest);
 1091|     83|    }
 1092|    756|  }
 1093|       |
 1094|    108|  std::string record;
 1095|    108|  edit.EncodeTo(&record);
 1096|    108|  return log->AddRecord(record);
 1097|    108|}
_ZNK7leveldb10VersionSet13NumLevelFilesEi:
 1099|    572|int VersionSet::NumLevelFiles(int level) const {
 1100|    572|  assert(level >= 0);
 1101|       |  assert(level < config::kNumLevels);
 1102|    572|  return current_->files_[level].size();
 1103|    572|}
_ZNK7leveldb10VersionSet12LevelSummaryEPNS0_19LevelSummaryStorageE:
 1105|      9|const char* VersionSet::LevelSummary(LevelSummaryStorage* scratch) const {
 1106|       |  // Update code if kNumLevels changes
 1107|      9|  static_assert(config::kNumLevels == 7, "");
 1108|      9|  std::snprintf(
 1109|      9|      scratch->buffer, sizeof(scratch->buffer), "files[ %d %d %d %d %d %d %d ]",
 1110|      9|      int(current_->files_[0].size()), int(current_->files_[1].size()),
 1111|      9|      int(current_->files_[2].size()), int(current_->files_[3].size()),
 1112|      9|      int(current_->files_[4].size()), int(current_->files_[5].size()),
 1113|      9|      int(current_->files_[6].size()));
 1114|      9|  return scratch->buffer;
 1115|      9|}
_ZN7leveldb10VersionSet12AddLiveFilesEPNSt3__13setImNS1_4lessImEENS1_9allocatorImEEEE:
 1149|    244|void VersionSet::AddLiveFiles(std::set<uint64_t>* live) {
 1150|    488|  for (Version* v = dummy_versions_.next_; v != &dummy_versions_;
  ------------------
  |  Branch (1150:44): [True: 244, False: 244]
  ------------------
 1151|    244|       v = v->next_) {
 1152|  1.95k|    for (int level = 0; level < config::kNumLevels; level++) {
  ------------------
  |  Branch (1152:25): [True: 1.70k, False: 244]
  ------------------
 1153|  1.70k|      const std::vector<FileMetaData*>& files = v->files_[level];
 1154|  1.96k|      for (size_t i = 0; i < files.size(); i++) {
  ------------------
  |  Branch (1154:26): [True: 259, False: 1.70k]
  ------------------
 1155|    259|        live->insert(files[i]->number);
 1156|    259|      }
 1157|  1.70k|    }
 1158|    244|  }
 1159|    244|}
_ZN7leveldb10VersionSet8GetRangeERKNSt3__16vectorIPNS_12FileMetaDataENS1_9allocatorIS4_EEEEPNS_11InternalKeyESB_:
 1188|     23|                          InternalKey* smallest, InternalKey* largest) {
 1189|     23|  assert(!inputs.empty());
 1190|     23|  smallest->Clear();
 1191|     23|  largest->Clear();
 1192|     83|  for (size_t i = 0; i < inputs.size(); i++) {
  ------------------
  |  Branch (1192:22): [True: 60, False: 23]
  ------------------
 1193|     60|    FileMetaData* f = inputs[i];
 1194|     60|    if (i == 0) {
  ------------------
  |  Branch (1194:9): [True: 23, False: 37]
  ------------------
 1195|     23|      *smallest = f->smallest;
 1196|     23|      *largest = f->largest;
 1197|     37|    } else {
 1198|     37|      if (icmp_.Compare(f->smallest, *smallest) < 0) {
  ------------------
  |  Branch (1198:11): [True: 0, False: 37]
  ------------------
 1199|      0|        *smallest = f->smallest;
 1200|      0|      }
 1201|     37|      if (icmp_.Compare(f->largest, *largest) > 0) {
  ------------------
  |  Branch (1201:11): [True: 15, False: 22]
  ------------------
 1202|     15|        *largest = f->largest;
 1203|     15|      }
 1204|     37|    }
 1205|     60|  }
 1206|     23|}
_ZN7leveldb10VersionSet9GetRange2ERKNSt3__16vectorIPNS_12FileMetaDataENS1_9allocatorIS4_EEEES9_PNS_11InternalKeyESB_:
 1213|      9|                           InternalKey* smallest, InternalKey* largest) {
 1214|      9|  std::vector<FileMetaData*> all = inputs1;
 1215|      9|  all.insert(all.end(), inputs2.begin(), inputs2.end());
 1216|      9|  GetRange(all, smallest, largest);
 1217|      9|}
_ZN7leveldb10VersionSet17MakeInputIteratorEPNS_10CompactionE:
 1219|      8|Iterator* VersionSet::MakeInputIterator(Compaction* c) {
 1220|      8|  ReadOptions options;
 1221|      8|  options.verify_checksums = options_->paranoid_checks;
 1222|      8|  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|      8|  const int space = (c->level() == 0 ? c->inputs_[0].size() + 1 : 2);
  ------------------
  |  Branch (1227:22): [True: 8, False: 0]
  ------------------
 1228|      8|  Iterator** list = new Iterator*[space];
 1229|      8|  int num = 0;
 1230|     24|  for (int which = 0; which < 2; which++) {
  ------------------
  |  Branch (1230:23): [True: 16, False: 8]
  ------------------
 1231|     16|    if (!c->inputs_[which].empty()) {
  ------------------
  |  Branch (1231:9): [True: 11, False: 5]
  ------------------
 1232|     11|      if (c->level() + which == 0) {
  ------------------
  |  Branch (1232:11): [True: 8, False: 3]
  ------------------
 1233|      8|        const std::vector<FileMetaData*>& files = c->inputs_[which];
 1234|     33|        for (size_t i = 0; i < files.size(); i++) {
  ------------------
  |  Branch (1234:28): [True: 25, False: 8]
  ------------------
 1235|     25|          list[num++] = table_cache_->NewIterator(options, files[i]->number,
 1236|     25|                                                  files[i]->file_size);
 1237|     25|        }
 1238|      8|      } else {
 1239|       |        // Create concatenating iterator for the files from this level
 1240|      3|        list[num++] = NewTwoLevelIterator(
 1241|      3|            new Version::LevelFileNumIterator(icmp_, &c->inputs_[which]),
 1242|      3|            &GetFileIterator, table_cache_, options);
 1243|      3|      }
 1244|     11|    }
 1245|     16|  }
 1246|       |  assert(num <= space);
 1247|      8|  Iterator* result = NewMergingIterator(&icmp_, list, num);
 1248|      8|  delete[] list;
 1249|      8|  return result;
 1250|      8|}
_ZN7leveldb10VersionSet14PickCompactionEv:
 1252|      5|Compaction* VersionSet::PickCompaction() {
 1253|      5|  Compaction* c;
 1254|      5|  int level;
 1255|       |
 1256|       |  // We prefer compactions triggered by too much data in a level over
 1257|       |  // the compactions triggered by seeks.
 1258|      5|  const bool size_compaction = (current_->compaction_score_ >= 1);
 1259|      5|  const bool seek_compaction = (current_->file_to_compact_ != nullptr);
 1260|      5|  if (size_compaction) {
  ------------------
  |  Branch (1260:7): [True: 5, False: 0]
  ------------------
 1261|      5|    level = current_->compaction_level_;
 1262|      5|    assert(level >= 0);
 1263|      5|    assert(level + 1 < config::kNumLevels);
 1264|      5|    c = new Compaction(options_, level);
 1265|       |
 1266|       |    // Pick the first file that comes after compact_pointer_[level]
 1267|     17|    for (size_t i = 0; i < current_->files_[level].size(); i++) {
  ------------------
  |  Branch (1267:24): [True: 14, False: 3]
  ------------------
 1268|     14|      FileMetaData* f = current_->files_[level][i];
 1269|     14|      if (compact_pointer_[level].empty() ||
  ------------------
  |  Branch (1269:11): [True: 1, False: 13]
  |  Branch (1269:11): [True: 2, False: 12]
  ------------------
 1270|     13|          icmp_.Compare(f->largest.Encode(), compact_pointer_[level]) > 0) {
  ------------------
  |  Branch (1270:11): [True: 1, False: 12]
  ------------------
 1271|      2|        c->inputs_[0].push_back(f);
 1272|      2|        break;
 1273|      2|      }
 1274|     14|    }
 1275|      5|    if (c->inputs_[0].empty()) {
  ------------------
  |  Branch (1275:9): [True: 3, False: 2]
  ------------------
 1276|       |      // Wrap-around to the beginning of the key space
 1277|      3|      c->inputs_[0].push_back(current_->files_[level][0]);
 1278|      3|    }
 1279|      5|  } 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|      5|  c->input_version_ = current_;
 1288|      5|  c->input_version_->Ref();
 1289|       |
 1290|       |  // Files in level 0 may overlap each other, so pick up all overlapping ones
 1291|      5|  if (level == 0) {
  ------------------
  |  Branch (1291:7): [True: 5, False: 0]
  ------------------
 1292|      5|    InternalKey smallest, largest;
 1293|      5|    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|      5|    current_->GetOverlappingInputs(0, &smallest, &largest, &c->inputs_[0]);
 1298|      5|    assert(!c->inputs_[0].empty());
 1299|      5|  }
 1300|       |
 1301|      5|  SetupOtherInputs(c);
 1302|       |
 1303|      5|  return c;
 1304|      5|}
_ZN7leveldb14FindLargestKeyERKNS_21InternalKeyComparatorERKNSt3__16vectorIPNS_12FileMetaDataENS3_9allocatorIS6_EEEEPNS_11InternalKeyE:
 1310|     21|                    InternalKey* largest_key) {
 1311|     21|  if (files.empty()) {
  ------------------
  |  Branch (1311:7): [True: 6, False: 15]
  ------------------
 1312|      6|    return false;
 1313|      6|  }
 1314|     15|  *largest_key = files[0]->largest;
 1315|     41|  for (size_t i = 1; i < files.size(); ++i) {
  ------------------
  |  Branch (1315:22): [True: 26, False: 15]
  ------------------
 1316|     26|    FileMetaData* f = files[i];
 1317|     26|    if (icmp.Compare(f->largest, *largest_key) > 0) {
  ------------------
  |  Branch (1317:9): [True: 12, False: 14]
  ------------------
 1318|     12|      *largest_key = f->largest;
 1319|     12|    }
 1320|     26|  }
 1321|     15|  return true;
 1322|     21|}
_ZN7leveldb24FindSmallestBoundaryFileERKNS_21InternalKeyComparatorERKNSt3__16vectorIPNS_12FileMetaDataENS3_9allocatorIS6_EEEERKNS_11InternalKeyE:
 1329|     15|    const InternalKey& largest_key) {
 1330|     15|  const Comparator* user_cmp = icmp.user_comparator();
 1331|     15|  FileMetaData* smallest_boundary_file = nullptr;
 1332|     64|  for (size_t i = 0; i < level_files.size(); ++i) {
  ------------------
  |  Branch (1332:22): [True: 49, False: 15]
  ------------------
 1333|     49|    FileMetaData* f = level_files[i];
 1334|     49|    if (icmp.Compare(f->smallest, largest_key) > 0 &&
  ------------------
  |  Branch (1334:9): [True: 7, False: 42]
  |  Branch (1334:9): [True: 0, False: 49]
  ------------------
 1335|      7|        user_cmp->Compare(f->smallest.user_key(), largest_key.user_key()) ==
  ------------------
  |  Branch (1335:9): [True: 0, False: 7]
  ------------------
 1336|      7|            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|     49|  }
 1343|     15|  return smallest_boundary_file;
 1344|     15|}
_ZN7leveldb17AddBoundaryInputsERKNS_21InternalKeyComparatorERKNSt3__16vectorIPNS_12FileMetaDataENS3_9allocatorIS6_EEEEPS9_:
 1362|     21|                       std::vector<FileMetaData*>* compaction_files) {
 1363|     21|  InternalKey largest_key;
 1364|       |
 1365|       |  // Quick return if compaction_files is empty.
 1366|     21|  if (!FindLargestKey(icmp, *compaction_files, &largest_key)) {
  ------------------
  |  Branch (1366:7): [True: 6, False: 15]
  ------------------
 1367|      6|    return;
 1368|      6|  }
 1369|       |
 1370|     15|  bool continue_searching = true;
 1371|     30|  while (continue_searching) {
  ------------------
  |  Branch (1371:10): [True: 15, False: 15]
  ------------------
 1372|     15|    FileMetaData* smallest_boundary_file =
 1373|     15|        FindSmallestBoundaryFile(icmp, level_files, largest_key);
 1374|       |
 1375|       |    // If a boundary file was found advance largest_key, otherwise we're done.
 1376|     15|    if (smallest_boundary_file != NULL) {
  ------------------
  |  Branch (1376:9): [True: 0, False: 15]
  ------------------
 1377|      0|      compaction_files->push_back(smallest_boundary_file);
 1378|      0|      largest_key = smallest_boundary_file->largest;
 1379|     15|    } else {
 1380|     15|      continue_searching = false;
 1381|     15|    }
 1382|     15|  }
 1383|     15|}
_ZN7leveldb10VersionSet16SetupOtherInputsEPNS_10CompactionE:
 1385|      9|void VersionSet::SetupOtherInputs(Compaction* c) {
 1386|      9|  const int level = c->level();
 1387|      9|  InternalKey smallest, largest;
 1388|       |
 1389|      9|  AddBoundaryInputs(icmp_, current_->files_[level], &c->inputs_[0]);
 1390|      9|  GetRange(c->inputs_[0], &smallest, &largest);
 1391|       |
 1392|      9|  current_->GetOverlappingInputs(level + 1, &smallest, &largest,
 1393|      9|                                 &c->inputs_[1]);
 1394|      9|  AddBoundaryInputs(icmp_, current_->files_[level + 1], &c->inputs_[1]);
 1395|       |
 1396|       |  // Get entire range covered by compaction
 1397|      9|  InternalKey all_start, all_limit;
 1398|      9|  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|      9|  if (!c->inputs_[1].empty()) {
  ------------------
  |  Branch (1402:7): [True: 3, False: 6]
  ------------------
 1403|      3|    std::vector<FileMetaData*> expanded0;
 1404|      3|    current_->GetOverlappingInputs(level, &all_start, &all_limit, &expanded0);
 1405|      3|    AddBoundaryInputs(icmp_, current_->files_[level], &expanded0);
 1406|      3|    const int64_t inputs0_size = TotalFileSize(c->inputs_[0]);
 1407|      3|    const int64_t inputs1_size = TotalFileSize(c->inputs_[1]);
 1408|      3|    const int64_t expanded0_size = TotalFileSize(expanded0);
 1409|      3|    if (expanded0.size() > c->inputs_[0].size() &&
  ------------------
  |  Branch (1409:9): [True: 0, False: 3]
  ------------------
 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|      3|  }
 1432|       |
 1433|       |  // Compute the set of grandparent files that overlap this compaction
 1434|       |  // (parent == level+1; grandparent == level+2)
 1435|      9|  if (level + 2 < config::kNumLevels) {
  ------------------
  |  Branch (1435:7): [True: 9, False: 0]
  ------------------
 1436|      9|    current_->GetOverlappingInputs(level + 2, &all_start, &all_limit,
 1437|      9|                                   &c->grandparents_);
 1438|      9|  }
 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|      9|  compact_pointer_[level] = largest.Encode().ToString();
 1445|      9|  c->edit_.SetCompactPointer(level, largest);
 1446|      9|}
_ZN7leveldb10VersionSet12CompactRangeEiPKNS_11InternalKeyES3_:
 1449|     24|                                     const InternalKey* end) {
 1450|     24|  std::vector<FileMetaData*> inputs;
 1451|     24|  current_->GetOverlappingInputs(level, begin, end, &inputs);
 1452|     24|  if (inputs.empty()) {
  ------------------
  |  Branch (1452:7): [True: 20, False: 4]
  ------------------
 1453|     20|    return nullptr;
 1454|     20|  }
 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|      4|  if (level > 0) {
  ------------------
  |  Branch (1460:7): [True: 0, False: 4]
  ------------------
 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|      4|  Compaction* c = new Compaction(options_, level);
 1474|      4|  c->input_version_ = current_;
 1475|      4|  c->input_version_->Ref();
 1476|      4|  c->inputs_[0] = inputs;
 1477|      4|  SetupOtherInputs(c);
 1478|      4|  return c;
 1479|     24|}
_ZN7leveldb10CompactionC2EPKNS_7OptionsEi:
 1482|      9|    : level_(level),
 1483|      9|      max_output_file_size_(MaxFileSizeForLevel(options, level)),
 1484|      9|      input_version_(nullptr),
 1485|      9|      grandparent_index_(0),
 1486|      9|      seen_key_(false),
 1487|      9|      overlapped_bytes_(0) {
 1488|     72|  for (int i = 0; i < config::kNumLevels; i++) {
  ------------------
  |  Branch (1488:19): [True: 63, False: 9]
  ------------------
 1489|     63|    level_ptrs_[i] = 0;
 1490|     63|  }
 1491|      9|}
_ZN7leveldb10CompactionD2Ev:
 1493|      9|Compaction::~Compaction() {
 1494|      9|  if (input_version_ != nullptr) {
  ------------------
  |  Branch (1494:7): [True: 1, False: 8]
  ------------------
 1495|      1|    input_version_->Unref();
 1496|      1|  }
 1497|      9|}
_ZNK7leveldb10Compaction13IsTrivialMoveEv:
 1499|      5|bool Compaction::IsTrivialMove() const {
 1500|      5|  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|      5|  return (num_input_files(0) == 1 && num_input_files(1) == 0 &&
  ------------------
  |  Branch (1504:11): [True: 1, False: 4]
  |  Branch (1504:38): [True: 1, False: 0]
  ------------------
 1505|      1|          TotalFileSize(grandparents_) <=
  ------------------
  |  Branch (1505:11): [True: 1, False: 0]
  ------------------
 1506|      1|              MaxGrandParentOverlapBytes(vset->options_));
 1507|      5|}
_ZN7leveldb10Compaction17AddInputDeletionsEPNS_11VersionEditE:
 1509|      8|void Compaction::AddInputDeletions(VersionEdit* edit) {
 1510|     24|  for (int which = 0; which < 2; which++) {
  ------------------
  |  Branch (1510:23): [True: 16, False: 8]
  ------------------
 1511|     44|    for (size_t i = 0; i < inputs_[which].size(); i++) {
  ------------------
  |  Branch (1511:24): [True: 28, False: 16]
  ------------------
 1512|     28|      edit->RemoveFile(level_ + which, inputs_[which][i]->number);
 1513|     28|    }
 1514|     16|  }
 1515|      8|}
_ZN7leveldb10Compaction17IsBaseLevelForKeyERKNS_5SliceE:
 1517|      8|bool Compaction::IsBaseLevelForKey(const Slice& user_key) {
 1518|       |  // Maybe use binary search to find right entry instead of linear search?
 1519|      8|  const Comparator* user_cmp = input_version_->vset_->icmp_.user_comparator();
 1520|     48|  for (int lvl = level_ + 2; lvl < config::kNumLevels; lvl++) {
  ------------------
  |  Branch (1520:30): [True: 40, False: 8]
  ------------------
 1521|     40|    const std::vector<FileMetaData*>& files = input_version_->files_[lvl];
 1522|     40|    while (level_ptrs_[lvl] < files.size()) {
  ------------------
  |  Branch (1522:12): [True: 0, False: 40]
  ------------------
 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|     40|  }
 1535|      8|  return true;
 1536|      8|}
_ZN7leveldb10Compaction16ShouldStopBeforeERKNS_5SliceE:
 1538|    477|bool Compaction::ShouldStopBefore(const Slice& internal_key) {
 1539|    477|  const VersionSet* vset = input_version_->vset_;
 1540|       |  // Scan to find earliest grandparent file that contains key.
 1541|    477|  const InternalKeyComparator* icmp = &vset->icmp_;
 1542|    477|  while (grandparent_index_ < grandparents_.size() &&
  ------------------
  |  Branch (1542:10): [True: 0, False: 477]
  |  Branch (1542:10): [True: 0, False: 477]
  ------------------
 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|    477|  seen_key_ = true;
 1552|       |
 1553|    477|  if (overlapped_bytes_ > MaxGrandParentOverlapBytes(vset->options_)) {
  ------------------
  |  Branch (1553:7): [True: 0, False: 477]
  ------------------
 1554|       |    // Too much overlap for current output; start new output
 1555|      0|    overlapped_bytes_ = 0;
 1556|      0|    return true;
 1557|    477|  } else {
 1558|    477|    return false;
 1559|    477|  }
 1560|    477|}
_ZN7leveldb10Compaction13ReleaseInputsEv:
 1562|      8|void Compaction::ReleaseInputs() {
 1563|      8|  if (input_version_ != nullptr) {
  ------------------
  |  Branch (1563:7): [True: 8, False: 0]
  ------------------
 1564|      8|    input_version_->Unref();
 1565|      8|    input_version_ = nullptr;
 1566|      8|  }
 1567|      8|}
version_set.cc:_ZN7leveldbL9AfterFileEPKNS_10ComparatorEPKNS_5SliceEPKNS_12FileMetaDataE:
  108|      6|                      const FileMetaData* f) {
  109|       |  // null user_key occurs before all keys and is therefore never after *f
  110|      6|  return (user_key != nullptr &&
  ------------------
  |  Branch (110:11): [True: 6, False: 0]
  ------------------
  111|      6|          ucmp->Compare(*user_key, f->largest.user_key()) > 0);
  ------------------
  |  Branch (111:11): [True: 0, False: 6]
  ------------------
  112|      6|}
version_set.cc:_ZN7leveldbL10BeforeFileEPKNS_10ComparatorEPKNS_5SliceEPKNS_12FileMetaDataE:
  115|      9|                       const FileMetaData* f) {
  116|       |  // null user_key occurs after all keys and is therefore never before *f
  117|      9|  return (user_key != nullptr &&
  ------------------
  |  Branch (117:11): [True: 9, False: 0]
  ------------------
  118|      9|          ucmp->Compare(*user_key, f->smallest.user_key()) < 0);
  ------------------
  |  Branch (118:11): [True: 0, False: 9]
  ------------------
  119|      9|}
_ZN7leveldb7Version20LevelFileNumIteratorC2ERKNS_21InternalKeyComparatorEPKNSt3__16vectorIPNS_12FileMetaDataENS5_9allocatorIS8_EEEE:
  167|     22|      : icmp_(icmp), flist_(flist), index_(flist->size()) {  // Marks as invalid
  168|     22|  }
_ZNK7leveldb7Version20LevelFileNumIterator5ValidEv:
  169|     42|  bool Valid() const override { return index_ < flist_->size(); }
_ZN7leveldb7Version20LevelFileNumIterator11SeekToFirstEv:
  173|     10|  void SeekToFirst() override { index_ = 0; }
_ZN7leveldb7Version20LevelFileNumIterator4NextEv:
  177|     10|  void Next() override {
  178|       |    assert(Valid());
  179|     10|    index_++;
  180|     10|  }
_ZNK7leveldb7Version20LevelFileNumIterator3keyEv:
  189|     10|  Slice key() const override {
  190|       |    assert(Valid());
  191|     10|    return (*flist_)[index_]->largest.Encode();
  192|     10|  }
_ZNK7leveldb7Version20LevelFileNumIterator5valueEv:
  193|     10|  Slice value() const override {
  194|       |    assert(Valid());
  195|     10|    EncodeFixed64(value_buf_, (*flist_)[index_]->number);
  196|     10|    EncodeFixed64(value_buf_ + 8, (*flist_)[index_]->file_size);
  197|     10|    return Slice(value_buf_, sizeof(value_buf_));
  198|     10|  }
_ZNK7leveldb7Version20LevelFileNumIterator6statusEv:
  199|      6|  Status status() const override { return Status::OK(); }
version_set.cc:_ZN7leveldbL15GetFileIteratorEPvRKNS_11ReadOptionsERKNS_5SliceE:
  211|     10|                                 const Slice& file_value) {
  212|     10|  TableCache* cache = reinterpret_cast<TableCache*>(arg);
  213|     10|  if (file_value.size() != 16) {
  ------------------
  |  Branch (213:7): [True: 0, False: 10]
  ------------------
  214|      0|    return NewErrorIterator(
  215|      0|        Status::Corruption("FileReader invoked with unexpected value"));
  216|     10|  } else {
  217|     10|    return cache->NewIterator(options, DecodeFixed64(file_value.data()),
  218|     10|                              DecodeFixed64(file_value.data() + 8));
  219|     10|  }
  220|     10|}
version_set.cc:_ZN7leveldbL11NewestFirstEPNS_12FileMetaDataES1_:
  277|      9|static bool NewestFirst(FileMetaData* a, FileMetaData* b) {
  278|      9|  return a->number > b->number;
  279|      9|}
version_set.cc:_ZZN7leveldb7Version3GetERKNS_11ReadOptionsERKNS_9LookupKeyEPNSt3__112basic_stringIcNS7_11char_traitsIcEENS7_9allocatorIcEEEEPNS0_8GetStatsEEN5State5MatchEPviPNS_12FileMetaDataE:
  341|     15|    static bool Match(void* arg, int level, FileMetaData* f) {
  342|     15|      State* state = reinterpret_cast<State*>(arg);
  343|       |
  344|     15|      if (state->stats->seek_file == nullptr &&
  ------------------
  |  Branch (344:11): [True: 9, False: 6]
  ------------------
  345|      9|          state->last_file_read != nullptr) {
  ------------------
  |  Branch (345:11): [True: 3, False: 6]
  ------------------
  346|       |        // We have had more than one seek for this read.  Charge the 1st file.
  347|      3|        state->stats->seek_file = state->last_file_read;
  348|      3|        state->stats->seek_file_level = state->last_file_read_level;
  349|      3|      }
  350|       |
  351|     15|      state->last_file_read = f;
  352|     15|      state->last_file_read_level = level;
  353|       |
  354|     15|      state->s = state->vset->table_cache_->Get(*state->options, f->number,
  355|     15|                                                f->file_size, state->ikey,
  356|     15|                                                &state->saver, SaveValue);
  357|     15|      if (!state->s.ok()) {
  ------------------
  |  Branch (357:11): [True: 0, False: 15]
  ------------------
  358|      0|        state->found = true;
  359|      0|        return false;
  360|      0|      }
  361|     15|      switch (state->saver.state) {
  ------------------
  |  Branch (361:15): [True: 15, False: 0]
  ------------------
  362|     15|        case kNotFound:
  ------------------
  |  Branch (362:9): [True: 15, False: 0]
  ------------------
  363|     15|          return true;  // Keep searching in other files
  364|      0|        case kFound:
  ------------------
  |  Branch (364:9): [True: 0, False: 15]
  ------------------
  365|      0|          state->found = true;
  366|      0|          return false;
  367|      0|        case kDeleted:
  ------------------
  |  Branch (367:9): [True: 0, False: 15]
  ------------------
  368|      0|          return false;
  369|      0|        case kCorrupt:
  ------------------
  |  Branch (369:9): [True: 0, False: 15]
  ------------------
  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|     15|      }
  375|       |
  376|       |      // Not reached. Added to avoid false compilation warnings of
  377|       |      // "control reaches end of non-void function".
  378|      0|      return false;
  379|     15|    }
version_set.cc:_ZN7leveldbL9SaveValueEPvRKNS_5SliceES3_:
  262|     15|static void SaveValue(void* arg, const Slice& ikey, const Slice& v) {
  263|     15|  Saver* s = reinterpret_cast<Saver*>(arg);
  264|     15|  ParsedInternalKey parsed_key;
  265|     15|  if (!ParseInternalKey(ikey, &parsed_key)) {
  ------------------
  |  Branch (265:7): [True: 0, False: 15]
  ------------------
  266|      0|    s->state = kCorrupt;
  267|     15|  } else {
  268|     15|    if (s->ucmp->Compare(parsed_key.user_key, s->user_key) == 0) {
  ------------------
  |  Branch (268:9): [True: 0, False: 15]
  ------------------
  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|     15|  }
  275|     15|}
version_set.cc:_ZZN7leveldb7Version16RecordReadSampleENS_5SliceEEN5State5MatchEPviPNS_12FileMetaDataE:
  425|     13|    static bool Match(void* arg, int level, FileMetaData* f) {
  426|     13|      State* state = reinterpret_cast<State*>(arg);
  427|     13|      state->matches++;
  428|     13|      if (state->matches == 1) {
  ------------------
  |  Branch (428:11): [True: 10, False: 3]
  ------------------
  429|       |        // Remember first match.
  430|     10|        state->stats.seek_file = f;
  431|     10|        state->stats.seek_file_level = level;
  432|     10|      }
  433|       |      // We can stop iterating once we have a second match.
  434|     13|      return state->matches < 2;
  435|     13|    }
version_set.cc:_ZN7leveldbL13TotalFileSizeERKNSt3__16vectorIPNS_12FileMetaDataENS0_9allocatorIS3_EEEE:
   59|  1.23k|static int64_t TotalFileSize(const std::vector<FileMetaData*>& files) {
   60|  1.23k|  int64_t sum = 0;
   61|  1.35k|  for (size_t i = 0; i < files.size(); i++) {
  ------------------
  |  Branch (61:22): [True: 112, False: 1.23k]
  ------------------
   62|    112|    sum += files[i]->file_size;
   63|    112|  }
   64|  1.23k|  return sum;
   65|  1.23k|}
version_set.cc:_ZN7leveldbL26MaxGrandParentOverlapBytesEPKNS_7OptionsE:
   30|    482|static int64_t MaxGrandParentOverlapBytes(const Options* options) {
   31|    482|  return 10 * TargetFileSize(options);
   32|    482|}
_ZN7leveldb10VersionSet7BuilderC2EPS0_PNS_7VersionE:
  598|    245|  Builder(VersionSet* vset, Version* base) : vset_(vset), base_(base) {
  599|    245|    base_->Ref();
  600|    245|    BySmallestKey cmp;
  601|    245|    cmp.internal_comparator = &vset_->icmp_;
  602|  1.96k|    for (int level = 0; level < config::kNumLevels; level++) {
  ------------------
  |  Branch (602:25): [True: 1.71k, False: 245]
  ------------------
  603|  1.71k|      levels_[level].added_files = new FileSet(cmp);
  604|  1.71k|    }
  605|    245|  }
_ZN7leveldb10VersionSet7Builder5ApplyEPKNS_11VersionEditE:
  629|    325|  void Apply(const VersionEdit* edit) {
  630|       |    // Update compaction pointers
  631|    358|    for (size_t i = 0; i < edit->compact_pointers_.size(); i++) {
  ------------------
  |  Branch (631:24): [True: 33, False: 325]
  ------------------
  632|     33|      const int level = edit->compact_pointers_[i].first;
  633|     33|      vset_->compact_pointer_[level] =
  634|     33|          edit->compact_pointers_[i].second.Encode().ToString();
  635|     33|    }
  636|       |
  637|       |    // Delete files
  638|    325|    for (const auto& deleted_file_set_kvp : edit->deleted_files_) {
  ------------------
  |  Branch (638:43): [True: 58, False: 325]
  ------------------
  639|     58|      const int level = deleted_file_set_kvp.first;
  640|     58|      const uint64_t number = deleted_file_set_kvp.second;
  641|     58|      levels_[level].deleted_files.insert(number);
  642|     58|    }
  643|       |
  644|       |    // Add new files
  645|    490|    for (size_t i = 0; i < edit->new_files_.size(); i++) {
  ------------------
  |  Branch (645:24): [True: 165, False: 325]
  ------------------
  646|    165|      const int level = edit->new_files_[i].first;
  647|    165|      FileMetaData* f = new FileMetaData(edit->new_files_[i].second);
  648|    165|      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|    165|      f->allowed_seeks = static_cast<int>((f->file_size / 16384U));
  664|    165|      if (f->allowed_seeks < 100) f->allowed_seeks = 100;
  ------------------
  |  Branch (664:11): [True: 165, False: 0]
  ------------------
  665|       |
  666|    165|      levels_[level].deleted_files.erase(f->number);
  667|    165|      levels_[level].added_files->insert(f);
  668|    165|    }
  669|    325|  }
_ZNK7leveldb10VersionSet7Builder13BySmallestKeyclEPNS_12FileMetaDataES4_:
  575|    146|    bool operator()(FileMetaData* f1, FileMetaData* f2) const {
  576|    146|      int r = internal_comparator->Compare(f1->smallest, f2->smallest);
  577|    146|      if (r != 0) {
  ------------------
  |  Branch (577:11): [True: 146, False: 0]
  ------------------
  578|    146|        return (r < 0);
  579|    146|      } else {
  580|       |        // Break ties by file number
  581|      0|        return (f1->number < f2->number);
  582|      0|      }
  583|    146|    }
_ZN7leveldb10VersionSet7Builder6SaveToEPNS_7VersionE:
  672|    245|  void SaveTo(Version* v) {
  673|    245|    BySmallestKey cmp;
  674|    245|    cmp.internal_comparator = &vset_->icmp_;
  675|  1.96k|    for (int level = 0; level < config::kNumLevels; level++) {
  ------------------
  |  Branch (675:25): [True: 1.71k, False: 245]
  ------------------
  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.71k|      const std::vector<FileMetaData*>& base_files = base_->files_[level];
  679|  1.71k|      std::vector<FileMetaData*>::const_iterator base_iter = base_files.begin();
  680|  1.71k|      std::vector<FileMetaData*>::const_iterator base_end = base_files.end();
  681|  1.71k|      const FileSet* added_files = levels_[level].added_files;
  682|  1.71k|      v->files_[level].reserve(base_files.size() + added_files->size());
  683|  1.71k|      for (const auto& added_file : *added_files) {
  ------------------
  |  Branch (683:35): [True: 165, False: 1.71k]
  ------------------
  684|       |        // Add all smaller files listed in base_
  685|    165|        for (std::vector<FileMetaData*>::const_iterator bpos =
  686|    165|                 std::upper_bound(base_iter, base_end, added_file, cmp);
  687|    190|             base_iter != bpos; ++base_iter) {
  ------------------
  |  Branch (687:14): [True: 25, False: 165]
  ------------------
  688|     25|          MaybeAddFile(v, level, *base_iter);
  689|     25|        }
  690|       |
  691|    165|        MaybeAddFile(v, level, added_file);
  692|    165|      }
  693|       |
  694|       |      // Add remaining base files
  695|  1.84k|      for (; base_iter != base_end; ++base_iter) {
  ------------------
  |  Branch (695:14): [True: 132, False: 1.71k]
  ------------------
  696|    132|        MaybeAddFile(v, level, *base_iter);
  697|    132|      }
  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.71k|    }
  715|    245|  }
_ZN7leveldb10VersionSet7Builder12MaybeAddFileEPNS_7VersionEiPNS_12FileMetaDataE:
  717|    322|  void MaybeAddFile(Version* v, int level, FileMetaData* f) {
  718|    322|    if (levels_[level].deleted_files.count(f->number) > 0) {
  ------------------
  |  Branch (718:9): [True: 58, False: 264]
  ------------------
  719|       |      // File is deleted: do nothing
  720|    264|    } else {
  721|    264|      std::vector<FileMetaData*>* files = &v->files_[level];
  722|    264|      if (level > 0 && !files->empty()) {
  ------------------
  |  Branch (722:11): [True: 85, False: 179]
  |  Branch (722:24): [True: 3, False: 82]
  ------------------
  723|       |        // Must not overlap
  724|       |        assert(vset_->icmp_.Compare((*files)[files->size() - 1]->largest,
  725|      3|                                    f->smallest) < 0);
  726|      3|      }
  727|    264|      f->refs++;
  728|    264|      files->push_back(f);
  729|    264|    }
  730|    322|  }
_ZN7leveldb10VersionSet7BuilderD2Ev:
  607|    245|  ~Builder() {
  608|  1.96k|    for (int level = 0; level < config::kNumLevels; level++) {
  ------------------
  |  Branch (608:25): [True: 1.71k, False: 245]
  ------------------
  609|  1.71k|      const FileSet* added = levels_[level].added_files;
  610|  1.71k|      std::vector<FileMetaData*> to_unref;
  611|  1.71k|      to_unref.reserve(added->size());
  612|  1.88k|      for (FileSet::const_iterator it = added->begin(); it != added->end();
  ------------------
  |  Branch (612:57): [True: 165, False: 1.71k]
  ------------------
  613|  1.71k|           ++it) {
  614|    165|        to_unref.push_back(*it);
  615|    165|      }
  616|  1.71k|      delete added;
  617|  1.88k|      for (uint32_t i = 0; i < to_unref.size(); i++) {
  ------------------
  |  Branch (617:28): [True: 165, False: 1.71k]
  ------------------
  618|    165|        FileMetaData* f = to_unref[i];
  619|    165|        f->refs--;
  620|    165|        if (f->refs <= 0) {
  ------------------
  |  Branch (620:13): [True: 29, False: 136]
  ------------------
  621|     29|          delete f;
  622|     29|        }
  623|    165|      }
  624|  1.71k|    }
  625|    245|    base_->Unref();
  626|    245|  }
version_set.cc:_ZN7leveldbL14TargetFileSizeEPKNS_7OptionsE:
   24|    491|static size_t TargetFileSize(const Options* options) {
   25|    491|  return options->max_file_size;
   26|    491|}
version_set.cc:_ZN7leveldbL16MaxBytesForLevelEPKNS_7OptionsEi:
   41|  1.22k|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.22k|  double result = 10. * 1048576.0;
   47|  3.67k|  while (level > 1) {
  ------------------
  |  Branch (47:10): [True: 2.45k, False: 1.22k]
  ------------------
   48|  2.45k|    result *= 10;
   49|  2.45k|    level--;
   50|  2.45k|  }
   51|  1.22k|  return result;
   52|  1.22k|}
version_set.cc:_ZN7leveldbL19MaxFileSizeForLevelEPKNS_7OptionsEi:
   54|      9|static uint64_t MaxFileSizeForLevel(const Options* options, int level) {
   55|       |  // We could vary per level to reduce number of files?
   56|      9|  return TargetFileSize(options);
   57|      9|}

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

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

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

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

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

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

_ZN7leveldb14SequentialFileC2Ev:
  224|    276|  SequentialFile() = default;
_ZN7leveldb16RandomAccessFileC2Ev:
  254|     88|  RandomAccessFile() = default;
_ZN7leveldb12WritableFileC2Ev:
  279|    494|  WritableFile() = default;
_ZN7leveldb8FileLockC2Ev:
  309|    108|  FileLock() = default;
_ZN7leveldb6LoggerC2Ev:
  295|    108|  Logger() = default;

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

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

_ZN7leveldb5SliceC2ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
   36|  13.7k|  Slice(const std::string& s) : data_(s.data()), size_(s.size()) {}
_ZN7leveldb5SliceC2Ev:
   30|  6.83k|  Slice() : data_(""), size_(0) {}
_ZN7leveldb5SliceC2EPKcm:
   33|  40.0k|  Slice(const char* d, size_t n) : data_(d), size_(n) {}
_ZN7leveldb5SliceC2EPKc:
   39|  11.0k|  Slice(const char* s) : data_(s), size_(strlen(s)) {}
_ZNK7leveldb5Slice4dataEv:
   46|  53.5k|  const char* data() const { return data_; }
_ZNK7leveldb5Slice4sizeEv:
   49|  4.46M|  size_t size() const { return size_; }
_ZNK7leveldb5Slice5emptyEv:
   52|  2.19k|  bool empty() const { return size_ == 0; }
_ZNK7leveldb5SliceixEm:
   59|  4.39M|  char operator[](size_t n) const {
   60|       |    assert(n < size());
   61|  4.39M|    return data_[n];
   62|  4.39M|  }
_ZN7leveldb5Slice5clearEv:
   65|  1.66k|  void clear() {
   66|  1.66k|    data_ = "";
   67|  1.66k|    size_ = 0;
   68|  1.66k|  }
_ZN7leveldb5Slice13remove_prefixEm:
   71|  6.20k|  void remove_prefix(size_t n) {
   72|       |    assert(n <= size());
   73|  6.20k|    data_ += n;
   74|  6.20k|    size_ -= n;
   75|  6.20k|  }
_ZNK7leveldb5Slice8ToStringEv:
   78|    516|  std::string ToString() const { return std::string(data_, size_); }
_ZNK7leveldb5Slice11starts_withERKS0_:
   87|  1.91k|  bool starts_with(const Slice& x) const {
   88|  1.91k|    return ((size_ >= x.size_) && (memcmp(data_, x.data_, x.size_) == 0));
  ------------------
  |  Branch (88:13): [True: 1.42k, False: 491]
  |  Branch (88:35): [True: 510, False: 913]
  ------------------
   89|  1.91k|  }
_ZN7leveldbeqERKNS_5SliceES2_:
   96|  8.86k|inline bool operator==(const Slice& x, const Slice& y) {
   97|  8.86k|  return ((x.size() == y.size()) &&
  ------------------
  |  Branch (97:11): [True: 2.23k, False: 6.63k]
  ------------------
   98|  2.23k|          (memcmp(x.data(), y.data(), x.size()) == 0));
  ------------------
  |  Branch (98:11): [True: 1.51k, False: 715]
  ------------------
   99|  8.86k|}
_ZN7leveldbneERKNS_5SliceES2_:
  101|     81|inline bool operator!=(const Slice& x, const Slice& y) { return !(x == y); }
_ZNK7leveldb5Slice7compareERKS0_:
  103|  7.28k|inline int Slice::compare(const Slice& b) const {
  104|  7.28k|  const size_t min_len = (size_ < b.size_) ? size_ : b.size_;
  ------------------
  |  Branch (104:26): [True: 3.10k, False: 4.18k]
  ------------------
  105|  7.28k|  int r = memcmp(data_, b.data_, min_len);
  106|  7.28k|  if (r == 0) {
  ------------------
  |  Branch (106:7): [True: 121, False: 7.16k]
  ------------------
  107|    121|    if (size_ < b.size_)
  ------------------
  |  Branch (107:9): [True: 10, False: 111]
  ------------------
  108|     10|      r = -1;
  109|    111|    else if (size_ > b.size_)
  ------------------
  |  Branch (109:14): [True: 8, False: 103]
  ------------------
  110|      8|      r = +1;
  111|    121|  }
  112|  7.28k|  return r;
  113|  7.28k|}

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

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

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

_ZN7leveldb4port5MutexC2Ev:
   53|  3.78k|  Mutex() = default;
_ZN7leveldb4port7CondVarC2EPNS0_5MutexE:
   71|    681|  explicit CondVar(Mutex* mu) : mu_(mu) { assert(mu != nullptr); }
_ZN7leveldb4port5Mutex4LockEv:
   59|  3.25k|  void Lock() EXCLUSIVE_LOCK_FUNCTION() { mu_.lock(); }
_ZN7leveldb4port7CondVar4WaitEv:
   77|     88|  void Wait() {
   78|     88|    std::unique_lock<std::mutex> lock(mu_->mu_, std::adopt_lock);
   79|     88|    cv_.wait(lock);
   80|     88|    lock.release();
   81|     88|  }
_ZN7leveldb4port5Mutex6UnlockEv:
   60|  3.25k|  void Unlock() UNLOCK_FUNCTION() { mu_.unlock(); }
_ZN7leveldb4port7CondVarD2Ev:
   72|    680|  ~CondVar() = default;
_ZN7leveldb4port5Mutex10AssertHeldEv:
   61|  1.77k|  void AssertHeld() ASSERT_EXCLUSIVE_LOCK() {}
_ZN7leveldb4port7CondVar9SignalAllEv:
   83|     50|  void SignalAll() { cv_.notify_all(); }
_ZN7leveldb4port7CondVar6SignalEv:
   82|     50|  void Signal() { cv_.notify_one(); }
_ZN7leveldb4port15Snappy_CompressEPKcmPNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEE:
   91|    624|                            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|    624|  (void)input;
  101|    624|  (void)length;
  102|    624|  (void)output;
  103|    624|#endif  // HAVE_SNAPPY
  104|       |
  105|    624|  return false;
  106|    624|}
_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|    538|    : data_(contents.data.data()),
   27|    538|      size_(contents.data.size()),
   28|    538|      owned_(contents.heap_allocated) {
   29|    538|  if (size_ < sizeof(uint32_t)) {
  ------------------
  |  Branch (29:7): [True: 0, False: 538]
  ------------------
   30|      0|    size_ = 0;  // Error marker
   31|    538|  } else {
   32|    538|    size_t max_restarts_allowed = (size_ - sizeof(uint32_t)) / sizeof(uint32_t);
   33|    538|    if (NumRestarts() > max_restarts_allowed) {
  ------------------
  |  Branch (33:9): [True: 0, False: 538]
  ------------------
   34|       |      // The size is too small for NumRestarts()
   35|      0|      size_ = 0;
   36|    538|    } else {
   37|    538|      restart_offset_ = size_ - (1 + NumRestarts()) * sizeof(uint32_t);
   38|    538|    }
   39|    538|  }
   40|    538|}
_ZN7leveldb5BlockD2Ev:
   42|    538|Block::~Block() {
   43|    538|  if (owned_) {
  ------------------
  |  Branch (43:7): [True: 0, False: 538]
  ------------------
   44|      0|    delete[] data_;
   45|      0|  }
   46|    538|}
_ZN7leveldb5Block11NewIteratorEPKNS_10ComparatorE:
  280|    591|Iterator* Block::NewIterator(const Comparator* comparator) {
  281|    591|  if (size_ < sizeof(uint32_t)) {
  ------------------
  |  Branch (281:7): [True: 0, False: 591]
  ------------------
  282|      0|    return NewErrorIterator(Status::Corruption("bad block contents"));
  283|      0|  }
  284|    591|  const uint32_t num_restarts = NumRestarts();
  285|    591|  if (num_restarts == 0) {
  ------------------
  |  Branch (285:7): [True: 0, False: 591]
  ------------------
  286|      0|    return NewEmptyIterator();
  287|    591|  } else {
  288|    591|    return new Iter(comparator, data_, restart_offset_, num_restarts);
  289|    591|  }
  290|    591|}
_ZNK7leveldb5Block11NumRestartsEv:
   20|  1.66k|inline uint32_t Block::NumRestarts() const {
   21|       |  assert(size_ >= sizeof(uint32_t));
   22|  1.66k|  return DecodeFixed32(data_ + size_ - sizeof(uint32_t));
   23|  1.66k|}
_ZN7leveldb5Block4IterC2EPKNS_10ComparatorEPKcjj:
  118|    591|      : comparator_(comparator),
  119|    591|        data_(data),
  120|    591|        restarts_(restarts),
  121|    591|        num_restarts_(num_restarts),
  122|    591|        current_(restarts_),
  123|    591|        restart_index_(num_restarts_) {
  124|       |    assert(num_restarts_ > 0);
  125|    591|  }
_ZNK7leveldb5Block4Iter5ValidEv:
  127|  2.23k|  bool Valid() const override { return current_ < restarts_; }
_ZN7leveldb5Block4Iter11SeekToFirstEv:
  229|    483|  void SeekToFirst() override {
  230|    483|    SeekToRestartPoint(0);
  231|    483|    ParseNextKey();
  232|    483|  }
_ZN7leveldb5Block4Iter18SeekToRestartPointEj:
  105|    513|  void SeekToRestartPoint(uint32_t index) {
  106|    513|    key_.clear();
  107|    513|    restart_index_ = index;
  108|       |    // current_ will be fixed by ParseNextKey();
  109|       |
  110|       |    // ParseNextKey() starts at the end of value_, so set value_ accordingly
  111|    513|    uint32_t offset = GetRestartPoint(index);
  112|    513|    value_ = Slice(data_ + offset, 0);
  113|    513|  }
_ZN7leveldb5Block4Iter15GetRestartPointEj:
  100|  1.35k|  uint32_t GetRestartPoint(uint32_t index) {
  101|       |    assert(index < num_restarts_);
  102|  1.35k|    return DecodeFixed32(data_ + restarts_ + index * sizeof(uint32_t));
  103|  1.35k|  }
_ZN7leveldb5Block4Iter12ParseNextKeyEv:
  250|  1.66k|  bool ParseNextKey() {
  251|  1.66k|    current_ = NextEntryOffset();
  252|  1.66k|    const char* p = data_ + current_;
  253|  1.66k|    const char* limit = data_ + restarts_;  // Restarts come right after data
  254|  1.66k|    if (p >= limit) {
  ------------------
  |  Branch (254:9): [True: 483, False: 1.18k]
  ------------------
  255|       |      // No more entries to return.  Mark as invalid.
  256|    483|      current_ = restarts_;
  257|    483|      restart_index_ = num_restarts_;
  258|    483|      return false;
  259|    483|    }
  260|       |
  261|       |    // Decode next entry
  262|  1.18k|    uint32_t shared, non_shared, value_length;
  263|  1.18k|    p = DecodeEntry(p, limit, &shared, &non_shared, &value_length);
  264|  1.18k|    if (p == nullptr || key_.size() < shared) {
  ------------------
  |  Branch (264:9): [True: 0, False: 1.18k]
  |  Branch (264:25): [True: 0, False: 1.18k]
  ------------------
  265|      0|      CorruptionError();
  266|      0|      return false;
  267|  1.18k|    } else {
  268|  1.18k|      key_.resize(shared);
  269|  1.18k|      key_.append(p, non_shared);
  270|  1.18k|      value_ = Slice(p + non_shared, value_length);
  271|  1.53k|      while (restart_index_ + 1 < num_restarts_ &&
  ------------------
  |  Branch (271:14): [True: 804, False: 727]
  ------------------
  272|    804|             GetRestartPoint(restart_index_ + 1) < current_) {
  ------------------
  |  Branch (272:14): [True: 351, False: 453]
  ------------------
  273|    351|        ++restart_index_;
  274|    351|      }
  275|  1.18k|      return true;
  276|  1.18k|    }
  277|  1.18k|  }
_ZNK7leveldb5Block4Iter15NextEntryOffsetEv:
   96|  1.66k|  inline uint32_t NextEntryOffset() const {
   97|  1.66k|    return (value_.data() + value_.size()) - data_;
   98|  1.66k|  }
block.cc:_ZN7leveldbL11DecodeEntryEPKcS1_PjS2_S2_:
   57|  1.21k|                                      uint32_t* value_length) {
   58|  1.21k|  if (limit - p < 3) return nullptr;
  ------------------
  |  Branch (58:7): [True: 0, False: 1.21k]
  ------------------
   59|  1.21k|  *shared = reinterpret_cast<const uint8_t*>(p)[0];
   60|  1.21k|  *non_shared = reinterpret_cast<const uint8_t*>(p)[1];
   61|  1.21k|  *value_length = reinterpret_cast<const uint8_t*>(p)[2];
   62|  1.21k|  if ((*shared | *non_shared | *value_length) < 128) {
  ------------------
  |  Branch (62:7): [True: 516, False: 700]
  ------------------
   63|       |    // Fast path: all three values are encoded in one byte each
   64|    516|    p += 3;
   65|    700|  } else {
   66|    700|    if ((p = GetVarint32Ptr(p, limit, shared)) == nullptr) return nullptr;
  ------------------
  |  Branch (66:9): [True: 0, False: 700]
  ------------------
   67|    700|    if ((p = GetVarint32Ptr(p, limit, non_shared)) == nullptr) return nullptr;
  ------------------
  |  Branch (67:9): [True: 0, False: 700]
  ------------------
   68|    700|    if ((p = GetVarint32Ptr(p, limit, value_length)) == nullptr) return nullptr;
  ------------------
  |  Branch (68:9): [True: 0, False: 700]
  ------------------
   69|    700|  }
   70|       |
   71|  1.21k|  if (static_cast<uint32_t>(limit - p) < (*non_shared + *value_length)) {
  ------------------
  |  Branch (71:7): [True: 0, False: 1.21k]
  ------------------
   72|      0|    return nullptr;
   73|      0|  }
   74|  1.21k|  return p;
   75|  1.21k|}
_ZN7leveldb5Block4Iter4SeekERKNS_5SliceE:
  164|     30|  void Seek(const Slice& target) override {
  165|       |    // Binary search in restart array to find the last restart point
  166|       |    // with a key < target
  167|     30|    uint32_t left = 0;
  168|     30|    uint32_t right = num_restarts_ - 1;
  169|     30|    int current_key_compare = 0;
  170|       |
  171|     30|    if (Valid()) {
  ------------------
  |  Branch (171:9): [True: 0, False: 30]
  ------------------
  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|     66|    while (left < right) {
  ------------------
  |  Branch (187:12): [True: 36, False: 30]
  ------------------
  188|     36|      uint32_t mid = (left + right + 1) / 2;
  189|     36|      uint32_t region_offset = GetRestartPoint(mid);
  190|     36|      uint32_t shared, non_shared, value_length;
  191|     36|      const char* key_ptr =
  192|     36|          DecodeEntry(data_ + region_offset, data_ + restarts_, &shared,
  193|     36|                      &non_shared, &value_length);
  194|     36|      if (key_ptr == nullptr || (shared != 0)) {
  ------------------
  |  Branch (194:11): [True: 0, False: 36]
  |  Branch (194:33): [True: 0, False: 36]
  ------------------
  195|      0|        CorruptionError();
  196|      0|        return;
  197|      0|      }
  198|     36|      Slice mid_key(key_ptr, non_shared);
  199|     36|      if (Compare(mid_key, target) < 0) {
  ------------------
  |  Branch (199:11): [True: 15, False: 21]
  ------------------
  200|       |        // Key at "mid" is smaller than "target".  Therefore all
  201|       |        // blocks before "mid" are uninteresting.
  202|     15|        left = mid;
  203|     21|      } else {
  204|       |        // Key at "mid" is >= "target".  Therefore all blocks at or
  205|       |        // after "mid" are uninteresting.
  206|     21|        right = mid - 1;
  207|     21|      }
  208|     36|    }
  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|     30|    assert(current_key_compare == 0 || Valid());
  214|     30|    bool skip_seek = left == restart_index_ && current_key_compare < 0;
  ------------------
  |  Branch (214:22): [True: 0, False: 30]
  |  Branch (214:48): [True: 0, False: 0]
  ------------------
  215|     30|    if (!skip_seek) {
  ------------------
  |  Branch (215:9): [True: 30, False: 0]
  ------------------
  216|     30|      SeekToRestartPoint(left);
  217|     30|    }
  218|       |    // Linear search (within restart block) for first key >= target
  219|     51|    while (true) {
  ------------------
  |  Branch (219:12): [True: 51, Folded]
  ------------------
  220|     51|      if (!ParseNextKey()) {
  ------------------
  |  Branch (220:11): [True: 0, False: 51]
  ------------------
  221|      0|        return;
  222|      0|      }
  223|     51|      if (Compare(key_, target) >= 0) {
  ------------------
  |  Branch (223:11): [True: 30, False: 21]
  ------------------
  224|     30|        return;
  225|     30|      }
  226|     51|    }
  227|     30|  }
_ZNK7leveldb5Block4Iter7CompareERKNS_5SliceES4_:
   91|     87|  inline int Compare(const Slice& a, const Slice& b) const {
   92|     87|    return comparator_->Compare(a, b);
   93|     87|  }
_ZN7leveldb5Block4Iter4NextEv:
  138|  1.12k|  void Next() override {
  139|       |    assert(Valid());
  140|  1.12k|    ParseNextKey();
  141|  1.12k|  }
_ZNK7leveldb5Block4Iter3keyEv:
  129|  1.14k|  Slice key() const override {
  130|       |    assert(Valid());
  131|  1.14k|    return key_;
  132|  1.14k|  }
_ZNK7leveldb5Block4Iter5valueEv:
  133|  1.16k|  Slice value() const override {
  134|       |    assert(Valid());
  135|  1.16k|    return value_;
  136|  1.16k|  }
_ZNK7leveldb5Block4Iter6statusEv:
  128|    577|  Status status() const override { return status_; }

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

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

_ZNK7leveldb11BlockHandle8EncodeToEPNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
   16|    624|void BlockHandle::EncodeTo(std::string* dst) const {
   17|       |  // Sanity check that all fields have been set
   18|    624|  assert(offset_ != ~static_cast<uint64_t>(0));
   19|       |  assert(size_ != ~static_cast<uint64_t>(0));
   20|    624|  PutVarint64(dst, offset_);
   21|    624|  PutVarint64(dst, size_);
   22|    624|}
_ZN7leveldb11BlockHandle10DecodeFromEPNS_5SliceE:
   24|    626|Status BlockHandle::DecodeFrom(Slice* input) {
   25|    626|  if (GetVarint64(input, &offset_) && GetVarint64(input, &size_)) {
  ------------------
  |  Branch (25:7): [True: 626, False: 0]
  |  Branch (25:39): [True: 626, False: 0]
  ------------------
   26|    626|    return Status::OK();
   27|    626|  } else {
   28|      0|    return Status::Corruption("bad block handle");
   29|      0|  }
   30|    626|}
_ZNK7leveldb6Footer8EncodeToEPNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
   32|     52|void Footer::EncodeTo(std::string* dst) const {
   33|     52|  const size_t original_size = dst->size();
   34|     52|  metaindex_handle_.EncodeTo(dst);
   35|     52|  index_handle_.EncodeTo(dst);
   36|     52|  dst->resize(2 * BlockHandle::kMaxEncodedLength);  // Padding
   37|     52|  PutFixed32(dst, static_cast<uint32_t>(kTableMagicNumber & 0xffffffffu));
   38|     52|  PutFixed32(dst, static_cast<uint32_t>(kTableMagicNumber >> 32));
   39|       |  assert(dst->size() == original_size + kEncodedLength);
   40|     52|  (void)original_size;  // Disable unused variable warning.
   41|     52|}
_ZN7leveldb6Footer10DecodeFromEPNS_5SliceE:
   43|     88|Status Footer::DecodeFrom(Slice* input) {
   44|     88|  if (input->size() < kEncodedLength) {
  ------------------
  |  Branch (44:7): [True: 0, False: 88]
  ------------------
   45|      0|    return Status::Corruption("not an sstable (footer too short)");
   46|      0|  }
   47|       |
   48|     88|  const char* magic_ptr = input->data() + kEncodedLength - 8;
   49|     88|  const uint32_t magic_lo = DecodeFixed32(magic_ptr);
   50|     88|  const uint32_t magic_hi = DecodeFixed32(magic_ptr + 4);
   51|     88|  const uint64_t magic = ((static_cast<uint64_t>(magic_hi) << 32) |
   52|     88|                          (static_cast<uint64_t>(magic_lo)));
   53|     88|  if (magic != kTableMagicNumber) {
  ------------------
  |  Branch (53:7): [True: 0, False: 88]
  ------------------
   54|      0|    return Status::Corruption("not an sstable (bad magic number)");
   55|      0|  }
   56|       |
   57|     88|  Status result = metaindex_handle_.DecodeFrom(input);
   58|     88|  if (result.ok()) {
  ------------------
  |  Branch (58:7): [True: 88, False: 0]
  ------------------
   59|     88|    result = index_handle_.DecodeFrom(input);
   60|     88|  }
   61|     88|  if (result.ok()) {
  ------------------
  |  Branch (61:7): [True: 88, False: 0]
  ------------------
   62|       |    // We skip over any leftover data (just padding for now) in "input"
   63|     88|    const char* end = magic_ptr + 8;
   64|     88|    *input = Slice(end, input->data() + input->size() - end);
   65|     88|  }
   66|     88|  return result;
   67|     88|}
_ZN7leveldb9ReadBlockEPNS_16RandomAccessFileERKNS_11ReadOptionsERKNS_11BlockHandleEPNS_13BlockContentsE:
   70|    538|                 const BlockHandle& handle, BlockContents* result) {
   71|    538|  result->data = Slice();
   72|    538|  result->cachable = false;
   73|    538|  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|    538|  size_t n = static_cast<size_t>(handle.size());
   78|    538|  char* buf = new char[n + kBlockTrailerSize];
   79|    538|  Slice contents;
   80|    538|  Status s = file->Read(handle.offset(), n + kBlockTrailerSize, &contents, buf);
   81|    538|  if (!s.ok()) {
  ------------------
  |  Branch (81:7): [True: 0, False: 538]
  ------------------
   82|      0|    delete[] buf;
   83|      0|    return s;
   84|      0|  }
   85|    538|  if (contents.size() != n + kBlockTrailerSize) {
  ------------------
  |  Branch (85:7): [True: 0, False: 538]
  ------------------
   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|    538|  const char* data = contents.data();  // Pointer to where Read put the data
   92|    538|  if (options.verify_checksums) {
  ------------------
  |  Branch (92:7): [True: 0, False: 538]
  ------------------
   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|    538|  switch (data[n]) {
  103|    538|    case kNoCompression:
  ------------------
  |  Branch (103:5): [True: 538, False: 0]
  ------------------
  104|    538|      if (data != buf) {
  ------------------
  |  Branch (104:11): [True: 538, 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|    538|        delete[] buf;
  109|    538|        result->data = Slice(data, n);
  110|    538|        result->heap_allocated = false;
  111|    538|        result->cachable = false;  // Do not double-cache
  112|    538|      } 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|    538|      break;
  120|      0|    case kSnappyCompression: {
  ------------------
  |  Branch (120:5): [True: 0, False: 538]
  ------------------
  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: 538]
  ------------------
  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: 538]
  ------------------
  157|      0|      delete[] buf;
  158|      0|      return Status::Corruption("bad block type");
  159|    538|  }
  160|       |
  161|    538|  return Status::OK();
  162|    538|}

_ZN7leveldb11BlockHandle10set_offsetEm:
   32|    624|  void set_offset(uint64_t offset) { offset_ = offset; }
_ZN7leveldb11BlockHandle8set_sizeEm:
   36|    624|  void set_size(uint64_t size) { size_ = size; }
_ZN7leveldb11BlockHandleC2Ev:
   95|  1.04k|    : offset_(~static_cast<uint64_t>(0)), size_(~static_cast<uint64_t>(0)) {}
_ZN7leveldb6FooterC2Ev:
   55|    140|  Footer() = default;
_ZN7leveldb6Footer20set_metaindex_handleERKNS_11BlockHandleE:
   59|     52|  void set_metaindex_handle(const BlockHandle& h) { metaindex_handle_ = h; }
_ZN7leveldb6Footer16set_index_handleERKNS_11BlockHandleE:
   63|     52|  void set_index_handle(const BlockHandle& h) { index_handle_ = h; }
_ZNK7leveldb11BlockHandle6offsetEv:
   31|    988|  uint64_t offset() const { return offset_; }
_ZNK7leveldb11BlockHandle4sizeEv:
   35|    538|  uint64_t size() const { return size_; }
_ZNK7leveldb6Footer16metaindex_handleEv:
   58|     88|  const BlockHandle& metaindex_handle() const { return metaindex_handle_; }
_ZNK7leveldb6Footer12index_handleEv:
   62|     88|  const BlockHandle& index_handle() const { return index_handle_; }

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

_ZN7leveldb15IteratorWrapperC2Ev:
   19|    117|  IteratorWrapper() : iter_(nullptr), valid_(false) {}
_ZN7leveldb15IteratorWrapper3SetEPNS_8IteratorE:
   26|    974|  void Set(Iterator* iter) {
   27|    974|    delete iter_;
   28|    974|    iter_ = iter;
   29|    974|    if (iter_ == nullptr) {
  ------------------
  |  Branch (29:9): [True: 264, False: 710]
  ------------------
   30|    264|      valid_ = false;
   31|    710|    } else {
   32|    710|      Update();
   33|    710|    }
   34|    974|  }
_ZN7leveldb15IteratorWrapper6UpdateEv:
   78|  3.45k|  void Update() {
   79|  3.45k|    valid_ = iter_->Valid();
   80|  3.45k|    if (valid_) {
  ------------------
  |  Branch (80:9): [True: 2.17k, False: 1.27k]
  ------------------
   81|  2.17k|      key_ = iter_->key();
   82|  2.17k|    }
   83|  3.45k|  }
_ZN7leveldb15IteratorWrapperD2Ev:
   21|    413|  ~IteratorWrapper() { delete iter_; }
_ZN7leveldb15IteratorWrapper11SeekToFirstEv:
   66|    563|  void SeekToFirst() {
   67|       |    assert(iter_);
   68|    563|    iter_->SeekToFirst();
   69|    563|    Update();
   70|    563|  }
_ZNK7leveldb15IteratorWrapper5ValidEv:
   37|  6.66k|  bool Valid() const { return valid_; }
_ZNK7leveldb15IteratorWrapper3keyEv:
   38|  5.92k|  Slice key() const {
   39|       |    assert(Valid());
   40|  5.92k|    return key_;
   41|  5.92k|  }
_ZN7leveldb15IteratorWrapper4NextEv:
   51|  2.17k|  void Next() {
   52|       |    assert(iter_);
   53|  2.17k|    iter_->Next();
   54|  2.17k|    Update();
   55|  2.17k|  }
_ZNK7leveldb15IteratorWrapper5valueEv:
   42|  2.16k|  Slice value() const {
   43|       |    assert(Valid());
   44|  2.16k|    return iter_->value();
   45|  2.16k|  }
_ZNK7leveldb15IteratorWrapper6statusEv:
   47|    619|  Status status() const {
   48|       |    assert(iter_);
   49|    619|    return iter_->status();
   50|    619|  }
_ZN7leveldb15IteratorWrapperC2EPNS_8IteratorE:
   20|    296|  explicit IteratorWrapper(Iterator* iter) : iter_(nullptr) { Set(iter); }
_ZNK7leveldb15IteratorWrapper4iterEv:
   22|  3.12k|  Iterator* iter() const { return iter_; }

_ZN7leveldb18NewMergingIteratorEPKNS_10ComparatorEPPNS_8IteratorEi:
  180|     48|                             int n) {
  181|     48|  assert(n >= 0);
  182|     48|  if (n == 0) {
  ------------------
  |  Branch (182:7): [True: 0, False: 48]
  ------------------
  183|      0|    return NewEmptyIterator();
  184|     48|  } else if (n == 1) {
  ------------------
  |  Branch (184:14): [True: 9, False: 39]
  ------------------
  185|      9|    return children[0];
  186|     39|  } else {
  187|     39|    return new MergingIterator(comparator, children, n);
  188|     39|  }
  189|     48|}
merger.cc:_ZN7leveldb12_GLOBAL__N_115MergingIteratorC2EPKNS_10ComparatorEPPNS_8IteratorEi:
   17|     39|      : comparator_(comparator),
   18|     39|        children_(new IteratorWrapper[n]),
   19|     39|        n_(n),
   20|     39|        current_(nullptr),
   21|     39|        direction_(kForward) {
   22|    156|    for (int i = 0; i < n; i++) {
  ------------------
  |  Branch (22:21): [True: 117, False: 39]
  ------------------
   23|    117|      children_[i].Set(children[i]);
   24|    117|    }
   25|     39|  }
merger.cc:_ZN7leveldb12_GLOBAL__N_115MergingIteratorD2Ev:
   27|     39|  ~MergingIterator() override { delete[] children_; }
merger.cc:_ZNK7leveldb12_GLOBAL__N_115MergingIterator5ValidEv:
   29|    758|  bool Valid() const override { return (current_ != nullptr); }
merger.cc:_ZN7leveldb12_GLOBAL__N_115MergingIterator11SeekToFirstEv:
   31|     20|  void SeekToFirst() override {
   32|     80|    for (int i = 0; i < n_; i++) {
  ------------------
  |  Branch (32:21): [True: 60, False: 20]
  ------------------
   33|     60|      children_[i].SeekToFirst();
   34|     60|    }
   35|     20|    FindSmallest();
   36|     20|    direction_ = kForward;
   37|     20|  }
merger.cc:_ZN7leveldb12_GLOBAL__N_115MergingIterator12FindSmallestEv:
  148|    758|void MergingIterator::FindSmallest() {
  149|    758|  IteratorWrapper* smallest = nullptr;
  150|  3.83k|  for (int i = 0; i < n_; i++) {
  ------------------
  |  Branch (150:19): [True: 3.07k, False: 758]
  ------------------
  151|  3.07k|    IteratorWrapper* child = &children_[i];
  152|  3.07k|    if (child->Valid()) {
  ------------------
  |  Branch (152:9): [True: 2.70k, False: 368]
  ------------------
  153|  2.70k|      if (smallest == nullptr) {
  ------------------
  |  Branch (153:11): [True: 738, False: 1.96k]
  ------------------
  154|    738|        smallest = child;
  155|  1.96k|      } else if (comparator_->Compare(child->key(), smallest->key()) < 0) {
  ------------------
  |  Branch (155:18): [True: 597, False: 1.37k]
  ------------------
  156|    597|        smallest = child;
  157|    597|      }
  158|  2.70k|    }
  159|  3.07k|  }
  160|    758|  current_ = smallest;
  161|    758|}
merger.cc:_ZN7leveldb12_GLOBAL__N_115MergingIterator4NextEv:
   55|    738|  void Next() override {
   56|    738|    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|    738|    if (direction_ != kForward) {
  ------------------
  |  Branch (63:9): [True: 0, False: 738]
  ------------------
   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|    738|    current_->Next();
   78|    738|    FindSmallest();
   79|    738|  }
merger.cc:_ZNK7leveldb12_GLOBAL__N_115MergingIterator3keyEv:
  110|    995|  Slice key() const override {
  111|       |    assert(Valid());
  112|    995|    return current_->key();
  113|    995|  }
merger.cc:_ZNK7leveldb12_GLOBAL__N_115MergingIterator5valueEv:
  115|    730|  Slice value() const override {
  116|       |    assert(Valid());
  117|    730|    return current_->value();
  118|    730|  }
merger.cc:_ZNK7leveldb12_GLOBAL__N_115MergingIterator6statusEv:
  120|     16|  Status status() const override {
  121|     16|    Status status;
  122|     72|    for (int i = 0; i < n_; i++) {
  ------------------
  |  Branch (122:21): [True: 56, False: 16]
  ------------------
  123|     56|      status = children_[i].status();
  124|     56|      if (!status.ok()) {
  ------------------
  |  Branch (124:11): [True: 0, False: 56]
  ------------------
  125|      0|        break;
  126|      0|      }
  127|     56|    }
  128|     16|    return status;
  129|     16|  }

_ZN7leveldb5Table4OpenERKNS_7OptionsEPNS_16RandomAccessFileEmPPS0_:
   39|     88|                   uint64_t size, Table** table) {
   40|     88|  *table = nullptr;
   41|     88|  if (size < Footer::kEncodedLength) {
  ------------------
  |  Branch (41:7): [True: 0, False: 88]
  ------------------
   42|      0|    return Status::Corruption("file is too short to be an sstable");
   43|      0|  }
   44|       |
   45|     88|  char footer_space[Footer::kEncodedLength];
   46|     88|  Slice footer_input;
   47|     88|  Status s = file->Read(size - Footer::kEncodedLength, Footer::kEncodedLength,
   48|     88|                        &footer_input, footer_space);
   49|     88|  if (!s.ok()) return s;
  ------------------
  |  Branch (49:7): [True: 0, False: 88]
  ------------------
   50|       |
   51|     88|  Footer footer;
   52|     88|  s = footer.DecodeFrom(&footer_input);
   53|     88|  if (!s.ok()) return s;
  ------------------
  |  Branch (53:7): [True: 0, False: 88]
  ------------------
   54|       |
   55|       |  // Read the index block
   56|     88|  BlockContents index_block_contents;
   57|     88|  ReadOptions opt;
   58|     88|  if (options.paranoid_checks) {
  ------------------
  |  Branch (58:7): [True: 0, False: 88]
  ------------------
   59|      0|    opt.verify_checksums = true;
   60|      0|  }
   61|     88|  s = ReadBlock(file, opt, footer.index_handle(), &index_block_contents);
   62|       |
   63|     88|  if (s.ok()) {
  ------------------
  |  Branch (63:7): [True: 88, False: 0]
  ------------------
   64|       |    // We've successfully read the footer and the index block: we're
   65|       |    // ready to serve requests.
   66|     88|    Block* index_block = new Block(index_block_contents);
   67|     88|    Rep* rep = new Table::Rep;
   68|     88|    rep->options = options;
   69|     88|    rep->file = file;
   70|     88|    rep->metaindex_handle = footer.metaindex_handle();
   71|     88|    rep->index_block = index_block;
   72|     88|    rep->cache_id = (options.block_cache ? options.block_cache->NewId() : 0);
  ------------------
  |  Branch (72:22): [True: 88, False: 0]
  ------------------
   73|     88|    rep->filter_data = nullptr;
   74|     88|    rep->filter = nullptr;
   75|     88|    *table = new Table(rep);
   76|     88|    (*table)->ReadMeta(footer);
   77|     88|  }
   78|       |
   79|     88|  return s;
   80|     88|}
_ZN7leveldb5Table8ReadMetaERKNS_6FooterE:
   82|     88|void Table::ReadMeta(const Footer& footer) {
   83|     88|  if (rep_->options.filter_policy == nullptr) {
  ------------------
  |  Branch (83:7): [True: 88, False: 0]
  ------------------
   84|     88|    return;  // Do not need any metadata
   85|     88|  }
   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|     88|Table::~Table() { delete rep_; }
_ZN7leveldb5Table11BlockReaderEPvRKNS_11ReadOptionsERKNS_5SliceE:
  154|    450|                             const Slice& index_value) {
  155|    450|  Table* table = reinterpret_cast<Table*>(arg);
  156|    450|  Cache* block_cache = table->rep_->options.block_cache;
  157|    450|  Block* block = nullptr;
  158|    450|  Cache::Handle* cache_handle = nullptr;
  159|       |
  160|    450|  BlockHandle handle;
  161|    450|  Slice input = index_value;
  162|    450|  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|    450|  if (s.ok()) {
  ------------------
  |  Branch (166:7): [True: 450, False: 0]
  ------------------
  167|    450|    BlockContents contents;
  168|    450|    if (block_cache != nullptr) {
  ------------------
  |  Branch (168:9): [True: 450, False: 0]
  ------------------
  169|    450|      char cache_key_buffer[16];
  170|    450|      EncodeFixed64(cache_key_buffer, table->rep_->cache_id);
  171|    450|      EncodeFixed64(cache_key_buffer + 8, handle.offset());
  172|    450|      Slice key(cache_key_buffer, sizeof(cache_key_buffer));
  173|    450|      cache_handle = block_cache->Lookup(key);
  174|    450|      if (cache_handle != nullptr) {
  ------------------
  |  Branch (174:11): [True: 0, False: 450]
  ------------------
  175|      0|        block = reinterpret_cast<Block*>(block_cache->Value(cache_handle));
  176|    450|      } else {
  177|    450|        s = ReadBlock(table->rep_->file, options, handle, &contents);
  178|    450|        if (s.ok()) {
  ------------------
  |  Branch (178:13): [True: 450, False: 0]
  ------------------
  179|    450|          block = new Block(contents);
  180|    450|          if (contents.cachable && options.fill_cache) {
  ------------------
  |  Branch (180:15): [True: 0, False: 450]
  |  Branch (180:36): [True: 0, False: 0]
  ------------------
  181|      0|            cache_handle = block_cache->Insert(key, block, block->size(),
  182|      0|                                               &DeleteCachedBlock);
  183|      0|          }
  184|    450|        }
  185|    450|      }
  186|    450|    } 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|    450|  }
  193|       |
  194|    450|  Iterator* iter;
  195|    450|  if (block != nullptr) {
  ------------------
  |  Branch (195:7): [True: 450, False: 0]
  ------------------
  196|    450|    iter = block->NewIterator(table->rep_->options.comparator);
  197|    450|    if (cache_handle == nullptr) {
  ------------------
  |  Branch (197:9): [True: 450, False: 0]
  ------------------
  198|    450|      iter->RegisterCleanup(&DeleteBlock, block, nullptr);
  199|    450|    } else {
  200|      0|      iter->RegisterCleanup(&ReleaseBlock, block_cache, cache_handle);
  201|      0|    }
  202|    450|  } else {
  203|      0|    iter = NewErrorIterator(s);
  204|      0|  }
  205|    450|  return iter;
  206|    450|}
_ZNK7leveldb5Table11NewIteratorERKNS_11ReadOptionsE:
  208|    126|Iterator* Table::NewIterator(const ReadOptions& options) const {
  209|    126|  return NewTwoLevelIterator(
  210|    126|      rep_->index_block->NewIterator(rep_->options.comparator),
  211|    126|      &Table::BlockReader, const_cast<Table*>(this), options);
  212|    126|}
_ZN7leveldb5Table11InternalGetERKNS_11ReadOptionsERKNS_5SliceEPvPFvS7_S6_S6_E:
  216|     15|                                                const Slice&)) {
  217|     15|  Status s;
  218|     15|  Iterator* iiter = rep_->index_block->NewIterator(rep_->options.comparator);
  219|     15|  iiter->Seek(k);
  220|     15|  if (iiter->Valid()) {
  ------------------
  |  Branch (220:7): [True: 15, False: 0]
  ------------------
  221|     15|    Slice handle_value = iiter->value();
  222|     15|    FilterBlockReader* filter = rep_->filter;
  223|     15|    BlockHandle handle;
  224|     15|    if (filter != nullptr && handle.DecodeFrom(&handle_value).ok() &&
  ------------------
  |  Branch (224:9): [True: 0, False: 15]
  |  Branch (224:9): [True: 0, False: 15]
  |  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|     15|    } else {
  228|     15|      Iterator* block_iter = BlockReader(this, options, iiter->value());
  229|     15|      block_iter->Seek(k);
  230|     15|      if (block_iter->Valid()) {
  ------------------
  |  Branch (230:11): [True: 15, False: 0]
  ------------------
  231|     15|        (*handle_result)(arg, block_iter->key(), block_iter->value());
  232|     15|      }
  233|     15|      s = block_iter->status();
  234|     15|      delete block_iter;
  235|     15|    }
  236|     15|  }
  237|     15|  if (s.ok()) {
  ------------------
  |  Branch (237:7): [True: 15, False: 0]
  ------------------
  238|     15|    s = iiter->status();
  239|     15|  }
  240|     15|  delete iiter;
  241|     15|  return s;
  242|     15|}
_ZN7leveldb5Table3RepD2Ev:
   21|     88|  ~Rep() {
   22|     88|    delete filter;
   23|     88|    delete[] filter_data;
   24|     88|    delete index_block;
   25|     88|  }
table.cc:_ZN7leveldbL11DeleteBlockEPvS0_:
  136|    450|static void DeleteBlock(void* arg, void* ignored) {
  137|    450|  delete reinterpret_cast<Block*>(arg);
  138|    450|}

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

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

_ZN7leveldb5ArenaC2Ev:
   12|    164|    : alloc_ptr_(nullptr), alloc_bytes_remaining_(0), memory_usage_(0) {}
_ZN7leveldb5ArenaD2Ev:
   14|    164|Arena::~Arena() {
   15|    761|  for (size_t i = 0; i < blocks_.size(); i++) {
  ------------------
  |  Branch (15:22): [True: 597, False: 164]
  ------------------
   16|    597|    delete[] blocks_[i];
   17|    597|  }
   18|    164|}
_ZN7leveldb5Arena16AllocateFallbackEm:
   20|    597|char* Arena::AllocateFallback(size_t bytes) {
   21|    597|  if (bytes > kBlockSize / 4) {
  ------------------
  |  Branch (21:7): [True: 410, False: 187]
  ------------------
   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|    410|    char* result = AllocateNewBlock(bytes);
   25|    410|    return result;
   26|    410|  }
   27|       |
   28|       |  // We waste the remaining space in the current block.
   29|    187|  alloc_ptr_ = AllocateNewBlock(kBlockSize);
   30|    187|  alloc_bytes_remaining_ = kBlockSize;
   31|       |
   32|    187|  char* result = alloc_ptr_;
   33|    187|  alloc_ptr_ += bytes;
   34|    187|  alloc_bytes_remaining_ -= bytes;
   35|    187|  return result;
   36|    597|}
_ZN7leveldb5Arena15AllocateAlignedEm:
   38|    862|char* Arena::AllocateAligned(size_t bytes) {
   39|    862|  const int align = (sizeof(void*) > 8) ? sizeof(void*) : 8;
  ------------------
  |  Branch (39:21): [Folded, False: 862]
  ------------------
   40|    862|  static_assert((align & (align - 1)) == 0,
   41|    862|                "Pointer size should be a power of 2");
   42|    862|  size_t current_mod = reinterpret_cast<uintptr_t>(alloc_ptr_) & (align - 1);
   43|    862|  size_t slop = (current_mod == 0 ? 0 : align - current_mod);
  ------------------
  |  Branch (43:18): [True: 609, False: 253]
  ------------------
   44|    862|  size_t needed = bytes + slop;
   45|    862|  char* result;
   46|    862|  if (needed <= alloc_bytes_remaining_) {
  ------------------
  |  Branch (46:7): [True: 692, False: 170]
  ------------------
   47|    692|    result = alloc_ptr_ + slop;
   48|    692|    alloc_ptr_ += needed;
   49|    692|    alloc_bytes_remaining_ -= needed;
   50|    692|  } else {
   51|       |    // AllocateFallback always returned aligned memory
   52|    170|    result = AllocateFallback(bytes);
   53|    170|  }
   54|       |  assert((reinterpret_cast<uintptr_t>(result) & (align - 1)) == 0);
   55|    862|  return result;
   56|    862|}
_ZN7leveldb5Arena16AllocateNewBlockEm:
   58|    597|char* Arena::AllocateNewBlock(size_t block_bytes) {
   59|    597|  char* result = new char[block_bytes];
   60|    597|  blocks_.push_back(result);
   61|    597|  memory_usage_.fetch_add(block_bytes + sizeof(char*),
   62|    597|                          std::memory_order_relaxed);
   63|    597|  return result;
   64|    597|}

_ZNK7leveldb5Arena11MemoryUsageEv:
   33|    718|  size_t MemoryUsage() const {
   34|    718|    return memory_usage_.load(std::memory_order_relaxed);
   35|    718|  }
_ZN7leveldb5Arena8AllocateEm:
   55|    698|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|    698|  assert(bytes > 0);
   60|    698|  if (bytes <= alloc_bytes_remaining_) {
  ------------------
  |  Branch (60:7): [True: 271, False: 427]
  ------------------
   61|    271|    char* result = alloc_ptr_;
   62|    271|    alloc_ptr_ += bytes;
   63|    271|    alloc_bytes_remaining_ -= bytes;
   64|    271|    return result;
   65|    271|  }
   66|    427|  return AllocateFallback(bytes);
   67|    698|}

_ZN7leveldb5CacheD2Ev:
   18|    216|Cache::~Cache() {}
_ZN7leveldb11NewLRUCacheEm:
  399|    216|Cache* NewLRUCache(size_t capacity) { return new ShardedLRUCache(capacity); }
cache.cc:_ZN7leveldb12_GLOBAL__N_115ShardedLRUCacheC2Em:
  352|    216|  explicit ShardedLRUCache(size_t capacity) : last_id_(0) {
  353|    216|    const size_t per_shard = (capacity + (kNumShards - 1)) / kNumShards;
  354|  3.67k|    for (int s = 0; s < kNumShards; s++) {
  ------------------
  |  Branch (354:21): [True: 3.45k, False: 216]
  ------------------
  355|  3.45k|      shard_[s].SetCapacity(per_shard);
  356|  3.45k|    }
  357|    216|  }
cache.cc:_ZN7leveldb12_GLOBAL__N_18LRUCacheC2Ev:
  198|  3.45k|LRUCache::LRUCache() : capacity_(0), usage_(0) {
  199|       |  // Make empty circular linked lists.
  200|  3.45k|  lru_.next = &lru_;
  201|  3.45k|  lru_.prev = &lru_;
  202|  3.45k|  in_use_.next = &in_use_;
  203|  3.45k|  in_use_.prev = &in_use_;
  204|  3.45k|}
cache.cc:_ZN7leveldb12_GLOBAL__N_111HandleTableC2Ev:
   72|  3.45k|  HandleTable() : length_(0), elems_(0), list_(nullptr) { Resize(); }
cache.cc:_ZN7leveldb12_GLOBAL__N_111HandleTable6ResizeEv:
  123|  3.45k|  void Resize() {
  124|  3.45k|    uint32_t new_length = 4;
  125|  3.45k|    while (new_length < elems_) {
  ------------------
  |  Branch (125:12): [True: 0, False: 3.45k]
  ------------------
  126|      0|      new_length *= 2;
  127|      0|    }
  128|  3.45k|    LRUHandle** new_list = new LRUHandle*[new_length];
  129|  3.45k|    memset(new_list, 0, sizeof(new_list[0]) * new_length);
  130|  3.45k|    uint32_t count = 0;
  131|  3.45k|    for (uint32_t i = 0; i < length_; i++) {
  ------------------
  |  Branch (131:26): [True: 0, False: 3.45k]
  ------------------
  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.45k|    delete[] list_;
  145|  3.45k|    list_ = new_list;
  146|  3.45k|    length_ = new_length;
  147|  3.45k|  }
cache.cc:_ZN7leveldb12_GLOBAL__N_18LRUCache11SetCapacityEm:
  157|  3.45k|  void SetCapacity(size_t capacity) { capacity_ = capacity; }
cache.cc:_ZN7leveldb12_GLOBAL__N_115ShardedLRUCacheD2Ev:
  358|    216|  ~ShardedLRUCache() override {}
cache.cc:_ZN7leveldb12_GLOBAL__N_18LRUCacheD2Ev:
  206|  3.45k|LRUCache::~LRUCache() {
  207|  3.45k|  assert(in_use_.next == &in_use_);  // Error if caller has an unreleased handle
  208|  3.51k|  for (LRUHandle* e = lru_.next; e != &lru_;) {
  ------------------
  |  Branch (208:34): [True: 60, False: 3.45k]
  ------------------
  209|     60|    LRUHandle* next = e->next;
  210|     60|    assert(e->in_cache);
  211|     60|    e->in_cache = false;
  212|       |    assert(e->refs == 1);  // Invariant of lru_ list.
  213|     60|    Unref(e);
  214|     60|    e = next;
  215|     60|  }
  216|  3.45k|}
cache.cc:_ZN7leveldb12_GLOBAL__N_18LRUCache5UnrefEPNS0_9LRUHandleE:
  226|    229|void LRUCache::Unref(LRUHandle* e) {
  227|    229|  assert(e->refs > 0);
  228|    229|  e->refs--;
  229|    229|  if (e->refs == 0) {  // Deallocate.
  ------------------
  |  Branch (229:7): [True: 88, False: 141]
  ------------------
  230|     88|    assert(!e->in_cache);
  231|     88|    (*e->deleter)(e->key(), e->value);
  232|     88|    free(e);
  233|    141|  } else if (e->in_cache && e->refs == 1) {
  ------------------
  |  Branch (233:14): [True: 141, False: 0]
  |  Branch (233:29): [True: 141, False: 0]
  ------------------
  234|       |    // No longer in use; move to lru_ list.
  235|    141|    LRU_Remove(e);
  236|    141|    LRU_Append(&lru_, e);
  237|    141|  }
  238|    229|}
cache.cc:_ZNK7leveldb12_GLOBAL__N_19LRUHandle3keyEv:
   56|    257|  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|    257|    assert(next != this);
   60|       |
   61|    257|    return Slice(key_data, key_length);
   62|    257|  }
cache.cc:_ZN7leveldb12_GLOBAL__N_18LRUCache10LRU_RemoveEPNS0_9LRUHandleE:
  240|    222|void LRUCache::LRU_Remove(LRUHandle* e) {
  241|    222|  e->next->prev = e->prev;
  242|    222|  e->prev->next = e->next;
  243|    222|}
cache.cc:_ZN7leveldb12_GLOBAL__N_18LRUCache10LRU_AppendEPNS0_9LRUHandleES3_:
  245|    282|void LRUCache::LRU_Append(LRUHandle* list, LRUHandle* e) {
  246|       |  // Make "e" newest entry by inserting just before *list
  247|    282|  e->next = list;
  248|    282|  e->prev = list->prev;
  249|    282|  e->prev->next = e;
  250|    282|  e->next->prev = e;
  251|    282|}
cache.cc:_ZN7leveldb12_GLOBAL__N_111HandleTableD2Ev:
   73|  3.45k|  ~HandleTable() { delete[] list_; }
cache.cc:_ZN7leveldb12_GLOBAL__N_115ShardedLRUCache6InsertERKNS_5SliceEPvmPFvS4_S5_E:
  360|     88|                 void (*deleter)(const Slice& key, void* value)) override {
  361|     88|    const uint32_t hash = HashSlice(key);
  362|     88|    return shard_[Shard(hash)].Insert(key, hash, value, charge, deleter);
  363|     88|  }
cache.cc:_ZN7leveldb12_GLOBAL__N_115ShardedLRUCache9HashSliceERKNS_5SliceE:
  345|    707|  static inline uint32_t HashSlice(const Slice& s) {
  346|    707|    return Hash(s.data(), s.size(), 0);
  347|    707|  }
cache.cc:_ZN7leveldb12_GLOBAL__N_115ShardedLRUCache5ShardEj:
  349|    848|  static uint32_t Shard(uint32_t hash) { return hash >> (32 - kNumShardBits); }
cache.cc:_ZN7leveldb12_GLOBAL__N_18LRUCache6InsertERKNS_5SliceEjPvmPFvS4_S5_E:
  270|     88|                                                void* value)) {
  271|     88|  MutexLock l(&mutex_);
  272|       |
  273|     88|  LRUHandle* e =
  274|     88|      reinterpret_cast<LRUHandle*>(malloc(sizeof(LRUHandle) - 1 + key.size()));
  275|     88|  e->value = value;
  276|     88|  e->deleter = deleter;
  277|     88|  e->charge = charge;
  278|     88|  e->key_length = key.size();
  279|     88|  e->hash = hash;
  280|     88|  e->in_cache = false;
  281|     88|  e->refs = 1;  // for the returned handle.
  282|     88|  std::memcpy(e->key_data, key.data(), key.size());
  283|       |
  284|     88|  if (capacity_ > 0) {
  ------------------
  |  Branch (284:7): [True: 88, False: 0]
  ------------------
  285|     88|    e->refs++;  // for the cache's reference.
  286|     88|    e->in_cache = true;
  287|     88|    LRU_Append(&in_use_, e);
  288|     88|    usage_ += charge;
  289|     88|    FinishErase(table_.Insert(e));
  290|     88|  } 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|     88|  while (usage_ > capacity_ && lru_.next != &lru_) {
  ------------------
  |  Branch (294:10): [True: 0, False: 88]
  |  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|     88|  return reinterpret_cast<Cache::Handle*>(e);
  304|     88|}
cache.cc:_ZN7leveldb12_GLOBAL__N_18LRUCache11FinishEraseEPNS0_9LRUHandleE:
  308|    116|bool LRUCache::FinishErase(LRUHandle* e) {
  309|    116|  if (e != nullptr) {
  ------------------
  |  Branch (309:7): [True: 28, False: 88]
  ------------------
  310|       |    assert(e->in_cache);
  311|     28|    LRU_Remove(e);
  312|     28|    e->in_cache = false;
  313|     28|    usage_ -= e->charge;
  314|     28|    Unref(e);
  315|     28|  }
  316|    116|  return e != nullptr;
  317|    116|}
cache.cc:_ZN7leveldb12_GLOBAL__N_111HandleTable6InsertEPNS0_9LRUHandleE:
   79|     88|  LRUHandle* Insert(LRUHandle* h) {
   80|     88|    LRUHandle** ptr = FindPointer(h->key(), h->hash);
   81|     88|    LRUHandle* old = *ptr;
   82|     88|    h->next_hash = (old == nullptr ? nullptr : old->next_hash);
  ------------------
  |  Branch (82:21): [True: 88, False: 0]
  ------------------
   83|     88|    *ptr = h;
   84|     88|    if (old == nullptr) {
  ------------------
  |  Branch (84:9): [True: 88, False: 0]
  ------------------
   85|     88|      ++elems_;
   86|     88|      if (elems_ > length_) {
  ------------------
  |  Branch (86:11): [True: 0, False: 88]
  ------------------
   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|     88|    }
   92|     88|    return old;
   93|     88|  }
cache.cc:_ZN7leveldb12_GLOBAL__N_111HandleTable11FindPointerERKNS_5SliceEj:
  115|    707|  LRUHandle** FindPointer(const Slice& key, uint32_t hash) {
  116|    707|    LRUHandle** ptr = &list_[hash & (length_ - 1)];
  117|    710|    while (*ptr != nullptr && ((*ptr)->hash != hash || key != (*ptr)->key())) {
  ------------------
  |  Branch (117:12): [True: 84, False: 626]
  |  Branch (117:12): [True: 3, False: 707]
  |  Branch (117:32): [True: 3, False: 81]
  |  Branch (117:56): [True: 0, False: 81]
  ------------------
  118|      3|      ptr = &(*ptr)->next_hash;
  119|      3|    }
  120|    707|    return ptr;
  121|    707|  }
cache.cc:_ZN7leveldb12_GLOBAL__N_111HandleTable6RemoveERKNS_5SliceEj:
   95|     28|  LRUHandle* Remove(const Slice& key, uint32_t hash) {
   96|     28|    LRUHandle** ptr = FindPointer(key, hash);
   97|     28|    LRUHandle* result = *ptr;
   98|     28|    if (result != nullptr) {
  ------------------
  |  Branch (98:9): [True: 28, False: 0]
  ------------------
   99|     28|      *ptr = result->next_hash;
  100|     28|      --elems_;
  101|     28|    }
  102|     28|    return result;
  103|     28|  }
cache.cc:_ZN7leveldb12_GLOBAL__N_115ShardedLRUCache6LookupERKNS_5SliceE:
  364|    591|  Handle* Lookup(const Slice& key) override {
  365|    591|    const uint32_t hash = HashSlice(key);
  366|    591|    return shard_[Shard(hash)].Lookup(key, hash);
  367|    591|  }
cache.cc:_ZN7leveldb12_GLOBAL__N_18LRUCache6LookupERKNS_5SliceEj:
  253|    591|Cache::Handle* LRUCache::Lookup(const Slice& key, uint32_t hash) {
  254|    591|  MutexLock l(&mutex_);
  255|    591|  LRUHandle* e = table_.Lookup(key, hash);
  256|    591|  if (e != nullptr) {
  ------------------
  |  Branch (256:7): [True: 53, False: 538]
  ------------------
  257|     53|    Ref(e);
  258|     53|  }
  259|    591|  return reinterpret_cast<Cache::Handle*>(e);
  260|    591|}
cache.cc:_ZN7leveldb12_GLOBAL__N_111HandleTable6LookupERKNS_5SliceEj:
   75|    591|  LRUHandle* Lookup(const Slice& key, uint32_t hash) {
   76|    591|    return *FindPointer(key, hash);
   77|    591|  }
cache.cc:_ZN7leveldb12_GLOBAL__N_18LRUCache3RefEPNS0_9LRUHandleE:
  218|     53|void LRUCache::Ref(LRUHandle* e) {
  219|     53|  if (e->refs == 1 && e->in_cache) {  // If on lru_ list, move to in_use_ list.
  ------------------
  |  Branch (219:7): [True: 53, False: 0]
  |  Branch (219:23): [True: 53, False: 0]
  ------------------
  220|     53|    LRU_Remove(e);
  221|     53|    LRU_Append(&in_use_, e);
  222|     53|  }
  223|     53|  e->refs++;
  224|     53|}
cache.cc:_ZN7leveldb12_GLOBAL__N_115ShardedLRUCache7ReleaseEPNS_5Cache6HandleE:
  368|    141|  void Release(Handle* handle) override {
  369|    141|    LRUHandle* h = reinterpret_cast<LRUHandle*>(handle);
  370|    141|    shard_[Shard(h->hash)].Release(handle);
  371|    141|  }
cache.cc:_ZN7leveldb12_GLOBAL__N_18LRUCache7ReleaseEPNS_5Cache6HandleE:
  262|    141|void LRUCache::Release(Cache::Handle* handle) {
  263|    141|  MutexLock l(&mutex_);
  264|    141|  Unref(reinterpret_cast<LRUHandle*>(handle));
  265|    141|}
cache.cc:_ZN7leveldb12_GLOBAL__N_115ShardedLRUCache5ValueEPNS_5Cache6HandleE:
  376|    141|  void* Value(Handle* handle) override {
  377|    141|    return reinterpret_cast<LRUHandle*>(handle)->value;
  378|    141|  }
cache.cc:_ZN7leveldb12_GLOBAL__N_115ShardedLRUCache5EraseERKNS_5SliceE:
  372|     28|  void Erase(const Slice& key) override {
  373|     28|    const uint32_t hash = HashSlice(key);
  374|     28|    shard_[Shard(hash)].Erase(key, hash);
  375|     28|  }
cache.cc:_ZN7leveldb12_GLOBAL__N_18LRUCache5EraseERKNS_5SliceEj:
  319|     28|void LRUCache::Erase(const Slice& key, uint32_t hash) {
  320|     28|  MutexLock l(&mutex_);
  321|     28|  FinishErase(table_.Remove(key, hash));
  322|     28|}
cache.cc:_ZN7leveldb12_GLOBAL__N_115ShardedLRUCache5NewIdEv:
  379|     88|  uint64_t NewId() override {
  380|     88|    MutexLock l(&id_mutex_);
  381|     88|    return ++(last_id_);
  382|     88|  }

_ZN7leveldb10PutFixed32EPNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEj:
    9|  1.82k|void PutFixed32(std::string* dst, uint32_t value) {
   10|  1.82k|  char buf[sizeof(value)];
   11|  1.82k|  EncodeFixed32(buf, value);
   12|  1.82k|  dst->append(buf, sizeof(buf));
   13|  1.82k|}
_ZN7leveldb10PutFixed64EPNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEm:
   15|    624|void PutFixed64(std::string* dst, uint64_t value) {
   16|    624|  char buf[sizeof(value)];
   17|    624|  EncodeFixed64(buf, value);
   18|    624|  dst->append(buf, sizeof(buf));
   19|    624|}
_ZN7leveldb14EncodeVarint32EPcj:
   21|  8.28k|char* EncodeVarint32(char* dst, uint32_t v) {
   22|       |  // Operate on characters as unsigneds
   23|  8.28k|  uint8_t* ptr = reinterpret_cast<uint8_t*>(dst);
   24|  8.28k|  static const int B = 128;
   25|  8.28k|  if (v < (1 << 7)) {
  ------------------
  |  Branch (25:7): [True: 4.83k, False: 3.44k]
  ------------------
   26|  4.83k|    *(ptr++) = v;
   27|  4.83k|  } else if (v < (1 << 14)) {
  ------------------
  |  Branch (27:14): [True: 3.17k, False: 270]
  ------------------
   28|  3.17k|    *(ptr++) = v | B;
   29|  3.17k|    *(ptr++) = v >> 7;
   30|  3.17k|  } else if (v < (1 << 21)) {
  ------------------
  |  Branch (30:14): [True: 270, False: 0]
  ------------------
   31|    270|    *(ptr++) = v | B;
   32|    270|    *(ptr++) = (v >> 7) | B;
   33|    270|    *(ptr++) = v >> 14;
   34|    270|  } 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|  8.28k|  return reinterpret_cast<char*>(ptr);
   47|  8.28k|}
_ZN7leveldb11PutVarint32EPNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEj:
   49|  6.86k|void PutVarint32(std::string* dst, uint32_t v) {
   50|  6.86k|  char buf[5];
   51|  6.86k|  char* ptr = EncodeVarint32(buf, v);
   52|  6.86k|  dst->append(buf, ptr - buf);
   53|  6.86k|}
_ZN7leveldb14EncodeVarint64EPcm:
   55|  2.24k|char* EncodeVarint64(char* dst, uint64_t v) {
   56|  2.24k|  static const int B = 128;
   57|  2.24k|  uint8_t* ptr = reinterpret_cast<uint8_t*>(dst);
   58|  4.07k|  while (v >= B) {
  ------------------
  |  Branch (58:10): [True: 1.82k, False: 2.24k]
  ------------------
   59|  1.82k|    *(ptr++) = v | B;
   60|  1.82k|    v >>= 7;
   61|  1.82k|  }
   62|  2.24k|  *(ptr++) = static_cast<uint8_t>(v);
   63|  2.24k|  return reinterpret_cast<char*>(ptr);
   64|  2.24k|}
_ZN7leveldb11PutVarint64EPNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEm:
   66|  2.24k|void PutVarint64(std::string* dst, uint64_t v) {
   67|  2.24k|  char buf[10];
   68|  2.24k|  char* ptr = EncodeVarint64(buf, v);
   69|  2.24k|  dst->append(buf, ptr - buf);
   70|  2.24k|}
_ZN7leveldb22PutLengthPrefixedSliceEPNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEERKNS_5SliceE:
   72|  1.54k|void PutLengthPrefixedSlice(std::string* dst, const Slice& value) {
   73|  1.54k|  PutVarint32(dst, value.size());
   74|  1.54k|  dst->append(value.data(), value.size());
   75|  1.54k|}
_ZN7leveldb12VarintLengthEm:
   77|  1.39k|int VarintLength(uint64_t v) {
   78|  1.39k|  int len = 1;
   79|  2.48k|  while (v >= 128) {
  ------------------
  |  Branch (79:10): [True: 1.08k, False: 1.39k]
  ------------------
   80|  1.08k|    v >>= 7;
   81|  1.08k|    len++;
   82|  1.08k|  }
   83|  1.39k|  return len;
   84|  1.39k|}
_ZN7leveldb22GetVarint32PtrFallbackEPKcS1_Pj:
   87|  7.72k|                                   uint32_t* value) {
   88|  7.72k|  uint32_t result = 0;
   89|  15.7k|  for (uint32_t shift = 0; shift <= 28 && p < limit; shift += 7) {
  ------------------
  |  Branch (89:28): [True: 15.7k, False: 0]
  |  Branch (89:43): [True: 15.5k, False: 188]
  ------------------
   90|  15.5k|    uint32_t byte = *(reinterpret_cast<const uint8_t*>(p));
   91|  15.5k|    p++;
   92|  15.5k|    if (byte & 128) {
  ------------------
  |  Branch (92:9): [True: 8.05k, False: 7.54k]
  ------------------
   93|       |      // More bytes are present
   94|  8.05k|      result |= ((byte & 127) << shift);
   95|  8.05k|    } else {
   96|  7.54k|      result |= (byte << shift);
   97|  7.54k|      *value = result;
   98|  7.54k|      return reinterpret_cast<const char*>(p);
   99|  7.54k|    }
  100|  15.5k|  }
  101|    188|  return nullptr;
  102|  7.72k|}
_ZN7leveldb11GetVarint32EPNS_5SliceEPj:
  104|  2.82k|bool GetVarint32(Slice* input, uint32_t* value) {
  105|  2.82k|  const char* p = input->data();
  106|  2.82k|  const char* limit = p + input->size();
  107|  2.82k|  const char* q = GetVarint32Ptr(p, limit, value);
  108|  2.82k|  if (q == nullptr) {
  ------------------
  |  Branch (108:7): [True: 188, False: 2.63k]
  ------------------
  109|    188|    return false;
  110|  2.63k|  } else {
  111|  2.63k|    *input = Slice(q, limit - q);
  112|  2.63k|    return true;
  113|  2.63k|  }
  114|  2.82k|}
_ZN7leveldb14GetVarint64PtrEPKcS1_Pm:
  116|  1.97k|const char* GetVarint64Ptr(const char* p, const char* limit, uint64_t* value) {
  117|  1.97k|  uint64_t result = 0;
  118|  3.66k|  for (uint32_t shift = 0; shift <= 63 && p < limit; shift += 7) {
  ------------------
  |  Branch (118:28): [True: 3.66k, False: 0]
  |  Branch (118:43): [True: 3.66k, False: 0]
  ------------------
  119|  3.66k|    uint64_t byte = *(reinterpret_cast<const uint8_t*>(p));
  120|  3.66k|    p++;
  121|  3.66k|    if (byte & 128) {
  ------------------
  |  Branch (121:9): [True: 1.68k, False: 1.97k]
  ------------------
  122|       |      // More bytes are present
  123|  1.68k|      result |= ((byte & 127) << shift);
  124|  1.97k|    } else {
  125|  1.97k|      result |= (byte << shift);
  126|  1.97k|      *value = result;
  127|  1.97k|      return reinterpret_cast<const char*>(p);
  128|  1.97k|    }
  129|  3.66k|  }
  130|      0|  return nullptr;
  131|  1.97k|}
_ZN7leveldb11GetVarint64EPNS_5SliceEPm:
  133|  1.97k|bool GetVarint64(Slice* input, uint64_t* value) {
  134|  1.97k|  const char* p = input->data();
  135|  1.97k|  const char* limit = p + input->size();
  136|  1.97k|  const char* q = GetVarint64Ptr(p, limit, value);
  137|  1.97k|  if (q == nullptr) {
  ------------------
  |  Branch (137:7): [True: 0, False: 1.97k]
  ------------------
  138|      0|    return false;
  139|  1.97k|  } else {
  140|  1.97k|    *input = Slice(q, limit - q);
  141|  1.97k|    return true;
  142|  1.97k|  }
  143|  1.97k|}
_ZN7leveldb22GetLengthPrefixedSliceEPNS_5SliceES1_:
  145|  1.72k|bool GetLengthPrefixedSlice(Slice* input, Slice* result) {
  146|  1.72k|  uint32_t len;
  147|  1.72k|  if (GetVarint32(input, &len) && input->size() >= len) {
  ------------------
  |  Branch (147:7): [True: 1.72k, False: 0]
  |  Branch (147:35): [True: 1.72k, False: 0]
  ------------------
  148|  1.72k|    *result = Slice(input->data(), len);
  149|  1.72k|    input->remove_prefix(len);
  150|  1.72k|    return true;
  151|  1.72k|  } else {
  152|      0|    return false;
  153|      0|  }
  154|  1.72k|}

_ZN7leveldb13DecodeFixed64EPKc:
   91|  1.79k|inline uint64_t DecodeFixed64(const char* ptr) {
   92|  1.79k|  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.79k|  return (static_cast<uint64_t>(buffer[0])) |
   96|  1.79k|         (static_cast<uint64_t>(buffer[1]) << 8) |
   97|  1.79k|         (static_cast<uint64_t>(buffer[2]) << 16) |
   98|  1.79k|         (static_cast<uint64_t>(buffer[3]) << 24) |
   99|  1.79k|         (static_cast<uint64_t>(buffer[4]) << 32) |
  100|  1.79k|         (static_cast<uint64_t>(buffer[5]) << 40) |
  101|  1.79k|         (static_cast<uint64_t>(buffer[6]) << 48) |
  102|  1.79k|         (static_cast<uint64_t>(buffer[7]) << 56);
  103|  1.79k|}
_ZN7leveldb13EncodeFixed32EPcj:
   54|  5.93k|inline void EncodeFixed32(char* dst, uint32_t value) {
   55|  5.93k|  uint8_t* const buffer = reinterpret_cast<uint8_t*>(dst);
   56|       |
   57|       |  // Recent clang and gcc optimize this to a single mov / str instruction.
   58|  5.93k|  buffer[0] = static_cast<uint8_t>(value);
   59|  5.93k|  buffer[1] = static_cast<uint8_t>(value >> 8);
   60|  5.93k|  buffer[2] = static_cast<uint8_t>(value >> 16);
   61|  5.93k|  buffer[3] = static_cast<uint8_t>(value >> 24);
   62|  5.93k|}
_ZN7leveldb13EncodeFixed64EPcm:
   64|  2.98k|inline void EncodeFixed64(char* dst, uint64_t value) {
   65|  2.98k|  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.98k|  buffer[0] = static_cast<uint8_t>(value);
   69|  2.98k|  buffer[1] = static_cast<uint8_t>(value >> 8);
   70|  2.98k|  buffer[2] = static_cast<uint8_t>(value >> 16);
   71|  2.98k|  buffer[3] = static_cast<uint8_t>(value >> 24);
   72|  2.98k|  buffer[4] = static_cast<uint8_t>(value >> 32);
   73|  2.98k|  buffer[5] = static_cast<uint8_t>(value >> 40);
   74|  2.98k|  buffer[6] = static_cast<uint8_t>(value >> 48);
   75|  2.98k|  buffer[7] = static_cast<uint8_t>(value >> 56);
   76|  2.98k|}
_ZN7leveldb13DecodeFixed32EPKc:
   81|  26.4M|inline uint32_t DecodeFixed32(const char* ptr) {
   82|  26.4M|  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|  26.4M|  return (static_cast<uint32_t>(buffer[0])) |
   86|  26.4M|         (static_cast<uint32_t>(buffer[1]) << 8) |
   87|  26.4M|         (static_cast<uint32_t>(buffer[2]) << 16) |
   88|  26.4M|         (static_cast<uint32_t>(buffer[3]) << 24);
   89|  26.4M|}
_ZN7leveldb14GetVarint32PtrEPKcS1_Pj:
  109|  12.1k|                                  uint32_t* value) {
  110|  12.1k|  if (p < limit) {
  ------------------
  |  Branch (110:7): [True: 11.9k, False: 188]
  ------------------
  111|  11.9k|    uint32_t result = *(reinterpret_cast<const uint8_t*>(p));
  112|  11.9k|    if ((result & 128) == 0) {
  ------------------
  |  Branch (112:9): [True: 4.38k, False: 7.54k]
  ------------------
  113|  4.38k|      *value = result;
  114|  4.38k|      return p + 1;
  115|  4.38k|    }
  116|  11.9k|  }
  117|  7.72k|  return GetVarint32PtrFallback(p, limit, value);
  118|  12.1k|}

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

_ZN7leveldb6crc32c6ExtendEjPKcm:
  276|  6.77k|uint32_t Extend(uint32_t crc, const char* data, size_t n) {
  277|  6.77k|  static bool accelerate = CanAccelerateCRC32C();
  278|  6.77k|  if (accelerate) {
  ------------------
  |  Branch (278:7): [True: 0, False: 6.77k]
  ------------------
  279|      0|    return port::AcceleratedCRC32C(crc, data, n);
  280|      0|  }
  281|       |
  282|  6.77k|  const uint8_t* p = reinterpret_cast<const uint8_t*>(data);
  283|  6.77k|  const uint8_t* e = p + n;
  284|  6.77k|  uint32_t l = crc ^ kCRC32Xor;
  285|       |
  286|       |// Process one byte at a time.
  287|  6.77k|#define STEP1                              \
  288|  6.77k|  do {                                     \
  289|  6.77k|    int c = (l & 0xff) ^ *p++;             \
  290|  6.77k|    l = kByteExtensionTable[c] ^ (l >> 8); \
  291|  6.77k|  } while (0)
  292|       |
  293|       |// Process one of the 4 strides of 4-byte data.
  294|  6.77k|#define STEP4(s)                                                               \
  295|  6.77k|  do {                                                                         \
  296|  6.77k|    crc##s = ReadUint32LE(p + s * 4) ^ kStrideExtensionTable3[crc##s & 0xff] ^ \
  297|  6.77k|             kStrideExtensionTable2[(crc##s >> 8) & 0xff] ^                    \
  298|  6.77k|             kStrideExtensionTable1[(crc##s >> 16) & 0xff] ^                   \
  299|  6.77k|             kStrideExtensionTable0[crc##s >> 24];                             \
  300|  6.77k|  } while (0)
  301|       |
  302|       |// Process a 16-byte swath of 4 strides, each of which has 4 bytes of data.
  303|  6.77k|#define STEP16 \
  304|  6.77k|  do {         \
  305|  6.77k|    STEP4(0);  \
  306|  6.77k|    STEP4(1);  \
  307|  6.77k|    STEP4(2);  \
  308|  6.77k|    STEP4(3);  \
  309|  6.77k|    p += 16;   \
  310|  6.77k|  } while (0)
  311|       |
  312|       |// Process 4 bytes that were already loaded into a word.
  313|  6.77k|#define STEP4W(w)                                   \
  314|  6.77k|  do {                                              \
  315|  6.77k|    w ^= l;                                         \
  316|  6.77k|    for (size_t i = 0; i < 4; ++i) {                \
  317|  6.77k|      w = (w >> 8) ^ kByteExtensionTable[w & 0xff]; \
  318|  6.77k|    }                                               \
  319|  6.77k|    l = w;                                          \
  320|  6.77k|  } 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.77k|  const uint8_t* x = RoundUp<4>(p);
  325|  6.77k|  if (x <= e) {
  ------------------
  |  Branch (325:7): [True: 6.77k, False: 0]
  ------------------
  326|       |    // Process bytes p is 4-byte aligned.
  327|  14.8k|    while (p != x) {
  ------------------
  |  Branch (327:12): [True: 8.04k, False: 6.77k]
  ------------------
  328|  8.04k|      STEP1;
  ------------------
  |  |  288|  8.04k|  do {                                     \
  |  |  289|  8.04k|    int c = (l & 0xff) ^ *p++;             \
  |  |  290|  8.04k|    l = kByteExtensionTable[c] ^ (l >> 8); \
  |  |  291|  8.04k|  } while (0)
  |  |  ------------------
  |  |  |  Branch (291:12): [Folded, False: 8.04k]
  |  |  ------------------
  ------------------
  329|  8.04k|    }
  330|  6.77k|  }
  331|       |
  332|  6.77k|  if ((e - p) >= 16) {
  ------------------
  |  Branch (332:7): [True: 4.54k, False: 2.22k]
  ------------------
  333|       |    // Load a 16-byte swath into the stride partial results.
  334|  4.54k|    uint32_t crc0 = ReadUint32LE(p + 0 * 4) ^ l;
  335|  4.54k|    uint32_t crc1 = ReadUint32LE(p + 1 * 4);
  336|  4.54k|    uint32_t crc2 = ReadUint32LE(p + 2 * 4);
  337|  4.54k|    uint32_t crc3 = ReadUint32LE(p + 3 * 4);
  338|  4.54k|    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.60M|    while ((e - p) >= 16) {
  ------------------
  |  Branch (345:12): [True: 6.60M, False: 4.54k]
  ------------------
  346|  6.60M|      STEP16;
  ------------------
  |  |  304|  6.60M|  do {         \
  |  |  305|  6.60M|    STEP4(0);  \
  |  |  ------------------
  |  |  |  |  295|  6.60M|  do {                                                                         \
  |  |  |  |  296|  6.60M|    crc##s = ReadUint32LE(p + s * 4) ^ kStrideExtensionTable3[crc##s & 0xff] ^ \
  |  |  |  |  297|  6.60M|             kStrideExtensionTable2[(crc##s >> 8) & 0xff] ^                    \
  |  |  |  |  298|  6.60M|             kStrideExtensionTable1[(crc##s >> 16) & 0xff] ^                   \
  |  |  |  |  299|  6.60M|             kStrideExtensionTable0[crc##s >> 24];                             \
  |  |  |  |  300|  6.60M|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (300:12): [Folded, False: 6.60M]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  306|  6.60M|    STEP4(1);  \
  |  |  ------------------
  |  |  |  |  295|  6.60M|  do {                                                                         \
  |  |  |  |  296|  6.60M|    crc##s = ReadUint32LE(p + s * 4) ^ kStrideExtensionTable3[crc##s & 0xff] ^ \
  |  |  |  |  297|  6.60M|             kStrideExtensionTable2[(crc##s >> 8) & 0xff] ^                    \
  |  |  |  |  298|  6.60M|             kStrideExtensionTable1[(crc##s >> 16) & 0xff] ^                   \
  |  |  |  |  299|  6.60M|             kStrideExtensionTable0[crc##s >> 24];                             \
  |  |  |  |  300|  6.60M|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (300:12): [Folded, False: 6.60M]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  307|  6.60M|    STEP4(2);  \
  |  |  ------------------
  |  |  |  |  295|  6.60M|  do {                                                                         \
  |  |  |  |  296|  6.60M|    crc##s = ReadUint32LE(p + s * 4) ^ kStrideExtensionTable3[crc##s & 0xff] ^ \
  |  |  |  |  297|  6.60M|             kStrideExtensionTable2[(crc##s >> 8) & 0xff] ^                    \
  |  |  |  |  298|  6.60M|             kStrideExtensionTable1[(crc##s >> 16) & 0xff] ^                   \
  |  |  |  |  299|  6.60M|             kStrideExtensionTable0[crc##s >> 24];                             \
  |  |  |  |  300|  6.60M|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (300:12): [Folded, False: 6.60M]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  308|  6.60M|    STEP4(3);  \
  |  |  ------------------
  |  |  |  |  295|  6.60M|  do {                                                                         \
  |  |  |  |  296|  6.60M|    crc##s = ReadUint32LE(p + s * 4) ^ kStrideExtensionTable3[crc##s & 0xff] ^ \
  |  |  |  |  297|  6.60M|             kStrideExtensionTable2[(crc##s >> 8) & 0xff] ^                    \
  |  |  |  |  298|  6.60M|             kStrideExtensionTable1[(crc##s >> 16) & 0xff] ^                   \
  |  |  |  |  299|  6.60M|             kStrideExtensionTable0[crc##s >> 24];                             \
  |  |  |  |  300|  6.60M|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (300:12): [Folded, False: 6.60M]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  309|  6.60M|    p += 16;   \
  |  |  310|  6.60M|  } while (0)
  |  |  ------------------
  |  |  |  Branch (310:12): [Folded, False: 6.60M]
  |  |  ------------------
  ------------------
  347|  6.60M|    }
  348|       |
  349|       |    // Advance one word at a time as far as possible.
  350|  11.6k|    while ((e - p) >= 4) {
  ------------------
  |  Branch (350:12): [True: 7.07k, False: 4.54k]
  ------------------
  351|  7.07k|      STEP4(0);
  ------------------
  |  |  295|  7.07k|  do {                                                                         \
  |  |  296|  7.07k|    crc##s = ReadUint32LE(p + s * 4) ^ kStrideExtensionTable3[crc##s & 0xff] ^ \
  |  |  297|  7.07k|             kStrideExtensionTable2[(crc##s >> 8) & 0xff] ^                    \
  |  |  298|  7.07k|             kStrideExtensionTable1[(crc##s >> 16) & 0xff] ^                   \
  |  |  299|  7.07k|             kStrideExtensionTable0[crc##s >> 24];                             \
  |  |  300|  7.07k|  } while (0)
  |  |  ------------------
  |  |  |  Branch (300:12): [Folded, False: 7.07k]
  |  |  ------------------
  ------------------
  352|  7.07k|      uint32_t tmp = crc0;
  353|  7.07k|      crc0 = crc1;
  354|  7.07k|      crc1 = crc2;
  355|  7.07k|      crc2 = crc3;
  356|  7.07k|      crc3 = tmp;
  357|  7.07k|      p += 4;
  358|  7.07k|    }
  359|       |
  360|       |    // Combine the 4 partial stride results.
  361|  4.54k|    l = 0;
  362|  4.54k|    STEP4W(crc0);
  ------------------
  |  |  314|  4.54k|  do {                                              \
  |  |  315|  4.54k|    w ^= l;                                         \
  |  |  316|  22.7k|    for (size_t i = 0; i < 4; ++i) {                \
  |  |  ------------------
  |  |  |  Branch (316:24): [True: 18.1k, False: 4.54k]
  |  |  ------------------
  |  |  317|  18.1k|      w = (w >> 8) ^ kByteExtensionTable[w & 0xff]; \
  |  |  318|  18.1k|    }                                               \
  |  |  319|  4.54k|    l = w;                                          \
  |  |  320|  4.54k|  } while (0)
  |  |  ------------------
  |  |  |  Branch (320:12): [Folded, False: 4.54k]
  |  |  ------------------
  ------------------
  363|  4.54k|    STEP4W(crc1);
  ------------------
  |  |  314|  4.54k|  do {                                              \
  |  |  315|  4.54k|    w ^= l;                                         \
  |  |  316|  22.7k|    for (size_t i = 0; i < 4; ++i) {                \
  |  |  ------------------
  |  |  |  Branch (316:24): [True: 18.1k, False: 4.54k]
  |  |  ------------------
  |  |  317|  18.1k|      w = (w >> 8) ^ kByteExtensionTable[w & 0xff]; \
  |  |  318|  18.1k|    }                                               \
  |  |  319|  4.54k|    l = w;                                          \
  |  |  320|  4.54k|  } while (0)
  |  |  ------------------
  |  |  |  Branch (320:12): [Folded, False: 4.54k]
  |  |  ------------------
  ------------------
  364|  4.54k|    STEP4W(crc2);
  ------------------
  |  |  314|  4.54k|  do {                                              \
  |  |  315|  4.54k|    w ^= l;                                         \
  |  |  316|  22.7k|    for (size_t i = 0; i < 4; ++i) {                \
  |  |  ------------------
  |  |  |  Branch (316:24): [True: 18.1k, False: 4.54k]
  |  |  ------------------
  |  |  317|  18.1k|      w = (w >> 8) ^ kByteExtensionTable[w & 0xff]; \
  |  |  318|  18.1k|    }                                               \
  |  |  319|  4.54k|    l = w;                                          \
  |  |  320|  4.54k|  } while (0)
  |  |  ------------------
  |  |  |  Branch (320:12): [Folded, False: 4.54k]
  |  |  ------------------
  ------------------
  365|  4.54k|    STEP4W(crc3);
  ------------------
  |  |  314|  4.54k|  do {                                              \
  |  |  315|  4.54k|    w ^= l;                                         \
  |  |  316|  22.7k|    for (size_t i = 0; i < 4; ++i) {                \
  |  |  ------------------
  |  |  |  Branch (316:24): [True: 18.1k, False: 4.54k]
  |  |  ------------------
  |  |  317|  18.1k|      w = (w >> 8) ^ kByteExtensionTable[w & 0xff]; \
  |  |  318|  18.1k|    }                                               \
  |  |  319|  4.54k|    l = w;                                          \
  |  |  320|  4.54k|  } while (0)
  |  |  ------------------
  |  |  |  Branch (320:12): [Folded, False: 4.54k]
  |  |  ------------------
  ------------------
  366|  4.54k|  }
  367|       |
  368|       |  // Process the last few bytes.
  369|  13.2k|  while (p != e) {
  ------------------
  |  Branch (369:10): [True: 6.46k, False: 6.77k]
  ------------------
  370|  6.46k|    STEP1;
  ------------------
  |  |  288|  6.46k|  do {                                     \
  |  |  289|  6.46k|    int c = (l & 0xff) ^ *p++;             \
  |  |  290|  6.46k|    l = kByteExtensionTable[c] ^ (l >> 8); \
  |  |  291|  6.46k|  } while (0)
  |  |  ------------------
  |  |  |  Branch (291:12): [Folded, False: 6.46k]
  |  |  ------------------
  ------------------
  371|  6.46k|  }
  372|  6.77k|#undef STEP4W
  373|  6.77k|#undef STEP16
  374|  6.77k|#undef STEP4
  375|  6.77k|#undef STEP1
  376|  6.77k|  return l ^ kCRC32Xor;
  377|  6.77k|}
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.77k|constexpr inline const uint8_t* RoundUp(const uint8_t* pointer) {
  258|  6.77k|  return reinterpret_cast<uint8_t*>(
  259|  6.77k|      (reinterpret_cast<uintptr_t>(pointer) + (N - 1)) &
  260|  6.77k|      ~static_cast<uintptr_t>(N - 1));
  261|  6.77k|}
crc32c.cc:_ZN7leveldb6crc32c12_GLOBAL__N_112ReadUint32LEEPKh:
  249|  26.4M|inline uint32_t ReadUint32LE(const uint8_t* buffer) {
  250|  26.4M|  return DecodeFixed32(reinterpret_cast<const char*>(buffer));
  251|  26.4M|}

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

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

_ZN7leveldb3Env7DefaultEv:
  924|    196|Env* Env::Default() {
  925|    196|  static PosixDefaultEnv env_container;
  926|    196|  return env_container.env();
  927|    196|}
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|    276|                           SequentialFile** result) override {
  530|    276|    int fd = ::open(filename.c_str(), O_RDONLY | kOpenBaseFlags);
  531|    276|    if (fd < 0) {
  ------------------
  |  Branch (531:9): [True: 0, False: 276]
  ------------------
  532|      0|      *result = nullptr;
  533|      0|      return PosixError(filename, errno);
  534|      0|    }
  535|       |
  536|    276|    *result = new PosixSequentialFile(filename, fd);
  537|    276|    return Status::OK();
  538|    276|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_110PosixErrorERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEi:
   61|    228|Status PosixError(const std::string& context, int error_number) {
   62|    228|  if (error_number == ENOENT) {
  ------------------
  |  Branch (62:7): [True: 61, False: 167]
  ------------------
   63|     61|    return Status::NotFound(context, std::strerror(error_number));
   64|    167|  } else {
   65|    167|    return Status::IOError(context, std::strerror(error_number));
   66|    167|  }
   67|    228|}
env_posix.cc:_ZN7leveldb12_GLOBAL__N_119PosixSequentialFileC2ENSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEi:
  139|    276|      : fd_(fd), filename_(std::move(filename)) {}
env_posix.cc:_ZN7leveldb12_GLOBAL__N_119PosixSequentialFileD2Ev:
  140|    276|  ~PosixSequentialFile() override { close(fd_); }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_119PosixSequentialFile4ReadEmPNS_5SliceEPc:
  142|  1.21k|  Status Read(size_t n, Slice* result, char* scratch) override {
  143|  1.21k|    Status status;
  144|  1.21k|    while (true) {
  ------------------
  |  Branch (144:12): [True: 1.21k, Folded]
  ------------------
  145|  1.21k|      ::ssize_t read_size = ::read(fd_, scratch, n);
  146|  1.21k|      if (read_size < 0) {  // Read error.
  ------------------
  |  Branch (146:11): [True: 0, False: 1.21k]
  ------------------
  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.21k|      *result = Slice(scratch, read_size);
  154|  1.21k|      break;
  155|  1.21k|    }
  156|  1.21k|    return status;
  157|  1.21k|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_18PosixEnv19NewRandomAccessFileERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPPNS_16RandomAccessFileE:
  541|     88|                             RandomAccessFile** result) override {
  542|     88|    *result = nullptr;
  543|     88|    int fd = ::open(filename.c_str(), O_RDONLY | kOpenBaseFlags);
  544|     88|    if (fd < 0) {
  ------------------
  |  Branch (544:9): [True: 0, False: 88]
  ------------------
  545|      0|      return PosixError(filename, errno);
  546|      0|    }
  547|       |
  548|     88|    if (!mmap_limiter_.Acquire()) {
  ------------------
  |  Branch (548:9): [True: 0, False: 88]
  ------------------
  549|      0|      *result = new PosixRandomAccessFile(filename, fd, &fd_limiter_);
  550|      0|      return Status::OK();
  551|      0|    }
  552|       |
  553|     88|    uint64_t file_size;
  554|     88|    Status status = GetFileSize(filename, &file_size);
  555|     88|    if (status.ok()) {
  ------------------
  |  Branch (555:9): [True: 88, False: 0]
  ------------------
  556|     88|      void* mmap_base =
  557|     88|          ::mmap(/*addr=*/nullptr, file_size, PROT_READ, MAP_SHARED, fd, 0);
  558|     88|      if (mmap_base != MAP_FAILED) {
  ------------------
  |  Branch (558:11): [True: 88, False: 0]
  ------------------
  559|     88|        *result = new PosixMmapReadableFile(filename,
  560|     88|                                            reinterpret_cast<char*>(mmap_base),
  561|     88|                                            file_size, &mmap_limiter_);
  562|     88|      } else {
  563|      0|        status = PosixError(filename, errno);
  564|      0|      }
  565|     88|    }
  566|     88|    ::close(fd);
  567|     88|    if (!status.ok()) {
  ------------------
  |  Branch (567:9): [True: 0, False: 88]
  ------------------
  568|      0|      mmap_limiter_.Release();
  569|      0|    }
  570|     88|    return status;
  571|     88|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_17Limiter7AcquireEv:
   90|     88|  bool Acquire() {
   91|     88|    int old_acquires_allowed =
   92|     88|        acquires_allowed_.fetch_sub(1, std::memory_order_relaxed);
   93|       |
   94|     88|    if (old_acquires_allowed > 0) return true;
  ------------------
  |  Branch (94:9): [True: 88, 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|     88|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_121PosixMmapReadableFileC2ENSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPcmPNS0_7LimiterE:
  249|     88|      : mmap_base_(mmap_base),
  250|     88|        length_(length),
  251|     88|        mmap_limiter_(mmap_limiter),
  252|     88|        filename_(std::move(filename)) {}
env_posix.cc:_ZN7leveldb12_GLOBAL__N_121PosixMmapReadableFileD2Ev:
  254|     88|  ~PosixMmapReadableFile() override {
  255|     88|    ::munmap(static_cast<void*>(mmap_base_), length_);
  256|     88|    mmap_limiter_->Release();
  257|     88|  }
env_posix.cc:_ZNK7leveldb12_GLOBAL__N_121PosixMmapReadableFile4ReadEmmPNS_5SliceEPc:
  260|    626|              char* scratch) const override {
  261|    626|    if (offset + n > length_) {
  ------------------
  |  Branch (261:9): [True: 0, False: 626]
  ------------------
  262|      0|      *result = Slice();
  263|      0|      return PosixError(filename_, EINVAL);
  264|      0|    }
  265|       |
  266|    626|    *result = Slice(mmap_base_ + offset, n);
  267|    626|    return Status::OK();
  268|    626|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_17Limiter7ReleaseEv:
  109|     88|  void Release() {
  110|     88|    int old_acquires_allowed =
  111|     88|        acquires_allowed_.fetch_add(1, std::memory_order_relaxed);
  112|       |
  113|       |    // Silence compiler warnings about unused arguments when NDEBUG is defined.
  114|     88|    (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|     88|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_18PosixEnv15NewWritableFileERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPPNS_12WritableFileE:
  574|    494|                         WritableFile** result) override {
  575|    494|    int fd = ::open(filename.c_str(),
  576|    494|                    O_TRUNC | O_WRONLY | O_CREAT | kOpenBaseFlags, 0644);
  577|    494|    if (fd < 0) {
  ------------------
  |  Branch (577:9): [True: 0, False: 494]
  ------------------
  578|      0|      *result = nullptr;
  579|      0|      return PosixError(filename, errno);
  580|      0|    }
  581|       |
  582|    494|    *result = new PosixWritableFile(filename, fd);
  583|    494|    return Status::OK();
  584|    494|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_117PosixWritableFileC2ENSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEi:
  280|    494|      : pos_(0),
  281|    494|        fd_(fd),
  282|    494|        is_manifest_(IsManifest(filename)),
  283|    494|        filename_(std::move(filename)),
  284|    494|        dirname_(Dirname(filename_)) {}
env_posix.cc:_ZN7leveldb12_GLOBAL__N_117PosixWritableFile10IsManifestERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  453|    494|  static bool IsManifest(const std::string& filename) {
  454|    494|    return Basename(filename).starts_with("MANIFEST");
  455|    494|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_117PosixWritableFile8BasenameERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  439|    494|  static Slice Basename(const std::string& filename) {
  440|    494|    std::string::size_type separator_pos = filename.rfind('/');
  441|    494|    if (separator_pos == std::string::npos) {
  ------------------
  |  Branch (441:9): [True: 0, False: 494]
  ------------------
  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|    494|    assert(filename.find('/', separator_pos + 1) == std::string::npos);
  447|       |
  448|    494|    return Slice(filename.data() + separator_pos + 1,
  449|    494|                 filename.length() - separator_pos - 1);
  450|    494|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_117PosixWritableFile7DirnameERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  423|    494|  static std::string Dirname(const std::string& filename) {
  424|    494|    std::string::size_type separator_pos = filename.rfind('/');
  425|    494|    if (separator_pos == std::string::npos) {
  ------------------
  |  Branch (425:9): [True: 0, False: 494]
  ------------------
  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|    494|    assert(filename.find('/', separator_pos + 1) == std::string::npos);
  431|       |
  432|    494|    return filename.substr(0, separator_pos);
  433|    494|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_117PosixWritableFileD2Ev:
  286|    494|  ~PosixWritableFile() override {
  287|    494|    if (fd_ >= 0) {
  ------------------
  |  Branch (287:9): [True: 216, False: 278]
  ------------------
  288|       |      // Ignoring any potential errors
  289|    216|      Close();
  290|    216|    }
  291|    494|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_117PosixWritableFile6AppendERKNS_5SliceE:
  293|  7.33k|  Status Append(const Slice& data) override {
  294|  7.33k|    size_t write_size = data.size();
  295|  7.33k|    const char* write_data = data.data();
  296|       |
  297|       |    // Fit as much as possible into buffer.
  298|  7.33k|    size_t copy_size = std::min(write_size, kWritableFileBufferSize - pos_);
  299|  7.33k|    std::memcpy(buf_ + pos_, write_data, copy_size);
  300|  7.33k|    write_data += copy_size;
  301|  7.33k|    write_size -= copy_size;
  302|  7.33k|    pos_ += copy_size;
  303|  7.33k|    if (write_size == 0) {
  ------------------
  |  Branch (303:9): [True: 7.32k, False: 8]
  ------------------
  304|  7.32k|      return Status::OK();
  305|  7.32k|    }
  306|       |
  307|       |    // Can't fit in buffer, so need to do at least one write.
  308|      8|    Status status = FlushBuffer();
  309|      8|    if (!status.ok()) {
  ------------------
  |  Branch (309:9): [True: 0, False: 8]
  ------------------
  310|      0|      return status;
  311|      0|    }
  312|       |
  313|       |    // Small writes go to buffer, large writes are written directly.
  314|      8|    if (write_size < kWritableFileBufferSize) {
  ------------------
  |  Branch (314:9): [True: 0, False: 8]
  ------------------
  315|      0|      std::memcpy(buf_, write_data, write_size);
  316|      0|      pos_ = write_size;
  317|      0|      return Status::OK();
  318|      0|    }
  319|      8|    return WriteUnbuffered(write_data, write_size);
  320|      8|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_117PosixWritableFile11FlushBufferEv:
  354|  4.35k|  Status FlushBuffer() {
  355|  4.35k|    Status status = WriteUnbuffered(buf_, pos_);
  356|  4.35k|    pos_ = 0;
  357|  4.35k|    return status;
  358|  4.35k|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_117PosixWritableFile15WriteUnbufferedEPKcm:
  360|  4.36k|  Status WriteUnbuffered(const char* data, size_t size) {
  361|  8.04k|    while (size > 0) {
  ------------------
  |  Branch (361:12): [True: 3.68k, False: 4.36k]
  ------------------
  362|  3.68k|      ssize_t write_result = ::write(fd_, data, size);
  363|  3.68k|      if (write_result < 0) {
  ------------------
  |  Branch (363:11): [True: 0, False: 3.68k]
  ------------------
  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.68k|      data += write_result;
  370|  3.68k|      size -= write_result;
  371|  3.68k|    }
  372|  4.36k|    return Status::OK();
  373|  4.36k|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_117PosixWritableFile5CloseEv:
  322|    494|  Status Close() override {
  323|    494|    Status status = FlushBuffer();
  324|    494|    const int close_result = ::close(fd_);
  325|    494|    if (close_result < 0 && status.ok()) {
  ------------------
  |  Branch (325:9): [True: 0, False: 494]
  |  Branch (325:29): [True: 0, False: 0]
  ------------------
  326|       |      status = PosixError(filename_, errno);
  327|      0|    }
  328|    494|    fd_ = -1;
  329|    494|    return status;
  330|    494|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_117PosixWritableFile5FlushEv:
  332|  3.45k|  Status Flush() override { return FlushBuffer(); }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_117PosixWritableFile4SyncEv:
  334|    395|  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|    395|    Status status = SyncDirIfManifest();
  341|    395|    if (!status.ok()) {
  ------------------
  |  Branch (341:9): [True: 0, False: 395]
  ------------------
  342|      0|      return status;
  343|      0|    }
  344|       |
  345|    395|    status = FlushBuffer();
  346|    395|    if (!status.ok()) {
  ------------------
  |  Branch (346:9): [True: 0, False: 395]
  ------------------
  347|      0|      return status;
  348|      0|    }
  349|       |
  350|    395|    return SyncFd(fd_, filename_);
  351|    395|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_117PosixWritableFile17SyncDirIfManifestEv:
  375|    395|  Status SyncDirIfManifest() {
  376|    395|    Status status;
  377|    395|    if (!is_manifest_) {
  ------------------
  |  Branch (377:9): [True: 209, False: 186]
  ------------------
  378|    209|      return status;
  379|    209|    }
  380|       |
  381|    186|    int fd = ::open(dirname_.c_str(), O_RDONLY | kOpenBaseFlags);
  382|    186|    if (fd < 0) {
  ------------------
  |  Branch (382:9): [True: 0, False: 186]
  ------------------
  383|      0|      status = PosixError(dirname_, errno);
  384|    186|    } else {
  385|    186|      status = SyncFd(fd, dirname_);
  386|    186|      ::close(fd);
  387|    186|    }
  388|    186|    return status;
  389|    395|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_117PosixWritableFile6SyncFdEiRKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  397|    581|  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|    581|#if HAVE_FDATASYNC
  409|    581|    bool sync_success = ::fdatasync(fd) == 0;
  410|       |#else
  411|       |    bool sync_success = ::fsync(fd) == 0;
  412|       |#endif  // HAVE_FDATASYNC
  413|       |
  414|    581|    if (sync_success) {
  ------------------
  |  Branch (414:9): [True: 581, False: 0]
  ------------------
  415|    581|      return Status::OK();
  416|    581|    }
  417|      0|    return PosixError(fd_path, errno);
  418|    581|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_18PosixEnv10FileExistsERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  599|    108|  bool FileExists(const std::string& filename) override {
  600|       |    return ::access(filename.c_str(), F_OK) == 0;
  601|    108|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_18PosixEnv11GetChildrenERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPNS2_6vectorIS8_NS6_IS8_EEEE:
  604|    244|                     std::vector<std::string>* result) override {
  605|    244|    result->clear();
  606|    244|    ::DIR* dir = ::opendir(directory_path.c_str());
  607|    244|    if (dir == nullptr) {
  ------------------
  |  Branch (607:9): [True: 0, False: 244]
  ------------------
  608|      0|      return PosixError(directory_path, errno);
  609|      0|    }
  610|    244|    struct ::dirent* entry;
  611|  2.52k|    while ((entry = ::readdir(dir)) != nullptr) {
  ------------------
  |  Branch (611:12): [True: 2.27k, False: 244]
  ------------------
  612|  2.27k|      result->emplace_back(entry->d_name);
  613|  2.27k|    }
  614|    244|    ::closedir(dir);
  615|    244|    return Status::OK();
  616|    244|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_18PosixEnv10RemoveFileERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  618|    228|  Status RemoveFile(const std::string& filename) override {
  619|    228|    if (::unlink(filename.c_str()) != 0) {
  ------------------
  |  Branch (619:9): [True: 12, False: 216]
  ------------------
  620|     12|      return PosixError(filename, errno);
  621|     12|    }
  622|    216|    return Status::OK();
  623|    228|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_18PosixEnv9CreateDirERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  625|    216|  Status CreateDir(const std::string& dirname) override {
  626|    216|    if (::mkdir(dirname.c_str(), 0755) != 0) {
  ------------------
  |  Branch (626:9): [True: 167, False: 49]
  ------------------
  627|    167|      return PosixError(dirname, errno);
  628|    167|    }
  629|     49|    return Status::OK();
  630|    216|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_18PosixEnv11GetFileSizeERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPm:
  639|     88|  Status GetFileSize(const std::string& filename, uint64_t* size) override {
  640|     88|    struct ::stat file_stat;
  641|     88|    if (::stat(filename.c_str(), &file_stat) != 0) {
  ------------------
  |  Branch (641:9): [True: 0, False: 88]
  ------------------
  642|      0|      *size = 0;
  643|      0|      return PosixError(filename, errno);
  644|      0|    }
  645|     88|    *size = file_stat.st_size;
  646|     88|    return Status::OK();
  647|     88|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_18PosixEnv10RenameFileERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEESA_:
  649|    265|  Status RenameFile(const std::string& from, const std::string& to) override {
  650|    265|    if (std::rename(from.c_str(), to.c_str()) != 0) {
  ------------------
  |  Branch (650:9): [True: 49, False: 216]
  ------------------
  651|     49|      return PosixError(from, errno);
  652|     49|    }
  653|    216|    return Status::OK();
  654|    265|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_18PosixEnv8LockFileERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPPNS_8FileLockE:
  656|    108|  Status LockFile(const std::string& filename, FileLock** lock) override {
  657|    108|    *lock = nullptr;
  658|       |
  659|    108|    int fd = ::open(filename.c_str(), O_RDWR | O_CREAT | kOpenBaseFlags, 0644);
  660|    108|    if (fd < 0) {
  ------------------
  |  Branch (660:9): [True: 0, False: 108]
  ------------------
  661|      0|      return PosixError(filename, errno);
  662|      0|    }
  663|       |
  664|    108|    if (!locks_.Insert(filename)) {
  ------------------
  |  Branch (664:9): [True: 0, False: 108]
  ------------------
  665|      0|      ::close(fd);
  666|      0|      return Status::IOError("lock " + filename, "already held by process");
  667|      0|    }
  668|       |
  669|    108|    if (LockOrUnlock(fd, true) == -1) {
  ------------------
  |  Branch (669:9): [True: 0, False: 108]
  ------------------
  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|    108|    *lock = new PosixFileLock(fd, filename);
  677|    108|    return Status::OK();
  678|    108|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_114PosixLockTable6InsertERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  501|    108|  bool Insert(const std::string& fname) LOCKS_EXCLUDED(mu_) {
  502|    108|    mu_.Lock();
  503|    108|    bool succeeded = locked_files_.insert(fname).second;
  504|    108|    mu_.Unlock();
  505|    108|    return succeeded;
  506|    108|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_112LockOrUnlockEib:
  467|    216|int LockOrUnlock(int fd, bool lock) {
  468|    216|  errno = 0;
  469|    216|  struct ::flock file_lock_info;
  470|    216|  std::memset(&file_lock_info, 0, sizeof(file_lock_info));
  471|    216|  file_lock_info.l_type = (lock ? F_WRLCK : F_UNLCK);
  ------------------
  |  Branch (471:28): [True: 108, False: 108]
  ------------------
  472|    216|  file_lock_info.l_whence = SEEK_SET;
  473|    216|  file_lock_info.l_start = 0;
  474|    216|  file_lock_info.l_len = 0;  // Lock/unlock entire file.
  475|       |  return ::fcntl(fd, F_SETLK, &file_lock_info);
  476|    216|}
env_posix.cc:_ZN7leveldb12_GLOBAL__N_114PosixLockTable6RemoveERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  507|    108|  void Remove(const std::string& fname) LOCKS_EXCLUDED(mu_) {
  508|    108|    mu_.Lock();
  509|    108|    locked_files_.erase(fname);
  510|    108|    mu_.Unlock();
  511|    108|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_113PosixFileLockC2EiNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  482|    108|      : fd_(fd), filename_(std::move(filename)) {}
env_posix.cc:_ZN7leveldb12_GLOBAL__N_18PosixEnv10UnlockFileEPNS_8FileLockE:
  680|    108|  Status UnlockFile(FileLock* lock) override {
  681|    108|    PosixFileLock* posix_file_lock = static_cast<PosixFileLock*>(lock);
  682|    108|    if (LockOrUnlock(posix_file_lock->fd(), false) == -1) {
  ------------------
  |  Branch (682:9): [True: 0, False: 108]
  ------------------
  683|      0|      return PosixError("unlock " + posix_file_lock->filename(), errno);
  684|      0|    }
  685|    108|    locks_.Remove(posix_file_lock->filename());
  686|    108|    ::close(posix_file_lock->fd());
  687|    108|    delete posix_file_lock;
  688|    108|    return Status::OK();
  689|    108|  }
env_posix.cc:_ZNK7leveldb12_GLOBAL__N_113PosixFileLock2fdEv:
  484|    216|  int fd() const { return fd_; }
env_posix.cc:_ZNK7leveldb12_GLOBAL__N_113PosixFileLock8filenameEv:
  485|    108|  const std::string& filename() const { return filename_; }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_18PosixEnv8ScheduleEPFvPvES2_:
  816|     50|    void* background_work_arg) {
  817|     50|  background_work_mutex_.Lock();
  818|       |
  819|       |  // Start the background thread, if we haven't done so already.
  820|     50|  if (!started_background_thread_) {
  ------------------
  |  Branch (820:7): [True: 1, False: 49]
  ------------------
  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|     50|  if (background_work_queue_.empty()) {
  ------------------
  |  Branch (827:7): [True: 50, False: 0]
  ------------------
  828|     50|    background_work_cv_.Signal();
  829|     50|  }
  830|       |
  831|     50|  background_work_queue_.emplace(background_work_function, background_work_arg);
  832|     50|  background_work_mutex_.Unlock();
  833|     50|}
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|     52|  while (true) {
  ------------------
  |  Branch (836:10): [True: 51, Folded]
  ------------------
  837|     51|    background_work_mutex_.Lock();
  838|       |
  839|       |    // Wait until there is work to be done.
  840|     93|    while (background_work_queue_.empty()) {
  ------------------
  |  Branch (840:12): [True: 42, False: 51]
  ------------------
  841|     42|      background_work_cv_.Wait();
  842|     42|    }
  843|       |
  844|     51|    assert(!background_work_queue_.empty());
  845|     51|    auto background_work_function = background_work_queue_.front().function;
  846|     51|    void* background_work_arg = background_work_queue_.front().arg;
  847|     51|    background_work_queue_.pop();
  848|       |
  849|     51|    background_work_mutex_.Unlock();
  850|     51|    background_work_function(background_work_arg);
  851|     51|  }
  852|      1|}
env_posix.cc:_ZN7leveldb12_GLOBAL__N_18PosixEnv18BackgroundWorkItemC2EPFvPvES3_:
  762|     50|        : function(function), arg(arg) {}
env_posix.cc:_ZN7leveldb12_GLOBAL__N_18PosixEnv9NewLoggerERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPPNS_6LoggerE:
  717|    108|  Status NewLogger(const std::string& filename, Logger** result) override {
  718|    108|    int fd = ::open(filename.c_str(),
  719|    108|                    O_APPEND | O_WRONLY | O_CREAT | kOpenBaseFlags, 0644);
  720|    108|    if (fd < 0) {
  ------------------
  |  Branch (720:9): [True: 0, False: 108]
  ------------------
  721|      0|      *result = nullptr;
  722|      0|      return PosixError(filename, errno);
  723|      0|    }
  724|       |
  725|    108|    std::FILE* fp = ::fdopen(fd, "w");
  726|    108|    if (fp == nullptr) {
  ------------------
  |  Branch (726:9): [True: 0, False: 108]
  ------------------
  727|      0|      ::close(fd);
  728|      0|      *result = nullptr;
  729|      0|      return PosixError(filename, errno);
  730|    108|    } else {
  731|    108|      *result = new PosixLogger(fp);
  732|    108|      return Status::OK();
  733|    108|    }
  734|    108|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_18PosixEnv9NowMicrosEv:
  736|    128|  uint64_t NowMicros() override {
  737|    128|    static constexpr uint64_t kUsecondsPerSecond = 1000000;
  738|    128|    struct ::timeval tv;
  739|    128|    ::gettimeofday(&tv, nullptr);
  740|    128|    return static_cast<uint64_t>(tv.tv_sec) * kUsecondsPerSecond + tv.tv_usec;
  741|    128|  }
env_posix.cc:_ZN7leveldb12_GLOBAL__N_112SingletonEnvINS0_8PosixEnvEE3envEv:
  890|    196|  Env* env() { return reinterpret_cast<Env*>(&env_storage_); }

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

_ZN7leveldb4HashEPKcmj:
   22|    707|uint32_t Hash(const char* data, size_t n, uint32_t seed) {
   23|       |  // Similar to murmur hash
   24|    707|  const uint32_t m = 0xc6a4a793;
   25|    707|  const uint32_t r = 24;
   26|    707|  const char* limit = data + n;
   27|    707|  uint32_t h = seed ^ (n * m);
   28|       |
   29|       |  // Pick up four bytes at a time
   30|  3.02k|  while (limit - data >= 4) {
  ------------------
  |  Branch (30:10): [True: 2.31k, False: 707]
  ------------------
   31|  2.31k|    uint32_t w = DecodeFixed32(data);
   32|  2.31k|    data += 4;
   33|  2.31k|    h += w;
   34|  2.31k|    h *= m;
   35|  2.31k|    h ^= (h >> 16);
   36|  2.31k|  }
   37|       |
   38|       |  // Pick up remaining bytes
   39|    707|  switch (limit - data) {
  ------------------
  |  Branch (39:11): [True: 0, False: 707]
  ------------------
   40|      0|    case 3:
  ------------------
  |  Branch (40:5): [True: 0, False: 707]
  ------------------
   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: 707]
  ------------------
   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: 707]
  ------------------
   47|      0|      h += static_cast<uint8_t>(data[0]);
   48|      0|      h *= m;
   49|      0|      h ^= (h >> r);
   50|      0|      break;
   51|    707|  }
   52|    707|  return h;
   53|    707|}

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

_ZN7leveldb9MutexLockC2EPNS_4port5MutexE:
   25|  1.72k|  explicit MutexLock(port::Mutex* mu) EXCLUSIVE_LOCK_FUNCTION(mu) : mu_(mu) {
   26|  1.72k|    this->mu_->Lock();
   27|  1.72k|  }
_ZN7leveldb9MutexLockD2Ev:
   28|  1.72k|  ~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|    196|  InstanceType* get() {
   41|    196|    return reinterpret_cast<InstanceType*>(&instance_storage_);
   42|    196|  }

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

_ZN7leveldb11PosixLoggerC2EP8_IO_FILE:
   29|    108|  explicit PosixLogger(std::FILE* fp) : fp_(fp) { assert(fp != nullptr); }
_ZN7leveldb11PosixLoggerD2Ev:
   31|    108|  ~PosixLogger() override { std::fclose(fp_); }
_ZN7leveldb11PosixLogger4LogvEPKcP13__va_list_tag:
   33|    494|  void Logv(const char* format, std::va_list arguments) override {
   34|       |    // Record the time as close to the Logv() call as possible.
   35|    494|    struct ::timeval now_timeval;
   36|    494|    ::gettimeofday(&now_timeval, nullptr);
   37|    494|    const std::time_t now_seconds = now_timeval.tv_sec;
   38|    494|    struct std::tm now_components;
   39|    494|    ::localtime_r(&now_seconds, &now_components);
   40|       |
   41|       |    // Record the thread ID.
   42|    494|    constexpr const int kMaxThreadIdSize = 32;
   43|    494|    std::ostringstream thread_stream;
   44|    494|    thread_stream << std::this_thread::get_id();
   45|    494|    std::string thread_id = thread_stream.str();
   46|    494|    if (thread_id.size() > kMaxThreadIdSize) {
  ------------------
  |  Branch (46:9): [True: 0, False: 494]
  ------------------
   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|    494|    constexpr const int kStackBufferSize = 512;
   53|    494|    char stack_buffer[kStackBufferSize];
   54|    494|    static_assert(sizeof(stack_buffer) == static_cast<size_t>(kStackBufferSize),
   55|    494|                  "sizeof(char) is expected to be 1 in C++");
   56|       |
   57|    494|    int dynamic_buffer_size = 0;  // Computed in the first iteration.
   58|    509|    for (int iteration = 0; iteration < 2; ++iteration) {
  ------------------
  |  Branch (58:29): [True: 509, False: 0]
  ------------------
   59|    509|      const int buffer_size =
   60|    509|          (iteration == 0) ? kStackBufferSize : dynamic_buffer_size;
  ------------------
  |  Branch (60:11): [True: 494, False: 15]
  ------------------
   61|    509|      char* const buffer =
   62|    509|          (iteration == 0) ? stack_buffer : new char[dynamic_buffer_size];
  ------------------
  |  Branch (62:11): [True: 494, False: 15]
  ------------------
   63|       |
   64|       |      // Print the header into the buffer.
   65|    509|      int buffer_offset = std::snprintf(
   66|    509|          buffer, buffer_size, "%04d/%02d/%02d-%02d:%02d:%02d.%06d %s ",
   67|    509|          now_components.tm_year + 1900, now_components.tm_mon + 1,
   68|    509|          now_components.tm_mday, now_components.tm_hour, now_components.tm_min,
   69|    509|          now_components.tm_sec, static_cast<int>(now_timeval.tv_usec),
   70|    509|          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|    509|      assert(buffer_offset <= 28 + kMaxThreadIdSize);
   76|    509|      static_assert(28 + kMaxThreadIdSize < kStackBufferSize,
   77|    509|                    "stack-allocated buffer may not fit the message header");
   78|    509|      assert(buffer_offset < buffer_size);
   79|       |
   80|       |      // Print the message into the buffer.
   81|    509|      std::va_list arguments_copy;
   82|    509|      va_copy(arguments_copy, arguments);
   83|    509|      buffer_offset +=
   84|    509|          std::vsnprintf(buffer + buffer_offset, buffer_size - buffer_offset,
   85|    509|                         format, arguments_copy);
   86|    509|      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|    509|      if (buffer_offset >= buffer_size - 1) {
  ------------------
  |  Branch (90:11): [True: 15, False: 494]
  ------------------
   91|       |        // The message did not fit into the buffer.
   92|     15|        if (iteration == 0) {
  ------------------
  |  Branch (92:13): [True: 15, 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|     15|          dynamic_buffer_size = buffer_offset + 2;
   97|     15|          continue;
   98|     15|        }
   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|     15|        assert(false);
  104|      0|        buffer_offset = buffer_size - 1;
  105|      0|      }
  106|       |
  107|       |      // Add a newline if necessary.
  108|    494|      if (buffer[buffer_offset - 1] != '\n') {
  ------------------
  |  Branch (108:11): [True: 253, False: 241]
  ------------------
  109|    253|        buffer[buffer_offset] = '\n';
  110|    253|        ++buffer_offset;
  111|    253|      }
  112|       |
  113|    494|      assert(buffer_offset <= buffer_size);
  114|    494|      std::fwrite(buffer, 1, buffer_offset, fp_);
  115|    494|      std::fflush(fp_);
  116|       |
  117|    494|      if (iteration != 0) {
  ------------------
  |  Branch (117:11): [True: 15, False: 479]
  ------------------
  118|     15|        delete[] buffer;
  119|     15|      }
  120|    494|      break;
  121|    509|    }
  122|    494|  }

_ZN7leveldb6RandomC2Ej:
   20|    204|  explicit Random(uint32_t s) : seed_(s & 0x7fffffffu) {
   21|       |    // Avoid bad seeds.
   22|    204|    if (seed_ == 0 || seed_ == 2147483647L) {
  ------------------
  |  Branch (22:9): [True: 0, False: 204]
  |  Branch (22:23): [True: 0, False: 204]
  ------------------
   23|      0|      seed_ = 1;
   24|      0|    }
   25|    204|  }
_ZN7leveldb6Random4NextEv:
   26|    932|  uint32_t Next() {
   27|    932|    static const uint32_t M = 2147483647L;  // 2^31-1
   28|    932|    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|    932|    uint64_t product = seed_ * A;
   36|       |
   37|       |    // Compute (product % M) using the fact that ((x << 31) % M) == x.
   38|    932|    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|    932|    if (seed_ > M) {
  ------------------
  |  Branch (42:9): [True: 0, False: 932]
  ------------------
   43|      0|      seed_ -= M;
   44|      0|    }
   45|    932|    return seed_;
   46|    932|  }
_ZN7leveldb6Random7UniformEi:
   49|     50|  uint32_t Uniform(int n) { return Next() % n; }
_ZN7leveldb6Random5OneInEi:
   53|    882|  bool OneIn(int n) { return (Next() % n) == 0; }

_ZN7leveldb6StatusC2ENS0_4CodeERKNS_5SliceES4_:
   21|    252|Status::Status(Code code, const Slice& msg, const Slice& msg2) {
   22|    252|  assert(code != kOk);
   23|    252|  const uint32_t len1 = static_cast<uint32_t>(msg.size());
   24|    252|  const uint32_t len2 = static_cast<uint32_t>(msg2.size());
   25|    252|  const uint32_t size = len1 + (len2 ? (2 + len2) : 0);
  ------------------
  |  Branch (25:33): [True: 228, False: 24]
  ------------------
   26|    252|  char* result = new char[size + 5];
   27|    252|  std::memcpy(result, &size, sizeof(size));
   28|    252|  result[4] = static_cast<char>(code);
   29|    252|  std::memcpy(result + 5, msg.data(), len1);
   30|    252|  if (len2) {
  ------------------
  |  Branch (30:7): [True: 228, False: 24]
  ------------------
   31|    228|    result[5 + len1] = ':';
   32|    228|    result[6 + len1] = ' ';
   33|    228|    std::memcpy(result + 7 + len1, msg2.data(), len2);
   34|    228|  }
   35|    252|  state_ = result;
   36|    252|}
_ZNK7leveldb6Status8ToStringEv:
   38|     57|std::string Status::ToString() const {
   39|     57|  if (state_ == nullptr) {
  ------------------
  |  Branch (39:7): [True: 57, False: 0]
  ------------------
   40|     57|    return "OK";
   41|     57|  } 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|     57|}

