Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
REntry.hxx
Go to the documentation of this file.
1/// \file ROOT/REntry.hxx
2/// \ingroup NTuple
3/// \author Jakob Blomer <jblomer@cern.ch>
4/// \date 2018-07-19
5
6/*************************************************************************
7 * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
8 * All rights reserved. *
9 * *
10 * For the licensing terms see $ROOTSYS/LICENSE. *
11 * For the list of contributors see $ROOTSYS/README/CREDITS. *
12 *************************************************************************/
13
14#ifndef ROOT_REntry
15#define ROOT_REntry
16
17#include <ROOT/RError.hxx>
18#include <ROOT/RField.hxx>
19#include <ROOT/RFieldToken.hxx>
20#include <string_view>
21
22#include <TError.h>
23
24#include <algorithm>
25#include <iterator>
26#include <memory>
27#include <type_traits>
28#include <utility>
29#include <vector>
30#include <unordered_map>
31
32namespace ROOT {
33
34class RNTupleReader;
35
36namespace Experimental {
37class RNTupleFillContext;
38class RNTupleProcessor;
39class RNTupleSingleProcessor;
40class RNTupleChainProcessor;
41class RNTupleJoinProcessor;
42} // namespace Experimental
43
44// clang-format off
45/**
46\class ROOT::REntry
47\ingroup NTuple
48\brief The REntry is a collection of values in an RNTuple corresponding to a complete row in the data set.
49
50The entry provides a memory-managed binder for a set of values read from fields in an RNTuple. The memory locations that are associated
51with values are managed through shared pointers.
52*/
53// clang-format on
54class REntry {
55 friend class RNTupleModel;
56 friend class RNTupleReader;
62
63private:
64 /// The entry must be linked to a specific model, identified by a model ID
65 std::uint64_t fModelId = 0;
66 /// The entry and its tokens are also linked to a specific schema, identified by a schema ID
67 std::uint64_t fSchemaId = 0;
68 /// Corresponds to the fields of the linked model
69 std::vector<ROOT::RFieldBase::RValue> fValues;
70 /// For fast lookup of token IDs given a (sub)field name present in the entry
71 std::unordered_map<std::string, std::size_t> fFieldName2Token;
72 /// To ensure that the entry is standalone, a copy of all field types
73 std::vector<std::string> fFieldTypes;
74
75 /// Creation of entries can be done by the RNTupleModel, the RNTupleReader, or the RNTupleWriter.
76 REntry() = default;
77 explicit REntry(std::uint64_t modelId, std::uint64_t schemaId) : fModelId(modelId), fSchemaId(schemaId) {}
78
80 {
81 fFieldName2Token[value.GetField().GetQualifiedFieldName()] = fValues.size();
82 fFieldTypes.push_back(value.GetField().GetTypeName());
83 fValues.emplace_back(std::move(value));
84 }
85
86 /// While building the entry, adds a new value for the field and returns the value's shared pointer
87 template <typename T>
88 std::shared_ptr<T> AddValue(ROOT::RField<T> &field)
89 {
90 fFieldName2Token[field.GetQualifiedFieldName()] = fValues.size();
91 fFieldTypes.push_back(field.GetTypeName());
92 auto value = field.CreateValue();
93 fValues.emplace_back(value);
94 return value.template GetPtr<T>();
95 }
96
97 /// Update the RValue for a field in the entry. To be used when its underlying ROOT::RFieldBase changes, which
98 /// typically happens when the page source from which the field values are read changes.
100 {
101 std::swap(fValues.at(token.fIndex), value);
102 }
104 {
105 std::swap(fValues.at(token.fIndex), value);
106 }
107
108 /// Return the RValue currently bound to the provided field.
111
113 {
114 for (auto &v : fValues) {
115 v.Read(index);
116 }
117 }
118
119 std::size_t Append()
120 {
121 std::size_t bytesWritten = 0;
122 for (auto &v : fValues) {
123 bytesWritten += v.Append();
124 }
125 return bytesWritten;
126 }
127
129 {
130 if (fSchemaId != token.fSchemaId) {
131 throw RException(R__FAIL("invalid token for this entry, "
132 "make sure to use a token from a model with the same schema as this entry."));
133 }
134 }
135
136 /// This function has linear complexity, only use it for more helpful error messages!
137 const std::string &FindFieldName(ROOT::RFieldToken token) const
138 {
139 for (const auto &[fieldName, index] : fFieldName2Token) {
140 if (index == token.fIndex) {
141 return fieldName;
142 }
143 }
144 // Should never happen, but avoid compiler warning about "returning reference to local temporary object".
145 static const std::string empty = "";
146 return empty;
147 }
148
149 template <typename T>
151 {
152 if constexpr (!std::is_void_v<T>) {
154 throw RException(R__FAIL("type mismatch for field " + FindFieldName(token) + ": " +
155 fFieldTypes[token.fIndex] + " vs. " + ROOT::RField<T>::TypeName()));
156 }
157 }
158 }
159
160public:
161 using ConstIterator_t = decltype(fValues)::const_iterator;
162
163 REntry(const REntry &other) = delete;
164 REntry &operator=(const REntry &other) = delete;
165 REntry(REntry &&other) = default;
167 ~REntry() = default;
168
169 /// The ordinal of the (sub)field fieldName; can be used in other methods to address the corresponding value
170 ROOT::RFieldToken GetToken(std::string_view fieldName) const
171 {
172 auto it = fFieldName2Token.find(std::string(fieldName));
173 if (it == fFieldName2Token.end()) {
174 throw RException(R__FAIL("invalid field name: " + std::string(fieldName)));
175 }
176 return ROOT::RFieldToken(it->second, fSchemaId);
177 }
178
179 /// Create a new value for the field referenced by `token`.
181 {
183 fValues[token.fIndex].EmplaceNew();
184 }
185
186 /// Create a new value for the field referenced by its name.
188
189 /// Bind the value for the field, referenced by `token`, to `objPtr`.
190 ///
191 /// \sa BindValue(std::string_view, std::shared_ptr<T>)
192 template <typename T>
193 void BindValue(ROOT::RFieldToken token, std::shared_ptr<T> objPtr)
194 {
197 fValues[token.fIndex].Bind(objPtr);
198 }
199
200 /// Bind the value for the field, referenced by its name, to `objPtr`.
201 ///
202 /// Ownership is shared with the caller and the object will be kept alive until it is replaced (by a call to
203 /// EmplaceNewValue, BindValue, or BindRawPtr) or the entry is destructed.
204 ///
205 /// **Note**: if `T = void`, type checks are disabled. It is the caller's responsibility to match the field and
206 /// object types.
207 template <typename T>
208 void BindValue(std::string_view fieldName, std::shared_ptr<T> objPtr)
209 {
211 }
212
213 /// Bind the value for the field, referenced by `token`, to `rawPtr`.
214 ///
215 /// \sa BindRawPtr(std::string_view, T *)
216 template <typename T>
223
224 /// Bind the value for the field, referenced by its name, to `rawPtr`.
225 ///
226 /// The caller retains ownership of the object and must ensure it is kept alive when reading or writing using the
227 /// entry.
228 ///
229 /// **Note**: if `T = void`, type checks are disabled. It is the caller's responsibility to match the field and
230 /// object types.
231 template <typename T>
232 void BindRawPtr(std::string_view fieldName, T *rawPtr)
233 {
235 }
236
237 /// Get the (typed) pointer to the value for the field referenced by `token`.
238 ///
239 /// \sa GetPtr(std::string_view)
240 template <typename T>
241 std::shared_ptr<T> GetPtr(ROOT::RFieldToken token) const
242 {
245 return std::static_pointer_cast<T>(fValues[token.fIndex].GetPtr<void>());
246 }
247
248 /// Get the (typed) pointer to the value for the field referenced by `token`.
249 ///
250 /// Ownership is shared and the caller can continue to use the object after the entry is destructed.
251 ///
252 /// **Note**: if `T = void`, type checks are disabled. It is the caller's responsibility to use the returned pointer
253 /// according to the field type.
254 template <typename T>
255 std::shared_ptr<T> GetPtr(std::string_view fieldName) const
256 {
258 }
259
260 const std::string &GetTypeName(ROOT::RFieldToken token) const
261 {
263 return fFieldTypes[token.fIndex];
264 }
265
266 const std::string &GetTypeName(std::string_view fieldName) const { return GetTypeName(GetToken(fieldName)); }
267
268 std::uint64_t GetModelId() const { return fModelId; }
269 std::uint64_t GetSchemaId() const { return fSchemaId; }
270
271 ConstIterator_t begin() const { return fValues.cbegin(); }
272 ConstIterator_t end() const { return fValues.cend(); }
273};
274
275} // namespace ROOT
276
277#endif
#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:299
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Processor specialization for vertically combined (chained) RNTupleProcessors.
A context for filling entries (data) into clusters of an RNTuple.
Processor specialization for horizontally combined (joined) RNTuples.
Interface for iterating over entries of RNTuples and vertically concatenated RNTuples (chains).
Processor specialization for processing a single RNTuple.
The REntry is a collection of values in an RNTuple corresponding to a complete row in the data set.
Definition REntry.hxx:54
std::uint64_t fModelId
The entry must be linked to a specific model, identified by a model ID.
Definition REntry.hxx:65
void EmplaceNewValue(ROOT::RFieldToken token)
Create a new value for the field referenced by token.
Definition REntry.hxx:180
std::shared_ptr< T > GetPtr(ROOT::RFieldToken token) const
Get the (typed) pointer to the value for the field referenced by token.
Definition REntry.hxx:241
std::vector< ROOT::RFieldBase::RValue > fValues
Corresponds to the fields of the linked model.
Definition REntry.hxx:69
std::uint64_t GetModelId() const
Definition REntry.hxx:268
void BindValue(std::string_view fieldName, std::shared_ptr< T > objPtr)
Bind the value for the field, referenced by its name, to objPtr.
Definition REntry.hxx:208
void BindValue(ROOT::RFieldToken token, std::shared_ptr< T > objPtr)
Bind the value for the field, referenced by token, to objPtr.
Definition REntry.hxx:193
std::uint64_t GetSchemaId() const
Definition REntry.hxx:269
REntry(const REntry &other)=delete
const std::string & FindFieldName(ROOT::RFieldToken token) const
This function has linear complexity, only use it for more helpful error messages!
Definition REntry.hxx:137
const std::string & GetTypeName(ROOT::RFieldToken token) const
Definition REntry.hxx:260
void EnsureMatchingType(ROOT::RFieldToken token) const
Definition REntry.hxx:150
ConstIterator_t begin() const
Definition REntry.hxx:271
void Read(ROOT::NTupleSize_t index)
Definition REntry.hxx:112
std::vector< std::string > fFieldTypes
To ensure that the entry is standalone, a copy of all field types.
Definition REntry.hxx:73
std::uint64_t fSchemaId
The entry and its tokens are also linked to a specific schema, identified by a schema ID.
Definition REntry.hxx:67
void BindRawPtr(std::string_view fieldName, T *rawPtr)
Bind the value for the field, referenced by its name, to rawPtr.
Definition REntry.hxx:232
ROOT::RFieldBase::RValue & GetValue(std::string_view fieldName)
Definition REntry.hxx:110
void AddValue(ROOT::RFieldBase::RValue &&value)
Definition REntry.hxx:79
std::shared_ptr< T > GetPtr(std::string_view fieldName) const
Get the (typed) pointer to the value for the field referenced by token.
Definition REntry.hxx:255
REntry()=default
Creation of entries can be done by the RNTupleModel, the RNTupleReader, or the RNTupleWriter.
REntry(std::uint64_t modelId, std::uint64_t schemaId)
Definition REntry.hxx:77
REntry & operator=(REntry &&other)=default
REntry & operator=(const REntry &other)=delete
ConstIterator_t end() const
Definition REntry.hxx:272
std::shared_ptr< T > AddValue(ROOT::RField< T > &field)
While building the entry, adds a new value for the field and returns the value's shared pointer.
Definition REntry.hxx:88
void EnsureMatchingModel(ROOT::RFieldToken token) const
Definition REntry.hxx:128
void UpdateValue(ROOT::RFieldToken token, ROOT::RFieldBase::RValue &&value)
Update the RValue for a field in the entry.
Definition REntry.hxx:99
void BindRawPtr(ROOT::RFieldToken token, T *rawPtr)
Bind the value for the field, referenced by token, to rawPtr.
Definition REntry.hxx:217
ROOT::RFieldBase::RValue & GetValue(ROOT::RFieldToken token)
Return the RValue currently bound to the provided field.
Definition REntry.hxx:109
void EmplaceNewValue(std::string_view fieldName)
Create a new value for the field referenced by its name.
Definition REntry.hxx:187
std::size_t Append()
Definition REntry.hxx:119
~REntry()=default
REntry(REntry &&other)=default
ROOT::RFieldToken GetToken(std::string_view fieldName) const
The ordinal of the (sub)field fieldName; can be used in other methods to address the corresponding va...
Definition REntry.hxx:170
void UpdateValue(ROOT::RFieldToken token, ROOT::RFieldBase::RValue &value)
Definition REntry.hxx:103
std::unordered_map< std::string, std::size_t > fFieldName2Token
For fast lookup of token IDs given a (sub)field name present in the entry.
Definition REntry.hxx:71
const std::string & GetTypeName(std::string_view fieldName) const
Definition REntry.hxx:266
Base class for all ROOT issued exceptions.
Definition RError.hxx:79
Points to an object with RNTuple I/O support and keeps a pointer to the corresponding field.
A field token identifies a (sub)field in an entry.
Classes with dictionaries that can be inspected by TClass.
Definition RField.hxx:285
The RNTupleModel encapulates the schema of an RNTuple.
Reads RNTuple data from storage.
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.