Fix handling of too-small filter partition size (#6905)
Summary: Because ARM and some other platforms have a larger cache line size, they have a larger minimum filter size, which causes recently added PartitionedMultiGet test in db_bloom_filter_test to fail on those platforms. The code would actually end up using larger partitions, because keys_per_partition_ would be 0 and never == number of keys added. The code now attempts to get as close as possible to the small target size, while fully utilizing that filter size, if the target partition size is smaller than the minimum filter size. Also updated the test to break more uniformly across platforms Pull Request resolved: https://github.com/facebook/rocksdb/pull/6905 Test Plan: updated test, tested on ARM Reviewed By: anand1976 Differential Revision: D21840639 Pulled By: pdillinger fbshipit-source-id: 11684b6d35f43d2e98b85ddb2c8dcfd59d670817
This commit is contained in:
parent
2adb7e3768
commit
9360776cb9
@ -1063,12 +1063,21 @@ TEST_P(DBBloomFilterTestVaryPrefixAndFormatVer, PartitionedMultiGet) {
|
||||
bbto.partition_filters = true;
|
||||
bbto.index_type = BlockBasedTableOptions::IndexType::kTwoLevelIndexSearch;
|
||||
bbto.whole_key_filtering = !use_prefix_;
|
||||
bbto.metadata_block_size = 128;
|
||||
if (use_prefix_) { // (not related to prefix, just alternating between)
|
||||
// Make sure code appropriately deals with metadata block size setting
|
||||
// that is "too small" (smaller than minimum size for filter builder)
|
||||
bbto.metadata_block_size = 63;
|
||||
} else {
|
||||
// Make sure the test will work even on platforms with large minimum
|
||||
// filter size, due to large cache line size.
|
||||
// (Largest cache line size + 10+% overhead.)
|
||||
bbto.metadata_block_size = 290;
|
||||
}
|
||||
options.table_factory.reset(NewBlockBasedTableFactory(bbto));
|
||||
DestroyAndReopen(options);
|
||||
ReadOptions ropts;
|
||||
|
||||
constexpr uint32_t N = 10000;
|
||||
constexpr uint32_t N = 12000;
|
||||
// Add N/2 evens
|
||||
for (uint32_t i = 0; i < N; i += 2) {
|
||||
ASSERT_OK(Put(UKey(i), UKey(i)));
|
||||
|
@ -35,6 +35,25 @@ PartitionedFilterBlockBuilder::PartitionedFilterBlockBuilder(
|
||||
keys_added_to_partition_(0) {
|
||||
keys_per_partition_ =
|
||||
filter_bits_builder_->CalculateNumEntry(partition_size);
|
||||
if (keys_per_partition_ < 1) {
|
||||
// partition_size (minus buffer, ~10%) might be smaller than minimum
|
||||
// filter size, sometimes based on cache line size. Try to find that
|
||||
// minimum size without CalculateSpace (not necessarily available).
|
||||
uint32_t larger = std::max(partition_size + 4, uint32_t{16});
|
||||
for (;;) {
|
||||
keys_per_partition_ = filter_bits_builder_->CalculateNumEntry(larger);
|
||||
if (keys_per_partition_ >= 1) {
|
||||
break;
|
||||
}
|
||||
larger += larger / 4;
|
||||
if (larger > 100000) {
|
||||
// might be a broken implementation. substitute something reasonable:
|
||||
// 1 key / byte.
|
||||
keys_per_partition_ = partition_size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PartitionedFilterBlockBuilder::~PartitionedFilterBlockBuilder() {}
|
||||
|
Loading…
Reference in New Issue
Block a user