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;
35class RNTupleAttrSetReader;
36
37namespace Internal {
38struct RNTupleAttrEntry;
39}
40
41namespace Internal {
42class RNTupleMergeStrategySlow;
43}
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;
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 {
91 fFieldTypes.push_back(field.GetTypeName());
92 auto value = field.CreateValue();
93 fValues.emplace_back(value);
94 // We know that the created RValue has the right type, skip the unnecessary check.
95 return std::static_pointer_cast<T>(value.template GetPtr<void>());
96 }
97
99 {
100 for (auto &v : fValues) {
101 v.Read(index);
102 }
103 }
104
105 std::size_t Append()
106 {
107 std::size_t bytesWritten = 0;
108 for (auto &v : fValues) {
109 bytesWritten += v.Append();
110 }
111 return bytesWritten;
112 }
113
115 {
116 if (fSchemaId != token.fSchemaId) {
117 throw RException(R__FAIL("invalid token for this entry, "
118 "make sure to use a token from a model with the same schema as this entry."));
119 }
120 }
121
122 /// This function has linear complexity, only use it for more helpful error messages!
123 const std::string &FindFieldName(ROOT::RFieldToken token) const
124 {
125 for (const auto &[fieldName, index] : fFieldName2Token) {
126 if (index == token.fIndex) {
127 return fieldName;
128 }
129 }
130 // Should never happen, but avoid compiler warning about "returning reference to local temporary object".
131 static const std::string empty = "";
132 return empty;
133 }
134
135 template <typename T>
136 void EnsureMatchingType(ROOT::RFieldToken token [[maybe_unused]]) const
137 {
138 if constexpr (!std::is_void_v<T>) {
139 if (!Internal::IsMatchingFieldType<T>(fFieldTypes[token.fIndex])) {
140 throw RException(R__FAIL("type mismatch for field " + FindFieldName(token) + ": " +
141 fFieldTypes[token.fIndex] + " vs. " + ROOT::RField<T>::TypeName()));
142 }
143 }
144 }
145
146public:
147 using ConstIterator_t = decltype(fValues)::const_iterator;
148
149 REntry(const REntry &other) = delete;
150 REntry &operator=(const REntry &other) = delete;
151 REntry(REntry &&other) = default;
152 REntry &operator=(REntry &&other) = default;
153 ~REntry() = default;
154
155 /// The ordinal of the (sub)field fieldName; can be used in other methods to address the corresponding value
156 ROOT::RFieldToken GetToken(std::string_view fieldName) const
157 {
158 auto it = fFieldName2Token.find(std::string(fieldName));
159 if (it == fFieldName2Token.end()) {
160 throw RException(R__FAIL("invalid field name: " + std::string(fieldName)));
161 }
162 return ROOT::RFieldToken(it->second, fSchemaId);
163 }
164
165 /// Create a new value for the field referenced by `token`.
167 {
168 EnsureMatchingModel(token);
169 fValues[token.fIndex].EmplaceNew();
170 }
171
172 /// Create a new value for the field referenced by its name.
173 void EmplaceNewValue(std::string_view fieldName) { EmplaceNewValue(GetToken(fieldName)); }
174
175 /// Bind the value for the field, referenced by `token`, to `objPtr`.
176 ///
177 /// \sa BindValue(std::string_view, std::shared_ptr<T>)
178 template <typename T>
179 void BindValue(ROOT::RFieldToken token, std::shared_ptr<T> objPtr)
180 {
181 EnsureMatchingModel(token);
182 EnsureMatchingType<T>(token);
183 fValues[token.fIndex].Bind(objPtr);
184 }
185
186 /// Bind the value for the field, referenced by its name, to `objPtr`.
187 ///
188 /// Ownership is shared with the caller and the object will be kept alive until it is replaced (by a call to
189 /// EmplaceNewValue, BindValue, or BindRawPtr) or the entry is destructed.
190 ///
191 /// **Note**: if `T = void`, type checks are disabled. It is the caller's responsibility to match the field and
192 /// object types.
193 template <typename T>
194 void BindValue(std::string_view fieldName, std::shared_ptr<T> objPtr)
195 {
196 BindValue<T>(GetToken(fieldName), objPtr);
197 }
198
199 /// Bind the value for the field, referenced by `token`, to `rawPtr`.
200 ///
201 /// \sa BindRawPtr(std::string_view, T *)
202 template <typename T>
203 void BindRawPtr(ROOT::RFieldToken token, T *rawPtr)
204 {
205 EnsureMatchingModel(token);
206 EnsureMatchingType<T>(token);
207 fValues[token.fIndex].BindRawPtr(rawPtr);
208 }
209
210 /// Bind the value for the field, referenced by its name, to `rawPtr`.
211 ///
212 /// The caller retains ownership of the object and must ensure it is kept alive when reading or writing using the
213 /// entry.
214 ///
215 /// **Note**: if `T = void`, type checks are disabled. It is the caller's responsibility to match the field and
216 /// object types.
217 template <typename T>
218 void BindRawPtr(std::string_view fieldName, T *rawPtr)
219 {
220 BindRawPtr<T>(GetToken(fieldName), rawPtr);
221 }
222
223 /// Get the (typed) pointer to the value for the field referenced by `token`.
224 ///
225 /// \sa GetPtr(std::string_view)
226 template <typename T>
227 std::shared_ptr<T> GetPtr(ROOT::RFieldToken token) const
228 {
229 EnsureMatchingModel(token);
230 EnsureMatchingType<T>(token);
231 return std::static_pointer_cast<T>(fValues[token.fIndex].GetPtr<void>());
232 }
233
234 /// Get the (typed) pointer to the value for the field referenced by `token`.
235 ///
236 /// Ownership is shared and the caller can continue to use the object after the entry is destructed.
237 ///
238 /// **Note**: if `T = void`, type checks are disabled. It is the caller's responsibility to use the returned pointer
239 /// according to the field type.
240 template <typename T>
241 std::shared_ptr<T> GetPtr(std::string_view fieldName) const
242 {
243 return GetPtr<T>(GetToken(fieldName));
244 }
245
246 const std::string &GetTypeName(ROOT::RFieldToken token) const
247 {
248 EnsureMatchingModel(token);
249 return fFieldTypes[token.fIndex];
250 }
251
252 const std::string &GetTypeName(std::string_view fieldName) const { return GetTypeName(GetToken(fieldName)); }
253
254 bool HasField(std::string_view fieldName) const { return fFieldName2Token.count(std::string(fieldName)) > 0; }
255
256 std::uint64_t GetModelId() const { return fModelId; }
257 std::uint64_t GetSchemaId() const { return fSchemaId; }
258
259 ConstIterator_t begin() const { return fValues.cbegin(); }
260 ConstIterator_t end() const { return fValues.cend(); }
261};
262
263} // namespace ROOT
264
265#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
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:65
void EmplaceNewValue(ROOT::RFieldToken token)
Create a new value for the field referenced by token.
Definition REntry.hxx:166
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:227
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:256
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:194
void BindValue(ROOT::RFieldToken token, std::shared_ptr< T > objPtr)
Bind the value for the field, referenced by token, to objPtr.
Definition REntry.hxx:179
std::uint64_t GetSchemaId() const
Definition REntry.hxx:257
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:123
const std::string & GetTypeName(ROOT::RFieldToken token) const
Definition REntry.hxx:246
void EnsureMatchingType(ROOT::RFieldToken token) const
Definition REntry.hxx:136
ConstIterator_t begin() const
Definition REntry.hxx:259
void Read(ROOT::NTupleSize_t index)
Definition REntry.hxx:98
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:218
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:241
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:260
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
bool HasField(std::string_view fieldName) const
Definition REntry.hxx:254
void EnsureMatchingModel(ROOT::RFieldToken token) const
Definition REntry.hxx:114
void BindRawPtr(ROOT::RFieldToken token, T *rawPtr)
Bind the value for the field, referenced by token, to rawPtr.
Definition REntry.hxx:203
void EmplaceNewValue(std::string_view fieldName)
Create a new value for the field referenced by its name.
Definition REntry.hxx:173
std::size_t Append()
Definition REntry.hxx:105
decltype(fValues)::const_iterator ConstIterator_t
Definition REntry.hxx:147
~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:156
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:252
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
Class used to read a RNTupleAttrSet in the context of a RNTupleReader.
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.