From b010116d8263db1ba3f6ea5b30f9886243320a59 Mon Sep 17 00:00:00 2001 From: Dmitri Smirnov Date: Wed, 10 Jan 2018 17:03:12 -0800 Subject: [PATCH] Eliminate some redundant block reads. Summary: Re-use metadata for reading Compression Dictionary on BlockBased table open, this saves two reads from disk. This helps to our 999 percentile in 5.6.1 where prefetch buffer is not present. Closes https://github.com/facebook/rocksdb/pull/3354 Differential Revision: D6695753 Pulled By: ajkr fbshipit-source-id: bb8acd9e9e66e65b89c548ab8940570ae360333c --- table/block_based_table_reader.cc | 26 +++++++++++++++----------- table/table_properties.cc | 5 +++-- table/table_properties_internal.h | 3 ++- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/table/block_based_table_reader.cc b/table/block_based_table_reader.cc index 6b47fcb30..f87c09ef4 100644 --- a/table/block_based_table_reader.cc +++ b/table/block_based_table_reader.cc @@ -759,23 +759,27 @@ Status BlockBasedTable::Open(const ImmutableCFOptions& ioptions, // Read the compression dictionary meta block bool found_compression_dict; - s = SeekToCompressionDictBlock(meta_iter.get(), &found_compression_dict); + BlockHandle compression_dict_handle; + s = SeekToCompressionDictBlock(meta_iter.get(), &found_compression_dict, + &compression_dict_handle); if (!s.ok()) { ROCKS_LOG_WARN( rep->ioptions.info_log, "Error when seeking to compression dictionary block from file: %s", s.ToString().c_str()); - } else if (found_compression_dict) { + } else if (found_compression_dict && !compression_dict_handle.IsNull()) { // TODO(andrewkr): Add to block cache if cache_index_and_filter_blocks is // true. - unique_ptr compression_dict_block{new BlockContents()}; - // TODO(andrewkr): ReadMetaBlock repeats SeekToCompressionDictBlock(). - // maybe decode a handle from meta_iter - // and do ReadBlockContents(handle) instead - s = rocksdb::ReadMetaBlock(rep->file.get(), prefetch_buffer.get(), - file_size, kBlockBasedTableMagicNumber, - rep->ioptions, rocksdb::kCompressionDictBlock, - compression_dict_block.get()); + std::unique_ptr compression_dict_cont{new BlockContents()}; + PersistentCacheOptions cache_options; + ReadOptions read_options; + read_options.verify_checksums = false; + BlockFetcher compression_block_fetcher( + rep->file.get(), prefetch_buffer.get(), rep->footer, read_options, + compression_dict_handle, compression_dict_cont.get(), rep->ioptions, false /* decompress */, + Slice() /*compression dict*/, cache_options); + s = compression_block_fetcher.ReadBlockContents(); + if (!s.ok()) { ROCKS_LOG_WARN( rep->ioptions.info_log, @@ -783,7 +787,7 @@ Status BlockBasedTable::Open(const ImmutableCFOptions& ioptions, "block %s", s.ToString().c_str()); } else { - rep->compression_dict_block = std::move(compression_dict_block); + rep->compression_dict_block = std::move(compression_dict_cont); } } diff --git a/table/table_properties.cc b/table/table_properties.cc index 24453f6f9..4adced5ec 100644 --- a/table/table_properties.cc +++ b/table/table_properties.cc @@ -215,8 +215,9 @@ Status SeekToPropertiesBlock(InternalIterator* meta_iter, bool* is_found) { // Seek to the compression dictionary block. // Return true if it successfully seeks to that block. -Status SeekToCompressionDictBlock(InternalIterator* meta_iter, bool* is_found) { - return SeekToMetaBlock(meta_iter, kCompressionDictBlock, is_found); +Status SeekToCompressionDictBlock(InternalIterator* meta_iter, bool* is_found, + BlockHandle* block_handle) { + return SeekToMetaBlock(meta_iter, kCompressionDictBlock, is_found, block_handle); } Status SeekToRangeDelBlock(InternalIterator* meta_iter, bool* is_found, diff --git a/table/table_properties_internal.h b/table/table_properties_internal.h index 2a8942734..b4e95750b 100644 --- a/table/table_properties_internal.h +++ b/table/table_properties_internal.h @@ -21,7 +21,8 @@ Status SeekToPropertiesBlock(InternalIterator* meta_iter, bool* is_found); // Seek to the compression dictionary block. // If it successfully seeks to the properties block, "is_found" will be // set to true. -Status SeekToCompressionDictBlock(InternalIterator* meta_iter, bool* is_found); +Status SeekToCompressionDictBlock(InternalIterator* meta_iter, bool* is_found, + BlockHandle* block_handle); // TODO(andrewkr) should not put all meta block in table_properties.h/cc Status SeekToRangeDelBlock(InternalIterator* meta_iter, bool* is_found,