Summary: When a block based table file is opened, if prefetch_index_and_filter is true, it will prefetch the index and filter blocks, putting them into the block cache. What this feature adds: when a L0 block based table file is opened, if pin_l0_filter_and_index_blocks_in_cache is true in the options (and prefetch_index_and_filter is true), then the filter and index blocks aren't released back to the block cache at the end of BlockBasedTableReader::Open(). Instead the table reader takes ownership of them, hence pinning them, ie. the LRU cache will never push them out. Meanwhile in the table reader, further accesses will not hit the block cache, thus avoiding lock contention. When the table reader is destroyed, it releases the pinned blocks (if there were any). This has to happen before the cache is destroyed, so I had to introduce a TableReader::Close(), to guarantee the order of destruction. Test Plan: Added two unit tests for this. Existing unit tests run fine (default is pin_l0_filter_and_index_blocks_in_cache=false). DISABLE_JEMALLOC=1 OPT=-g make all valgrind_check -j32 Mac: OK. Linux: with D55287 patched in it's OK. Reviewers: sdong Reviewed By: sdong Subscribers: andrewkr, leveldb, dhruba Differential Revision: https://reviews.facebook.net/D54801
93 lines
3.9 KiB
C++
93 lines
3.9 KiB
C++
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
|
|
// This source code is licensed under the BSD-style license found in the
|
|
// LICENSE file in the root directory of this source tree. An additional grant
|
|
// of patent rights can be found in the PATENTS file in the same directory.
|
|
//
|
|
// This file implements the "bridge" between Java and C++ for rocksdb::Options.
|
|
|
|
#include <jni.h>
|
|
#include "include/org_rocksdb_PlainTableConfig.h"
|
|
#include "include/org_rocksdb_BlockBasedTableConfig.h"
|
|
#include "rocksdb/table.h"
|
|
#include "rocksdb/cache.h"
|
|
#include "rocksdb/filter_policy.h"
|
|
|
|
/*
|
|
* Class: org_rocksdb_PlainTableConfig
|
|
* Method: newTableFactoryHandle
|
|
* Signature: (IIDIIBZZ)J
|
|
*/
|
|
jlong Java_org_rocksdb_PlainTableConfig_newTableFactoryHandle(
|
|
JNIEnv* env, jobject jobj, jint jkey_size, jint jbloom_bits_per_key,
|
|
jdouble jhash_table_ratio, jint jindex_sparseness,
|
|
jint jhuge_page_tlb_size, jbyte jencoding_type,
|
|
jboolean jfull_scan_mode, jboolean jstore_index_in_file) {
|
|
rocksdb::PlainTableOptions options = rocksdb::PlainTableOptions();
|
|
options.user_key_len = jkey_size;
|
|
options.bloom_bits_per_key = jbloom_bits_per_key;
|
|
options.hash_table_ratio = jhash_table_ratio;
|
|
options.index_sparseness = jindex_sparseness;
|
|
options.huge_page_tlb_size = jhuge_page_tlb_size;
|
|
options.encoding_type = static_cast<rocksdb::EncodingType>(
|
|
jencoding_type);
|
|
options.full_scan_mode = jfull_scan_mode;
|
|
options.store_index_in_file = jstore_index_in_file;
|
|
return reinterpret_cast<jlong>(rocksdb::NewPlainTableFactory(options));
|
|
}
|
|
|
|
/*
|
|
* Class: org_rocksdb_BlockBasedTableConfig
|
|
* Method: newTableFactoryHandle
|
|
* Signature: (ZJIJIIZIZZZJIBBI)J
|
|
*/
|
|
jlong Java_org_rocksdb_BlockBasedTableConfig_newTableFactoryHandle(
|
|
JNIEnv* env, jobject jobj, jboolean no_block_cache, jlong block_cache_size,
|
|
jint block_cache_num_shardbits, jlong block_size, jint block_size_deviation,
|
|
jint block_restart_interval, jboolean whole_key_filtering,
|
|
jlong jfilterPolicy, jboolean cache_index_and_filter_blocks,
|
|
jboolean pin_l0_filter_and_index_blocks_in_cache,
|
|
jboolean hash_index_allow_collision, jlong block_cache_compressed_size,
|
|
jint block_cache_compressd_num_shard_bits, jbyte jchecksum_type,
|
|
jbyte jindex_type, jint jformat_version) {
|
|
rocksdb::BlockBasedTableOptions options;
|
|
options.no_block_cache = no_block_cache;
|
|
|
|
if (!no_block_cache && block_cache_size > 0) {
|
|
if (block_cache_num_shardbits > 0) {
|
|
options.block_cache =
|
|
rocksdb::NewLRUCache(block_cache_size, block_cache_num_shardbits);
|
|
} else {
|
|
options.block_cache = rocksdb::NewLRUCache(block_cache_size);
|
|
}
|
|
}
|
|
options.block_size = block_size;
|
|
options.block_size_deviation = block_size_deviation;
|
|
options.block_restart_interval = block_restart_interval;
|
|
options.whole_key_filtering = whole_key_filtering;
|
|
if (jfilterPolicy > 0) {
|
|
std::shared_ptr<rocksdb::FilterPolicy> *pFilterPolicy =
|
|
reinterpret_cast<std::shared_ptr<rocksdb::FilterPolicy> *>(
|
|
jfilterPolicy);
|
|
options.filter_policy = *pFilterPolicy;
|
|
}
|
|
options.cache_index_and_filter_blocks = cache_index_and_filter_blocks;
|
|
options.pin_l0_filter_and_index_blocks_in_cache =
|
|
pin_l0_filter_and_index_blocks_in_cache;
|
|
options.hash_index_allow_collision = hash_index_allow_collision;
|
|
if (block_cache_compressed_size > 0) {
|
|
if (block_cache_compressd_num_shard_bits > 0) {
|
|
options.block_cache =
|
|
rocksdb::NewLRUCache(block_cache_compressed_size,
|
|
block_cache_compressd_num_shard_bits);
|
|
} else {
|
|
options.block_cache = rocksdb::NewLRUCache(block_cache_compressed_size);
|
|
}
|
|
}
|
|
options.checksum = static_cast<rocksdb::ChecksumType>(jchecksum_type);
|
|
options.index_type = static_cast<
|
|
rocksdb::BlockBasedTableOptions::IndexType>(jindex_type);
|
|
options.format_version = jformat_version;
|
|
|
|
return reinterpret_cast<jlong>(rocksdb::NewBlockBasedTableFactory(options));
|
|
}
|