Skip to content

Commit

Permalink
Set optimize_filters_for_memory by default (facebook#12377)
Browse files Browse the repository at this point in the history
Summary:
This feature has been around for a couple of years and users haven't reported any problems with it.

Not quite related: fixed a technical ODR violation in public header for info_log_level in case DEBUG build status changes.

Pull Request resolved: facebook#12377

Test Plan: unit tests updated, already in crash test. Some unit tests are expecting specific behaviors of optimize_filters_for_memory=false and we now need to bake that in.

Reviewed By: jowlyzhang

Differential Revision: D54129517

Pulled By: pdillinger

fbshipit-source-id: a64b614840eadd18b892624187b3e122bab6719c
  • Loading branch information
pdillinger authored and facebook-github-bot committed Apr 30, 2024
1 parent 5c1334f commit 45c1051
Show file tree
Hide file tree
Showing 12 changed files with 55 additions and 18 deletions.
2 changes: 2 additions & 0 deletions db/c_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -1318,6 +1318,8 @@ int main(int argc, char** argv) {
policy = rocksdb_filterpolicy_create_ribbon_hybrid(8.0, 1);
}
rocksdb_block_based_options_set_filter_policy(table_options, policy);
rocksdb_block_based_options_set_optimize_filters_for_memory(table_options,
0);

// Create new database
rocksdb_close(db);
Expand Down
2 changes: 2 additions & 0 deletions db/db_bloom_filter_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,7 @@ TEST_P(DBBloomFilterTestWithParam, BloomFilter) {
BlockBasedTableOptions table_options;
table_options.no_block_cache = true;
table_options.filter_policy = Create(10, bfp_impl_);
table_options.optimize_filters_for_memory = false;
table_options.partition_filters = partition_filters_;
if (partition_filters_) {
table_options.index_type =
Expand Down Expand Up @@ -1695,6 +1696,7 @@ TEST_F(DBBloomFilterTest, ContextCustomFilterPolicy) {
BlockBasedTableOptions table_options;
table_options.filter_policy = policy;
table_options.format_version = 5;
table_options.optimize_filters_for_memory = false;
options.table_factory.reset(NewBlockBasedTableFactory(table_options));

ASSERT_OK(TryReopen(options));
Expand Down
9 changes: 9 additions & 0 deletions env/env.cc
Original file line number Diff line number Diff line change
Expand Up @@ -825,6 +825,15 @@ WritableFile::~WritableFile() = default;

MemoryMappedFileBuffer::~MemoryMappedFileBuffer() = default;

// This const variable can be used in public headers without introducing the
// possibility of ODR violations due to varying macro definitions.
const InfoLogLevel Logger::kDefaultLogLevel =
#ifdef NDEBUG
INFO_LEVEL;
#else
DEBUG_LEVEL;
#endif // NDEBUG

Logger::~Logger() = default;

Status Logger::Close() {
Expand Down
4 changes: 4 additions & 0 deletions include/rocksdb/env.h
Original file line number Diff line number Diff line change
Expand Up @@ -1209,6 +1209,10 @@ class Logger {
public:
static constexpr size_t kDoNotSupportGetLogFileSize = SIZE_MAX;

// Set to INFO_LEVEL when RocksDB is compiled in release mode, and
// DEBUG_LEVEL when compiled in debug mode. See DBOptions::info_log_level.
static const InfoLogLevel kDefaultLogLevel;

explicit Logger(const InfoLogLevel log_level = InfoLogLevel::INFO_LEVEL)
: closed_(false), log_level_(log_level) {}
// No copying allowed
Expand Down
9 changes: 4 additions & 5 deletions include/rocksdb/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -643,11 +643,10 @@ struct DBOptions {
// Default: nullptr
std::shared_ptr<Logger> info_log = nullptr;

#ifdef NDEBUG
InfoLogLevel info_log_level = INFO_LEVEL;
#else
InfoLogLevel info_log_level = DEBUG_LEVEL;
#endif // NDEBUG
// Minimum level for sending log messages to info_log. The default is
// INFO_LEVEL when RocksDB is compiled in release mode, and DEBUG_LEVEL
// when it is compiled in debug mode.
InfoLogLevel info_log_level = Logger::kDefaultLogLevel;

// Number of open files that can be used by the DB. You may need to
// increase this if your database has a large working set. Value -1 means
Expand Down
12 changes: 6 additions & 6 deletions include/rocksdb/table.h
Original file line number Diff line number Diff line change
Expand Up @@ -426,12 +426,12 @@ struct BlockBasedTableOptions {
// the block cache better at using space it is allowed. (These issues
// should not arise with partitioned filters.)
//
// NOTE: Do not set to true if you do not trust malloc_usable_size. With
// this option, RocksDB might access an allocated memory object beyond its
// original size if malloc_usable_size says it is safe to do so. While this
// can be considered bad practice, it should not produce undefined behavior
// unless malloc_usable_size is buggy or broken.
bool optimize_filters_for_memory = false;
// NOTE: Set to false if you do not trust malloc_usable_size. When set to
// true, RocksDB might access an allocated memory object beyond its original
// size if malloc_usable_size says it is safe to do so. While this can be
// considered bad practice, it should not produce undefined behavior unless
// malloc_usable_size is buggy or broken.
bool optimize_filters_for_memory = true;

// Use delta encoding to compress keys in blocks.
// ReadOptions::pin_data requires this option to be disabled.
Expand Down
2 changes: 1 addition & 1 deletion java/src/main/java/org/rocksdb/BlockBasedTableConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public BlockBasedTableConfig() {
indexBlockRestartInterval = 1;
metadataBlockSize = 4096;
partitionFilters = false;
optimizeFiltersForMemory = false;
optimizeFiltersForMemory = true;
useDeltaEncoding = true;
filterPolicy = null;
wholeKeyFiltering = true;
Expand Down
2 changes: 1 addition & 1 deletion java/src/test/java/org/rocksdb/OptionsUtilTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ private void verifyTableFormatOptions(final LoaderUnderTest loaderUnderTest)
altCFTableConfig.setIndexBlockRestartInterval(6);
altCFTableConfig.setMetadataBlockSize(12 * 1024);
altCFTableConfig.setPartitionFilters(true);
altCFTableConfig.setOptimizeFiltersForMemory(true);
altCFTableConfig.setOptimizeFiltersForMemory(false);
altCFTableConfig.setUseDeltaEncoding(false);
altCFTableConfig.setFilterPolicy(new BloomFilter(7.5));
altCFTableConfig.setWholeKeyFiltering(false);
Expand Down
1 change: 1 addition & 0 deletions memory/memory_allocator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,5 @@ Status MemoryAllocator::CreateFromString(
copy.invoke_prepare_options = true;
return LoadManagedObject<MemoryAllocator>(copy, value, result);
}

} // namespace ROCKSDB_NAMESPACE
15 changes: 12 additions & 3 deletions table/block_based/filter_policy.cc
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,9 @@ class FastLocalBloomBitsBuilder : public XXPH3FilterBitsBuilder {
}

double EstimatedFpRate(size_t keys, size_t len_with_metadata) override {
if (len_with_metadata <= kMetadataLen) {
return keys > 0 ? 1.0 : 0.0;
}
int num_probes = GetNumProbes(keys, len_with_metadata);
return FastLocalBloomImpl::EstimatedFpRate(
keys, len_with_metadata - kMetadataLen, num_probes, /*hash bits*/ 64);
Expand Down Expand Up @@ -891,6 +894,9 @@ class Standard128RibbonBitsBuilder : public XXPH3FilterBitsBuilder {

double EstimatedFpRate(size_t num_entries,
size_t len_with_metadata) override {
if (len_with_metadata <= kMetadataLen) {
return num_entries > 0 ? 1.0 : 0.0;
}
if (num_entries > kMaxRibbonEntries) {
// More entries than supported by this Ribbon
return bloom_fallback_.EstimatedFpRate(num_entries, len_with_metadata);
Expand Down Expand Up @@ -1030,9 +1036,12 @@ class LegacyBloomBitsBuilder : public BuiltinFilterBitsBuilder {
return CalculateSpace(num_entries, &dont_care1, &dont_care2);
}

double EstimatedFpRate(size_t keys, size_t bytes) override {
return LegacyBloomImpl::EstimatedFpRate(keys, bytes - kMetadataLen,
num_probes_);
double EstimatedFpRate(size_t keys, size_t len_with_metadata) override {
if (len_with_metadata <= kMetadataLen) {
return keys > 0 ? 1.0 : 0.0;
}
return LegacyBloomImpl::EstimatedFpRate(
keys, len_with_metadata - kMetadataLen, num_probes_);
}

size_t ApproximateNumEntries(size_t bytes) override;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
`BlockBasedTableOptions::optimize_filters_for_memory` is now set to true by default. When `partition_filters=false`, this could lead to somewhat increased average RSS memory usage by the block cache, but this "extra" usage is within the allowed memory budget and should make memory usage more consistent (by minimizing internal fragmentation for more kinds of blocks).
14 changes: 12 additions & 2 deletions util/bloom_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,9 @@ TEST_P(FullBloomTest, FullSmall) {
}

TEST_P(FullBloomTest, FullVaryingLengths) {
// Match how this test was originally built
table_options_.optimize_filters_for_memory = false;

char buffer[sizeof(int)];

// Count number of filters that significantly exceed the false positive rate
Expand Down Expand Up @@ -335,6 +338,9 @@ TEST_P(FullBloomTest, FullVaryingLengths) {
}

TEST_P(FullBloomTest, OptimizeForMemory) {
// Verify default option
EXPECT_EQ(BlockBasedTableOptions().optimize_filters_for_memory, true);

char buffer[sizeof(int)];
for (bool offm : {true, false}) {
table_options_.optimize_filters_for_memory = offm;
Expand All @@ -354,8 +360,9 @@ TEST_P(FullBloomTest, OptimizeForMemory) {
Build();
size_t size = FilterData().size();
total_size += size;
// optimize_filters_for_memory currently depends on malloc_usable_size
// but we run the rest of the test to ensure no bad behavior without it.
// optimize_filters_for_memory currently only has an effect with
// malloc_usable_size support, but we run the rest of the test to ensure
// no bad behavior without it.
#ifdef ROCKSDB_MALLOC_USABLE_SIZE
size = malloc_usable_size(const_cast<char*>(FilterData().data()));
#endif // ROCKSDB_MALLOC_USABLE_SIZE
Expand Down Expand Up @@ -508,6 +515,9 @@ inline uint32_t SelectByCacheLineSize(uint32_t for64, uint32_t for128,
// ability to read filters generated using other cache line sizes.
// See RawSchema.
TEST_P(FullBloomTest, Schema) {
// Match how this test was originally built
table_options_.optimize_filters_for_memory = false;

#define EXPECT_EQ_Bloom(a, b) \
{ \
if (GetParam() != kStandard128Ribbon) { \
Expand Down

0 comments on commit 45c1051

Please sign in to comment.