From 29d5ddb94e8b1f729d90211a3801a286f658a4db Mon Sep 17 00:00:00 2001 From: Andrea Bocci Date: Sat, 17 Oct 2026 23:03:45 +0200 Subject: [PATCH] [core] Use the lz4 tool compression levels for LZ4 Use the same compression levels as the lz4 command line tool: level 1 is the fast compressor, level 2 is the medium compressor added in LZ4 1.10.0 (or the fast compressor with older versions), and higher levels use the high-compression (HC) compressor with the given level. With older LZ4 versions level 2 keeps using the fast compressor, as the lz4 tool does. The on-disk format does not change. --- README/ReleaseNotes/v642/index.md | 1 + core/lz4/src/ZipLZ4.cxx | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/README/ReleaseNotes/v642/index.md b/README/ReleaseNotes/v642/index.md index 0cde4d2caf113..2f403975f72a5 100644 --- a/README/ReleaseNotes/v642/index.md +++ b/README/ReleaseNotes/v642/index.md @@ -152,6 +152,7 @@ Replace `obj.Connect(signal, "TPyDispatcher", disp, "Dispatch()")` with ## I/O * Reading a collection without its dictionary no longer crashes when the elements hold a `std::string` or a `TString`. The emulated collection proxy relocated its elements with a raw memory copy when its buffer had to grow, which corrupts an object that points into itself, such as a `std::string` using the small string optimization; the invalid pointer was then freed when the object was destroyed. Such elements are now destroyed and reconstructed at the new location instead. This affected for instance a `std::vector>` read back without a dictionary. +* The LZ4 compression levels now follow those of the `lz4` command line tool. Level 1 uses the fast compressor as before. Level 2 uses the faster high-compression mode introduced in LZ4 1.10.0, or the fast compressor with older LZ4 versions. Level 3 now uses the high-compression (HC) compressor, like levels 4 to 9. Previously, levels 1 to 3 all used the fast compressor and produced identical output. Files written with levels 2 and 3 can be read by older ROOT versions, since the on-disk format is unchanged. ## Core diff --git a/core/lz4/src/ZipLZ4.cxx b/core/lz4/src/ZipLZ4.cxx index 9096507489c1d..8f0c3a7aaeeaf 100644 --- a/core/lz4/src/ZipLZ4.cxx +++ b/core/lz4/src/ZipLZ4.cxx @@ -77,7 +77,11 @@ void R__zipLZ4(int cxlevel, int *srcsize, const char *src, int *tgtsize, char *t if (cxlevel > 9) { cxlevel = 9; } - if (cxlevel >= 4) { + // Use the same compression levels as the lz4 command line tool: level 1 is the fast compressor, level 2 is the + // "medium" compressor added in LZ4 1.10.0 (or the fast compressor with older versions), and higher levels use + // the high-compression (HC) compressor with the given level. + const int minHCLevel = (LZ4_version >= 11000) ? 2 : 3; + if (cxlevel >= minHCLevel) { returnStatus = LZ4_compress_HC(src, &tgt[kHeaderSize], *srcsize, *tgtsize - kHeaderSize, cxlevel); } else { returnStatus = LZ4_compress_default(src, &tgt[kHeaderSize], *srcsize, *tgtsize - kHeaderSize);