Avoid cache lookups for range deletion meta-block
Summary: I added the Cache::Ref() function a couple weeks ago (#1761) to make this feature possible. Like other meta-blocks, rep_->range_del_entry holds a cache handle to pin the range deletion block in uncompressed block cache for the duration of the table reader's lifetime. We can reuse this cache handle to create an iterator over this meta-block without any cache lookup. Ref() is used to increment the cache handle's refcount in case the returned iterator outlives the table reader. Closes https://github.com/facebook/rocksdb/pull/1801 Differential Revision: D4458782 Pulled By: ajkr fbshipit-source-id: 2883f10
This commit is contained in:
parent
94a0c32e73
commit
3b35134e4b
@ -1489,13 +1489,30 @@ InternalIterator* BlockBasedTable::NewIterator(const ReadOptions& read_options,
|
|||||||
InternalIterator* BlockBasedTable::NewRangeTombstoneIterator(
|
InternalIterator* BlockBasedTable::NewRangeTombstoneIterator(
|
||||||
const ReadOptions& read_options) {
|
const ReadOptions& read_options) {
|
||||||
if (rep_->range_del_handle.IsNull()) {
|
if (rep_->range_del_handle.IsNull()) {
|
||||||
|
// The block didn't exist, nullptr indicates no range tombstones.
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
if (rep_->range_del_entry.cache_handle != nullptr) {
|
||||||
|
// We have a handle to an uncompressed block cache entry that's held for
|
||||||
|
// this table's lifetime. Increment its refcount before returning an
|
||||||
|
// iterator based on it since the returned iterator may outlive this table
|
||||||
|
// reader.
|
||||||
|
assert(rep_->range_del_entry.value != nullptr);
|
||||||
|
Cache* block_cache = rep_->table_options.block_cache.get();
|
||||||
|
assert(block_cache != nullptr);
|
||||||
|
if (block_cache->Ref(rep_->range_del_entry.cache_handle)) {
|
||||||
|
auto iter = rep_->range_del_entry.value->NewIterator(
|
||||||
|
&rep_->internal_comparator, nullptr /* iter */,
|
||||||
|
true /* total_order_seek */, rep_->ioptions.statistics);
|
||||||
|
iter->RegisterCleanup(&ReleaseCachedEntry, block_cache,
|
||||||
|
rep_->range_del_entry.cache_handle);
|
||||||
|
return iter;
|
||||||
|
}
|
||||||
|
}
|
||||||
std::string str;
|
std::string str;
|
||||||
rep_->range_del_handle.EncodeTo(&str);
|
rep_->range_del_handle.EncodeTo(&str);
|
||||||
// Even though range_del_entry already references the meta-block when block
|
// The meta-block exists but isn't in uncompressed block cache (maybe because
|
||||||
// cache is enabled, we still call the below function to get another reference
|
// it is disabled), so go through the full lookup process.
|
||||||
// since the caller may need the iterator beyond this table reader's lifetime.
|
|
||||||
return NewDataBlockIterator(rep_, read_options, Slice(str));
|
return NewDataBlockIterator(rep_, read_options, Slice(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user