diff --git a/db/db_iter.cc b/db/db_iter.cc index 76fa00a8d..d04d30e9e 100644 --- a/db/db_iter.cc +++ b/db/db_iter.cc @@ -186,9 +186,17 @@ void DBIter::Next() { if (!iter_->Valid()) { iter_->SeekToFirst(); } + } else if (iter_->Valid() && !current_entry_is_merged_) { + // If the current value is not a merge, the iter position is the + // current key, which is already returned. We can safely issue a + // Next() without checking the current key. + // If the current key is a merge, very likely iter already points + // to the next internal position. + iter_->Next(); } - // If the current value is merged, we might already hit end of iter_ + // Now we point to the next internal position, for both of merge and + // not merge cases. if (!iter_->Valid()) { valid_ = false; return; diff --git a/db/db_test.cc b/db/db_test.cc index 1ce4b6e30..71037bf4f 100644 --- a/db/db_test.cc +++ b/db/db_test.cc @@ -1910,9 +1910,10 @@ TEST_F(DBTest, IterReseek) { DestroyAndReopen(options); CreateAndReopenWithCF({"pikachu"}, options); - // insert two keys with same userkey and verify that + // insert three keys with same userkey and verify that // reseek is not invoked. For each of these test cases, // verify that we can find the next key "b". + ASSERT_OK(Put(1, "a", "zero")); ASSERT_OK(Put(1, "a", "one")); ASSERT_OK(Put(1, "a", "two")); ASSERT_OK(Put(1, "b", "bone"));