提交 addfe1ef 编写于 作者: I Islam AbdelRahman 提交者: Facebook Github Bot

Fix tombstone scans in SeekForPrev outside prefix

Summary:
When doing a Seek() or SeekForPrev() we should stop the moment we see a key with a different prefix as start if ReadOptions:: prefix_same_as_start was set to true

Right now we don't stop if we encounter a tombstone outside the prefix while executing SeekForPrev()
Closes https://github.com/facebook/rocksdb/pull/3067

Differential Revision: D6149638

Pulled By: IslamAbdelRahman

fbshipit-source-id: 7f659862d2bf552d3c9104a360c79439ceba2f18
上级 386a57e6
...@@ -715,6 +715,14 @@ void DBIter::PrevInternal() { ...@@ -715,6 +715,14 @@ void DBIter::PrevInternal() {
ExtractUserKey(iter_->key()), ExtractUserKey(iter_->key()),
!iter_->IsKeyPinned() || !pin_thru_lifetime_ /* copy */); !iter_->IsKeyPinned() || !pin_thru_lifetime_ /* copy */);
if (prefix_extractor_ && prefix_same_as_start_ &&
prefix_extractor_->Transform(saved_key_.GetUserKey())
.compare(prefix_start_key_) != 0) {
// Current key does not have the same prefix as start
valid_ = false;
return;
}
if (FindValueForCurrentKey()) { if (FindValueForCurrentKey()) {
if (!iter_->Valid()) { if (!iter_->Valid()) {
return; return;
...@@ -723,11 +731,6 @@ void DBIter::PrevInternal() { ...@@ -723,11 +731,6 @@ void DBIter::PrevInternal() {
if (user_comparator_->Equal(ikey.user_key, saved_key_.GetUserKey())) { if (user_comparator_->Equal(ikey.user_key, saved_key_.GetUserKey())) {
FindPrevUserKey(); FindPrevUserKey();
} }
if (valid_ && prefix_extractor_ && prefix_same_as_start_ &&
prefix_extractor_->Transform(saved_key_.GetUserKey())
.compare(prefix_start_key_) != 0) {
valid_ = false;
}
return; return;
} }
......
...@@ -2813,6 +2813,42 @@ TEST_F(DBIterWithMergeIterTest, InnerMergeIteratorDataRace8) { ...@@ -2813,6 +2813,42 @@ TEST_F(DBIterWithMergeIterTest, InnerMergeIteratorDataRace8) {
rocksdb::SyncPoint::GetInstance()->DisableProcessing(); rocksdb::SyncPoint::GetInstance()->DisableProcessing();
} }
TEST_F(DBIteratorTest, SeekPrefixTombstones) {
ReadOptions ro;
Options options;
options.prefix_extractor.reset(NewNoopTransform());
TestIterator* internal_iter = new TestIterator(BytewiseComparator());
internal_iter->AddDeletion("b");
internal_iter->AddDeletion("c");
internal_iter->AddDeletion("d");
internal_iter->AddDeletion("e");
internal_iter->AddDeletion("f");
internal_iter->AddDeletion("g");
internal_iter->Finish();
ro.prefix_same_as_start = true;
std::unique_ptr<Iterator> db_iter(NewDBIterator(
env_, ro, ImmutableCFOptions(options), BytewiseComparator(),
internal_iter, 10, options.max_sequential_skip_in_iterations,
nullptr /*read_callback*/));
int skipped_keys = 0;
get_perf_context()->Reset();
db_iter->SeekForPrev("z");
skipped_keys =
static_cast<int>(get_perf_context()->internal_key_skipped_count);
ASSERT_EQ(skipped_keys, 0);
get_perf_context()->Reset();
db_iter->Seek("a");
skipped_keys =
static_cast<int>(get_perf_context()->internal_key_skipped_count);
ASSERT_EQ(skipped_keys, 0);
}
} // namespace rocksdb } // namespace rocksdb
int main(int argc, char** argv) { int main(int argc, char** argv) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册