Eliminate a memcpy for uncompressed blocks
Summary: `ReadBlockFromFile` uses a stack buffer to hold small data blocks before passing them to the compression library, which outputs uncompressed data in a heap buffer. In the case of `kNoCompression` there is a `memcpy` to copy from stack buffer to heap buffer. This PR optimizes `ReadBlockFromFile` to skip the stack buffer for files whose blocks are known to be uncompressed. We determine this using the SST file property, "compression_name", if it's available. Closes https://github.com/facebook/rocksdb/pull/3472 Differential Revision: D6920848 Pulled By: ajkr fbshipit-source-id: 5c753e804efc178b9229ae5dbe6a4adc32031f07
This commit is contained in:
parent
a0931b3185
commit
e78715c29a
@ -759,7 +759,10 @@ Status BlockBasedTable::Open(const ImmutableCFOptions& ioptions,
|
||||
"block %s",
|
||||
s.ToString().c_str());
|
||||
} else {
|
||||
assert(table_properties != nullptr);
|
||||
rep->table_properties.reset(table_properties);
|
||||
rep->blocks_maybe_compressed = rep->table_properties->compression_name !=
|
||||
CompressionTypeToString(kNoCompression);
|
||||
}
|
||||
} else {
|
||||
ROCKS_LOG_ERROR(rep->ioptions.info_log,
|
||||
@ -1502,10 +1505,10 @@ BlockIter* BlockBasedTable::NewDataBlockIterator(
|
||||
{
|
||||
StopWatch sw(rep->ioptions.env, rep->ioptions.statistics,
|
||||
READ_BLOCK_GET_MICROS);
|
||||
s = ReadBlockFromFile(
|
||||
rep->file.get(), nullptr /* prefetch_buffer */, rep->footer, ro,
|
||||
handle, &block_value, rep->ioptions, true /* compress */,
|
||||
compression_dict, rep->persistent_cache_options, rep->global_seqno,
|
||||
s = ReadBlockFromFile(rep->file.get(), nullptr /* prefetch_buffer */,
|
||||
rep->footer, ro, handle, &block_value, rep->ioptions,
|
||||
rep->blocks_maybe_compressed, compression_dict,
|
||||
rep->persistent_cache_options, rep->global_seqno,
|
||||
rep->table_options.read_amp_bytes_per_bit);
|
||||
}
|
||||
if (s.ok()) {
|
||||
@ -1605,7 +1608,8 @@ Status BlockBasedTable::MaybeLoadDataBlockToCache(
|
||||
StopWatch sw(rep->ioptions.env, statistics, READ_BLOCK_GET_MICROS);
|
||||
s = ReadBlockFromFile(
|
||||
rep->file.get(), prefetch_buffer, rep->footer, ro, handle,
|
||||
&raw_block, rep->ioptions, block_cache_compressed == nullptr,
|
||||
&raw_block, rep->ioptions,
|
||||
block_cache_compressed == nullptr && rep->blocks_maybe_compressed,
|
||||
compression_dict, rep->persistent_cache_options, rep->global_seqno,
|
||||
rep->table_options.read_amp_bytes_per_bit);
|
||||
}
|
||||
|
@ -224,6 +224,7 @@ class BlockBasedTable : public TableReader {
|
||||
Rep* rep, const ReadOptions& ro, const BlockHandle& block_hanlde,
|
||||
BlockIter* input_iter = nullptr, bool is_index = false,
|
||||
GetContext* get_context = nullptr, Status s = Status());
|
||||
|
||||
// If block cache enabled (compressed or uncompressed), looks for the block
|
||||
// identified by handle in (1) uncompressed cache, (2) compressed cache, and
|
||||
// then (3) file. If found, inserts into the cache(s) that were searched
|
||||
@ -495,6 +496,11 @@ struct BlockBasedTable::Rep {
|
||||
// A value of kDisableGlobalSequenceNumber means that this feature is disabled
|
||||
// and every key have it's own seqno.
|
||||
SequenceNumber global_seqno;
|
||||
|
||||
// If false, blocks in this file are definitely all uncompressed. Knowing this
|
||||
// before reading individual blocks enables certain optimizations.
|
||||
bool blocks_maybe_compressed = true;
|
||||
|
||||
bool closed = false;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user