Use user-provided ReadOptions for metadata block reads more often (#11208)

Summary:
This is mostly taken from https://github.com/facebook/rocksdb/issues/10427 with my own comments addressed. This PR plumbs the user’s `ReadOptions` down to `GetOrReadIndexBlock()`, `GetOrReadFilterBlock()`, and `GetFilterPartitionBlock()`. Now those functions no longer have to make up a `ReadOptions` with incomplete information.

I also let `PartitionIndexReader::NewIterator()` pass through its caller's `ReadOptions::verify_checksums`, which was inexplicably dropped previously.

Fixes https://github.com/facebook/rocksdb/issues/10463

Pull Request resolved: https://github.com/facebook/rocksdb/pull/11208

Test Plan:
Functional:
- Measured `-verify_checksum=false` applies to metadata blocks read outside of table open
  - setup command: `TEST_TMPDIR=/tmp/100M-DB/ ./db_bench -benchmarks=filluniquerandom,waitforcompaction -write_buffer_size=1048576 -target_file_size_base=1048576 -max_bytes_for_level_base=4194304 -compression_type=none -num=1638400 -key_size=8 -value_size=56`
  - run command: `TEST_TMPDIR=/tmp/100M-DB/ ./db_bench -benchmarks=readrandom -use_existing_db=true -write_buffer_size=1048576 -target_file_size_base=1048576 -max_bytes_for_level_base=4194304 -compression_type=none -num=1638400 -key_size=8 -value_size=56 -duration=10 -threads=32 -cache_size=131072 -statistics=true -verify_checksum=false -open_files=20 -cache_index_and_filter_blocks=true`
  - before: `rocksdb.block.checksum.compute.count COUNT : 384353`
  - after: `rocksdb.block.checksum.compute.count COUNT : 22`

Performance:
- Setup command (tmpfs, 128MB logical data size, cache indexes/filters without pinning so index/filter lookups go through table reader): `TEST_TMPDIR=/dev/shm/128M-DB/ ./db_bench -benchmarks=filluniquerandom,waitforcompaction -write_buffer_size=131072 -target_file_size_base=131072 -max_bytes_for_level_base=524288 -compression_type=none -num=4194304 -key_size=8 -value_size=24 -bloom_bits=8 -whole_key_filtering=1`
- Measured point lookup performance. Database is fully cached to emphasize any new callstack overheads
  - Command: `TEST_TMPDIR=/dev/shm/128M-DB/ ./db_bench -benchmarks=readrandom[-W1][-X20] -use_existing_db=true -cache_index_and_filter_blocks=true -disable_auto_compactions=true -num=4194304 -key_size=8 -value_size=24 -bloom_bits=8 -whole_key_filtering=1 -duration=10 -cache_size=1048576000`
  - Before: `readrandom [AVG    20 runs] : 274848 (± 3717) ops/sec;    8.4 (± 0.1) MB/sec`
  - After: `readrandom [AVG    20 runs] : 277904 (± 4474) ops/sec;    8.5 (± 0.1) MB/sec`

Reviewed By: hx235

Differential Revision: D43145366

Pulled By: ajkr

fbshipit-source-id: 75ec062ece86a82cd788783de9de2c72df57f994
oxigraph-8.3.2
Andrew Kryczka 2 years ago committed by Facebook GitHub Bot
parent 03ccb1cd42
commit b45738622a
  1. 1
      HISTORY.md
  2. 5
      table/block_based/binary_search_index_reader.cc
  3. 26
      table/block_based/block_based_table_reader.cc
  4. 4
      table/block_based/block_based_table_reader.h
  5. 2
      table/block_based/block_based_table_reader_sync_and_async.h
  6. 15
      table/block_based/filter_block.h
  7. 14
      table/block_based/filter_block_reader_common.cc
  8. 4
      table/block_based/filter_block_reader_common.h
  9. 41
      table/block_based/full_filter_block.cc
  10. 16
      table/block_based/full_filter_block.h
  11. 48
      table/block_based/full_filter_block_test.cc
  12. 5
      table/block_based/hash_index_reader.cc
  13. 9
      table/block_based/index_reader_common.cc
  14. 6
      table/block_based/index_reader_common.h
  15. 62
      table/block_based/partitioned_filter_block.cc
  16. 21
      table/block_based/partitioned_filter_block.h
  17. 16
      table/block_based/partitioned_filter_block_test.cc
  18. 11
      table/block_based/partitioned_index_reader.cc
  19. 2
      util/filter_bench.cc

@ -7,6 +7,7 @@
### Behavior changes ### Behavior changes
* Changed default block cache size from an 8MB to 32MB LRUCache, which increases the default number of cache shards from 16 to 64. This change is intended to minimize cache mutex contention under stress conditions. See https://github.com/facebook/rocksdb/wiki/Block-Cache for more information. * Changed default block cache size from an 8MB to 32MB LRUCache, which increases the default number of cache shards from 16 to 64. This change is intended to minimize cache mutex contention under stress conditions. See https://github.com/facebook/rocksdb/wiki/Block-Cache for more information.
* For level compaction with `level_compaction_dynamic_level_bytes=true`, RocksDB now trivially moves levels down to fill LSM starting from bottommost level during DB open. See more in comments for option `level_compaction_dynamic_level_bytes`. * For level compaction with `level_compaction_dynamic_level_bytes=true`, RocksDB now trivially moves levels down to fill LSM starting from bottommost level during DB open. See more in comments for option `level_compaction_dynamic_level_bytes`.
* User-provided `ReadOptions` take effect for more reads of non-`CacheEntryRole::kDataBlock` blocks.
### New Features ### New Features
* Add experimental `PerfContext` counters `iter_{next|prev|seek}_count` for db iterator, each counting the times of corresponding API being called. * Add experimental `PerfContext` counters `iter_{next|prev|seek}_count` for db iterator, each counting the times of corresponding API being called.

@ -46,9 +46,8 @@ InternalIteratorBase<IndexValue>* BinarySearchIndexReader::NewIterator(
const BlockBasedTable::Rep* rep = table()->get_rep(); const BlockBasedTable::Rep* rep = table()->get_rep();
const bool no_io = (read_options.read_tier == kBlockCacheTier); const bool no_io = (read_options.read_tier == kBlockCacheTier);
CachableEntry<Block> index_block; CachableEntry<Block> index_block;
const Status s = const Status s = GetOrReadIndexBlock(no_io, get_context, lookup_context,
GetOrReadIndexBlock(no_io, read_options.rate_limiter_priority, &index_block, read_options);
get_context, lookup_context, &index_block);
if (!s.ok()) { if (!s.ok()) {
if (iter != nullptr) { if (iter != nullptr) {
iter->Invalidate(s); iter->Invalidate(s);

@ -1781,7 +1781,7 @@ bool BlockBasedTable::PrefixRangeMayMatch(
read_options.iterate_upper_bound, user_key_without_ts, prefix_extractor, read_options.iterate_upper_bound, user_key_without_ts, prefix_extractor,
rep_->internal_comparator.user_comparator(), const_ikey_ptr, rep_->internal_comparator.user_comparator(), const_ikey_ptr,
&filter_checked, need_upper_bound_check, no_io, lookup_context, &filter_checked, need_upper_bound_check, no_io, lookup_context,
read_options.rate_limiter_priority); read_options);
} }
if (filter_checked) { if (filter_checked) {
@ -1855,7 +1855,7 @@ bool BlockBasedTable::FullFilterKeyMayMatch(
FilterBlockReader* filter, const Slice& internal_key, const bool no_io, FilterBlockReader* filter, const Slice& internal_key, const bool no_io,
const SliceTransform* prefix_extractor, GetContext* get_context, const SliceTransform* prefix_extractor, GetContext* get_context,
BlockCacheLookupContext* lookup_context, BlockCacheLookupContext* lookup_context,
Env::IOPriority rate_limiter_priority) const { const ReadOptions& read_options) const {
if (filter == nullptr) { if (filter == nullptr) {
return true; return true;
} }
@ -1865,15 +1865,13 @@ bool BlockBasedTable::FullFilterKeyMayMatch(
size_t ts_sz = rep_->internal_comparator.user_comparator()->timestamp_size(); size_t ts_sz = rep_->internal_comparator.user_comparator()->timestamp_size();
Slice user_key_without_ts = StripTimestampFromUserKey(user_key, ts_sz); Slice user_key_without_ts = StripTimestampFromUserKey(user_key, ts_sz);
if (rep_->whole_key_filtering) { if (rep_->whole_key_filtering) {
may_match = may_match = filter->KeyMayMatch(user_key_without_ts, no_io, const_ikey_ptr,
filter->KeyMayMatch(user_key_without_ts, no_io, const_ikey_ptr, get_context, lookup_context, read_options);
get_context, lookup_context, rate_limiter_priority);
} else if (!PrefixExtractorChanged(prefix_extractor) && } else if (!PrefixExtractorChanged(prefix_extractor) &&
prefix_extractor->InDomain(user_key_without_ts) && prefix_extractor->InDomain(user_key_without_ts) &&
!filter->PrefixMayMatch( !filter->PrefixMayMatch(
prefix_extractor->Transform(user_key_without_ts), no_io, prefix_extractor->Transform(user_key_without_ts), no_io,
const_ikey_ptr, get_context, lookup_context, const_ikey_ptr, get_context, lookup_context, read_options)) {
rate_limiter_priority)) {
// FIXME ^^^: there should be no reason for Get() to depend on current // FIXME ^^^: there should be no reason for Get() to depend on current
// prefix_extractor at all. It should always use table_prefix_extractor. // prefix_extractor at all. It should always use table_prefix_extractor.
may_match = false; may_match = false;
@ -1889,14 +1887,14 @@ void BlockBasedTable::FullFilterKeysMayMatch(
FilterBlockReader* filter, MultiGetRange* range, const bool no_io, FilterBlockReader* filter, MultiGetRange* range, const bool no_io,
const SliceTransform* prefix_extractor, const SliceTransform* prefix_extractor,
BlockCacheLookupContext* lookup_context, BlockCacheLookupContext* lookup_context,
Env::IOPriority rate_limiter_priority) const { const ReadOptions& read_options) const {
if (filter == nullptr) { if (filter == nullptr) {
return; return;
} }
uint64_t before_keys = range->KeysLeft(); uint64_t before_keys = range->KeysLeft();
assert(before_keys > 0); // Caller should ensure assert(before_keys > 0); // Caller should ensure
if (rep_->whole_key_filtering) { if (rep_->whole_key_filtering) {
filter->KeysMayMatch(range, no_io, lookup_context, rate_limiter_priority); filter->KeysMayMatch(range, no_io, lookup_context, read_options);
uint64_t after_keys = range->KeysLeft(); uint64_t after_keys = range->KeysLeft();
if (after_keys) { if (after_keys) {
RecordTick(rep_->ioptions.stats, BLOOM_FILTER_FULL_POSITIVE, after_keys); RecordTick(rep_->ioptions.stats, BLOOM_FILTER_FULL_POSITIVE, after_keys);
@ -1913,7 +1911,7 @@ void BlockBasedTable::FullFilterKeysMayMatch(
// FIXME ^^^: there should be no reason for MultiGet() to depend on current // FIXME ^^^: there should be no reason for MultiGet() to depend on current
// prefix_extractor at all. It should always use table_prefix_extractor. // prefix_extractor at all. It should always use table_prefix_extractor.
filter->PrefixesMayMatch(range, prefix_extractor, false, lookup_context, filter->PrefixesMayMatch(range, prefix_extractor, false, lookup_context,
rate_limiter_priority); read_options);
RecordTick(rep_->ioptions.stats, BLOOM_FILTER_PREFIX_CHECKED, before_keys); RecordTick(rep_->ioptions.stats, BLOOM_FILTER_PREFIX_CHECKED, before_keys);
uint64_t after_keys = range->KeysLeft(); uint64_t after_keys = range->KeysLeft();
uint64_t filtered_keys = before_keys - after_keys; uint64_t filtered_keys = before_keys - after_keys;
@ -2010,9 +2008,9 @@ Status BlockBasedTable::Get(const ReadOptions& read_options, const Slice& key,
read_options.snapshot != nullptr; read_options.snapshot != nullptr;
} }
TEST_SYNC_POINT("BlockBasedTable::Get:BeforeFilterMatch"); TEST_SYNC_POINT("BlockBasedTable::Get:BeforeFilterMatch");
const bool may_match = FullFilterKeyMayMatch( const bool may_match =
filter, key, no_io, prefix_extractor, get_context, &lookup_context, FullFilterKeyMayMatch(filter, key, no_io, prefix_extractor, get_context,
read_options.rate_limiter_priority); &lookup_context, read_options);
TEST_SYNC_POINT("BlockBasedTable::Get:AfterFilterMatch"); TEST_SYNC_POINT("BlockBasedTable::Get:AfterFilterMatch");
if (!may_match) { if (!may_match) {
RecordTick(rep_->ioptions.stats, BLOOM_FILTER_USEFUL); RecordTick(rep_->ioptions.stats, BLOOM_FILTER_USEFUL);
@ -2182,7 +2180,7 @@ Status BlockBasedTable::MultiGetFilter(const ReadOptions& read_options,
TableReaderCaller::kUserMultiGet, tracing_mget_id, TableReaderCaller::kUserMultiGet, tracing_mget_id,
/*_get_from_user_specified_snapshot=*/read_options.snapshot != nullptr}; /*_get_from_user_specified_snapshot=*/read_options.snapshot != nullptr};
FullFilterKeysMayMatch(filter, mget_range, no_io, prefix_extractor, FullFilterKeysMayMatch(filter, mget_range, no_io, prefix_extractor,
&lookup_context, read_options.rate_limiter_priority); &lookup_context, read_options);
return Status::OK(); return Status::OK();
} }

@ -429,13 +429,13 @@ class BlockBasedTable : public TableReader {
const SliceTransform* prefix_extractor, const SliceTransform* prefix_extractor,
GetContext* get_context, GetContext* get_context,
BlockCacheLookupContext* lookup_context, BlockCacheLookupContext* lookup_context,
Env::IOPriority rate_limiter_priority) const; const ReadOptions& read_options) const;
void FullFilterKeysMayMatch(FilterBlockReader* filter, MultiGetRange* range, void FullFilterKeysMayMatch(FilterBlockReader* filter, MultiGetRange* range,
const bool no_io, const bool no_io,
const SliceTransform* prefix_extractor, const SliceTransform* prefix_extractor,
BlockCacheLookupContext* lookup_context, BlockCacheLookupContext* lookup_context,
Env::IOPriority rate_limiter_priority) const; const ReadOptions& read_options) const;
// If force_direct_prefetch is true, always prefetching to RocksDB // If force_direct_prefetch is true, always prefetching to RocksDB
// buffer, rather than calling RandomAccessFile::Prefetch(). // buffer, rather than calling RandomAccessFile::Prefetch().

@ -335,7 +335,7 @@ DEFINE_SYNC_AND_ASYNC(void, BlockBasedTable::MultiGet)
TableReaderCaller::kUserMultiGet, tracing_mget_id, TableReaderCaller::kUserMultiGet, tracing_mget_id,
/*_get_from_user_specified_snapshot=*/read_options.snapshot != nullptr}; /*_get_from_user_specified_snapshot=*/read_options.snapshot != nullptr};
FullFilterKeysMayMatch(filter, &sst_file_range, no_io, prefix_extractor, FullFilterKeysMayMatch(filter, &sst_file_range, no_io, prefix_extractor,
&lookup_context, read_options.rate_limiter_priority); &lookup_context, read_options);
if (!sst_file_range.empty()) { if (!sst_file_range.empty()) {
IndexBlockIter iiter_on_stack; IndexBlockIter iiter_on_stack;

@ -113,17 +113,17 @@ class FilterBlockReader {
const Slice* const const_ikey_ptr, const Slice* const const_ikey_ptr,
GetContext* get_context, GetContext* get_context,
BlockCacheLookupContext* lookup_context, BlockCacheLookupContext* lookup_context,
Env::IOPriority rate_limiter_priority) = 0; const ReadOptions& read_options) = 0;
virtual void KeysMayMatch(MultiGetRange* range, const bool no_io, virtual void KeysMayMatch(MultiGetRange* range, const bool no_io,
BlockCacheLookupContext* lookup_context, BlockCacheLookupContext* lookup_context,
Env::IOPriority rate_limiter_priority) { const ReadOptions& read_options) {
for (auto iter = range->begin(); iter != range->end(); ++iter) { for (auto iter = range->begin(); iter != range->end(); ++iter) {
const Slice ukey_without_ts = iter->ukey_without_ts; const Slice ukey_without_ts = iter->ukey_without_ts;
const Slice ikey = iter->ikey; const Slice ikey = iter->ikey;
GetContext* const get_context = iter->get_context; GetContext* const get_context = iter->get_context;
if (!KeyMayMatch(ukey_without_ts, no_io, &ikey, get_context, if (!KeyMayMatch(ukey_without_ts, no_io, &ikey, get_context,
lookup_context, rate_limiter_priority)) { lookup_context, read_options)) {
range->SkipKey(iter); range->SkipKey(iter);
} }
} }
@ -136,21 +136,20 @@ class FilterBlockReader {
const Slice* const const_ikey_ptr, const Slice* const const_ikey_ptr,
GetContext* get_context, GetContext* get_context,
BlockCacheLookupContext* lookup_context, BlockCacheLookupContext* lookup_context,
Env::IOPriority rate_limiter_priority) = 0; const ReadOptions& read_options) = 0;
virtual void PrefixesMayMatch(MultiGetRange* range, virtual void PrefixesMayMatch(MultiGetRange* range,
const SliceTransform* prefix_extractor, const SliceTransform* prefix_extractor,
const bool no_io, const bool no_io,
BlockCacheLookupContext* lookup_context, BlockCacheLookupContext* lookup_context,
Env::IOPriority rate_limiter_priority) { const ReadOptions& read_options) {
for (auto iter = range->begin(); iter != range->end(); ++iter) { for (auto iter = range->begin(); iter != range->end(); ++iter) {
const Slice ukey_without_ts = iter->ukey_without_ts; const Slice ukey_without_ts = iter->ukey_without_ts;
const Slice ikey = iter->ikey; const Slice ikey = iter->ikey;
GetContext* const get_context = iter->get_context; GetContext* const get_context = iter->get_context;
if (prefix_extractor->InDomain(ukey_without_ts) && if (prefix_extractor->InDomain(ukey_without_ts) &&
!PrefixMayMatch(prefix_extractor->Transform(ukey_without_ts), no_io, !PrefixMayMatch(prefix_extractor->Transform(ukey_without_ts), no_io,
&ikey, get_context, lookup_context, &ikey, get_context, lookup_context, read_options)) {
rate_limiter_priority)) {
range->SkipKey(iter); range->SkipKey(iter);
} }
} }
@ -176,7 +175,7 @@ class FilterBlockReader {
bool* filter_checked, bool need_upper_bound_check, bool* filter_checked, bool need_upper_bound_check,
bool no_io, bool no_io,
BlockCacheLookupContext* lookup_context, BlockCacheLookupContext* lookup_context,
Env::IOPriority rate_limiter_priority) = 0; const ReadOptions& read_options) = 0;
}; };
} // namespace ROCKSDB_NAMESPACE } // namespace ROCKSDB_NAMESPACE

@ -70,7 +70,7 @@ Status FilterBlockReaderCommon<TBlocklike>::GetOrReadFilterBlock(
bool no_io, GetContext* get_context, bool no_io, GetContext* get_context,
BlockCacheLookupContext* lookup_context, BlockCacheLookupContext* lookup_context,
CachableEntry<TBlocklike>* filter_block, CachableEntry<TBlocklike>* filter_block,
Env::IOPriority rate_limiter_priority) const { const ReadOptions& read_options) const {
assert(filter_block); assert(filter_block);
if (!filter_block_.IsEmpty()) { if (!filter_block_.IsEmpty()) {
@ -78,13 +78,12 @@ Status FilterBlockReaderCommon<TBlocklike>::GetOrReadFilterBlock(
return Status::OK(); return Status::OK();
} }
ReadOptions read_options; ReadOptions ro = read_options;
read_options.rate_limiter_priority = rate_limiter_priority;
if (no_io) { if (no_io) {
read_options.read_tier = kBlockCacheTier; ro.read_tier = kBlockCacheTier;
} }
return ReadFilterBlock(table_, nullptr /* prefetch_buffer */, read_options, return ReadFilterBlock(table_, nullptr /* prefetch_buffer */, ro,
cache_filter_blocks(), get_context, lookup_context, cache_filter_blocks(), get_context, lookup_context,
filter_block); filter_block);
} }
@ -104,8 +103,7 @@ bool FilterBlockReaderCommon<TBlocklike>::RangeMayExist(
const SliceTransform* prefix_extractor, const Comparator* comparator, const SliceTransform* prefix_extractor, const Comparator* comparator,
const Slice* const const_ikey_ptr, bool* filter_checked, const Slice* const const_ikey_ptr, bool* filter_checked,
bool need_upper_bound_check, bool no_io, bool need_upper_bound_check, bool no_io,
BlockCacheLookupContext* lookup_context, BlockCacheLookupContext* lookup_context, const ReadOptions& read_options) {
Env::IOPriority rate_limiter_priority) {
if (!prefix_extractor || !prefix_extractor->InDomain(user_key_without_ts)) { if (!prefix_extractor || !prefix_extractor->InDomain(user_key_without_ts)) {
*filter_checked = false; *filter_checked = false;
return true; return true;
@ -119,7 +117,7 @@ bool FilterBlockReaderCommon<TBlocklike>::RangeMayExist(
*filter_checked = true; *filter_checked = true;
return PrefixMayMatch(prefix, no_io, const_ikey_ptr, return PrefixMayMatch(prefix, no_io, const_ikey_ptr,
/* get_context */ nullptr, lookup_context, /* get_context */ nullptr, lookup_context,
rate_limiter_priority); read_options);
} }
} }

@ -40,7 +40,7 @@ class FilterBlockReaderCommon : public FilterBlockReader {
const Slice* const const_ikey_ptr, bool* filter_checked, const Slice* const const_ikey_ptr, bool* filter_checked,
bool need_upper_bound_check, bool no_io, bool need_upper_bound_check, bool no_io,
BlockCacheLookupContext* lookup_context, BlockCacheLookupContext* lookup_context,
Env::IOPriority rate_limiter_priority) override; const ReadOptions& read_options) override;
protected: protected:
static Status ReadFilterBlock(const BlockBasedTable* table, static Status ReadFilterBlock(const BlockBasedTable* table,
@ -58,7 +58,7 @@ class FilterBlockReaderCommon : public FilterBlockReader {
Status GetOrReadFilterBlock(bool no_io, GetContext* get_context, Status GetOrReadFilterBlock(bool no_io, GetContext* get_context,
BlockCacheLookupContext* lookup_context, BlockCacheLookupContext* lookup_context,
CachableEntry<TBlocklike>* filter_block, CachableEntry<TBlocklike>* filter_block,
Env::IOPriority rate_limiter_priority) const; const ReadOptions& read_options) const;
size_t ApproximateFilterBlockMemoryUsage() const; size_t ApproximateFilterBlockMemoryUsage() const;

@ -127,12 +127,11 @@ bool FullFilterBlockReader::KeyMayMatch(const Slice& key, const bool no_io,
const Slice* const /*const_ikey_ptr*/, const Slice* const /*const_ikey_ptr*/,
GetContext* get_context, GetContext* get_context,
BlockCacheLookupContext* lookup_context, BlockCacheLookupContext* lookup_context,
Env::IOPriority rate_limiter_priority) { const ReadOptions& read_options) {
if (!whole_key_filtering()) { if (!whole_key_filtering()) {
return true; return true;
} }
return MayMatch(key, no_io, get_context, lookup_context, return MayMatch(key, no_io, get_context, lookup_context, read_options);
rate_limiter_priority);
} }
std::unique_ptr<FilterBlockReader> FullFilterBlockReader::Create( std::unique_ptr<FilterBlockReader> FullFilterBlockReader::Create(
@ -165,20 +164,18 @@ std::unique_ptr<FilterBlockReader> FullFilterBlockReader::Create(
bool FullFilterBlockReader::PrefixMayMatch( bool FullFilterBlockReader::PrefixMayMatch(
const Slice& prefix, const bool no_io, const Slice& prefix, const bool no_io,
const Slice* const /*const_ikey_ptr*/, GetContext* get_context, const Slice* const /*const_ikey_ptr*/, GetContext* get_context,
BlockCacheLookupContext* lookup_context, BlockCacheLookupContext* lookup_context, const ReadOptions& read_options) {
Env::IOPriority rate_limiter_priority) { return MayMatch(prefix, no_io, get_context, lookup_context, read_options);
return MayMatch(prefix, no_io, get_context, lookup_context,
rate_limiter_priority);
} }
bool FullFilterBlockReader::MayMatch( bool FullFilterBlockReader::MayMatch(const Slice& entry, bool no_io,
const Slice& entry, bool no_io, GetContext* get_context, GetContext* get_context,
BlockCacheLookupContext* lookup_context, BlockCacheLookupContext* lookup_context,
Env::IOPriority rate_limiter_priority) const { const ReadOptions& read_options) const {
CachableEntry<ParsedFullFilterBlock> filter_block; CachableEntry<ParsedFullFilterBlock> filter_block;
const Status s = GetOrReadFilterBlock(no_io, get_context, lookup_context, const Status s = GetOrReadFilterBlock(no_io, get_context, lookup_context,
&filter_block, rate_limiter_priority); &filter_block, read_options);
if (!s.ok()) { if (!s.ok()) {
IGNORE_STATUS_IF_ERROR(s); IGNORE_STATUS_IF_ERROR(s);
return true; return true;
@ -203,33 +200,31 @@ bool FullFilterBlockReader::MayMatch(
void FullFilterBlockReader::KeysMayMatch( void FullFilterBlockReader::KeysMayMatch(
MultiGetRange* range, const bool no_io, MultiGetRange* range, const bool no_io,
BlockCacheLookupContext* lookup_context, BlockCacheLookupContext* lookup_context, const ReadOptions& read_options) {
Env::IOPriority rate_limiter_priority) {
if (!whole_key_filtering()) { if (!whole_key_filtering()) {
// Simply return. Don't skip any key - consider all keys as likely to be // Simply return. Don't skip any key - consider all keys as likely to be
// present // present
return; return;
} }
MayMatch(range, no_io, nullptr, lookup_context, rate_limiter_priority); MayMatch(range, no_io, nullptr, lookup_context, read_options);
} }
void FullFilterBlockReader::PrefixesMayMatch( void FullFilterBlockReader::PrefixesMayMatch(
MultiGetRange* range, const SliceTransform* prefix_extractor, MultiGetRange* range, const SliceTransform* prefix_extractor,
const bool no_io, BlockCacheLookupContext* lookup_context, const bool no_io, BlockCacheLookupContext* lookup_context,
Env::IOPriority rate_limiter_priority) { const ReadOptions& read_options) {
MayMatch(range, no_io, prefix_extractor, lookup_context, MayMatch(range, no_io, prefix_extractor, lookup_context, read_options);
rate_limiter_priority);
} }
void FullFilterBlockReader::MayMatch( void FullFilterBlockReader::MayMatch(MultiGetRange* range, bool no_io,
MultiGetRange* range, bool no_io, const SliceTransform* prefix_extractor, const SliceTransform* prefix_extractor,
BlockCacheLookupContext* lookup_context, BlockCacheLookupContext* lookup_context,
Env::IOPriority rate_limiter_priority) const { const ReadOptions& read_options) const {
CachableEntry<ParsedFullFilterBlock> filter_block; CachableEntry<ParsedFullFilterBlock> filter_block;
const Status s = const Status s =
GetOrReadFilterBlock(no_io, range->begin()->get_context, lookup_context, GetOrReadFilterBlock(no_io, range->begin()->get_context, lookup_context,
&filter_block, rate_limiter_priority); &filter_block, read_options);
if (!s.ok()) { if (!s.ok()) {
IGNORE_STATUS_IF_ERROR(s); IGNORE_STATUS_IF_ERROR(s);
return; return;

@ -108,40 +108,40 @@ class FullFilterBlockReader
bool KeyMayMatch(const Slice& key, const bool no_io, bool KeyMayMatch(const Slice& key, const bool no_io,
const Slice* const const_ikey_ptr, GetContext* get_context, const Slice* const const_ikey_ptr, GetContext* get_context,
BlockCacheLookupContext* lookup_context, BlockCacheLookupContext* lookup_context,
Env::IOPriority rate_limiter_priority) override; const ReadOptions& read_options) override;
bool PrefixMayMatch(const Slice& prefix, const bool no_io, bool PrefixMayMatch(const Slice& prefix, const bool no_io,
const Slice* const const_ikey_ptr, const Slice* const const_ikey_ptr,
GetContext* get_context, GetContext* get_context,
BlockCacheLookupContext* lookup_context, BlockCacheLookupContext* lookup_context,
Env::IOPriority rate_limiter_priority) override; const ReadOptions& read_options) override;
void KeysMayMatch(MultiGetRange* range, const bool no_io, void KeysMayMatch(MultiGetRange* range, const bool no_io,
BlockCacheLookupContext* lookup_context, BlockCacheLookupContext* lookup_context,
Env::IOPriority rate_limiter_priority) override; const ReadOptions& read_options) override;
// Used in partitioned filter code // Used in partitioned filter code
void KeysMayMatch2(MultiGetRange* range, void KeysMayMatch2(MultiGetRange* range,
const SliceTransform* /*prefix_extractor*/, const SliceTransform* /*prefix_extractor*/,
const bool no_io, BlockCacheLookupContext* lookup_context, const bool no_io, BlockCacheLookupContext* lookup_context,
Env::IOPriority rate_limiter_priority) { const ReadOptions& read_options) {
KeysMayMatch(range, no_io, lookup_context, rate_limiter_priority); KeysMayMatch(range, no_io, lookup_context, read_options);
} }
void PrefixesMayMatch(MultiGetRange* range, void PrefixesMayMatch(MultiGetRange* range,
const SliceTransform* prefix_extractor, const SliceTransform* prefix_extractor,
const bool no_io, const bool no_io,
BlockCacheLookupContext* lookup_context, BlockCacheLookupContext* lookup_context,
Env::IOPriority rate_limiter_priority) override; const ReadOptions& read_options) override;
size_t ApproximateMemoryUsage() const override; size_t ApproximateMemoryUsage() const override;
private: private:
bool MayMatch(const Slice& entry, bool no_io, GetContext* get_context, bool MayMatch(const Slice& entry, bool no_io, GetContext* get_context,
BlockCacheLookupContext* lookup_context, BlockCacheLookupContext* lookup_context,
Env::IOPriority rate_limiter_priority) const; const ReadOptions& read_options) const;
void MayMatch(MultiGetRange* range, bool no_io, void MayMatch(MultiGetRange* range, bool no_io,
const SliceTransform* prefix_extractor, const SliceTransform* prefix_extractor,
BlockCacheLookupContext* lookup_context, BlockCacheLookupContext* lookup_context,
Env::IOPriority rate_limiter_priority) const; const ReadOptions& read_options) const;
}; };
} // namespace ROCKSDB_NAMESPACE } // namespace ROCKSDB_NAMESPACE

@ -117,7 +117,7 @@ TEST_F(PluginFullFilterBlockTest, PluginEmptyBuilder) {
ASSERT_TRUE(reader.KeyMayMatch("foo", ASSERT_TRUE(reader.KeyMayMatch("foo",
/*no_io=*/false, /*const_ikey_ptr=*/nullptr, /*no_io=*/false, /*const_ikey_ptr=*/nullptr,
/*get_context=*/nullptr, /*get_context=*/nullptr,
/*lookup_context=*/nullptr, Env::IO_TOTAL)); /*lookup_context=*/nullptr, ReadOptions()));
} }
TEST_F(PluginFullFilterBlockTest, PluginSingleChunk) { TEST_F(PluginFullFilterBlockTest, PluginSingleChunk) {
@ -135,42 +135,34 @@ TEST_F(PluginFullFilterBlockTest, PluginSingleChunk) {
nullptr /* cache */, nullptr /* cache_handle */, true /* own_value */); nullptr /* cache */, nullptr /* cache_handle */, true /* own_value */);
FullFilterBlockReader reader(table_.get(), std::move(block)); FullFilterBlockReader reader(table_.get(), std::move(block));
Env::IOPriority rate_limiter_priority = Env::IO_TOTAL;
ASSERT_TRUE(reader.KeyMayMatch("foo", ASSERT_TRUE(reader.KeyMayMatch("foo",
/*no_io=*/false, /*const_ikey_ptr=*/nullptr, /*no_io=*/false, /*const_ikey_ptr=*/nullptr,
/*get_context=*/nullptr, /*get_context=*/nullptr,
/*lookup_context=*/nullptr, /*lookup_context=*/nullptr, ReadOptions()));
rate_limiter_priority));
ASSERT_TRUE(reader.KeyMayMatch("bar", ASSERT_TRUE(reader.KeyMayMatch("bar",
/*no_io=*/false, /*const_ikey_ptr=*/nullptr, /*no_io=*/false, /*const_ikey_ptr=*/nullptr,
/*get_context=*/nullptr, /*get_context=*/nullptr,
/*lookup_context=*/nullptr, /*lookup_context=*/nullptr, ReadOptions()));
rate_limiter_priority));
ASSERT_TRUE(reader.KeyMayMatch("box", ASSERT_TRUE(reader.KeyMayMatch("box",
/*no_io=*/false, /*const_ikey_ptr=*/nullptr, /*no_io=*/false, /*const_ikey_ptr=*/nullptr,
/*get_context=*/nullptr, /*get_context=*/nullptr,
/*lookup_context=*/nullptr, /*lookup_context=*/nullptr, ReadOptions()));
rate_limiter_priority));
ASSERT_TRUE(reader.KeyMayMatch("hello", ASSERT_TRUE(reader.KeyMayMatch("hello",
/*no_io=*/false, /*const_ikey_ptr=*/nullptr, /*no_io=*/false, /*const_ikey_ptr=*/nullptr,
/*get_context=*/nullptr, /*get_context=*/nullptr,
/*lookup_context=*/nullptr, /*lookup_context=*/nullptr, ReadOptions()));
rate_limiter_priority));
ASSERT_TRUE(reader.KeyMayMatch("foo", ASSERT_TRUE(reader.KeyMayMatch("foo",
/*no_io=*/false, /*const_ikey_ptr=*/nullptr, /*no_io=*/false, /*const_ikey_ptr=*/nullptr,
/*get_context=*/nullptr, /*get_context=*/nullptr,
/*lookup_context=*/nullptr, /*lookup_context=*/nullptr, ReadOptions()));
rate_limiter_priority));
ASSERT_TRUE(!reader.KeyMayMatch("missing", ASSERT_TRUE(!reader.KeyMayMatch("missing",
/*no_io=*/false, /*const_ikey_ptr=*/nullptr, /*no_io=*/false, /*const_ikey_ptr=*/nullptr,
/*get_context=*/nullptr, /*get_context=*/nullptr,
/*lookup_context=*/nullptr, /*lookup_context=*/nullptr, ReadOptions()));
rate_limiter_priority));
ASSERT_TRUE(!reader.KeyMayMatch("other", ASSERT_TRUE(!reader.KeyMayMatch("other",
/*no_io=*/false, /*const_ikey_ptr=*/nullptr, /*no_io=*/false, /*const_ikey_ptr=*/nullptr,
/*get_context=*/nullptr, /*get_context=*/nullptr,
/*lookup_context=*/nullptr, /*lookup_context=*/nullptr, ReadOptions()));
rate_limiter_priority));
} }
class FullFilterBlockTest : public mock::MockBlockBasedTableTester, class FullFilterBlockTest : public mock::MockBlockBasedTableTester,
@ -195,7 +187,7 @@ TEST_F(FullFilterBlockTest, EmptyBuilder) {
ASSERT_TRUE(reader.KeyMayMatch("foo", ASSERT_TRUE(reader.KeyMayMatch("foo",
/*no_io=*/false, /*const_ikey_ptr=*/nullptr, /*no_io=*/false, /*const_ikey_ptr=*/nullptr,
/*get_context=*/nullptr, /*get_context=*/nullptr,
/*lookup_context=*/nullptr, Env::IO_TOTAL)); /*lookup_context=*/nullptr, ReadOptions()));
} }
class CountUniqueFilterBitsBuilderWrapper : public FilterBitsBuilder { class CountUniqueFilterBitsBuilderWrapper : public FilterBitsBuilder {
@ -292,42 +284,34 @@ TEST_F(FullFilterBlockTest, SingleChunk) {
nullptr /* cache */, nullptr /* cache_handle */, true /* own_value */); nullptr /* cache */, nullptr /* cache_handle */, true /* own_value */);
FullFilterBlockReader reader(table_.get(), std::move(block)); FullFilterBlockReader reader(table_.get(), std::move(block));
Env::IOPriority rate_limiter_priority = Env::IO_TOTAL;
ASSERT_TRUE(reader.KeyMayMatch("foo", ASSERT_TRUE(reader.KeyMayMatch("foo",
/*no_io=*/false, /*const_ikey_ptr=*/nullptr, /*no_io=*/false, /*const_ikey_ptr=*/nullptr,
/*get_context=*/nullptr, /*get_context=*/nullptr,
/*lookup_context=*/nullptr, /*lookup_context=*/nullptr, ReadOptions()));
rate_limiter_priority));
ASSERT_TRUE(reader.KeyMayMatch("bar", ASSERT_TRUE(reader.KeyMayMatch("bar",
/*no_io=*/false, /*const_ikey_ptr=*/nullptr, /*no_io=*/false, /*const_ikey_ptr=*/nullptr,
/*get_context=*/nullptr, /*get_context=*/nullptr,
/*lookup_context=*/nullptr, /*lookup_context=*/nullptr, ReadOptions()));
rate_limiter_priority));
ASSERT_TRUE(reader.KeyMayMatch("box", ASSERT_TRUE(reader.KeyMayMatch("box",
/*no_io=*/false, /*const_ikey_ptr=*/nullptr, /*no_io=*/false, /*const_ikey_ptr=*/nullptr,
/*get_context=*/nullptr, /*get_context=*/nullptr,
/*lookup_context=*/nullptr, /*lookup_context=*/nullptr, ReadOptions()));
rate_limiter_priority));
ASSERT_TRUE(reader.KeyMayMatch("hello", ASSERT_TRUE(reader.KeyMayMatch("hello",
/*no_io=*/false, /*const_ikey_ptr=*/nullptr, /*no_io=*/false, /*const_ikey_ptr=*/nullptr,
/*get_context=*/nullptr, /*get_context=*/nullptr,
/*lookup_context=*/nullptr, /*lookup_context=*/nullptr, ReadOptions()));
rate_limiter_priority));
ASSERT_TRUE(reader.KeyMayMatch("foo", ASSERT_TRUE(reader.KeyMayMatch("foo",
/*no_io=*/false, /*const_ikey_ptr=*/nullptr, /*no_io=*/false, /*const_ikey_ptr=*/nullptr,
/*get_context=*/nullptr, /*get_context=*/nullptr,
/*lookup_context=*/nullptr, /*lookup_context=*/nullptr, ReadOptions()));
rate_limiter_priority));
ASSERT_TRUE(!reader.KeyMayMatch("missing", ASSERT_TRUE(!reader.KeyMayMatch("missing",
/*no_io=*/false, /*const_ikey_ptr=*/nullptr, /*no_io=*/false, /*const_ikey_ptr=*/nullptr,
/*get_context=*/nullptr, /*get_context=*/nullptr,
/*lookup_context=*/nullptr, /*lookup_context=*/nullptr, ReadOptions()));
rate_limiter_priority));
ASSERT_TRUE(!reader.KeyMayMatch("other", ASSERT_TRUE(!reader.KeyMayMatch("other",
/*no_io=*/false, /*const_ikey_ptr=*/nullptr, /*no_io=*/false, /*const_ikey_ptr=*/nullptr,
/*get_context=*/nullptr, /*get_context=*/nullptr,
/*lookup_context=*/nullptr, /*lookup_context=*/nullptr, ReadOptions()));
rate_limiter_priority));
} }
} // namespace ROCKSDB_NAMESPACE } // namespace ROCKSDB_NAMESPACE

@ -116,9 +116,8 @@ InternalIteratorBase<IndexValue>* HashIndexReader::NewIterator(
const BlockBasedTable::Rep* rep = table()->get_rep(); const BlockBasedTable::Rep* rep = table()->get_rep();
const bool no_io = (read_options.read_tier == kBlockCacheTier); const bool no_io = (read_options.read_tier == kBlockCacheTier);
CachableEntry<Block> index_block; CachableEntry<Block> index_block;
const Status s = const Status s = GetOrReadIndexBlock(no_io, get_context, lookup_context,
GetOrReadIndexBlock(no_io, read_options.rate_limiter_priority, &index_block, read_options);
get_context, lookup_context, &index_block);
if (!s.ok()) { if (!s.ok()) {
if (iter != nullptr) { if (iter != nullptr) {
iter->Invalidate(s); iter->Invalidate(s);

@ -35,9 +35,9 @@ Status BlockBasedTable::IndexReaderCommon::ReadIndexBlock(
} }
Status BlockBasedTable::IndexReaderCommon::GetOrReadIndexBlock( Status BlockBasedTable::IndexReaderCommon::GetOrReadIndexBlock(
bool no_io, Env::IOPriority rate_limiter_priority, GetContext* get_context, bool no_io, GetContext* get_context,
BlockCacheLookupContext* lookup_context, BlockCacheLookupContext* lookup_context, CachableEntry<Block>* index_block,
CachableEntry<Block>* index_block) const { const ReadOptions& ro) const {
assert(index_block != nullptr); assert(index_block != nullptr);
if (!index_block_.IsEmpty()) { if (!index_block_.IsEmpty()) {
@ -45,8 +45,7 @@ Status BlockBasedTable::IndexReaderCommon::GetOrReadIndexBlock(
return Status::OK(); return Status::OK();
} }
ReadOptions read_options; ReadOptions read_options = ro;
read_options.rate_limiter_priority = rate_limiter_priority;
if (no_io) { if (no_io) {
read_options.read_tier = kBlockCacheTier; read_options.read_tier = kBlockCacheTier;
} }

@ -65,10 +65,10 @@ class BlockBasedTable::IndexReaderCommon : public BlockBasedTable::IndexReader {
return table_->get_rep()->table_options.cache_index_and_filter_blocks; return table_->get_rep()->table_options.cache_index_and_filter_blocks;
} }
Status GetOrReadIndexBlock(bool no_io, Env::IOPriority rate_limiter_priority, Status GetOrReadIndexBlock(bool no_io, GetContext* get_context,
GetContext* get_context,
BlockCacheLookupContext* lookup_context, BlockCacheLookupContext* lookup_context,
CachableEntry<Block>* index_block) const; CachableEntry<Block>* index_block,
const ReadOptions& read_options) const;
size_t ApproximateIndexBlockMemoryUsage() const { size_t ApproximateIndexBlockMemoryUsage() const {
assert(!index_block_.GetOwnValue() || index_block_.GetValue() != nullptr); assert(!index_block_.GetOwnValue() || index_block_.GetValue() != nullptr);

@ -220,45 +220,43 @@ std::unique_ptr<FilterBlockReader> PartitionedFilterBlockReader::Create(
bool PartitionedFilterBlockReader::KeyMayMatch( bool PartitionedFilterBlockReader::KeyMayMatch(
const Slice& key, const bool no_io, const Slice* const const_ikey_ptr, const Slice& key, const bool no_io, const Slice* const const_ikey_ptr,
GetContext* get_context, BlockCacheLookupContext* lookup_context, GetContext* get_context, BlockCacheLookupContext* lookup_context,
Env::IOPriority rate_limiter_priority) { const ReadOptions& read_options) {
assert(const_ikey_ptr != nullptr); assert(const_ikey_ptr != nullptr);
if (!whole_key_filtering()) { if (!whole_key_filtering()) {
return true; return true;
} }
return MayMatch(key, no_io, const_ikey_ptr, get_context, lookup_context, return MayMatch(key, no_io, const_ikey_ptr, get_context, lookup_context,
rate_limiter_priority, &FullFilterBlockReader::KeyMayMatch); read_options, &FullFilterBlockReader::KeyMayMatch);
} }
void PartitionedFilterBlockReader::KeysMayMatch( void PartitionedFilterBlockReader::KeysMayMatch(
MultiGetRange* range, const bool no_io, MultiGetRange* range, const bool no_io,
BlockCacheLookupContext* lookup_context, BlockCacheLookupContext* lookup_context, const ReadOptions& read_options) {
Env::IOPriority rate_limiter_priority) {
if (!whole_key_filtering()) { if (!whole_key_filtering()) {
return; // Any/all may match return; // Any/all may match
} }
MayMatch(range, nullptr, no_io, lookup_context, rate_limiter_priority, MayMatch(range, nullptr, no_io, lookup_context, read_options,
&FullFilterBlockReader::KeysMayMatch2); &FullFilterBlockReader::KeysMayMatch2);
} }
bool PartitionedFilterBlockReader::PrefixMayMatch( bool PartitionedFilterBlockReader::PrefixMayMatch(
const Slice& prefix, const bool no_io, const Slice* const const_ikey_ptr, const Slice& prefix, const bool no_io, const Slice* const const_ikey_ptr,
GetContext* get_context, BlockCacheLookupContext* lookup_context, GetContext* get_context, BlockCacheLookupContext* lookup_context,
Env::IOPriority rate_limiter_priority) { const ReadOptions& read_options) {
assert(const_ikey_ptr != nullptr); assert(const_ikey_ptr != nullptr);
return MayMatch(prefix, no_io, const_ikey_ptr, get_context, lookup_context, return MayMatch(prefix, no_io, const_ikey_ptr, get_context, lookup_context,
rate_limiter_priority, read_options, &FullFilterBlockReader::PrefixMayMatch);
&FullFilterBlockReader::PrefixMayMatch);
} }
void PartitionedFilterBlockReader::PrefixesMayMatch( void PartitionedFilterBlockReader::PrefixesMayMatch(
MultiGetRange* range, const SliceTransform* prefix_extractor, MultiGetRange* range, const SliceTransform* prefix_extractor,
const bool no_io, BlockCacheLookupContext* lookup_context, const bool no_io, BlockCacheLookupContext* lookup_context,
Env::IOPriority rate_limiter_priority) { const ReadOptions& read_options) {
assert(prefix_extractor); assert(prefix_extractor);
MayMatch(range, prefix_extractor, no_io, lookup_context, MayMatch(range, prefix_extractor, no_io, lookup_context, read_options,
rate_limiter_priority, &FullFilterBlockReader::PrefixesMayMatch); &FullFilterBlockReader::PrefixesMayMatch);
} }
BlockHandle PartitionedFilterBlockReader::GetFilterPartitionHandle( BlockHandle PartitionedFilterBlockReader::GetFilterPartitionHandle(
@ -290,8 +288,7 @@ BlockHandle PartitionedFilterBlockReader::GetFilterPartitionHandle(
Status PartitionedFilterBlockReader::GetFilterPartitionBlock( Status PartitionedFilterBlockReader::GetFilterPartitionBlock(
FilePrefetchBuffer* prefetch_buffer, const BlockHandle& fltr_blk_handle, FilePrefetchBuffer* prefetch_buffer, const BlockHandle& fltr_blk_handle,
bool no_io, GetContext* get_context, bool no_io, GetContext* get_context,
BlockCacheLookupContext* lookup_context, BlockCacheLookupContext* lookup_context, const ReadOptions& _read_options,
Env::IOPriority rate_limiter_priority,
CachableEntry<ParsedFullFilterBlock>* filter_block) const { CachableEntry<ParsedFullFilterBlock>* filter_block) const {
assert(table()); assert(table());
assert(filter_block); assert(filter_block);
@ -307,8 +304,7 @@ Status PartitionedFilterBlockReader::GetFilterPartitionBlock(
} }
} }
ReadOptions read_options; ReadOptions read_options = _read_options;
read_options.rate_limiter_priority = rate_limiter_priority;
if (no_io) { if (no_io) {
read_options.read_tier = kBlockCacheTier; read_options.read_tier = kBlockCacheTier;
} }
@ -326,11 +322,10 @@ Status PartitionedFilterBlockReader::GetFilterPartitionBlock(
bool PartitionedFilterBlockReader::MayMatch( bool PartitionedFilterBlockReader::MayMatch(
const Slice& slice, bool no_io, const Slice* const_ikey_ptr, const Slice& slice, bool no_io, const Slice* const_ikey_ptr,
GetContext* get_context, BlockCacheLookupContext* lookup_context, GetContext* get_context, BlockCacheLookupContext* lookup_context,
Env::IOPriority rate_limiter_priority, const ReadOptions& read_options, FilterFunction filter_function) const {
FilterFunction filter_function) const {
CachableEntry<Block_kFilterPartitionIndex> filter_block; CachableEntry<Block_kFilterPartitionIndex> filter_block;
Status s = GetOrReadFilterBlock(no_io, get_context, lookup_context, Status s = GetOrReadFilterBlock(no_io, get_context, lookup_context,
&filter_block, rate_limiter_priority); &filter_block, read_options);
if (UNLIKELY(!s.ok())) { if (UNLIKELY(!s.ok())) {
IGNORE_STATUS_IF_ERROR(s); IGNORE_STATUS_IF_ERROR(s);
return true; return true;
@ -347,8 +342,8 @@ bool PartitionedFilterBlockReader::MayMatch(
CachableEntry<ParsedFullFilterBlock> filter_partition_block; CachableEntry<ParsedFullFilterBlock> filter_partition_block;
s = GetFilterPartitionBlock(nullptr /* prefetch_buffer */, filter_handle, s = GetFilterPartitionBlock(nullptr /* prefetch_buffer */, filter_handle,
no_io, get_context, lookup_context, no_io, get_context, lookup_context, read_options,
rate_limiter_priority, &filter_partition_block); &filter_partition_block);
if (UNLIKELY(!s.ok())) { if (UNLIKELY(!s.ok())) {
IGNORE_STATUS_IF_ERROR(s); IGNORE_STATUS_IF_ERROR(s);
return true; return true;
@ -356,20 +351,17 @@ bool PartitionedFilterBlockReader::MayMatch(
FullFilterBlockReader filter_partition(table(), FullFilterBlockReader filter_partition(table(),
std::move(filter_partition_block)); std::move(filter_partition_block));
return (filter_partition.*filter_function)(slice, no_io, const_ikey_ptr, return (filter_partition.*filter_function)(
get_context, lookup_context, slice, no_io, const_ikey_ptr, get_context, lookup_context, read_options);
rate_limiter_priority);
} }
void PartitionedFilterBlockReader::MayMatch( void PartitionedFilterBlockReader::MayMatch(
MultiGetRange* range, const SliceTransform* prefix_extractor, bool no_io, MultiGetRange* range, const SliceTransform* prefix_extractor, bool no_io,
BlockCacheLookupContext* lookup_context, BlockCacheLookupContext* lookup_context, const ReadOptions& read_options,
Env::IOPriority rate_limiter_priority,
FilterManyFunction filter_function) const { FilterManyFunction filter_function) const {
CachableEntry<Block_kFilterPartitionIndex> filter_block; CachableEntry<Block_kFilterPartitionIndex> filter_block;
Status s = Status s = GetOrReadFilterBlock(no_io, range->begin()->get_context,
GetOrReadFilterBlock(no_io, range->begin()->get_context, lookup_context, lookup_context, &filter_block, read_options);
&filter_block, rate_limiter_priority);
if (UNLIKELY(!s.ok())) { if (UNLIKELY(!s.ok())) {
IGNORE_STATUS_IF_ERROR(s); IGNORE_STATUS_IF_ERROR(s);
return; // Any/all may match return; // Any/all may match
@ -393,7 +385,7 @@ void PartitionedFilterBlockReader::MayMatch(
this_filter_handle != prev_filter_handle) { this_filter_handle != prev_filter_handle) {
MultiGetRange subrange(*range, start_iter_same_handle, iter); MultiGetRange subrange(*range, start_iter_same_handle, iter);
MayMatchPartition(&subrange, prefix_extractor, prev_filter_handle, no_io, MayMatchPartition(&subrange, prefix_extractor, prev_filter_handle, no_io,
lookup_context, rate_limiter_priority, filter_function); lookup_context, read_options, filter_function);
range->AddSkipsFrom(subrange); range->AddSkipsFrom(subrange);
start_iter_same_handle = iter; start_iter_same_handle = iter;
} }
@ -409,7 +401,7 @@ void PartitionedFilterBlockReader::MayMatch(
if (!prev_filter_handle.IsNull()) { if (!prev_filter_handle.IsNull()) {
MultiGetRange subrange(*range, start_iter_same_handle, range->end()); MultiGetRange subrange(*range, start_iter_same_handle, range->end());
MayMatchPartition(&subrange, prefix_extractor, prev_filter_handle, no_io, MayMatchPartition(&subrange, prefix_extractor, prev_filter_handle, no_io,
lookup_context, rate_limiter_priority, filter_function); lookup_context, read_options, filter_function);
range->AddSkipsFrom(subrange); range->AddSkipsFrom(subrange);
} }
} }
@ -417,13 +409,12 @@ void PartitionedFilterBlockReader::MayMatch(
void PartitionedFilterBlockReader::MayMatchPartition( void PartitionedFilterBlockReader::MayMatchPartition(
MultiGetRange* range, const SliceTransform* prefix_extractor, MultiGetRange* range, const SliceTransform* prefix_extractor,
BlockHandle filter_handle, bool no_io, BlockHandle filter_handle, bool no_io,
BlockCacheLookupContext* lookup_context, BlockCacheLookupContext* lookup_context, const ReadOptions& read_options,
Env::IOPriority rate_limiter_priority,
FilterManyFunction filter_function) const { FilterManyFunction filter_function) const {
CachableEntry<ParsedFullFilterBlock> filter_partition_block; CachableEntry<ParsedFullFilterBlock> filter_partition_block;
Status s = GetFilterPartitionBlock( Status s = GetFilterPartitionBlock(
nullptr /* prefetch_buffer */, filter_handle, no_io, nullptr /* prefetch_buffer */, filter_handle, no_io,
range->begin()->get_context, lookup_context, rate_limiter_priority, range->begin()->get_context, lookup_context, read_options,
&filter_partition_block); &filter_partition_block);
if (UNLIKELY(!s.ok())) { if (UNLIKELY(!s.ok())) {
IGNORE_STATUS_IF_ERROR(s); IGNORE_STATUS_IF_ERROR(s);
@ -433,7 +424,7 @@ void PartitionedFilterBlockReader::MayMatchPartition(
FullFilterBlockReader filter_partition(table(), FullFilterBlockReader filter_partition(table(),
std::move(filter_partition_block)); std::move(filter_partition_block));
(filter_partition.*filter_function)(range, prefix_extractor, no_io, (filter_partition.*filter_function)(range, prefix_extractor, no_io,
lookup_context, rate_limiter_priority); lookup_context, read_options);
} }
size_t PartitionedFilterBlockReader::ApproximateMemoryUsage() const { size_t PartitionedFilterBlockReader::ApproximateMemoryUsage() const {
@ -460,8 +451,7 @@ Status PartitionedFilterBlockReader::CacheDependencies(const ReadOptions& ro,
CachableEntry<Block_kFilterPartitionIndex> filter_block; CachableEntry<Block_kFilterPartitionIndex> filter_block;
Status s = GetOrReadFilterBlock(false /* no_io */, nullptr /* get_context */, Status s = GetOrReadFilterBlock(false /* no_io */, nullptr /* get_context */,
&lookup_context, &filter_block, &lookup_context, &filter_block, ro);
ro.rate_limiter_priority);
if (!s.ok()) { if (!s.ok()) {
ROCKS_LOG_ERROR(rep->ioptions.logger, ROCKS_LOG_ERROR(rep->ioptions.logger,
"Error retrieving top-level filter block while trying to " "Error retrieving top-level filter block while trying to "

@ -115,21 +115,21 @@ class PartitionedFilterBlockReader
bool KeyMayMatch(const Slice& key, const bool no_io, bool KeyMayMatch(const Slice& key, const bool no_io,
const Slice* const const_ikey_ptr, GetContext* get_context, const Slice* const const_ikey_ptr, GetContext* get_context,
BlockCacheLookupContext* lookup_context, BlockCacheLookupContext* lookup_context,
Env::IOPriority rate_limiter_priority) override; const ReadOptions& read_options) override;
void KeysMayMatch(MultiGetRange* range, const bool no_io, void KeysMayMatch(MultiGetRange* range, const bool no_io,
BlockCacheLookupContext* lookup_context, BlockCacheLookupContext* lookup_context,
Env::IOPriority rate_limiter_priority) override; const ReadOptions& read_options) override;
bool PrefixMayMatch(const Slice& prefix, const bool no_io, bool PrefixMayMatch(const Slice& prefix, const bool no_io,
const Slice* const const_ikey_ptr, const Slice* const const_ikey_ptr,
GetContext* get_context, GetContext* get_context,
BlockCacheLookupContext* lookup_context, BlockCacheLookupContext* lookup_context,
Env::IOPriority rate_limiter_priority) override; const ReadOptions& read_options) override;
void PrefixesMayMatch(MultiGetRange* range, void PrefixesMayMatch(MultiGetRange* range,
const SliceTransform* prefix_extractor, const SliceTransform* prefix_extractor,
const bool no_io, const bool no_io,
BlockCacheLookupContext* lookup_context, BlockCacheLookupContext* lookup_context,
Env::IOPriority rate_limiter_priority) override; const ReadOptions& read_options) override;
size_t ApproximateMemoryUsage() const override; size_t ApproximateMemoryUsage() const override;
@ -140,32 +140,31 @@ class PartitionedFilterBlockReader
Status GetFilterPartitionBlock( Status GetFilterPartitionBlock(
FilePrefetchBuffer* prefetch_buffer, const BlockHandle& handle, FilePrefetchBuffer* prefetch_buffer, const BlockHandle& handle,
bool no_io, GetContext* get_context, bool no_io, GetContext* get_context,
BlockCacheLookupContext* lookup_context, BlockCacheLookupContext* lookup_context, const ReadOptions& read_options,
Env::IOPriority rate_limiter_priority,
CachableEntry<ParsedFullFilterBlock>* filter_block) const; CachableEntry<ParsedFullFilterBlock>* filter_block) const;
using FilterFunction = bool (FullFilterBlockReader::*)( using FilterFunction = bool (FullFilterBlockReader::*)(
const Slice& slice, const bool no_io, const Slice* const const_ikey_ptr, const Slice& slice, const bool no_io, const Slice* const const_ikey_ptr,
GetContext* get_context, BlockCacheLookupContext* lookup_context, GetContext* get_context, BlockCacheLookupContext* lookup_context,
Env::IOPriority rate_limiter_priority); const ReadOptions& read_options);
bool MayMatch(const Slice& slice, bool no_io, const Slice* const_ikey_ptr, bool MayMatch(const Slice& slice, bool no_io, const Slice* const_ikey_ptr,
GetContext* get_context, GetContext* get_context,
BlockCacheLookupContext* lookup_context, BlockCacheLookupContext* lookup_context,
Env::IOPriority rate_limiter_priority, const ReadOptions& read_options,
FilterFunction filter_function) const; FilterFunction filter_function) const;
using FilterManyFunction = void (FullFilterBlockReader::*)( using FilterManyFunction = void (FullFilterBlockReader::*)(
MultiGetRange* range, const SliceTransform* prefix_extractor, MultiGetRange* range, const SliceTransform* prefix_extractor,
const bool no_io, BlockCacheLookupContext* lookup_context, const bool no_io, BlockCacheLookupContext* lookup_context,
Env::IOPriority rate_limiter_priority); const ReadOptions& read_options);
void MayMatch(MultiGetRange* range, const SliceTransform* prefix_extractor, void MayMatch(MultiGetRange* range, const SliceTransform* prefix_extractor,
bool no_io, BlockCacheLookupContext* lookup_context, bool no_io, BlockCacheLookupContext* lookup_context,
Env::IOPriority rate_limiter_priority, const ReadOptions& read_options,
FilterManyFunction filter_function) const; FilterManyFunction filter_function) const;
void MayMatchPartition(MultiGetRange* range, void MayMatchPartition(MultiGetRange* range,
const SliceTransform* prefix_extractor, const SliceTransform* prefix_extractor,
BlockHandle filter_handle, bool no_io, BlockHandle filter_handle, bool no_io,
BlockCacheLookupContext* lookup_context, BlockCacheLookupContext* lookup_context,
Env::IOPriority rate_limiter_priority, const ReadOptions& read_options,
FilterManyFunction filter_function) const; FilterManyFunction filter_function) const;
Status CacheDependencies(const ReadOptions& ro, bool pin) override; Status CacheDependencies(const ReadOptions& ro, bool pin) override;

@ -167,7 +167,6 @@ class PartitionedFilterBlockTest
PartitionedIndexBuilder* pib, bool empty = false) { PartitionedIndexBuilder* pib, bool empty = false) {
std::unique_ptr<PartitionedFilterBlockReader> reader( std::unique_ptr<PartitionedFilterBlockReader> reader(
NewReader(builder, pib)); NewReader(builder, pib));
Env::IOPriority rate_limiter_priority = Env::IO_TOTAL;
// Querying added keys // Querying added keys
const bool no_io = true; const bool no_io = true;
for (auto key : keys) { for (auto key : keys) {
@ -176,7 +175,7 @@ class PartitionedFilterBlockTest
ASSERT_TRUE(reader->KeyMayMatch(key, !no_io, &ikey_slice, ASSERT_TRUE(reader->KeyMayMatch(key, !no_io, &ikey_slice,
/*get_context=*/nullptr, /*get_context=*/nullptr,
/*lookup_context=*/nullptr, /*lookup_context=*/nullptr,
rate_limiter_priority)); ReadOptions()));
} }
{ {
// querying a key twice // querying a key twice
@ -185,7 +184,7 @@ class PartitionedFilterBlockTest
ASSERT_TRUE(reader->KeyMayMatch(keys[0], !no_io, &ikey_slice, ASSERT_TRUE(reader->KeyMayMatch(keys[0], !no_io, &ikey_slice,
/*get_context=*/nullptr, /*get_context=*/nullptr,
/*lookup_context=*/nullptr, /*lookup_context=*/nullptr,
rate_limiter_priority)); ReadOptions()));
} }
// querying missing keys // querying missing keys
for (auto key : missing_keys) { for (auto key : missing_keys) {
@ -195,13 +194,13 @@ class PartitionedFilterBlockTest
ASSERT_TRUE(reader->KeyMayMatch(key, !no_io, &ikey_slice, ASSERT_TRUE(reader->KeyMayMatch(key, !no_io, &ikey_slice,
/*get_context=*/nullptr, /*get_context=*/nullptr,
/*lookup_context=*/nullptr, /*lookup_context=*/nullptr,
rate_limiter_priority)); ReadOptions()));
} else { } else {
// assuming a good hash function // assuming a good hash function
ASSERT_FALSE(reader->KeyMayMatch(key, !no_io, &ikey_slice, ASSERT_FALSE(reader->KeyMayMatch(key, !no_io, &ikey_slice,
/*get_context=*/nullptr, /*get_context=*/nullptr,
/*lookup_context=*/nullptr, /*lookup_context=*/nullptr,
rate_limiter_priority)); ReadOptions()));
} }
} }
} }
@ -354,7 +353,7 @@ TEST_P(PartitionedFilterBlockTest, SamePrefixInMultipleBlocks) {
/*no_io=*/false, &ikey_slice, /*no_io=*/false, &ikey_slice,
/*get_context=*/nullptr, /*get_context=*/nullptr,
/*lookup_context=*/nullptr, /*lookup_context=*/nullptr,
Env::IO_TOTAL)); ReadOptions()));
} }
// Non-existent keys but with the same prefix // Non-existent keys but with the same prefix
const std::string pnonkeys[4] = {"p-key9", "p-key11", "p-key21", "p-key31"}; const std::string pnonkeys[4] = {"p-key9", "p-key11", "p-key21", "p-key31"};
@ -365,7 +364,7 @@ TEST_P(PartitionedFilterBlockTest, SamePrefixInMultipleBlocks) {
/*no_io=*/false, &ikey_slice, /*no_io=*/false, &ikey_slice,
/*get_context=*/nullptr, /*get_context=*/nullptr,
/*lookup_context=*/nullptr, /*lookup_context=*/nullptr,
Env::IO_TOTAL)); ReadOptions()));
} }
} }
@ -396,7 +395,6 @@ TEST_P(PartitionedFilterBlockTest, PrefixInWrongPartitionBug) {
CutABlock(pib.get(), pkeys[4]); CutABlock(pib.get(), pkeys[4]);
std::unique_ptr<PartitionedFilterBlockReader> reader( std::unique_ptr<PartitionedFilterBlockReader> reader(
NewReader(builder.get(), pib.get())); NewReader(builder.get(), pib.get()));
Env::IOPriority rate_limiter_priority = Env::IO_TOTAL;
for (auto key : pkeys) { for (auto key : pkeys) {
auto prefix = prefix_extractor->Transform(key); auto prefix = prefix_extractor->Transform(key);
auto ikey = InternalKey(prefix, 0, ValueType::kTypeValue); auto ikey = InternalKey(prefix, 0, ValueType::kTypeValue);
@ -405,7 +403,7 @@ TEST_P(PartitionedFilterBlockTest, PrefixInWrongPartitionBug) {
/*no_io=*/false, &ikey_slice, /*no_io=*/false, &ikey_slice,
/*get_context=*/nullptr, /*get_context=*/nullptr,
/*lookup_context=*/nullptr, /*lookup_context=*/nullptr,
rate_limiter_priority)); ReadOptions()));
} }
} }

@ -49,9 +49,8 @@ InternalIteratorBase<IndexValue>* PartitionIndexReader::NewIterator(
BlockCacheLookupContext* lookup_context) { BlockCacheLookupContext* lookup_context) {
const bool no_io = (read_options.read_tier == kBlockCacheTier); const bool no_io = (read_options.read_tier == kBlockCacheTier);
CachableEntry<Block> index_block; CachableEntry<Block> index_block;
const Status s = const Status s = GetOrReadIndexBlock(no_io, get_context, lookup_context,
GetOrReadIndexBlock(no_io, read_options.rate_limiter_priority, &index_block, read_options);
get_context, lookup_context, &index_block);
if (!s.ok()) { if (!s.ok()) {
if (iter != nullptr) { if (iter != nullptr) {
iter->Invalidate(s); iter->Invalidate(s);
@ -85,6 +84,7 @@ InternalIteratorBase<IndexValue>* PartitionIndexReader::NewIterator(
ro.adaptive_readahead = read_options.adaptive_readahead; ro.adaptive_readahead = read_options.adaptive_readahead;
ro.async_io = read_options.async_io; ro.async_io = read_options.async_io;
ro.rate_limiter_priority = read_options.rate_limiter_priority; ro.rate_limiter_priority = read_options.rate_limiter_priority;
ro.verify_checksums = read_options.verify_checksums;
// We don't return pinned data from index blocks, so no need // We don't return pinned data from index blocks, so no need
// to set `block_contents_pinned`. // to set `block_contents_pinned`.
@ -127,9 +127,8 @@ Status PartitionIndexReader::CacheDependencies(const ReadOptions& ro,
CachableEntry<Block> index_block; CachableEntry<Block> index_block;
{ {
Status s = GetOrReadIndexBlock(false /* no_io */, ro.rate_limiter_priority, Status s = GetOrReadIndexBlock(false /* no_io */, nullptr /* get_context */,
nullptr /* get_context */, &lookup_context, &lookup_context, &index_block, ro);
&index_block);
if (!s.ok()) { if (!s.ok()) {
return s; return s;
} }

@ -728,7 +728,7 @@ double FilterBench::RandomQueryTest(uint32_t inside_threshold, bool dry_run,
batch_slices[i], batch_slices[i],
/*no_io=*/false, /*const_ikey_ptr=*/nullptr, /*no_io=*/false, /*const_ikey_ptr=*/nullptr,
/*get_context=*/nullptr, /*get_context=*/nullptr,
/*lookup_context=*/nullptr, Env::IO_TOTAL); /*lookup_context=*/nullptr, ROCKSDB_NAMESPACE::ReadOptions());
} }
} else { } else {
if (dry_run) { if (dry_run) {

Loading…
Cancel
Save