Selaa lähdekoodia

use ForEachOverlapping to impl Get

naive_version
neal-zhu 5 vuotta sitten
vanhempi
commit
6a90bb91ee
1 muutettua tiedostoa jossa 45 lisäystä ja 70 poistoa
  1. +45
    -70
      db/version_set.cc

+ 45
- 70
db/version_set.cc Näytä tiedosto

@ -330,94 +330,69 @@ Status Version::Get(const ReadOptions& options, const LookupKey& k,
const Comparator* ucmp = vset_->icmp_.user_comparator(); const Comparator* ucmp = vset_->icmp_.user_comparator();
Status s; Status s;
stats->seek_file = nullptr; struct State {
stats->seek_file_level = -1; GetStats* stats;
FileMetaData* last_file_read = nullptr; const ReadOptions* options;
int last_file_read_level = -1; Slice ikey;
Slice user_key;
// We can search level-by-level since entries never hop across const Comparator* ucmp;
// levels. Therefore we are guaranteed that if we find data std::string* value;
// in a smaller level, later levels are irrelevant.
std::vector<FileMetaData*> tmp;
FileMetaData* tmp2;
for (int level = 0; level < config::kNumLevels; level++) {
size_t num_files = files_[level].size();
if (num_files == 0) continue;
// Get the list of files to search in this level VersionSet *vset;
FileMetaData* const* files = &files_[level][0]; Status s;
if (level == 0) {
// Level-0 files may overlap each other. Find all files that
// overlap user_key and process them in order from newest to oldest.
tmp.reserve(num_files);
for (uint32_t i = 0; i < num_files; i++) {
FileMetaData* f = files[i];
if (ucmp->Compare(user_key, f->smallest.user_key()) >= 0 &&
ucmp->Compare(user_key, f->largest.user_key()) <= 0) {
tmp.push_back(f);
}
}
if (tmp.empty()) continue;
std::sort(tmp.begin(), tmp.end(), NewestFirst); static bool Match(void* arg, int level, FileMetaData* f) {
files = &tmp[0]; State* state = reinterpret_cast<State*>(arg);
num_files = tmp.size();
} else {
// Binary search to find earliest index whose largest key >= ikey.
uint32_t index = FindFile(vset_->icmp_, files_[level], ikey);
if (index >= num_files) {
files = nullptr;
num_files = 0;
} else {
tmp2 = files[index];
if (ucmp->Compare(user_key, tmp2->smallest.user_key()) < 0) {
// All of "tmp2" is past any data for user_key
files = nullptr;
num_files = 0;
} else {
files = &tmp2;
num_files = 1;
}
}
}
for (uint32_t i = 0; i < num_files; ++i) { if (state->stats->seek_file == nullptr) {
if (last_file_read != nullptr && stats->seek_file == nullptr) {
// We have had more than one seek for this read. Charge the 1st file. // We have had more than one seek for this read. Charge the 1st file.
stats->seek_file = last_file_read; state->stats->seek_file = f;
stats->seek_file_level = last_file_read_level; state->stats->seek_file_level = level;
} }
FileMetaData* f = files[i];
last_file_read = f;
last_file_read_level = level;
Saver saver; Saver saver;
saver.state = kNotFound; saver.state = kNotFound;
saver.ucmp = ucmp; saver.ucmp = state->ucmp;
saver.user_key = user_key; saver.user_key = state->user_key;
saver.value = value; saver.value = state->value;
s = vset_->table_cache_->Get(options, f->number, f->file_size, ikey, Status s = state->vset->table_cache_->Get(*state->options, f->number,
&saver, SaveValue); f->file_size, state->ikey,
&saver, SaveValue);
if (!s.ok()) { if (!s.ok()) {
return s; state->s = s;
return false;
} }
switch (saver.state) { switch (saver.state) {
case kNotFound: case kNotFound:
break; // Keep searching in other files return true; // Keep saerching in other files
case kFound: case kFound:
return s; state->s = s;
return false;
case kDeleted: case kDeleted:
s = Status::NotFound(Slice()); // Use empty error message for speed return false;
return s;
case kCorrupt: case kCorrupt:
s = Status::Corruption("corrupted key for ", user_key); state->s = Status::Corruption("corrupted key for ", state->user_key);
return s; return false;
} }
} }
} };
stats->seek_file = nullptr;
stats->seek_file_level = -1;
State state;
state.s = Status::NotFound(Slice());
state.stats = stats;
state.ikey = ikey;
state.user_key = user_key;
state.ucmp = ucmp;
state.value = value;
state.vset = vset_;
ForEachOverlapping(user_key, ikey, &state, &State::Match);
return Status::NotFound(Slice()); // Use an empty error message for speed return state.s;
} }
bool Version::UpdateStats(const GetStats& stats) { bool Version::UpdateStats(const GetStats& stats) {

||||||
x
 
000:0
Ladataan…
Peruuta
Tallenna