Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-16 09:08:34

0001 /// \file ROOT/RNTupleZip.hxx
0002 /// \ingroup NTuple
0003 /// \author Jakob Blomer <jblomer@cern.ch>
0004 /// \date 2019-11-21
0005 
0006 /*************************************************************************
0007  * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers.               *
0008  * All rights reserved.                                                  *
0009  *                                                                       *
0010  * For the licensing terms see $ROOTSYS/LICENSE.                         *
0011  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
0012  *************************************************************************/
0013 
0014 #ifndef ROOT_RNTupleZip
0015 #define ROOT_RNTupleZip
0016 
0017 #include <RZip.h>
0018 #include <TError.h>
0019 
0020 #include <algorithm>
0021 #include <array>
0022 #include <cstring>
0023 #include <functional>
0024 #include <memory>
0025 #include <utility>
0026 
0027 namespace ROOT {
0028 namespace Internal {
0029 
0030 // clang-format off
0031 /**
0032 \class ROOT::Internal::RNTupleCompressor
0033 \ingroup NTuple
0034 \brief Helper class to compress data blocks in the ROOT compression frame format
0035 */
0036 // clang-format on
0037 class RNTupleCompressor {
0038 public:
0039    RNTupleCompressor() = delete;
0040    RNTupleCompressor(const RNTupleCompressor &other) = delete;
0041    RNTupleCompressor &operator=(const RNTupleCompressor &other) = delete;
0042    RNTupleCompressor(RNTupleCompressor &&other) = delete;
0043    RNTupleCompressor &operator=(RNTupleCompressor &&other) = delete;
0044 
0045    /// Returns the size of the compressed data, written into the provided output buffer.
0046    static std::size_t Zip(const void *from, std::size_t nbytes, int compression, void *to)
0047    {
0048       R__ASSERT(from != nullptr);
0049       R__ASSERT(to != nullptr);
0050       auto cxLevel = compression % 100;
0051       if (cxLevel == 0) {
0052          memcpy(to, from, nbytes);
0053          return nbytes;
0054       }
0055 
0056       auto cxAlgorithm = static_cast<ROOT::RCompressionSetting::EAlgorithm::EValues>(compression / 100);
0057       unsigned int nZipBlocks = 1 + (nbytes - 1) / kMAXZIPBUF;
0058       char *source = const_cast<char *>(static_cast<const char *>(from));
0059       int szTarget = nbytes;
0060       char *target = reinterpret_cast<char *>(to);
0061       int szOutBlock = 0;
0062       int szRemaining = nbytes;
0063       size_t szZipData = 0;
0064       for (unsigned int i = 0; i < nZipBlocks; ++i) {
0065          int szSource = std::min(static_cast<int>(kMAXZIPBUF), szRemaining);
0066          R__zipMultipleAlgorithm(cxLevel, &szSource, source, &szTarget, target, &szOutBlock, cxAlgorithm);
0067          R__ASSERT(szOutBlock >= 0);
0068          if ((szOutBlock == 0) || (szOutBlock >= szSource)) {
0069             // Uncompressible block, we have to store the entire input data stream uncompressed
0070             memcpy(to, from, nbytes);
0071             return nbytes;
0072          }
0073 
0074          szZipData += szOutBlock;
0075          source += szSource;
0076          target += szOutBlock;
0077          szRemaining -= szSource;
0078       }
0079       R__ASSERT(szRemaining == 0);
0080       R__ASSERT(szZipData < nbytes);
0081       return szZipData;
0082    }
0083 };
0084 
0085 // clang-format off
0086 /**
0087 \class ROOT::Internal::RNTupleDecompressor
0088 \ingroup NTuple
0089 \brief Helper class to uncompress data blocks in the ROOT compression frame format
0090 */
0091 // clang-format on
0092 class RNTupleDecompressor {
0093 public:
0094    RNTupleDecompressor() = delete;
0095    RNTupleDecompressor(const RNTupleDecompressor &other) = delete;
0096    RNTupleDecompressor &operator=(const RNTupleDecompressor &other) = delete;
0097    RNTupleDecompressor(RNTupleDecompressor &&other) = delete;
0098    RNTupleDecompressor &operator=(RNTupleDecompressor &&other) = delete;
0099 
0100    /**
0101     * The nbytes parameter provides the size ls of the from buffer. The dataLen gives the size of the uncompressed data.
0102     * The block is uncompressed iff nbytes == dataLen.
0103     */
0104    static void Unzip(const void *from, size_t nbytes, size_t dataLen, void *to)
0105    {
0106       if (dataLen == nbytes) {
0107          memcpy(to, from, nbytes);
0108          return;
0109       }
0110       R__ASSERT(dataLen > nbytes);
0111 
0112       unsigned char *source = const_cast<unsigned char *>(static_cast<const unsigned char *>(from));
0113       unsigned char *target = static_cast<unsigned char *>(to);
0114       int szRemaining = dataLen;
0115       do {
0116          int szSource;
0117          int szTarget;
0118          int retval = R__unzip_header(&szSource, source, &szTarget);
0119          R__ASSERT(retval == 0);
0120          R__ASSERT(szSource > 0);
0121          R__ASSERT(szTarget > szSource);
0122          R__ASSERT(static_cast<unsigned int>(szSource) <= nbytes);
0123          R__ASSERT(static_cast<unsigned int>(szTarget) <= dataLen);
0124 
0125          int unzipBytes = 0;
0126          R__unzip(&szSource, source, &szTarget, target, &unzipBytes);
0127          R__ASSERT(unzipBytes == szTarget);
0128 
0129          target += szTarget;
0130          source += szSource;
0131          szRemaining -= unzipBytes;
0132       } while (szRemaining > 0);
0133       R__ASSERT(szRemaining == 0);
0134    }
0135 };
0136 
0137 } // namespace Internal
0138 } // namespace ROOT
0139 
0140 #endif