Fix issue in Iterator::Seek when using Block based filter block with prefix_extractor
Summary: Similar to D53385 we need to check InDomain before checking the filter block. Test Plan: unit tests Reviewers: yhchiang, rven, sdong Reviewed By: sdong Subscribers: dhruba Differential Revision: https://reviews.facebook.net/D53421
This commit is contained in:
parent
0be02649d8
commit
3bbf0e1e4f
@ -11077,6 +11077,7 @@ class SliceTransformLimitedDomain : public SliceTransform {
|
|||||||
|
|
||||||
TEST_F(DBTest, PrefixExtractorFullFilter) {
|
TEST_F(DBTest, PrefixExtractorFullFilter) {
|
||||||
BlockBasedTableOptions bbto;
|
BlockBasedTableOptions bbto;
|
||||||
|
// Full Filter Block
|
||||||
bbto.filter_policy.reset(rocksdb::NewBloomFilterPolicy(10, false));
|
bbto.filter_policy.reset(rocksdb::NewBloomFilterPolicy(10, false));
|
||||||
bbto.whole_key_filtering = false;
|
bbto.whole_key_filtering = false;
|
||||||
|
|
||||||
@ -11103,6 +11104,39 @@ TEST_F(DBTest, PrefixExtractorFullFilter) {
|
|||||||
ASSERT_EQ(Get("zzzzz_AAAA"), "val5");
|
ASSERT_EQ(Get("zzzzz_AAAA"), "val5");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(DBTest, PrefixExtractorBlockFilter) {
|
||||||
|
BlockBasedTableOptions bbto;
|
||||||
|
// Block Filter Block
|
||||||
|
bbto.filter_policy.reset(rocksdb::NewBloomFilterPolicy(10, true));
|
||||||
|
|
||||||
|
Options options = CurrentOptions();
|
||||||
|
options.prefix_extractor = std::make_shared<SliceTransformLimitedDomain>();
|
||||||
|
options.table_factory.reset(NewBlockBasedTableFactory(bbto));
|
||||||
|
|
||||||
|
DestroyAndReopen(options);
|
||||||
|
|
||||||
|
ASSERT_OK(Put("x1113_AAAA", "val3"));
|
||||||
|
ASSERT_OK(Put("x1114_AAAA", "val4"));
|
||||||
|
// Not in domain, wont be added to filter
|
||||||
|
ASSERT_OK(Put("zzzzz_AAAA", "val1"));
|
||||||
|
ASSERT_OK(Put("zzzzz_AAAB", "val2"));
|
||||||
|
ASSERT_OK(Put("zzzzz_AAAC", "val3"));
|
||||||
|
ASSERT_OK(Put("zzzzz_AAAD", "val4"));
|
||||||
|
|
||||||
|
ASSERT_OK(Flush());
|
||||||
|
|
||||||
|
std::vector<std::string> iter_res;
|
||||||
|
auto iter = db_->NewIterator(ReadOptions());
|
||||||
|
// Seek to a key that was not in Domain
|
||||||
|
for (iter->Seek("zzzzz_AAAA"); iter->Valid(); iter->Next()) {
|
||||||
|
iter_res.emplace_back(iter->value().ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> expected_res = {"val1", "val2", "val3", "val4"};
|
||||||
|
ASSERT_EQ(iter_res, expected_res);
|
||||||
|
delete iter;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef ROCKSDB_LITE
|
#ifndef ROCKSDB_LITE
|
||||||
class BloomStatsTestWithParam
|
class BloomStatsTestWithParam
|
||||||
: public DBTest,
|
: public DBTest,
|
||||||
|
@ -1120,8 +1120,11 @@ bool BlockBasedTable::PrefixMayMatch(const Slice& internal_key) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
assert(rep_->ioptions.prefix_extractor != nullptr);
|
assert(rep_->ioptions.prefix_extractor != nullptr);
|
||||||
auto prefix = rep_->ioptions.prefix_extractor->Transform(
|
auto user_key = ExtractUserKey(internal_key);
|
||||||
ExtractUserKey(internal_key));
|
if (!rep_->ioptions.prefix_extractor->InDomain(user_key)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
auto prefix = rep_->ioptions.prefix_extractor->Transform(user_key);
|
||||||
InternalKey internal_key_prefix(prefix, kMaxSequenceNumber, kTypeValue);
|
InternalKey internal_key_prefix(prefix, kMaxSequenceNumber, kTypeValue);
|
||||||
auto internal_prefix = internal_key_prefix.Encode();
|
auto internal_prefix = internal_key_prefix.Encode();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user