diff --git a/core/io/compression.cpp b/core/io/compression.cpp index 4e4627c40be..79f37db1328 100644 --- a/core/io/compression.cpp +++ b/core/io/compression.cpp @@ -42,6 +42,12 @@ #include #endif +// Caches for zstd. +static BinaryMutex mutex; +static ZSTD_DCtx *current_zstd_d_ctx = nullptr; +static bool current_zstd_long_distance_matching; +static int current_zstd_window_log_size; + int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size, Mode p_mode) { switch (p_mode) { case MODE_BROTLI: { @@ -187,12 +193,22 @@ int Compression::decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p return total; } break; case MODE_ZSTD: { - ZSTD_DCtx *dctx = ZSTD_createDCtx(); - if (zstd_long_distance_matching) { - ZSTD_DCtx_setParameter(dctx, ZSTD_d_windowLogMax, zstd_window_log_size); + MutexLock lock(mutex); + + if (!current_zstd_d_ctx || current_zstd_long_distance_matching != zstd_long_distance_matching || current_zstd_window_log_size != zstd_window_log_size) { + if (current_zstd_d_ctx) { + ZSTD_freeDCtx(current_zstd_d_ctx); + } + + current_zstd_d_ctx = ZSTD_createDCtx(); + if (zstd_long_distance_matching) { + ZSTD_DCtx_setParameter(current_zstd_d_ctx, ZSTD_d_windowLogMax, zstd_window_log_size); + } + current_zstd_long_distance_matching = zstd_long_distance_matching; + current_zstd_window_log_size = zstd_window_log_size; } - int ret = ZSTD_decompressDCtx(dctx, p_dst, p_dst_max_size, p_src, p_src_size); - ZSTD_freeDCtx(dctx); + + int ret = ZSTD_decompressDCtx(current_zstd_d_ctx, p_dst, p_dst_max_size, p_src, p_src_size); return ret; } break; }