diff --git a/db/db_test.cc b/db/db_test.cc index f2b6761c2..ef46f17fb 100644 --- a/db/db_test.cc +++ b/db/db_test.cc @@ -10058,6 +10058,52 @@ TEST_F(DBTest, WalFilterTestWithChangeBatchExtraKeys) { #endif // ROCKSDB_LITE +class SliceTransformLimitedDomain : public SliceTransform { + const char* Name() const override { return "SliceTransformLimitedDomain"; } + + Slice Transform(const Slice& src) const override { + return Slice(src.data(), 5); + } + + bool InDomain(const Slice& src) const override { + // prefix will be x???? + return src.size() >= 5 && src[0] == 'x'; + } + + bool InRange(const Slice& dst) const override { + // prefix will be x???? + return dst.size() == 5 && dst[0] == 'x'; + } +}; + +TEST_F(DBTest, PrefixExtractorFullFilter) { + BlockBasedTableOptions bbto; + bbto.filter_policy.reset(rocksdb::NewBloomFilterPolicy(10, false)); + bbto.whole_key_filtering = false; + + Options options = CurrentOptions(); + options.prefix_extractor = std::make_shared(); + options.table_factory.reset(NewBlockBasedTableFactory(bbto)); + + DestroyAndReopen(options); + + ASSERT_OK(Put("x1111_AAAA", "val1")); + ASSERT_OK(Put("x1112_AAAA", "val2")); + 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", "val5")); + + ASSERT_OK(Flush()); + + ASSERT_EQ(Get("x1111_AAAA"), "val1"); + ASSERT_EQ(Get("x1112_AAAA"), "val2"); + ASSERT_EQ(Get("x1113_AAAA"), "val3"); + ASSERT_EQ(Get("x1114_AAAA"), "val4"); + // Was not added to filter but rocksdb will try to read it from the filter + ASSERT_EQ(Get("zzzzz_AAAA"), "val5"); +} + #ifndef ROCKSDB_LITE class BloomStatsTestWithParam : public DBTest, diff --git a/table/block_based_table_reader.cc b/table/block_based_table_reader.cc index 4a358d361..3114a6f15 100644 --- a/table/block_based_table_reader.cc +++ b/table/block_based_table_reader.cc @@ -1207,6 +1207,7 @@ bool BlockBasedTable::FullFilterKeyMayMatch(FilterBlockReader* filter, return false; } if (rep_->ioptions.prefix_extractor && + rep_->ioptions.prefix_extractor->InDomain(user_key) && !filter->PrefixMayMatch( rep_->ioptions.prefix_extractor->Transform(user_key))) { return false;