From f44cb411cc41071158824356be5f6a8d6bc49f82 Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Thu, 26 Dec 2024 21:33:35 -0500 Subject: [PATCH] Package Kit & packagefs: Allocate scratch buffers for decompression further up. Zstd wants a ~90 KB scratch buffer to decompress our 64 KB chunks. Rather than let it allocate that itself every time, pass in a 2*64KB "scratch" buffer and statically allocate the working memory from it. Pass it down using iovecs, and pass down the other buffers in the same way, to reduce parameters. Further, rework the object_cache used for heap decompression buffers to contain objects sized as 4x64KB, so we only need to do one allocation and deallocation for the compression/decompression and scratch buffers. Set the minimum reserve to 1 so that the low-memory manager doesn't reclaim this, as we'll need it when reading back data. Improves packagefs I/O performance (and thus boot speeds at least a bit, it appears.) Change-Id: Id51f6f598b33b9d757a283184c533bb97049529f Reviewed-on: https://review.haiku-os.org/c/haiku/+/8717 Reviewed-by: waddlesplash Tested-by: Commit checker robot --- .../hpkg/PackageFileHeapAccessorBase.h | 14 ++--- .../package/hpkg/PackageFileHeapReader.h | 3 +- .../package/hpkg/PackageFileHeapWriter.h | 3 +- .../private/support/CompressionAlgorithm.h | 18 +++--- .../support/ZlibCompressionAlgorithm.h | 17 ++---- .../support/ZstdCompressionAlgorithm.h | 17 ++---- .../kernel/file_systems/packagefs/Jamfile | 2 +- .../packagefs/kernel_interface.cpp | 14 +++-- .../hpkg/PackageFileHeapAccessorBase.cpp | 59 ++++++++++--------- .../package/hpkg/PackageFileHeapReader.cpp | 5 +- .../package/hpkg/PackageFileHeapWriter.cpp | 22 +++---- .../package/hpkg/v1/PackageDataReaderV1.cpp | 11 ++-- src/kits/support/CompressionAlgorithm.cpp | 10 ++-- src/kits/support/ZlibCompressionAlgorithm.cpp | 26 ++++---- src/kits/support/ZstdCompressionAlgorithm.cpp | 34 +++++++---- 15 files changed, 128 insertions(+), 127 deletions(-) diff --git a/headers/private/package/hpkg/PackageFileHeapAccessorBase.h b/headers/private/package/hpkg/PackageFileHeapAccessorBase.h index 62817e2e01..904778c8f2 100644 --- a/headers/private/package/hpkg/PackageFileHeapAccessorBase.h +++ b/headers/private/package/hpkg/PackageFileHeapAccessorBase.h @@ -99,23 +99,23 @@ public: public: static const size_t kChunkSize = 64 * 1024; #if defined(_KERNEL_MODE) - static void* sChunkCache; + static void* sQuadChunkCache; #endif protected: virtual status_t ReadAndDecompressChunk(size_t chunkIndex, void* compressedDataBuffer, - void* uncompressedDataBuffer) = 0; + void* uncompressedDataBuffer, + iovec* scratchBuffer = NULL) = 0; status_t ReadAndDecompressChunkData(uint64 offset, size_t compressedSize, size_t uncompressedSize, void* compressedDataBuffer, - void* uncompressedDataBuffer); - status_t DecompressChunkData( - void* compressedDataBuffer, - size_t compressedSize, void* uncompressedDataBuffer, - size_t uncompressedSize); + iovec* scratchBuffer = NULL); + status_t DecompressChunkData(const iovec& compressedBuffer, + iovec& uncompressedBuffer, + iovec* scratchBuffer = NULL); status_t ReadFileData(uint64 offset, void* buffer, size_t size); diff --git a/headers/private/package/hpkg/PackageFileHeapReader.h b/headers/private/package/hpkg/PackageFileHeapReader.h index 00206eff3d..650af43096 100644 --- a/headers/private/package/hpkg/PackageFileHeapReader.h +++ b/headers/private/package/hpkg/PackageFileHeapReader.h @@ -42,7 +42,8 @@ public: protected: virtual status_t ReadAndDecompressChunk(size_t chunkIndex, void* compressedDataBuffer, - void* uncompressedDataBuffer); + void* uncompressedDataBuffer, + iovec* scratchBuffer = NULL); private: OffsetArray fOffsets; diff --git a/headers/private/package/hpkg/PackageFileHeapWriter.h b/headers/private/package/hpkg/PackageFileHeapWriter.h index 49588f1686..0bc8fbd051 100644 --- a/headers/private/package/hpkg/PackageFileHeapWriter.h +++ b/headers/private/package/hpkg/PackageFileHeapWriter.h @@ -57,7 +57,8 @@ public: protected: virtual status_t ReadAndDecompressChunk(size_t chunkIndex, void* compressedDataBuffer, - void* uncompressedDataBuffer); + void* uncompressedDataBuffer, + iovec* scratchBuffer = NULL); private: struct Chunk; diff --git a/headers/private/support/CompressionAlgorithm.h b/headers/private/support/CompressionAlgorithm.h index f2ca69c74d..fdd5a98937 100644 --- a/headers/private/support/CompressionAlgorithm.h +++ b/headers/private/support/CompressionAlgorithm.h @@ -7,6 +7,7 @@ #include +#include class BCompressionParameters { @@ -41,17 +42,12 @@ public: const BDecompressionParameters* parameters, BDataIO*& _stream); - virtual status_t CompressBuffer(const void* input, - size_t inputSize, void* output, - size_t outputSize, size_t& _compressedSize, - const BCompressionParameters* parameters - = NULL); - virtual status_t DecompressBuffer(const void* input, - size_t inputSize, void* output, - size_t outputSize, - size_t& _uncompressedSize, - const BDecompressionParameters* parameters - = NULL); + virtual status_t CompressBuffer(const iovec& input, iovec& output, + const BCompressionParameters* parameters = NULL, + iovec* scratch = NULL); + virtual status_t DecompressBuffer(const iovec& input, iovec& output, + const BDecompressionParameters* parameters = NULL, + iovec* scratch = NULL); protected: class BAbstractStream; diff --git a/headers/private/support/ZlibCompressionAlgorithm.h b/headers/private/support/ZlibCompressionAlgorithm.h index df9ddae54f..f99407bc13 100644 --- a/headers/private/support/ZlibCompressionAlgorithm.h +++ b/headers/private/support/ZlibCompressionAlgorithm.h @@ -73,17 +73,12 @@ public: const BDecompressionParameters* parameters, BDataIO*& _stream); - virtual status_t CompressBuffer(const void* input, - size_t inputSize, void* output, - size_t outputSize, size_t& _compressedSize, - const BCompressionParameters* parameters - = NULL); - virtual status_t DecompressBuffer(const void* input, - size_t inputSize, void* output, - size_t outputSize, - size_t& _uncompressedSize, - const BDecompressionParameters* parameters - = NULL); + virtual status_t CompressBuffer(const iovec& input, iovec& output, + const BCompressionParameters* parameters = NULL, + iovec* scratch = NULL); + virtual status_t DecompressBuffer(const iovec& input, iovec& output, + const BDecompressionParameters* parameters = NULL, + iovec* scratch = NULL); private: struct CompressionStrategy; diff --git a/headers/private/support/ZstdCompressionAlgorithm.h b/headers/private/support/ZstdCompressionAlgorithm.h index 207462188f..c43a442acc 100644 --- a/headers/private/support/ZstdCompressionAlgorithm.h +++ b/headers/private/support/ZstdCompressionAlgorithm.h @@ -69,17 +69,12 @@ public: const BDecompressionParameters* parameters, BDataIO*& _stream); - virtual status_t CompressBuffer(const void* input, - size_t inputSize, void* output, - size_t outputSize, size_t& _compressedSize, - const BCompressionParameters* parameters - = NULL); - virtual status_t DecompressBuffer(const void* input, - size_t inputSize, void* output, - size_t outputSize, - size_t& _uncompressedSize, - const BDecompressionParameters* parameters - = NULL); + virtual status_t CompressBuffer(const iovec& input, iovec& output, + const BCompressionParameters* parameters = NULL, + iovec* scratch = NULL); + virtual status_t DecompressBuffer(const iovec& input, iovec& output, + const BDecompressionParameters* parameters = NULL, + iovec* scratch = NULL); private: struct CompressionStrategy; diff --git a/src/add-ons/kernel/file_systems/packagefs/Jamfile b/src/add-ons/kernel/file_systems/packagefs/Jamfile index 7122663e2b..bfff8a7dcf 100644 --- a/src/add-ons/kernel/file_systems/packagefs/Jamfile +++ b/src/add-ons/kernel/file_systems/packagefs/Jamfile @@ -12,7 +12,7 @@ if [ FIsBuildFeatureEnabled zstd ] { UseBuildFeatureHeaders zstd ; Includes [ FGristFiles $(zstdSources) ] : [ BuildFeatureAttribute zstd : headers ] ; - SubDirC++Flags -DZSTD_ENABLED ; + SubDirC++Flags -DZSTD_ENABLED -DZSTD_STATIC_LINKING_ONLY ; } local subDirs = diff --git a/src/add-ons/kernel/file_systems/packagefs/kernel_interface.cpp b/src/add-ons/kernel/file_systems/packagefs/kernel_interface.cpp index 124bc937ed..8c50f5644e 100644 --- a/src/add-ons/kernel/file_systems/packagefs/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/kernel_interface.cpp @@ -1144,11 +1144,13 @@ packagefs_std_ops(int32 op, ...) return error; } - PackageFileHeapAccessorBase::sChunkCache = - create_object_cache_etc("pkgfs heap buffers", - PackageFileHeapAccessorBase::kChunkSize, sizeof(void*), - 0, /* magazine capacity, count */ 2, 1, - 0, NULL, NULL, NULL, NULL); + object_cache* quadChunkCache; + PackageFileHeapAccessorBase::sQuadChunkCache = quadChunkCache = + create_object_cache("pkgfs heap buffers", + PackageFileHeapAccessorBase::kChunkSize * 4, + 0, NULL, NULL, NULL); + object_cache_set_minimum_reserve(quadChunkCache, 1); + TwoKeyAVLTreeNode::sNodeCache = create_object_cache_etc("pkgfs TKAVLTreeNodes", sizeof(TwoKeyAVLTreeNode), 8, @@ -1172,7 +1174,7 @@ packagefs_std_ops(int32 op, ...) PackageFSRoot::GlobalUninit(); delete_object_cache(TwoKeyAVLTreeNode::sNodeCache); delete_object_cache((object_cache*) - PackageFileHeapAccessorBase::sChunkCache); + PackageFileHeapAccessorBase::sQuadChunkCache); StringConstants::Cleanup(); StringPool::Cleanup(); exit_debugging(); diff --git a/src/kits/package/hpkg/PackageFileHeapAccessorBase.cpp b/src/kits/package/hpkg/PackageFileHeapAccessorBase.cpp index 46c091d056..e0c6d3f6bd 100644 --- a/src/kits/package/hpkg/PackageFileHeapAccessorBase.cpp +++ b/src/kits/package/hpkg/PackageFileHeapAccessorBase.cpp @@ -31,7 +31,7 @@ namespace BPrivate { #if defined(_KERNEL_MODE) -void* PackageFileHeapAccessorBase::sChunkCache = NULL; +void* PackageFileHeapAccessorBase::sQuadChunkCache = NULL; #endif @@ -218,7 +218,7 @@ PackageFileHeapAccessorBase::ReadDataToOutput(off_t offset, size_t size, // allocate buffers for compressed and uncompressed data uint16* compressedDataBuffer, *uncompressedDataBuffer; - MemoryDeleter compressedMemoryDeleter, uncompressedMemoryDeleter; + iovec* scratch = NULL; #if defined(_KERNEL_MODE) && !defined(_BOOT_MODE) struct ObjectCacheDeleter { @@ -238,21 +238,24 @@ PackageFileHeapAccessorBase::ReadDataToOutput(off_t offset, size_t size, } }; - ObjectCacheDeleter compressedCacheDeleter((object_cache*)sChunkCache), - uncompressedCacheDeleter((object_cache*)sChunkCache); - if (sChunkCache != NULL) { - compressedDataBuffer = (uint16*)object_cache_alloc((object_cache*)sChunkCache, 0); - uncompressedDataBuffer = (uint16*)object_cache_alloc((object_cache*)sChunkCache, 0); - compressedCacheDeleter.object = compressedDataBuffer; - uncompressedCacheDeleter.object = uncompressedDataBuffer; - } else + ObjectCacheDeleter chunkBufferDeleter((object_cache*)sQuadChunkCache); + uint8* quadChunkBuffer = (uint8*)object_cache_alloc((object_cache*)sQuadChunkCache, 0); + chunkBufferDeleter.object = quadChunkBuffer; + + // segment data buffer + iovec localScratch; + compressedDataBuffer = (uint16*)(quadChunkBuffer + 0); + uncompressedDataBuffer = (uint16*)(quadChunkBuffer + kChunkSize); + localScratch.iov_base = (quadChunkBuffer + (kChunkSize * 2)); + localScratch.iov_len = kChunkSize * 2; + scratch = &localScratch; +#else + MemoryDeleter compressedMemoryDeleter, uncompressedMemoryDeleter; + compressedDataBuffer = (uint16*)malloc(kChunkSize); + uncompressedDataBuffer = (uint16*)malloc(kChunkSize); + compressedMemoryDeleter.SetTo(compressedDataBuffer); + uncompressedMemoryDeleter.SetTo(uncompressedDataBuffer); #endif - { - compressedDataBuffer = (uint16*)malloc(kChunkSize); - uncompressedDataBuffer = (uint16*)malloc(kChunkSize); - compressedMemoryDeleter.SetTo(compressedDataBuffer); - uncompressedMemoryDeleter.SetTo(uncompressedDataBuffer); - } if (compressedDataBuffer == NULL || uncompressedDataBuffer == NULL) return B_NO_MEMORY; @@ -264,7 +267,7 @@ PackageFileHeapAccessorBase::ReadDataToOutput(off_t offset, size_t size, while (remainingBytes > 0) { status_t error = ReadAndDecompressChunk(chunkIndex, - compressedDataBuffer, uncompressedDataBuffer); + compressedDataBuffer, uncompressedDataBuffer, scratch); if (error != B_OK) return error; @@ -289,8 +292,9 @@ PackageFileHeapAccessorBase::ReadDataToOutput(off_t offset, size_t size, status_t PackageFileHeapAccessorBase::ReadAndDecompressChunkData(uint64 offset, - size_t compressedSize, size_t uncompressedSize, void* compressedDataBuffer, - void* uncompressedDataBuffer) + size_t compressedSize, size_t uncompressedSize, + void* compressedDataBuffer, void* uncompressedDataBuffer, + iovec* scratchBuffer) { // if uncompressed, read directly into the uncompressed data buffer if (compressedSize == uncompressedSize) @@ -301,27 +305,26 @@ PackageFileHeapAccessorBase::ReadAndDecompressChunkData(uint64 offset, if (error != B_OK) return error; - return DecompressChunkData(compressedDataBuffer, compressedSize, - uncompressedDataBuffer, uncompressedSize); + iovec compressed = { compressedDataBuffer, compressedSize }, + uncompressed = { uncompressedDataBuffer, uncompressedSize }; + return DecompressChunkData(compressed, uncompressed, scratchBuffer); } status_t -PackageFileHeapAccessorBase::DecompressChunkData(void* compressedDataBuffer, - size_t compressedSize, void* uncompressedDataBuffer, - size_t uncompressedSize) +PackageFileHeapAccessorBase::DecompressChunkData(const iovec& compressed, + iovec& uncompressed, iovec* scratchBuffer) { - size_t actualSize; + const size_t uncompressedSize = uncompressed.iov_len; status_t error = fDecompressionAlgorithm->algorithm->DecompressBuffer( - compressedDataBuffer, compressedSize, uncompressedDataBuffer, - uncompressedSize, actualSize, fDecompressionAlgorithm->parameters); + compressed, uncompressed, fDecompressionAlgorithm->parameters, scratchBuffer); if (error != B_OK) { fErrorOutput->PrintError("Failed to decompress chunk data: %s\n", strerror(error)); return error; } - if (actualSize != uncompressedSize) { + if (uncompressed.iov_len != uncompressedSize) { fErrorOutput->PrintError("Failed to decompress chunk data: size " "mismatch\n"); return B_ERROR; diff --git a/src/kits/package/hpkg/PackageFileHeapReader.cpp b/src/kits/package/hpkg/PackageFileHeapReader.cpp index 796e51e1a4..5bbeeb0ff7 100644 --- a/src/kits/package/hpkg/PackageFileHeapReader.cpp +++ b/src/kits/package/hpkg/PackageFileHeapReader.cpp @@ -153,7 +153,8 @@ PackageFileHeapReader::Clone() const status_t PackageFileHeapReader::ReadAndDecompressChunk(size_t chunkIndex, - void* compressedDataBuffer, void* uncompressedDataBuffer) + void* compressedDataBuffer, void* uncompressedDataBuffer, + iovec* scratchBuffer) { uint64 offset = fOffsets[chunkIndex]; bool isLastChunk @@ -166,7 +167,7 @@ PackageFileHeapReader::ReadAndDecompressChunk(size_t chunkIndex, : kChunkSize; return ReadAndDecompressChunkData(offset, compressedSize, uncompressedSize, - compressedDataBuffer, uncompressedDataBuffer); + compressedDataBuffer, uncompressedDataBuffer, scratchBuffer); } diff --git a/src/kits/package/hpkg/PackageFileHeapWriter.cpp b/src/kits/package/hpkg/PackageFileHeapWriter.cpp index a86510784c..e5ac8991c3 100644 --- a/src/kits/package/hpkg/PackageFileHeapWriter.cpp +++ b/src/kits/package/hpkg/PackageFileHeapWriter.cpp @@ -409,9 +409,9 @@ PackageFileHeapWriter::RemoveDataRanges( } else if (decompressedChunk == &chunk) { uncompressedData = decompressionBuffer; } else { - status_t error = DecompressChunkData(chunk.buffer, - chunk.compressedSize, decompressionBuffer, - chunk.uncompressedSize); + iovec compressed = { chunk.buffer, chunk.compressedSize }, + uncompressed = { decompressionBuffer, chunk.uncompressedSize }; + status_t error = DecompressChunkData(compressed, uncompressed); if (error != B_OK) throw error; @@ -479,7 +479,8 @@ PackageFileHeapWriter::Finish() status_t PackageFileHeapWriter::ReadAndDecompressChunk(size_t chunkIndex, - void* compressedDataBuffer, void* uncompressedDataBuffer) + void* compressedDataBuffer, void* uncompressedDataBuffer, + iovec* scratchBuffer) { if (uint64(chunkIndex + 1) * kChunkSize > fUncompressedHeapSize) { // The chunk has not been written to disk yet. Its data are still in the @@ -496,7 +497,7 @@ PackageFileHeapWriter::ReadAndDecompressChunk(size_t chunkIndex, : fOffsets[chunkIndex + 1] - offset; return ReadAndDecompressChunkData(offset, compressedSize, kChunkSize, - compressedDataBuffer, uncompressedDataBuffer); + compressedDataBuffer, uncompressedDataBuffer, scratchBuffer); } @@ -562,9 +563,10 @@ PackageFileHeapWriter::_WriteDataCompressed(const void* data, size_t size) if (fCompressionAlgorithm == NULL) return B_BUFFER_OVERFLOW; - size_t compressedSize; - status_t error = fCompressionAlgorithm->algorithm->CompressBuffer(data, - size, fCompressedDataBuffer, size, compressedSize, + const iovec uncompressed = { (void*)data, size }; + iovec compressed = { fCompressedDataBuffer, size }; + status_t error = fCompressionAlgorithm->algorithm->CompressBuffer( + uncompressed, compressed, fCompressionAlgorithm->parameters); if (error != B_OK) { if (error != B_BUFFER_OVERFLOW) { @@ -575,10 +577,10 @@ PackageFileHeapWriter::_WriteDataCompressed(const void* data, size_t size) } // only use compressed data when we've actually saved space - if (compressedSize == size) + if (compressed.iov_len == size) return B_BUFFER_OVERFLOW; - return _WriteDataUncompressed(fCompressedDataBuffer, compressedSize); + return _WriteDataUncompressed(fCompressedDataBuffer, compressed.iov_len); } diff --git a/src/kits/package/hpkg/v1/PackageDataReaderV1.cpp b/src/kits/package/hpkg/v1/PackageDataReaderV1.cpp index 8b21446b5c..63d1bd6f42 100644 --- a/src/kits/package/hpkg/v1/PackageDataReaderV1.cpp +++ b/src/kits/package/hpkg/v1/PackageDataReaderV1.cpp @@ -293,12 +293,11 @@ private: if (error != B_OK) return error; - size_t actuallyUncompressedSize; - BZlibCompressionAlgorithm().DecompressBuffer( - readBuffer->Buffer(), compressedSize, - fUncompressBuffer->Buffer(), uncompressedSize, - actuallyUncompressedSize); - if (error == B_OK && actuallyUncompressedSize != uncompressedSize) + iovec compressed = { readBuffer->Buffer(), compressedSize }, + uncompressed = { fUncompressBuffer->Buffer(), uncompressedSize }; + error = BZlibCompressionAlgorithm().DecompressBuffer( + compressed, uncompressed); + if (error == B_OK && uncompressed.iov_len != uncompressedSize) error = B_BAD_DATA; } diff --git a/src/kits/support/CompressionAlgorithm.cpp b/src/kits/support/CompressionAlgorithm.cpp index ab7eb2cfff..e10d5e4e6a 100644 --- a/src/kits/support/CompressionAlgorithm.cpp +++ b/src/kits/support/CompressionAlgorithm.cpp @@ -84,18 +84,16 @@ BCompressionAlgorithm::CreateDecompressingOutputStream(BDataIO* output, status_t -BCompressionAlgorithm::CompressBuffer(const void* input, size_t inputSize, - void* output, size_t outputSize, size_t& _compressedSize, - const BCompressionParameters* parameters) +BCompressionAlgorithm::CompressBuffer(const iovec& input, iovec& output, + const BCompressionParameters* parameters, iovec* scratch) { return B_NOT_SUPPORTED; } status_t -BCompressionAlgorithm::DecompressBuffer(const void* input, - size_t inputSize, void* output, size_t outputSize, - size_t& _uncompressedSize, const BDecompressionParameters* parameters) +BCompressionAlgorithm::DecompressBuffer(const iovec& input, iovec& output, + const BDecompressionParameters* parameters, iovec* scratch) { return B_NOT_SUPPORTED; } diff --git a/src/kits/support/ZlibCompressionAlgorithm.cpp b/src/kits/support/ZlibCompressionAlgorithm.cpp index f49a781a25..05694e9348 100644 --- a/src/kits/support/ZlibCompressionAlgorithm.cpp +++ b/src/kits/support/ZlibCompressionAlgorithm.cpp @@ -366,9 +366,8 @@ BZlibCompressionAlgorithm::CreateDecompressingOutputStream(BDataIO* output, status_t -BZlibCompressionAlgorithm::CompressBuffer(const void* input, - size_t inputSize, void* output, size_t outputSize, size_t& _compressedSize, - const BCompressionParameters* parameters) +BZlibCompressionAlgorithm::CompressBuffer(const iovec& input, iovec& output, + const BCompressionParameters* parameters, iovec* scratch) { #ifdef B_ZLIB_COMPRESSION_SUPPORT const BZlibCompressionParameters* zlibParameters @@ -377,13 +376,13 @@ BZlibCompressionAlgorithm::CompressBuffer(const void* input, ? zlibParameters->CompressionLevel() : B_ZLIB_COMPRESSION_DEFAULT; - uLongf bytesUsed = outputSize; - int zlibError = compress2((Bytef*)output, &bytesUsed, (const Bytef*)input, - (uLong)inputSize, compressionLevel); + uLongf bytesUsed = output.iov_len; + int zlibError = compress2((Bytef*)output.iov_base, &bytesUsed, + (const Bytef*)input.iov_base, (uLong)input.iov_len, compressionLevel); if (zlibError != Z_OK) return _TranslateZlibError(zlibError); - _compressedSize = (size_t)bytesUsed; + output.iov_len = (size_t)bytesUsed; return B_OK; #else return B_NOT_SUPPORTED; @@ -392,17 +391,16 @@ BZlibCompressionAlgorithm::CompressBuffer(const void* input, status_t -BZlibCompressionAlgorithm::DecompressBuffer(const void* input, - size_t inputSize, void* output, size_t outputSize, - size_t& _uncompressedSize, const BDecompressionParameters* parameters) +BZlibCompressionAlgorithm::DecompressBuffer(const iovec& input, iovec& output, + const BDecompressionParameters* parameters, iovec* scratch) { - uLongf bytesUsed = outputSize; - int zlibError = uncompress((Bytef*)output, &bytesUsed, (const Bytef*)input, - (uLong)inputSize); + uLongf bytesUsed = output.iov_len; + int zlibError = uncompress((Bytef*)output.iov_base, &bytesUsed, + (const Bytef*)input.iov_base, (uLong)input.iov_len); if (zlibError != Z_OK) return _TranslateZlibError(zlibError); - _uncompressedSize = (size_t)bytesUsed; + output.iov_len = (size_t)bytesUsed; return B_OK; } diff --git a/src/kits/support/ZstdCompressionAlgorithm.cpp b/src/kits/support/ZstdCompressionAlgorithm.cpp index 5b6a1a2245..e3f3ee0312 100644 --- a/src/kits/support/ZstdCompressionAlgorithm.cpp +++ b/src/kits/support/ZstdCompressionAlgorithm.cpp @@ -18,6 +18,7 @@ #include #endif +#include #include @@ -367,23 +368,23 @@ BZstdCompressionAlgorithm::CreateDecompressingOutputStream(BDataIO* output, status_t -BZstdCompressionAlgorithm::CompressBuffer(const void* input, - size_t inputSize, void* output, size_t outputSize, size_t& _compressedSize, - const BCompressionParameters* parameters) +BZstdCompressionAlgorithm::CompressBuffer(const iovec& input, iovec& output, + const BCompressionParameters* parameters, iovec* scratch) { #ifdef B_ZSTD_COMPRESSION_SUPPORT + // TODO: Make use of scratch buffer (if available.) const BZstdCompressionParameters* zstdParameters = dynamic_cast(parameters); int compressionLevel = zstdParameters != NULL ? zstdParameters->CompressionLevel() : B_ZSTD_COMPRESSION_DEFAULT; - size_t zstdError = ZSTD_compress(output, outputSize, input, - inputSize, compressionLevel); + size_t zstdError = ZSTD_compress(output.iov_base, output.iov_len, + input.iov_base, input.iov_len, compressionLevel); if (ZSTD_isError(zstdError)) return _TranslateZstdError(zstdError); - _compressedSize = zstdError; + output.iov_len = zstdError; return B_OK; #else return B_NOT_SUPPORTED; @@ -392,17 +393,26 @@ BZstdCompressionAlgorithm::CompressBuffer(const void* input, status_t -BZstdCompressionAlgorithm::DecompressBuffer(const void* input, - size_t inputSize, void* output, size_t outputSize, - size_t& _uncompressedSize, const BDecompressionParameters* parameters) +BZstdCompressionAlgorithm::DecompressBuffer(const iovec& input, iovec& output, + const BDecompressionParameters* parameters, iovec* scratch) { #ifdef ZSTD_ENABLED - size_t zstdError = ZSTD_decompress(output, outputSize, input, - inputSize); + ZSTD_DCtx* dctx; + CObjectDeleter dctxDeleter; +#if defined(ZSTD_STATIC_LINKING_ONLY) + if (scratch != NULL) + dctx = ZSTD_initStaticDCtx(scratch->iov_base, scratch->iov_len); + else +#endif + dctxDeleter.SetTo(dctx = ZSTD_createDCtx()); + + size_t zstdError = ZSTD_decompressDCtx(dctx, + output.iov_base, output.iov_len, + input.iov_base, input.iov_len); if (ZSTD_isError(zstdError)) return _TranslateZstdError(zstdError); - _uncompressedSize = zstdError; + output.iov_len = zstdError; return B_OK; #else return B_NOT_SUPPORTED;