Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
REntry.hxx
Go to the documentation of this file.
1/// \file ROOT/REntry.hxx
2/// \author Jakob Blomer <jblomer@cern.ch>
3/// \date 2018-07-19
4
5/*************************************************************************
6 * Copyright (C) 1995-2019, 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_REntry
14#define ROOT_REntry
15
16#include <ROOT/RError.hxx>
17#include <ROOT/RField.hxx>
18#include <ROOT/RFieldToken.hxx>
19#include <string_view>
20
21#include <TError.h>
22
23#include <algorithm>
24#include <iterator>
25#include <memory>
26#include <type_traits>
27#include <utility>
28#include <vector>
29#include <unordered_map>
30
31namespace ROOT {
32
33class RNTupleFillContext;
34class RNTupleReader;
35
36namespace Experimental {
37class RNTupleAttrSetReader;
38
39namespace Internal {
40struct RNTupleAttrEntry;
41}
42} // namespace Experimental
43
44namespace Internal {
45class RNTupleMergeStrategySlow;
46}
47
48// clang-format off
49/**
50\class ROOT::REntry
51\ingroup NTuple
52\brief The REntry is a collection of values in an RNTuple corresponding to a complete row in the data set.
53
54The entry provides a memory-managed binder for a set of values read from fields in an RNTuple. The memory locations that are associated
55with values are managed through shared pointers.
56*/
57// clang-format on
58class REntry {
59 friend class RNTupleFillContext;
60 friend class RNTupleModel;
61 friend class RNTupleReader;
65
66private:
67 /// The entry must be linked to a specific model, identified by a model ID
68 std::uint64_t fModelId = 0;
69 /// The entry and its tokens are also linked to a specific schema, identified by a schema ID
70 std::uint64_t fSchemaId = 0;
71 /// Corresponds to the fields of the linked model
72 std::vector<ROOT::RFieldBase::RValue> fValues;
73 /// For fast lookup of token IDs given a (sub)field name present in the entry
74 std::unordered_map<std::string, std::size_t> fFieldName2Token;
75 /// To ensure that the entry is standalone, a copy of all field types
76 std::vector<std::string> fFieldTypes;
77
78 /// Creation of entries can be done by the RNTupleModel, the RNTupleReader, or the RNTupleWriter.
79 REntry() = default;
80 explicit REntry(std::uint64_t modelId, std::uint64_t schemaId) : fModelId(modelId), fSchemaId(schemaId) {}
81
83 {
84 fFieldName2Token[value.GetField().GetQualifiedFieldName()] = fValues.size();
85 fFieldTypes.push_back(value.GetField().GetTypeName());
86 fValues.emplace_back(std::move(value));
87 }
88
89 /// While building the entry, adds a new value for the field and returns the value's shared pointer
90 template <typename T>
91 std::shared_ptr<T> AddValue(ROOT::RField<T> &field)
92 {
94 fFieldTypes.push_back(field.GetTypeName());
95 auto value = field.CreateValue();
96 fValues.emplace_back(value);
97 // We know that the created RValue has the right type, skip the unnecessary check.
98 return std::static_pointer_cast<T>(value.template GetPtr<void>());
99 }
100
102 {
103 for (auto &v : fValues) {
104 v.Read(index);
105 }
106 }
107
108 std::size_t Append()
109 {
110 std::size_t bytesWritten = 0;
111 for (auto &v : fValues) {
112 bytesWritten += v.Append();
113 }
114 return bytesWritten;
115 }
116
118 {
119 if (fSchemaId != token.fSchemaId) {
120 throw RException(R__FAIL("invalid token for this entry, "
121 "make sure to use a token from a model with the same schema as this entry."));
122 }
123 }
124
125 /// This function has linear complexity, only use it for more helpful error messages!
126 const std::string &FindFieldName(ROOT::RFieldToken token) const
127 {
128 for (const auto &[fieldName, index] : fFieldName2Token) {
129 if (index == token.fIndex) {
130 return fieldName;
131 }
132 }
133 // Should never happen, but avoid compiler warning about "returning reference to local temporary object".
134 static const std::string empty = "";
135 return empty;
136 }
137
138 template <typename T>
139 void EnsureMatchingType(ROOT::RFieldToken token [[maybe_unused]]) const
140 {
141 if constexpr (!std::is_void_v<T>) {
142 if (!Internal::IsMatchingFieldType<T>(fFieldTypes[token.fIndex])) {
143 throw RException(R__FAIL("type mismatch for field " + FindFieldName(token) + ": " +
144 fFieldTypes[token.fIndex] + " vs. " + ROOT::RField<T>::TypeName()));
145 }
146 }
147 }
148
149public:
150 using ConstIterator_t = decltype(fValues)::const_iterator;
151
152 REntry(const REntry &other) = delete;
153 REntry &operator=(const REntry &other) = delete;
154 REntry(REntry &&other) = default;
155 REntry &operator=(REntry &&other) = default;
156 ~REntry() = default;
157
158 /// The ordinal of the (sub)field fieldName; can be used in other methods to address the corresponding value
159 ROOT::RFieldToken GetToken(std::string_view fieldName) const
160 {
161 auto it = fFieldName2Token.find(std::string(fieldName));
162 if (it == fFieldName2Token.end()) {
163 throw RException(R__FAIL("invalid field name: " + std::string(fieldName)));
164 }
165 return ROOT::RFieldToken(it->second, fSchemaId);
166 }
167
168 /// Create a new value for the field referenced by `token`.
170 {
171 EnsureMatchingModel(token);
172 fValues[token.fIndex].EmplaceNew();
173 }
174
175 /// Create a new value for the field referenced by its name.
176 void EmplaceNewValue(std::string_view fieldName) { EmplaceNewValue(GetToken(fieldName)); }
177
178 /// Bind the value for the field, referenced by `token`, to `objPtr`.
179 ///
180 /// \sa BindValue(std::string_view, std::shared_ptr<T>)
181 template <typename T>
182 void BindValue(ROOT::RFieldToken token, std::shared_ptr<T> objPtr)
183 {
184 EnsureMatchingModel(token);
185 EnsureMatchingType<T>(token);
186 fValues[token.fIndex].Bind(objPtr);
187 }
188
189 /// Bind the value for the field, referenced by its name, to `objPtr`.
190 ///
191 /// Ownership is shared with the caller and the object will be kept alive until it is replaced (by a call to
192 /// EmplaceNewValue, BindValue, or BindRawPtr) or the entry is destructed.
193 ///
194 /// **Note**: if `T = void`, type checks are disabled. It is the caller's responsibility to match the field and
195 /// object types.
196 template <typename T>
197 void BindValue(std::string_view fieldName, std::shared_ptr<T> objPtr)
198 {
199 BindValue<T>(GetToken(fieldName), objPtr);
200 }
201
202 /// Bind the value for the field, referenced by `token`, to `rawPtr`.
203 ///
204 /// \sa BindRawPtr(std::string_view, T *)
205 template <typename T>
206 void BindRawPtr(ROOT::RFieldToken token, T *rawPtr)
207 {
208 EnsureMatchingModel(token);
209 EnsureMatchingType<T>(token);
210 fValues[token.fIndex].BindRawPtr(rawPtr);
211 }
212
213 /// Bind the value for the field, referenced by its name, to `rawPtr`.
214 ///
215 /// The caller retains ownership of the object and must ensure it is kept alive when reading or writing using the
216 /// entry.
217 ///
218 /// **Note**: if `T = void`, type checks are disabled. It is the caller's responsibility to match the field and
219 /// object types.
220 template <typename T>
221 void BindRawPtr(std::string_view fieldName, T *rawPtr)
222 {
223 BindRawPtr<T>(GetToken(fieldName), rawPtr);
224 }
225
226 /// Get the (typed) pointer to the value for the field referenced by `token`.
227 ///
228 /// \sa GetPtr(std::string_view)
229 template <typename T>
230 std::shared_ptr<T> GetPtr(ROOT::RFieldToken token) const
231 {
232 EnsureMatchingModel(token);
233 EnsureMatchingType<T>(token);
234 return std::static_pointer_cast<T>(fValues[token.fIndex].GetPtr<void>());
235 }
236
237 /// Get the (typed) pointer to the value for the field referenced by `token`.
238 ///
239 /// Ownership is shared and the caller can continue to use the object after the entry is destructed.
240 ///
241 /// **Note**: if `T = void`, type checks are disabled. It is the caller's responsibility to use the returned pointer
242 /// according to the field type.
243 template <typename T>
244 std::shared_ptr<T> GetPtr(std::string_view fieldName) const
245 {
246 return GetPtr<T>(GetToken(fieldName));
247 }
248
249 const std::string &GetTypeName(ROOT::RFieldToken token) const
250 {
251 EnsureMatchingModel(token);
252 return fFieldTypes[token.fIndex];
253 }
254
255 const std::string &GetTypeName(std::string_view fieldName) const { return GetTypeName(GetToken(fieldName)); }
256
257 bool HasField(std::string_view fieldName) const { return fFieldName2Token.count(std::string(fieldName)) > 0; }
258
259 std::uint64_t GetModelId() const { return fModelId; }
260 std::uint64_t GetSchemaId() const { return fSchemaId; }
261
262 ConstIterator_t begin() const { return fValues.cbegin(); }
263 ConstIterator_t end() const { return fValues.cend(); }
264};
265
266} // namespace ROOT
267
268#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:322
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:58
std::uint64_t fModelId
The entry must be linked to a specific model, identified by a model ID.
Definition REntry.hxx:68
void EmplaceNewValue(ROOT::RFieldToken token)
Create a new value for the field referenced by token.
Definition REntry.hxx:169
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:230
std::vector< ROOT::RFieldBase::RValue > fValues
Corresponds to the fields of the linked model.
Definition REntry.hxx:72
std::uint64_t GetModelId() const
Definition REntry.hxx:259
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:197
void BindValue(ROOT::RFieldToken token, std::shared_ptr< T > objPtr)
Bind the value for the field, referenced by token, to objPtr.
Definition REntry.hxx:182
std::uint64_t GetSchemaId() const
Definition REntry.hxx:260
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:126
const std::string & GetTypeName(ROOT::RFieldToken token) const
Definition REntry.hxx:249
void EnsureMatchingType(ROOT::RFieldToken token) const
Definition REntry.hxx:139
ConstIterator_t begin() const
Definition REntry.hxx:262
void Read(ROOT::NTupleSize_t index)
Definition REntry.hxx:101
std::vector< std::string > fFieldTypes
To ensure that the entry is standalone, a copy of all field types.
Definition REntry.hxx:76
std::uint64_t fSchemaId
The entry and its tokens are also linked to a specific schema, identified by a schema ID.
Definition REntry.hxx:70
void BindRawPtr(std::string_view fieldName, T *rawPtr)
Bind the value for the field, referenced by its name, to rawPtr.
Definition REntry.hxx:221
void AddValue(ROOT::RFieldBase::RValue &&value)
Definition REntry.hxx:82
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:244
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:80
REntry & operator=(REntry &&other)=default
REntry & operator=(const REntry &other)=delete
ConstIterator_t end() const
Definition REntry.hxx:263
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:91
bool HasField(std::string_view fieldName) const
Definition REntry.hxx:257
void EnsureMatchingModel(ROOT::RFieldToken token) const
Definition REntry.hxx:117
void BindRawPtr(ROOT::RFieldToken token, T *rawPtr)
Bind the value for the field, referenced by token, to rawPtr.
Definition REntry.hxx:206
void EmplaceNewValue(std::string_view fieldName)
Create a new value for the field referenced by its name.
Definition REntry.hxx:176
std::size_t Append()
Definition REntry.hxx:108
decltype(fValues)::const_iterator ConstIterator_t
Definition REntry.hxx:150
~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:159
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:74
const std::string & GetTypeName(std::string_view fieldName) const
Definition REntry.hxx:255
Base class for all ROOT issued exceptions.
Definition RError.hxx:78
Points to an object with RNTuple I/O support and keeps a pointer to the corresponding field.
RValue CreateValue()
Generates an object of the field's type, wraps it in a shared pointer and returns it as an RValue con...
std::string GetQualifiedFieldName() const
Returns the field name and parent field names separated by dots (grandparent.parent....
const std::string & GetTypeName() const
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:342
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.