Skip to content

Commit

Permalink
Implement NextAndGetResult() in memtable and level iterator (facebook…
Browse files Browse the repository at this point in the history
…#7179)

Summary:
NextAndGetResult() is not implemented in memtable and is very simply implemented in level iterator. The result is that for a normal leveled iterator, performance regression will be observed for calling PrepareValue() for most iterator Next(). Mitigate the problem by implementing the function for both iterators. In level iterator, the implementation cannot be perfect as when calling file iterator's SeekToFirst() we don't have information about whether the value is prepared. Fortunately, the first key should not cause a big portion of the CPu.

Pull Request resolved: facebook#7179

Test Plan: Run normal crash test for a while.

Reviewed By: anand1976

Differential Revision: D22783840

fbshipit-source-id: c19f45cdf21b756190adef97a3b66ccde3936e05
  • Loading branch information
siying authored and facebook-github-bot committed Jul 29, 2020
1 parent d9d1907 commit 692f6a3
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 14 deletions.
10 changes: 10 additions & 0 deletions db/memtable.cc
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,16 @@ class MemTableIterator : public InternalIterator {
iter_->Next();
valid_ = iter_->Valid();
}
bool NextAndGetResult(IterateResult* result) override {
Next();
bool is_valid = valid_;
if (is_valid) {
result->key = key();
result->may_be_out_of_upper_bound = true;
result->value_prepared = true;
}
return is_valid;
}
void Prev() override {
PERF_COUNTER_ADD(prev_on_memtable_count, 1);
assert(Valid());
Expand Down
32 changes: 18 additions & 14 deletions db/version_set.cc
Original file line number Diff line number Diff line change
Expand Up @@ -970,13 +970,6 @@ class LevelIterator final : public InternalIterator {
void SetFileIterator(InternalIterator* iter);
void InitFileIterator(size_t new_file_index);

// Called by both of Next() and NextAndGetResult(). Force inline.
void NextImpl() {
assert(Valid());
file_iter_.Next();
SkipEmptyFileForward();
}

const Slice& file_smallest_key(size_t file_index) {
assert(file_index < flevel_->num_files);
return flevel_->files[file_index].smallest_key;
Expand Down Expand Up @@ -1140,15 +1133,26 @@ void LevelIterator::SeekToLast() {
CheckMayBeOutOfLowerBound();
}

void LevelIterator::Next() { NextImpl(); }
void LevelIterator::Next() {
assert(Valid());
file_iter_.Next();
SkipEmptyFileForward();
}

bool LevelIterator::NextAndGetResult(IterateResult* result) {
NextImpl();
bool is_valid = Valid();
if (is_valid) {
result->key = key();
result->may_be_out_of_upper_bound = MayBeOutOfUpperBound();
result->value_prepared = !allow_unprepared_value_;
assert(Valid());
bool is_valid = file_iter_.NextAndGetResult(result);
if (!is_valid) {
SkipEmptyFileForward();
is_valid = Valid();
if (is_valid) {
result->key = key();
result->may_be_out_of_upper_bound = MayBeOutOfUpperBound();
// Ideally, we should return the real file_iter_.value_prepared but the
// information is not here. It would casue an extra PrepareValue()
// for the first key of a file.
result->value_prepared = !allow_unprepared_value_;
}
}
return is_valid;
}
Expand Down
7 changes: 7 additions & 0 deletions table/iterator_wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,13 @@ class IteratorWrapperBase {
valid_ = iter_->NextAndGetResult(&result_);
assert(!valid_ || iter_->status().ok());
}
bool NextAndGetResult(IterateResult* result) {
assert(iter_);
valid_ = iter_->NextAndGetResult(&result_);
*result = result_;
assert(!valid_ || iter_->status().ok());
return valid_;
}
void Prev() {
assert(iter_);
iter_->Prev();
Expand Down

0 comments on commit 692f6a3

Please sign in to comment.