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 RNTupleFillContext;
35class RNTupleReader;
36
37namespace Experimental {
38class RNTupleAttrSetReader;
39
40namespace Internal {
41struct RNTupleAttrEntry;
42}
43} // namespace Experimental
44
45// clang-format off
46/**
47\class ROOT::REntry
48\ingroup NTuple
49\brief The REntry is a collection of values in an RNTuple corresponding to a complete row in the data set.
50
51The entry provides a memory-managed binder for a set of values read from fields in an RNTuple. The memory locations that are associated
52with values are managed through shared pointers.
53*/
54// clang-format on
55class REntry {
56 friend class RNTupleFillContext;
57 friend class RNTupleModel;
58 friend class RNTupleReader;
61
62private:
63 /// The entry must be linked to a specific model, identified by a model ID
64 std::uint64_t fModelId = 0;
65 /// The entry and its tokens are also linked to a specific schema, identified by a schema ID
66 std::uint64_t fSchemaId = 0;
67 /// Corresponds to the fields of the linked model
68 std::vector<ROOT::RFieldBase::RValue> fValues;
69 /// For fast lookup of token IDs given a (sub)field name present in the entry
70 std::unordered_map<std::string, std::size_t> fFieldName2Token;
71 /// To ensure that the entry is standalone, a copy of all field types
72 std::vector<std::string> fFieldTypes;
73
74 /// Creation of entries can be done by the RNTupleModel, the RNTupleReader, or the RNTupleWriter.
75 REntry() = default;
76 explicit REntry(std::uint64_t modelId, std::uint64_t schemaId) : fModelId(modelId), fSchemaId(schemaId) {}
77
79 {
80 fFieldName2Token[value.GetField().GetQualifiedFieldName()] = fValues.size();
81 fFieldTypes.push_back(value.GetField().GetTypeName());
82 fValues.emplace_back(std::move(value));
83 }
84
85 /// While building the entry, adds a new value for the field and returns the value's shared pointer
86 template <typename T>
87 std::shared_ptr<T> AddValue(ROOT::RField<T> &field)
88 {
89 fFieldName2Token[field.GetQualifiedFieldName()] = fValues.size();
90 fFieldTypes.push_back(field.GetTypeName());
91 auto value = field.CreateValue();
92 fValues.emplace_back(value);
93 // We know that the created RValue has the right type, skip the unnecessary check.
94 return std::static_pointer_cast<T>(value.template GetPtr<void>());
95 }
96
98 {
99 for (auto &v : fValues) {
100 v.Read(index);
101 }
102 }
103
104 std::size_t Append()
105 {
106 std::size_t bytesWritten = 0;
107 for (auto &v : fValues) {
108 bytesWritten += v.Append();
109 }
110 return bytesWritten;
111 }
112
114 {
115 if (fSchemaId != token.fSchemaId) {
116 throw RException(R__FAIL("invalid token for this entry, "
117 "make sure to use a token from a model with the same schema as this entry."));
118 }
119 }
120
121 /// This function has linear complexity, only use it for more helpful error messages!
122 const std::string &FindFieldName(ROOT::RFieldToken token) const
123 {
124 for (const auto &[fieldName, index] : fFieldName2Token) {
125 if (index == token.fIndex) {
126 return fieldName;
127 }
128 }
129 // Should never happen, but avoid compiler warning about "returning reference to local temporary object".
130 static const std::string empty = "";
131 return empty;
132 }
133
134 template <typename T>
136 {
137 if constexpr (!std::is_void_v<T>) {
138 if (!Internal::IsMatchingFieldType<T>(fFieldTypes[token.fIndex])) {
139 throw RException(R__FAIL("type mismatch for field " + FindFieldName(token) + ": " +
140 fFieldTypes[token.fIndex] + " vs. " + ROOT::RField<T>::TypeName()));
141 }
142 }
143 }
144
145public:
146 using ConstIterator_t = decltype(fValues)::const_iterator;
147
148 REntry(const REntry &other) = delete;
149 REntry &operator=(const REntry &other) = delete;
150 REntry(REntry &&other) = default;
152 ~REntry() = default;
153
154 /// The ordinal of the (sub)field fieldName; can be used in other methods to address the corresponding value
155 ROOT::RFieldToken GetToken(std::string_view fieldName) const
156 {
157 auto it = fFieldName2Token.find(std::string(fieldName));
158 if (it == fFieldName2Token.end()) {
159 throw RException(R__FAIL("invalid field name: " + std::string(fieldName)));
160 }
161 return ROOT::RFieldToken(it->second, fSchemaId);
162 }
163
164 /// Create a new value for the field referenced by `token`.
166 {
167 EnsureMatchingModel(token);
168 fValues[token.fIndex].EmplaceNew();
169 }
170
171 /// Create a new value for the field referenced by its name.
173
174 /// Bind the value for the field, referenced by `token`, to `objPtr`.
175 ///
176 /// \sa BindValue(std::string_view, std::shared_ptr<T>)
177 template <typename T>
178 void BindValue(ROOT::RFieldToken token, std::shared_ptr<T> objPtr)
179 {
180 EnsureMatchingModel(token);
182 fValues[token.fIndex].Bind(objPtr);
183 }
184
185 /// Bind the value for the field, referenced by its name, to `objPtr`.
186 ///
187 /// Ownership is shared with the caller and the object will be kept alive until it is replaced (by a call to
188 /// EmplaceNewValue, BindValue, or BindRawPtr) or the entry is destructed.
189 ///
190 /// **Note**: if `T = void`, type checks are disabled. It is the caller's responsibility to match the field and
191 /// object types.
192 template <typename T>
193 void BindValue(std::string_view fieldName, std::shared_ptr<T> objPtr)
194 {
196 }
197
198 /// Bind the value for the field, referenced by `token`, to `rawPtr`.
199 ///
200 /// \sa BindRawPtr(std::string_view, T *)
201 template <typename T>
203 {
204 EnsureMatchingModel(token);
206 fValues[token.fIndex].BindRawPtr(rawPtr);
207 }
208
209 /// Bind the value for the field, referenced by its name, to `rawPtr`.
210 ///
211 /// The caller retains ownership of the object and must ensure it is kept alive when reading or writing using the
212 /// entry.
213 ///
214 /// **Note**: if `T = void`, type checks are disabled. It is the caller's responsibility to match the field and
215 /// object types.
216 template <typename T>
217 void BindRawPtr(std::string_view fieldName, T *rawPtr)
218 {
220 }
221
222 /// Get the (typed) pointer to the value for the field referenced by `token`.
223 ///
224 /// \sa GetPtr(std::string_view)
225 template <typename T>
226 std::shared_ptr<T> GetPtr(ROOT::RFieldToken token) const
227 {
228 EnsureMatchingModel(token);
230 return std::static_pointer_cast<T>(fValues[token.fIndex].GetPtr<void>());
231 }
232
233 /// Get the (typed) pointer to the value for the field referenced by `token`.
234 ///
235 /// Ownership is shared and the caller can continue to use the object after the entry is destructed.
236 ///
237 /// **Note**: if `T = void`, type checks are disabled. It is the caller's responsibility to use the returned pointer
238 /// according to the field type.
239 template <typename T>
240 std::shared_ptr<T> GetPtr(std::string_view fieldName) const
241 {
243 }
244
245 const std::string &GetTypeName(ROOT::RFieldToken token) const
246 {
247 EnsureMatchingModel(token);
248 return fFieldTypes[token.fIndex];
249 }
250
251 const std::string &GetTypeName(std::string_view fieldName) const { return GetTypeName(GetToken(fieldName)); }
252
253 bool HasField(std::string_view fieldName) const { return fFieldName2Token.count(std::string(fieldName)) > 0; }
254
255 std::uint64_t GetModelId() const { return fModelId; }
256 std::uint64_t GetSchemaId() const { return fSchemaId; }
257
258 ConstIterator_t begin() const { return fValues.cbegin(); }
259 ConstIterator_t end() const { return fValues.cend(); }
260};
261
262} // namespace ROOT
263
264#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:300
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
Class used to read a RNTupleAttrSet in the context of a RNTupleReader.
The REntry is a collection of values in an RNTuple corresponding to a complete row in the data set.
Definition REntry.hxx:55
std::uint64_t fModelId
The entry must be linked to a specific model, identified by a model ID.
Definition REntry.hxx:64
void EmplaceNewValue(ROOT::RFieldToken token)
Create a new value for the field referenced by token.
Definition REntry.hxx:165
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:226
std::vector< ROOT::RFieldBase::RValue > fValues
Corresponds to the fields of the linked model.
Definition REntry.hxx:68
std::uint64_t GetModelId() const
Definition REntry.hxx:255
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:193
void BindValue(ROOT::RFieldToken token, std::shared_ptr< T > objPtr)
Bind the value for the field, referenced by token, to objPtr.
Definition REntry.hxx:178
std::uint64_t GetSchemaId() const
Definition REntry.hxx:256
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:122
const std::string & GetTypeName(ROOT::RFieldToken token) const
Definition REntry.hxx:245
void EnsureMatchingType(ROOT::RFieldToken token) const
Definition REntry.hxx:135
ConstIterator_t begin() const
Definition REntry.hxx:258
void Read(ROOT::NTupleSize_t index)
Definition REntry.hxx:97
std::vector< std::string > fFieldTypes
To ensure that the entry is standalone, a copy of all field types.
Definition REntry.hxx:72
std::uint64_t fSchemaId
The entry and its tokens are also linked to a specific schema, identified by a schema ID.
Definition REntry.hxx:66
void BindRawPtr(std::string_view fieldName, T *rawPtr)
Bind the value for the field, referenced by its name, to rawPtr.
Definition REntry.hxx:217
void AddValue(ROOT::RFieldBase::RValue &&value)
Definition REntry.hxx:78
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:240
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:76
REntry & operator=(REntry &&other)=default
REntry & operator=(const REntry &other)=delete
ConstIterator_t end() const
Definition REntry.hxx:259
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:87
bool HasField(std::string_view fieldName) const
Definition REntry.hxx:253
void EnsureMatchingModel(ROOT::RFieldToken token) const
Definition REntry.hxx:113
void BindRawPtr(ROOT::RFieldToken token, T *rawPtr)
Bind the value for the field, referenced by token, to rawPtr.
Definition REntry.hxx:202
void EmplaceNewValue(std::string_view fieldName)
Create a new value for the field referenced by its name.
Definition REntry.hxx:172
std::size_t Append()
Definition REntry.hxx:104
~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:155
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:70
const std::string & GetTypeName(std::string_view fieldName) const
Definition REntry.hxx:251
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.
std::size_t fIndex
The index of the field (top-level or registered subfield)
std::uint64_t fSchemaId
Safety check to prevent tokens from other models being used.
Classes with dictionaries that can be inspected by TClass.
Definition RField.hxx:323
A context for filling entries (data) into clusters of an RNTuple.
The RNTupleModel encapulates the schema of an RNTuple.
Reads RNTuple data from storage.
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
A pair of scoped + meta entry used by the RNTupleAttrSetWriter.