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(
const ReadOptions& read_options) {
if (rep_->range_del_handle.IsNull()) {
// The block didn't exist, nullptr indicates no range tombstones.
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;
rep_->range_del_handle.EncodeTo(&str);
// Even though range_del_entry already references the meta-block when block
// cache is enabled, we still call the below function to get another reference
// since the caller may need the iterator beyond this table reader's lifetime.
// The meta-block exists but isn't in uncompressed block cache (maybe because
// it is disabled), so go through the full lookup process.
return NewDataBlockIterator(rep_, read_options, Slice(str));
}