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