-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Add support for LZ4 #590
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for LZ4 #590
Changes from all commits
f950632
0ce7cdf
5324ee6
3542706
bfc45da
556238d
95f4378
08bbf46
ba6e454
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| # Find the LZ4 includes and library. | ||
| # | ||
| # This module defines | ||
| # LZ4_INCLUDE_DIR, where to locate LZ4 header files | ||
| # LZ4_LIBRARIES, the libraries to link against to use LZ4 | ||
| # LZ4_FOUND. If false, you cannot build anything that requires LZ4. | ||
|
|
||
| if(LZ4_CONFIG_EXECUTABLE) | ||
| set(LZ4_FIND_QUIETLY 1) | ||
| endif() | ||
| set(LZ4_FOUND 0) | ||
|
|
||
| find_path(LZ4_INCLUDE_DIR lz4.h | ||
| $ENV{LZ4_DIR}/include | ||
| /usr/local/include | ||
| /opt/lz4/include | ||
| DOC "Specify the directory containing lz4.h" | ||
| ) | ||
|
|
||
| find_library(LZ4_LIBRARY NAMES lz4 PATHS | ||
| $ENV{LZ4_DIR}/lib | ||
| /usr/local/lz4/lib | ||
| /usr/local/lib | ||
| /usr/lib/lz4 | ||
| /usr/local/lib/lz4 | ||
| /usr/lz4/lib /usr/lib | ||
| /usr/lz4 /usr/local/lz4 | ||
| /opt/lz4 /opt/lz4/lib | ||
| DOC "Specify the lz4 library here." | ||
| ) | ||
|
|
||
| if(LZ4_INCLUDE_DIR AND LZ4_LIBRARY) | ||
| set(LZ4_FOUND 1) | ||
| if(NOT LZ4_FIND_QUIETLY) | ||
| message(STATUS "Found LZ4 includes at ${LZ4_INCLUDE_DIR}") | ||
| message(STATUS "Found LZ4 library at ${LZ4_LIBRARY}") | ||
| endif() | ||
| endif() | ||
|
|
||
| set(LZ4_LIBRARIES ${LZ4_LIBRARY}) | ||
| mark_as_advanced(LZ4_FOUND LZ4_LIBRARY LZ4_INCLUDE_DIR) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| ############################################################################ | ||
| # CMakeLists.txt file for building ROOT core/lz4 package | ||
| ############################################################################ | ||
|
|
||
|
|
||
| #---The builtin LZ4 library is built using the CMake ExternalProject standard module | ||
| # in cmake/modules/SearchInstalledSoftare.cmake | ||
|
|
||
| #---Declare ZipLZ4 sources as part of libCore------------------------------- | ||
| set(headers ${CMAKE_CURRENT_SOURCE_DIR}/inc/ZipLZ4.h) | ||
| set(sources ${CMAKE_CURRENT_SOURCE_DIR}/src/ZipLZ4.c) | ||
|
|
||
|
|
||
| include_directories(${LZ4_INCLUDE_DIR}) | ||
| ROOT_OBJECT_LIBRARY(Lz4 ${sources}) | ||
|
|
||
| if(builtin_lz4) | ||
| add_dependencies(Lz4 LZ4) | ||
| endif() | ||
|
|
||
| ROOT_INSTALL_HEADERS() | ||
| install(FILES ${LZ4_headers} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| // Author: Brian Bockelman March 2015 | ||
|
|
||
| /************************************************************************* | ||
| * Copyright (C) 1995-2017, Rene Brun and Fons Rademakers. * | ||
| * All rights reserved. * | ||
| * * | ||
| * For the licensing terms see $ROOTSYS/LICENSE. * | ||
| * For the list of contributors see $ROOTSYS/README/CREDITS. * | ||
| *************************************************************************/ | ||
|
|
||
| void R__zipLZ4(int cxlevel, int *srcsize, char *src, int *tgtsize, char *tgt, int *irep); | ||
|
|
||
| void R__unzipLZ4(int *srcsize, unsigned char *src, int *tgtsize, unsigned char *tgt, int *irep); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,92 @@ | ||
| // Original Author: Brian Bockelman | ||
|
|
||
| /************************************************************************* | ||
| * Copyright (C) 1995-2017, Rene Brun and Fons Rademakers. * | ||
| * All rights reserved. * | ||
| * * | ||
| * For the licensing terms see $ROOTSYS/LICENSE. * | ||
| * For the list of contributors see $ROOTSYS/README/CREDITS. * | ||
| *************************************************************************/ | ||
|
|
||
| #include "ZipLZ4.h" | ||
| #include "lz4.h" | ||
| #include "lz4hc.h" | ||
| #include <stdio.h> | ||
| #include <stdint.h> | ||
|
|
||
| #include "RConfig.h" | ||
|
|
||
| static const int kHeaderSize = 9; | ||
|
|
||
| void R__zipLZ4(int cxlevel, int *srcsize, char *src, int *tgtsize, char *tgt, int *irep) | ||
| { | ||
| int LZ4_version = LZ4_versionNumber(); | ||
| uint64_t out_size; /* compressed size */ | ||
| uint64_t in_size = (unsigned)(*srcsize); | ||
|
|
||
| *irep = 0; | ||
|
|
||
| if (*tgtsize <= 0) { | ||
| return; | ||
| } | ||
|
|
||
| if (*srcsize > 0xffffff || *srcsize < 0) { | ||
| return; | ||
| } | ||
|
|
||
| int returnStatus; | ||
| if (cxlevel > 9) { | ||
| cxlevel = 9; | ||
| } | ||
| if (cxlevel >= 4) { | ||
| returnStatus = LZ4_compress_HC(src, &tgt[kHeaderSize], *srcsize, *tgtsize - kHeaderSize, cxlevel); | ||
| } else { | ||
| returnStatus = LZ4_compress_default(src, &tgt[kHeaderSize], *srcsize, *tgtsize - kHeaderSize); | ||
| } | ||
|
|
||
| if (R__unlikely(returnStatus == 0)) { /* LZ4 compression failed */ | ||
| return; | ||
| } | ||
|
|
||
| tgt[0] = 'L'; | ||
| tgt[1] = '4'; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would have been 'even' better if those had been abstracted out in the same place as the reading.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That would be difficult - the generic header code and the compression-format specific code is interspersed with the actual implementation of the "old-style" compression algorithm. I would prefer to defer this for follow-up work.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fair enough. For the record, I would use a (potential) new header defining a set of strings/arrays ....
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yup, that's what I was thinking - new header to define the constants and rationalize the layout of the files (particularly with an eye towards separating the old C code). |
||
| tgt[2] = (LZ4_version / (100 * 100)); | ||
|
|
||
| out_size = returnStatus; /* compressed size */ | ||
|
|
||
| tgt[3] = (char)(out_size & 0xff); | ||
| tgt[4] = (char)((out_size >> 8) & 0xff); | ||
| tgt[5] = (char)((out_size >> 16) & 0xff); | ||
|
|
||
| tgt[6] = (char)(in_size & 0xff); /* decompressed size */ | ||
| tgt[7] = (char)((in_size >> 8) & 0xff); | ||
| tgt[8] = (char)((in_size >> 16) & 0xff); | ||
|
|
||
| *irep = (int)returnStatus + kHeaderSize; | ||
| } | ||
|
|
||
| void R__unzipLZ4(int *srcsize, unsigned char *src, int *tgtsize, unsigned char *tgt, int *irep) | ||
| { | ||
| int LZ4_version = LZ4_versionNumber() / (100 * 100); | ||
| *irep = 0; | ||
| if (R__unlikely(src[0] != 'L' || src[1] != '4')) { | ||
| fprintf(stderr, "R__unzipLZ4: algorithm run against buffer with incorrect header (got %d%d; expected %d%d).\n", | ||
| src[0], src[1], 'L', '4'); | ||
| return; | ||
| } | ||
| if (R__unlikely(src[2] != LZ4_version)) { | ||
| fprintf(stderr, | ||
| "R__unzipLZ4: This version of LZ4 is incompatible with the on-disk version (got %d; expected %d).\n", | ||
| src[2], LZ4_version); | ||
| return; | ||
| } | ||
|
|
||
| int returnStatus = LZ4_decompress_safe((char *)(&src[kHeaderSize]), (char *)(tgt), *srcsize - kHeaderSize, *tgtsize); | ||
| if (R__unlikely(returnStatus < 0)) { | ||
| fprintf(stderr, "R__unzipLZ4: error in decompression around byte %d out of maximum %d.\n", -returnStatus, | ||
| *tgtsize); | ||
| return; | ||
| } | ||
|
|
||
| *irep = returnStatus; | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we transform the two similar if-stmts into one if-else?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not easily: the true-branch of the first
if-statement can affect the outcome of the second conditional.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I see. That part is tricky to read. Maybe we could add a clarification comment for the casual reader.