diff --git a/db/memtable.cc b/db/memtable.cc index b391fe561..422433459 100644 --- a/db/memtable.cc +++ b/db/memtable.cc @@ -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()); diff --git a/db/version_set.cc b/db/version_set.cc index 3ac5b0c83..67d1be3ad 100644 --- a/db/version_set.cc +++ b/db/version_set.cc @@ -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; @@ -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; } diff --git a/table/iterator_wrapper.h b/table/iterator_wrapper.h index b4b051ff6..010a23abf 100644 --- a/table/iterator_wrapper.h +++ b/table/iterator_wrapper.h @@ -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();