Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RNTupleFillContext.hxx
Go to the documentation of this file.
1/// \file ROOT/RNTupleFillContext.hxx
2/// \author Jakob Blomer <jblomer@cern.ch>
3/// \date 2024-02-22
4
5/*************************************************************************
6 * Copyright (C) 1995-2024, Rene Brun and Fons Rademakers. *
7 * All rights reserved. *
8 * *
9 * For the licensing terms see $ROOTSYS/LICENSE. *
10 * For the list of contributors see $ROOTSYS/README/CREDITS. *
11 *************************************************************************/
12
13#ifndef ROOT_RNTupleFillContext
14#define ROOT_RNTupleFillContext
15
16#include <ROOT/RConfig.hxx> // for R__unlikely
17#include <ROOT/REntry.hxx>
18#include <ROOT/RError.hxx>
19#include <ROOT/RPageStorage.hxx>
23#include <ROOT/RNTupleModel.hxx>
24#include <ROOT/RNTupleTypes.hxx>
25
26#include <cstddef>
27#include <cstdint>
28#include <memory>
29#include <vector>
30
31namespace ROOT {
32
33class RNTupleAttrSetWriter;
34
35// clang-format off
36/**
37\class ROOT::RNTupleFillContext
38\ingroup NTuple
39\brief A context for filling entries (data) into clusters of an RNTuple
40
41An output cluster can be filled with entries. The caller has to make sure that the data that gets filled into a cluster
42is not modified for the time of the Fill() call. The fill call serializes the C++ object into the column format and
43writes data into the corresponding column page buffers. Writing of the buffers to storage is deferred and can be
44triggered by FlushCluster() or by destructing the context. On I/O errors, an exception is thrown.
45
46Instances of this class are not meant to be used in isolation and can be created from an RNTupleParallelWriter. For
47sequential writing, please refer to RNTupleWriter.
48*/
49// clang-format on
51 friend class ROOT::RNTupleWriter;
54
55private:
56 /// The page sink's parallel page compression scheduler if IMT is on.
57 /// Needs to be destructed after the page sink is destructed and so declared before.
58 std::unique_ptr<ROOT::Internal::RPageStorage::RTaskScheduler> fZipTasks;
59 std::unique_ptr<ROOT::Internal::RPageSink> fSink;
60 /// Needs to be destructed before fSink
61 std::unique_ptr<ROOT::RNTupleModel> fModel;
62
64
67 /// Keeps track of the number of bytes written into the current cluster
68 std::size_t fUnzippedClusterSize = 0;
69 /// The total number of bytes written to storage (i.e., after compression)
70 std::uint64_t fNBytesFlushed = 0;
71 /// The total number of bytes filled into all the so far committed clusters,
72 /// i.e. the uncompressed size of the written clusters
73 std::uint64_t fNBytesFilled = 0;
74 /// Limit for committing cluster no matter the other tunables
76 /// Estimator of uncompressed cluster size, taking into account the estimated compression ratio
78
79 /// Whether to enable staged cluster committing, where only an explicit call to CommitStagedClusters() will logically
80 /// append the clusters to the RNTuple.
82 /// Vector of currently staged clusters.
83 std::vector<ROOT::Internal::RPageSink::RStagedCluster> fStagedClusters;
84
85 template <typename Entry>
86 void FillNoFlushImpl(Entry &entry, ROOT::RNTupleFillStatus &status)
87 {
88 if (R__unlikely(entry.GetModelId() != fModel->GetModelId()))
89 throw RException(R__FAIL("mismatch between entry and model"));
90
91 const std::size_t bytesWritten = entry.Append();
92 fUnzippedClusterSize += bytesWritten;
93 fNEntries++;
94
97 status.fLastEntrySize = bytesWritten;
98 status.fShouldFlushCluster =
100 }
101 template <typename Entry>
102 std::size_t FillImpl(Entry &entry)
103 {
105 FillNoFlushImpl(entry, status);
106 if (status.ShouldFlushCluster())
107 FlushCluster();
108 return status.GetLastEntrySize();
109 }
110
111 RNTupleFillContext(std::unique_ptr<ROOT::RNTupleModel> model, std::unique_ptr<ROOT::Internal::RPageSink> sink);
116
117public:
119
120 /// Fill an entry into this context, but don't commit the cluster. The calling code must pass an RNTupleFillStatus
121 /// and check RNTupleFillStatus::ShouldFlushCluster.
122 ///
123 /// This method will check the entry's model ID to ensure it comes from the context's own model or throw an exception
124 /// otherwise.
125 void FillNoFlush(ROOT::REntry &entry, ROOT::RNTupleFillStatus &status) { FillNoFlushImpl(entry, status); }
126 /// Fill an entry into this context. This method will check the entry's model ID to ensure it comes from the
127 /// context's own model or throw an exception otherwise.
128 /// \return The number of uncompressed bytes written.
129 std::size_t Fill(ROOT::REntry &entry) { return FillImpl(entry); }
130
131 /// Fill an RRawPtrWriteEntry into this context, but don't commit the cluster. The calling code must pass an
132 /// RNTupleFillStatus and check RNTupleFillStatus::ShouldFlushCluster.
133 ///
134 /// This method will check the entry's model ID to ensure it comes from the context's own model or throw an exception
135 /// otherwise.
137 {
138 FillNoFlushImpl(entry, status);
139 }
140 /// Fill an RRawPtrWriteEntry into this context. This method will check the entry's model ID to ensure it comes
141 /// from the context's own model or throw an exception otherwise.
142 /// \return The number of uncompressed bytes written.
143 std::size_t Fill(ROOT::Detail::RRawPtrWriteEntry &entry) { return FillImpl(entry); }
144
145 /// Flush column data, preparing for CommitCluster or to reduce memory usage. This will trigger compression of pages,
146 /// but not actually write to storage.
147 void FlushColumns();
148 /// Flush so far filled entries to storage
149 void FlushCluster();
150 /// Logically append staged clusters to the RNTuple.
152
153 const ROOT::RNTupleModel &GetModel() const { return *fModel; }
154 std::unique_ptr<ROOT::REntry> CreateEntry() const { return fModel->CreateEntry(); }
155 std::unique_ptr<ROOT::Detail::RRawPtrWriteEntry> CreateRawPtrWriteEntry() const
156 {
157 return fModel->CreateRawPtrWriteEntry();
158 }
159
160 /// Return the entry number that was last flushed in a cluster.
162 /// Return the number of entries filled so far.
164
165 void EnableStagedClusterCommitting(bool val = true)
166 {
167 if (!val && !fStagedClusters.empty()) {
168 throw RException(R__FAIL("cannot disable staged committing with pending clusters"));
169 }
171 }
173
176};
177
178} // namespace ROOT
179
180#endif // ROOT_RNTupleFillContext
#define R__unlikely(expr)
Definition RConfig.hxx:568
#define R__FAIL(msg)
Short-hand to return an RResult<T> in an error state; the RError is implicitly converted into RResult...
Definition RError.hxx:322
A container of const raw pointers, corresponding to a row in the data set.
A collection of Counter objects with a name, a unit, and a description.
The REntry is a collection of values in an RNTuple corresponding to a complete row in the data set.
Definition REntry.hxx:55
Base class for all ROOT issued exceptions.
Definition RError.hxx:78
Class used to write an RNTupleAttrSet in the context of an RNTupleWriter.
A context for filling entries (data) into clusters of an RNTuple.
void FlushCluster()
Flush so far filled entries to storage.
ROOT::NTupleSize_t fLastFlushed
void FillNoFlushImpl(Entry &entry, ROOT::RNTupleFillStatus &status)
std::size_t fUnzippedClusterSizeEst
Estimator of uncompressed cluster size, taking into account the estimated compression ratio.
std::size_t Fill(ROOT::Detail::RRawPtrWriteEntry &entry)
Fill an RRawPtrWriteEntry into this context.
std::uint64_t fNBytesFilled
The total number of bytes filled into all the so far committed clusters, i.e.
void EnableStagedClusterCommitting(bool val=true)
ROOT::NTupleSize_t GetLastFlushed() const
Return the entry number that was last flushed in a cluster.
Experimental::Detail::RNTupleMetrics fMetrics
bool IsStagedClusterCommittingEnabled() const
ROOT::NTupleSize_t GetNEntries() const
Return the number of entries filled so far.
std::uint64_t fNBytesFlushed
The total number of bytes written to storage (i.e., after compression)
std::size_t FillImpl(Entry &entry)
std::vector< ROOT::Internal::RPageSink::RStagedCluster > fStagedClusters
Vector of currently staged clusters.
void FlushColumns()
Flush column data, preparing for CommitCluster or to reduce memory usage.
std::unique_ptr< ROOT::REntry > CreateEntry() const
RNTupleFillContext(std::unique_ptr< ROOT::RNTupleModel > model, std::unique_ptr< ROOT::Internal::RPageSink > sink)
std::size_t fUnzippedClusterSize
Keeps track of the number of bytes written into the current cluster.
std::unique_ptr< ROOT::Detail::RRawPtrWriteEntry > CreateRawPtrWriteEntry() const
const ROOT::RNTupleModel & GetModel() const
RNTupleFillContext & operator=(const RNTupleFillContext &)=delete
const Experimental::Detail::RNTupleMetrics & GetMetrics() const
void FillNoFlush(ROOT::Detail::RRawPtrWriteEntry &entry, ROOT::RNTupleFillStatus &status)
Fill an RRawPtrWriteEntry into this context, but don't commit the cluster.
RNTupleFillContext(RNTupleFillContext &&)=delete
void CommitStagedClusters()
Logically append staged clusters to the RNTuple.
RNTupleFillContext(const RNTupleFillContext &)=delete
RNTupleFillContext & operator=(RNTupleFillContext &&)=delete
bool fStagedClusterCommitting
Whether to enable staged cluster committing, where only an explicit call to CommitStagedClusters() wi...
std::unique_ptr< ROOT::Internal::RPageStorage::RTaskScheduler > fZipTasks
The page sink's parallel page compression scheduler if IMT is on.
std::unique_ptr< ROOT::RNTupleModel > fModel
Needs to be destructed before fSink.
std::unique_ptr< ROOT::Internal::RPageSink > fSink
std::size_t fMaxUnzippedClusterSize
Limit for committing cluster no matter the other tunables.
void FillNoFlush(ROOT::REntry &entry, ROOT::RNTupleFillStatus &status)
Fill an entry into this context, but don't commit the cluster.
std::size_t Fill(ROOT::REntry &entry)
Fill an entry into this context.
A status object after filling an entry.
ROOT::NTupleSize_t fNEntriesSinceLastFlush
Number of entries written into the current cluster.
std::size_t fUnzippedClusterSize
Number of bytes written into the current cluster.
std::size_t fLastEntrySize
Number of bytes written for the last entry.
bool ShouldFlushCluster() const
Return true if the caller should call FlushCluster.
std::size_t GetLastEntrySize() const
Return the number of bytes for the last entry.
The RNTupleModel encapulates the schema of an RNTuple.
A writer to fill an RNTuple from multiple contexts.
An RNTuple that gets filled with entries (data) and writes them to storage.
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.