haiku/headers/private/package/hpkg/PackageFileHeapWriter.h
Augustin Cavalier f44cb411cc 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>
2024-12-30 19:04:10 +00:00

102 lines
2.3 KiB
C++

/*
* Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#ifndef _PACKAGE__HPKG__PRIVATE__PACKAGE_FILE_HEAP_WRITER_H_
#define _PACKAGE__HPKG__PRIVATE__PACKAGE_FILE_HEAP_WRITER_H_
#include <Array.h>
#include <package/hpkg/PackageFileHeapAccessorBase.h>
class BCompressionParameters;
namespace BPrivate {
template<typename Value> class RangeArray;
}
namespace BPackageKit {
namespace BHPKG {
class BDataReader;
class BErrorOutput;
namespace BPrivate {
class PackageFileHeapReader;
class PackageFileHeapWriter : public PackageFileHeapAccessorBase {
public:
PackageFileHeapWriter(BErrorOutput* errorOutput,
BPositionIO* file, off_t heapOffset,
CompressionAlgorithmOwner*
compressionAlgorithm,
DecompressionAlgorithmOwner*
decompressionAlgorithm);
~PackageFileHeapWriter();
void Init();
void Reinit(PackageFileHeapReader* heapReader);
status_t AddData(BDataReader& dataReader, off_t size,
uint64& _offset);
void AddDataThrows(const void* buffer, size_t size);
void RemoveDataRanges(
const ::BPrivate::RangeArray<uint64>&
ranges);
// doesn't truncate the file
status_t Finish();
protected:
virtual status_t ReadAndDecompressChunk(size_t chunkIndex,
void* compressedDataBuffer,
void* uncompressedDataBuffer,
iovec* scratchBuffer = NULL);
private:
struct Chunk;
struct ChunkSegment;
struct ChunkBuffer;
friend struct ChunkBuffer;
private:
void _Uninit();
status_t _FlushPendingData();
status_t _WriteChunk(const void* data, size_t size,
bool mayCompress);
status_t _WriteDataCompressed(const void* data,
size_t size);
status_t _WriteDataUncompressed(const void* data,
size_t size);
void _PushChunks(ChunkBuffer& chunkBuffer,
uint64 startOffset, uint64 endOffset);
void _UnwriteLastPartialChunk();
private:
void* fPendingDataBuffer;
void* fCompressedDataBuffer;
size_t fPendingDataSize;
Array<uint64> fOffsets;
CompressionAlgorithmOwner* fCompressionAlgorithm;
};
} // namespace BPrivate
} // namespace BHPKG
} // namespace BPackageKit
#endif // _PACKAGE__HPKG__PRIVATE__PACKAGE_FILE_HEAP_WRITER_H_