// Options that control read operations structLEVELDB_EXPORT ReadOptions { ReadOptions() = default;
// 如果true,所有从底层读取回来的数据都需要进行校验 // If true, all data read from underlying storage will be // verified against corresponding checksums. bool verify_checksums = false;
// 本次read的record是否需要缓存到内存? // Should the data read for this iteration be cached in memory? // Callers may wish to set this field to false for bulk scans. bool fill_cache = true;
// 如果提供快照(non-null),则从快照种读。如果不提供(null),则从implicit的快照种读 // If "snapshot" is non-null, read as of the supplied snapshot // (which must belong to the DB that is being read and which must // not have been released). If "snapshot" is null, use an implicit // snapshot of the state at the beginning of this read operation. const Snapshot* snapshot = nullptr; };
// 先在level0中search // Search level-0 in order from newest to oldest. std::vector<FileMetaData*> tmp; tmp.reserve(files_[0].size()); for (uint32_t i = 0; i < files_[0].size(); i++) { FileMetaData* f = files_[0][i]; if (ucmp->Compare(user_key, f->smallest.user_key()) >= 0 && ucmp->Compare(user_key, f->largest.user_key()) <= 0) { // 找到level0的sstable,这些sstable的range 都 包含了 user_key. tmp.push_back(f); } } if (!tmp.empty()) { std::sort(tmp.begin(), tmp.end(), NewestFirst); // sstables按照sequence number的由大到小排序(因为seq越大,代表数据越新) for (uint32_t i = 0; i < tmp.size(); i++) { if (!(*func)(arg, 0, tmp[i])) { // 调用Match函数 return; } } }
// 在其他level中查询 // Search other levels. for (int level = 1; level < config::kNumLevels; level++) { size_t num_files = files_[level].size(); if (num_files == 0) continue;
// Binary search to find earliest index whose largest key >= internal_key. uint32_t index = FindFile(vset_->icmp_, files_[level], internal_key); if (index < num_files) { FileMetaData* f = files_[level][index]; if (ucmp->Compare(user_key, f->smallest.user_key()) < 0) { // 本层中的最小key都比 internal key大,说明本层没有合适的sstable // All of "f" is past any data for user_key } else { if (!(*func)(arg, level, f)) { // 调用match return; } } } } }