Reuse allocations for decompression

This commit is contained in:
sfan5 2025-03-05 22:02:16 +01:00
parent 3c08380d18
commit 0a56b18cfb
6 changed files with 23 additions and 33 deletions

View File

@ -56,13 +56,12 @@ void BlockDecoder::decode(const ustring &datastr)
} }
m_version = version; m_version = version;
ustring datastr2;
if (version >= 29) { if (version >= 29) {
// decompress whole block at once // decompress whole block at once
m_zstd_decompressor.setData(data, length, 1); m_zstd_decompressor.setData(data, length, 1);
datastr2 = m_zstd_decompressor.decompress(); m_zstd_decompressor.decompress(m_scratch);
data = datastr2.c_str(); data = m_scratch.c_str();
length = datastr2.size(); length = m_scratch.size();
} }
size_t dataOffset = 0; size_t dataOffset = 0;
@ -115,8 +114,8 @@ void BlockDecoder::decode(const ustring &datastr)
// version < 29 // version < 29
ZlibDecompressor decompressor(data, length); ZlibDecompressor decompressor(data, length);
decompressor.setSeekPos(dataOffset); decompressor.setSeekPos(dataOffset);
m_mapData = decompressor.decompress(); decompressor.decompress(m_mapData);
decompressor.decompress(); // unused metadata decompressor.decompress(m_scratch); // unused metadata
dataOffset = decompressor.seekPos(); dataOffset = decompressor.seekPos();
// Skip unused node timers // Skip unused node timers

View File

@ -23,6 +23,7 @@ private:
u8 m_version, m_contentWidth; u8 m_version, m_contentWidth;
ustring m_mapData; ustring m_mapData;
// one instance for performance // cached allocations/instances for performance
ZstdDecompressor m_zstd_decompressor; ZstdDecompressor m_zstd_decompressor;
ustring m_scratch;
}; };

View File

@ -28,18 +28,13 @@ void ZlibDecompressor::setSeekPos(size_t seekPos)
m_seekPos = seekPos; m_seekPos = seekPos;
} }
size_t ZlibDecompressor::seekPos() const void ZlibDecompressor::decompress(ustring &buffer)
{
return m_seekPos;
}
ustring ZlibDecompressor::decompress()
{ {
const unsigned char *data = m_data + m_seekPos; const unsigned char *data = m_data + m_seekPos;
const size_t size = m_size - m_seekPos; const size_t size = m_size - m_seekPos;
ustring buffer; // output space is extended in chunks of this size
constexpr size_t BUFSIZE = 32 * 1024; constexpr size_t BUFSIZE = 8 * 1024;
z_stream strm; z_stream strm;
strm.zalloc = Z_NULL; strm.zalloc = Z_NULL;
@ -73,7 +68,5 @@ ustring ZlibDecompressor::decompress()
m_seekPos += strm.next_in - data; m_seekPos += strm.next_in - data;
buffer.resize(buffer.size() - strm.avail_out); buffer.resize(buffer.size() - strm.avail_out);
(void) Z(inflateEnd)(&strm); (void) Z(inflateEnd)(&strm);
return buffer;
} }

View File

@ -11,8 +11,10 @@ public:
ZlibDecompressor(const u8 *data, size_t size); ZlibDecompressor(const u8 *data, size_t size);
~ZlibDecompressor(); ~ZlibDecompressor();
void setSeekPos(size_t seekPos); void setSeekPos(size_t seekPos);
size_t seekPos() const; size_t seekPos() const { return m_seekPos; }
ustring decompress(); // Decompress and return one zlib stream from the buffer
// Advances seekPos as appropriate.
void decompress(ustring &dst);
private: private:
const u8 *m_data; const u8 *m_data;

View File

@ -21,18 +21,13 @@ void ZstdDecompressor::setData(const u8 *data, size_t size, size_t seekPos)
m_size = size; m_size = size;
} }
std::size_t ZstdDecompressor::seekPos() const void ZstdDecompressor::decompress(ustring &buffer)
{
return m_seekPos;
}
ustring ZstdDecompressor::decompress()
{ {
ZSTD_DStream *stream = reinterpret_cast<ZSTD_DStream*>(m_stream); ZSTD_DStream *stream = reinterpret_cast<ZSTD_DStream*>(m_stream);
ZSTD_inBuffer inbuf = { m_data, m_size, m_seekPos }; ZSTD_inBuffer inbuf = { m_data, m_size, m_seekPos };
ustring buffer; // output space is extended in chunks of this size
constexpr size_t BUFSIZE = 32 * 1024; constexpr size_t BUFSIZE = 8 * 1024;
buffer.resize(BUFSIZE); buffer.resize(BUFSIZE);
ZSTD_outBuffer outbuf = { &buffer[0], buffer.size(), 0 }; ZSTD_outBuffer outbuf = { &buffer[0], buffer.size(), 0 };
@ -42,17 +37,15 @@ ustring ZstdDecompressor::decompress()
size_t ret; size_t ret;
do { do {
ret = ZSTD_decompressStream(stream, &outbuf, &inbuf); ret = ZSTD_decompressStream(stream, &outbuf, &inbuf);
if (ret && ZSTD_isError(ret))
throw DecompressError();
if (outbuf.size == outbuf.pos) { if (outbuf.size == outbuf.pos) {
outbuf.size += BUFSIZE; outbuf.size += BUFSIZE;
buffer.resize(outbuf.size); buffer.resize(outbuf.size);
outbuf.dst = &buffer[0]; outbuf.dst = &buffer[0];
} }
if (ret && ZSTD_isError(ret))
throw DecompressError();
} while (ret != 0); } while (ret != 0);
m_seekPos = inbuf.pos; m_seekPos = inbuf.pos;
buffer.resize(outbuf.pos); buffer.resize(outbuf.pos);
return buffer;
} }

View File

@ -11,8 +11,10 @@ public:
ZstdDecompressor(); ZstdDecompressor();
~ZstdDecompressor(); ~ZstdDecompressor();
void setData(const u8 *data, size_t size, size_t seekPos); void setData(const u8 *data, size_t size, size_t seekPos);
size_t seekPos() const; size_t seekPos() const { return m_seekPos; }
ustring decompress(); // Decompress and return one zstd stream from the buffer
// Advances seekPos as appropriate.
void decompress(ustring &dst);
private: private:
void *m_stream; // ZSTD_DStream void *m_stream; // ZSTD_DStream