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:
Andrew Kryczka 2017-01-26 11:18:19 -08:00 committed by Facebook Github Bot
parent 94a0c32e73
commit 3b35134e4b

View File

@ -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));
} }