diff --git a/db/db_iterator_test.cc b/db/db_iterator_test.cc index 63a11752e..9df7bfbbc 100644 --- a/db/db_iterator_test.cc +++ b/db/db_iterator_test.cc @@ -2413,6 +2413,30 @@ TEST_P(DBIteratorTest, NonBlockingIterationBugRepro) { EXPECT_TRUE(iter->status().IsIncomplete()); } +TEST_P(DBIteratorTest, SeekBackwardAfterOutOfUpperBound) { + Put("a", ""); + Put("b", ""); + Flush(); + + ReadOptions ropt; + Slice ub = "b"; + ropt.iterate_upper_bound = &ub; + + std::unique_ptr it(dbfull()->NewIterator(ropt)); + it->SeekForPrev("a"); + ASSERT_TRUE(it->Valid()); + ASSERT_OK(it->status()); + ASSERT_EQ("a", it->key().ToString()); + it->Next(); + ASSERT_FALSE(it->Valid()); + ASSERT_OK(it->status()); + it->SeekForPrev("a"); + ASSERT_OK(it->status()); + + ASSERT_TRUE(it->Valid()); + ASSERT_EQ("a", it->key().ToString()); +} + INSTANTIATE_TEST_CASE_P(DBIteratorTestInstance, DBIteratorTest, testing::Values(true, false)); diff --git a/table/block_based_table_reader.cc b/table/block_based_table_reader.cc index 8b83cda53..e2d92529b 100644 --- a/table/block_based_table_reader.cc +++ b/table/block_based_table_reader.cc @@ -1991,6 +1991,7 @@ bool BlockBasedTable::PrefixMayMatch( template void BlockBasedTableIterator::Seek(const Slice& target) { + is_out_of_bound_ = false; if (!CheckPrefixMayMatch(target)) { ResetDataIter(); return; @@ -2020,6 +2021,7 @@ void BlockBasedTableIterator::Seek(const Slice& target) { template void BlockBasedTableIterator::SeekForPrev(const Slice& target) { + is_out_of_bound_ = false; if (!CheckPrefixMayMatch(target)) { ResetDataIter(); return; @@ -2062,6 +2064,7 @@ void BlockBasedTableIterator::SeekForPrev(const Slice& target) { template void BlockBasedTableIterator::SeekToFirst() { + is_out_of_bound_ = false; SavePrevIndexValue(); index_iter_->SeekToFirst(); if (!index_iter_->Valid()) { @@ -2075,6 +2078,7 @@ void BlockBasedTableIterator::SeekToFirst() { template void BlockBasedTableIterator::SeekToLast() { + is_out_of_bound_ = false; SavePrevIndexValue(); index_iter_->SeekToLast(); if (!index_iter_->Valid()) { @@ -2153,7 +2157,7 @@ void BlockBasedTableIterator::InitDataBlock() { template void BlockBasedTableIterator::FindKeyForward() { - is_out_of_bound_ = false; + assert(!is_out_of_bound_); // TODO the while loop inherits from two-level-iterator. We don't know // whether a block can be empty so it can be replaced by an "if". while (!block_iter_.Valid()) { @@ -2193,6 +2197,7 @@ void BlockBasedTableIterator::FindKeyForward() { template void BlockBasedTableIterator::FindKeyBackward() { + assert(!is_out_of_bound_); while (!block_iter_.Valid()) { if (!block_iter_.status().ok()) { return;