Skip to content

Commit

Permalink
Avoid intialization and copy of internal buffer
Browse files Browse the repository at this point in the history
Summary:
Compressors have an internal buffer that holds compressed data.
- This buffer, which can be large, doesn't need to be preinitialized, only allocated.
- If this buffer needs to grow and be reallocated, we don't need to preserve its current content.

Differential Revision: D60152613

fbshipit-source-id: b359f5f58c80beb51ad9f8cc5e6976f6e15af02f
  • Loading branch information
Georges Berenger authored and facebook-github-bot committed Jul 24, 2024
1 parent cc0ae1c commit 0c1948e
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 4 deletions.
7 changes: 5 additions & 2 deletions vrs/Compressor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,14 +117,15 @@ class Compressor::CompressorImpl {
}
}
uint32_t lz4Compress(
vector<uint8_t>& buffer,
vector<uninitialized_byte>& buffer,
const void* data,
size_t dataSize,
CompressionPreset preset) {
const auto* prefs = getLz4Preferences(preset);
size_t maxCompressedSize = LZ4F_compressFrameBound(dataSize, prefs);
// increase our internal buffer size if necessary
if (buffer.size() < maxCompressedSize) {
buffer.resize(0); // avoid copy of current data when resizing
buffer.resize(maxCompressedSize);
}
size_t result = LZ4F_compressFrame(buffer.data(), maxCompressedSize, data, dataSize, prefs);
Expand All @@ -142,14 +143,15 @@ class Compressor::CompressorImpl {
return 0;
}
uint32_t zstdCompress(
vector<uint8_t>& buffer,
vector<uninitialized_byte>& buffer,
const void* data,
size_t dataSize,
CompressionPreset preset) {
int compressionLevel = sZstdPresets[preset];
size_t maxCompressedSize = ZSTD_compressBound(dataSize);
// increase our internal buffer size if necessary
if (buffer.size() < maxCompressedSize) {
buffer.resize(0); // avoid copy of current data when resizing
buffer.resize(maxCompressedSize);
}
if (zstdContext_ == nullptr) {
Expand Down Expand Up @@ -265,6 +267,7 @@ int Compressor::startFrame(size_t frameSize, CompressionPreset zstdPreset, uint3
outSize = 0;
size_t minOutSize = ZSTD_CStreamOutSize();
if (buffer_.size() < minOutSize) {
buffer_.resize(0); // avoid copy of current data when resizing
buffer_.resize(minOutSize);
}
return impl_->startFrame(frameSize, zstdPreset);
Expand Down
10 changes: 8 additions & 2 deletions vrs/Compressor.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,16 +140,22 @@ class Compressor {

/// Really deallocate the buffer's memory (clear() doesn't do that)
void clear() {
std::vector<uint8_t> blank;
std::vector<uninitialized_byte> blank;
buffer_.swap(blank);
}

static bool shouldTryToCompress(CompressionPreset preset, size_t size);

struct uninitialized_byte final {
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init, modernize-use-equals-default)
uninitialized_byte() {} // do not use '= default' as it will initialize byte!
uint8_t byte;
};

private:
class CompressorImpl;
std::unique_ptr<CompressorImpl> impl_;
std::vector<uint8_t> buffer_;
std::vector<uninitialized_byte> buffer_;
};

} // namespace vrs

0 comments on commit 0c1948e

Please sign in to comment.