mirror of
https://review.haiku-os.org/haiku
synced 2025-01-18 12:38:51 +01:00
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 <waddlesplash@gmail.com> Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
This commit is contained in:
parent
7651b97c0a
commit
f44cb411cc
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
|
||||
#include <DataIO.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
|
||||
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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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 =
|
||||
|
@ -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<void*>::sNodeCache =
|
||||
create_object_cache_etc("pkgfs TKAVLTreeNodes",
|
||||
sizeof(TwoKeyAVLTreeNode<void*>), 8,
|
||||
@ -1172,7 +1174,7 @@ packagefs_std_ops(int32 op, ...)
|
||||
PackageFSRoot::GlobalUninit();
|
||||
delete_object_cache(TwoKeyAVLTreeNode<void*>::sNodeCache);
|
||||
delete_object_cache((object_cache*)
|
||||
PackageFileHeapAccessorBase::sChunkCache);
|
||||
PackageFileHeapAccessorBase::sQuadChunkCache);
|
||||
StringConstants::Cleanup();
|
||||
StringPool::Cleanup();
|
||||
exit_debugging();
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <zstd_errors.h>
|
||||
#endif
|
||||
|
||||
#include <AutoDeleter.h>
|
||||
#include <DataIO.h>
|
||||
|
||||
|
||||
@ -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<const BZstdCompressionParameters*>(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<ZSTD_DCtx, size_t, ZSTD_freeDCtx> 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;
|
||||
|
Loading…
Reference in New Issue
Block a user