Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:10:45

0001 /// \file ROOT/RNTupleFillContext.hxx
0002 /// \ingroup NTuple ROOT7
0003 /// \author Jakob Blomer <jblomer@cern.ch>
0004 /// \date 2024-02-22
0005 /// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
0006 /// is welcome!
0007 
0008 /*************************************************************************
0009  * Copyright (C) 1995-2024, Rene Brun and Fons Rademakers.               *
0010  * All rights reserved.                                                  *
0011  *                                                                       *
0012  * For the licensing terms see $ROOTSYS/LICENSE.                         *
0013  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
0014  *************************************************************************/
0015 
0016 #ifndef ROOT7_RNTupleFillContext
0017 #define ROOT7_RNTupleFillContext
0018 
0019 #include <ROOT/RConfig.hxx> // for R__unlikely
0020 #include <ROOT/REntry.hxx>
0021 #include <ROOT/RError.hxx>
0022 #include <ROOT/RNTupleMetrics.hxx>
0023 #include <ROOT/RNTupleModel.hxx>
0024 #include <ROOT/RNTupleUtil.hxx>
0025 
0026 #include <cstddef>
0027 #include <cstdint>
0028 #include <memory>
0029 
0030 namespace ROOT {
0031 namespace Experimental {
0032 
0033 namespace Internal {
0034 class RPageSink;
0035 }
0036 
0037 // clang-format off
0038 /**
0039 \class ROOT::Experimental::RNTupleFillContext
0040 \ingroup NTuple
0041 \brief A context for filling entries (data) into clusters of an RNTuple
0042 
0043 An output cluster can be filled with entries. The caller has to make sure that the data that gets filled into a cluster
0044 is not modified for the time of the Fill() call. The fill call serializes the C++ object into the column format and
0045 writes data into the corresponding column page buffers.  Writing of the buffers to storage is deferred and can be
0046 triggered by CommitCluster() or by destructing the context.  On I/O errors, an exception is thrown.
0047 
0048 Instances of this class are not meant to be used in isolation and can be created from an RNTupleParallelWriter. For
0049 sequential writing, please refer to RNTupleWriter.
0050 */
0051 // clang-format on
0052 class RNTupleFillContext {
0053    friend class RNTupleWriter;
0054    friend class RNTupleParallelWriter;
0055 
0056 private:
0057    std::unique_ptr<Internal::RPageSink> fSink;
0058    /// Needs to be destructed before fSink
0059    std::unique_ptr<RNTupleModel> fModel;
0060 
0061    Detail::RNTupleMetrics fMetrics;
0062 
0063    NTupleSize_t fLastCommitted = 0;
0064    NTupleSize_t fNEntries = 0;
0065    /// Keeps track of the number of bytes written into the current cluster
0066    std::size_t fUnzippedClusterSize = 0;
0067    /// The total number of bytes written to storage (i.e., after compression)
0068    std::uint64_t fNBytesCommitted = 0;
0069    /// The total number of bytes filled into all the so far committed clusters,
0070    /// i.e. the uncompressed size of the written clusters
0071    std::uint64_t fNBytesFilled = 0;
0072    /// Limit for committing cluster no matter the other tunables
0073    std::size_t fMaxUnzippedClusterSize;
0074    /// Estimator of uncompressed cluster size, taking into account the estimated compression ratio
0075    std::size_t fUnzippedClusterSizeEst;
0076 
0077    RNTupleFillContext(std::unique_ptr<RNTupleModel> model, std::unique_ptr<Internal::RPageSink> sink);
0078    RNTupleFillContext(const RNTupleFillContext &) = delete;
0079    RNTupleFillContext &operator=(const RNTupleFillContext &) = delete;
0080 
0081 public:
0082    ~RNTupleFillContext();
0083 
0084    /// Fill an entry into this context.  This method will perform a light check whether the entry comes from the
0085    /// context's own model.
0086    /// \return The number of uncompressed bytes written.
0087    std::size_t Fill(REntry &entry)
0088    {
0089       if (R__unlikely(entry.GetModelId() != fModel->GetModelId()))
0090          throw RException(R__FAIL("mismatch between entry and model"));
0091 
0092       const std::size_t bytesWritten = entry.Append();
0093       fUnzippedClusterSize += bytesWritten;
0094       fNEntries++;
0095       if ((fUnzippedClusterSize >= fMaxUnzippedClusterSize) || (fUnzippedClusterSize >= fUnzippedClusterSizeEst))
0096          CommitCluster();
0097       return bytesWritten;
0098    }
0099    /// Ensure that the data from the so far seen Fill calls has been written to storage
0100    void CommitCluster();
0101 
0102    std::unique_ptr<REntry> CreateEntry() { return fModel->CreateEntry(); }
0103 
0104    /// Return the entry number that was last committed in a cluster.
0105    NTupleSize_t GetLastCommitted() const { return fLastCommitted; }
0106    /// Return the number of entries filled so far.
0107    NTupleSize_t GetNEntries() const { return fNEntries; }
0108 
0109    void EnableMetrics() { fMetrics.Enable(); }
0110    const Detail::RNTupleMetrics &GetMetrics() const { return fMetrics; }
0111 }; // class RNTupleFillContext
0112 
0113 } // namespace Experimental
0114 } // namespace ROOT
0115 
0116 #endif // ROOT7_RNTupleFillContext