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 ROOT7
3/// \author Jakob Blomer <jblomer@cern.ch>
4/// \date 2018-07-19
5/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
6/// is welcome!
7
8/*************************************************************************
9 * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
10 * All rights reserved. *
11 * *
12 * For the licensing terms see $ROOTSYS/LICENSE. *
13 * For the list of contributors see $ROOTSYS/README/CREDITS. *
14 *************************************************************************/
15
16#ifndef ROOT7_REntry
17#define ROOT7_REntry
18
19#include <ROOT/RError.hxx>
20#include <ROOT/RField.hxx>
21#include <string_view>
22
23#include <TError.h>
24
25#include <algorithm>
26#include <iterator>
27#include <memory>
28#include <type_traits>
29#include <utility>
30#include <vector>
31#include <unordered_map>
32
33namespace ROOT {
34namespace Experimental {
35
36class RNTupleProcessor;
37class RNTupleSingleProcessor;
38class RNTupleChainProcessor;
39class RNTupleJoinProcessor;
40
41// clang-format off
42/**
43\class ROOT::Experimental::REntry
44\ingroup NTuple
45\brief The REntry is a collection of values in an ntuple corresponding to a complete row in the data set
46
47The entry provides a memory-managed binder for a set of values. Through shared pointers, the memory locations
48that are associated to values are managed.
49*/
50// clang-format on
51class REntry {
52 friend class RNTupleModel;
53 friend class RNTupleReader;
54 friend class RNTupleFillContext;
55 friend class RNTupleProcessor;
59
60public:
61 /// The field token identifies a (sub)field in this entry. It can be used for fast indexing in REntry's methods, e.g.
62 /// BindValue. The field token can also be created by the model.
64 friend class REntry;
65 friend class RNTupleModel;
66
67 std::size_t fIndex = 0; ///< The index in fValues that belongs to the field
68 std::uint64_t fSchemaId = std::uint64_t(-1); ///< Safety check to prevent tokens from other models being used
69 RFieldToken(std::size_t index, std::uint64_t schemaId) : fIndex(index), fSchemaId(schemaId) {}
70
71 public:
72 RFieldToken() = default; // The default constructed token cannot be used by any entry
73 };
74
75private:
76 /// The entry must be linked to a specific model, identified by a model ID
77 std::uint64_t fModelId = 0;
78 /// The entry and its tokens are also linked to a specific schema, identified by a schema ID
79 std::uint64_t fSchemaId = 0;
80 /// Corresponds to the fields of the linked model
81 std::vector<RFieldBase::RValue> fValues;
82 /// For fast lookup of token IDs given a (sub)field name present in the entry
83 std::unordered_map<std::string, std::size_t> fFieldName2Token;
84 /// To ensure that the entry is standalone, a copy of all field types
85 std::vector<std::string> fFieldTypes;
86
87 // Creation of entries is done by the RNTupleModel class
88
89 REntry() = default;
90 explicit REntry(std::uint64_t modelId, std::uint64_t schemaId) : fModelId(modelId), fSchemaId(schemaId) {}
91
93 {
94 fFieldName2Token[value.GetField().GetQualifiedFieldName()] = fValues.size();
95 fFieldTypes.push_back(value.GetField().GetTypeName());
96 fValues.emplace_back(std::move(value));
97 }
98
99 /// While building the entry, adds a new value to the list and return the value's shared pointer
100 template <typename T>
101 std::shared_ptr<T> AddValue(RField<T> &field)
102 {
104 fFieldTypes.push_back(field.GetTypeName());
105 auto value = field.CreateValue();
106 fValues.emplace_back(value);
107 return value.template GetPtr<T>();
108 }
109
110 /// Update the RValue for a field in the entry. To be used when its underlying RFieldBase changes, which typically
111 /// happens when page source the field values are read from changes.
112 void UpdateValue(RFieldToken token, RFieldBase::RValue &&value) { std::swap(fValues.at(token.fIndex), value); }
113 void UpdateValue(RFieldToken token, RFieldBase::RValue &value) { std::swap(fValues.at(token.fIndex), value); }
114
115 /// Return the RValue currently bound to the provided field.
117 RFieldBase::RValue &GetValue(std::string_view fieldName) { return GetValue(GetToken(fieldName)); }
118
120 {
121 for (auto &v : fValues) {
122 v.Read(index);
123 }
124 }
125
126 std::size_t Append()
127 {
128 std::size_t bytesWritten = 0;
129 for (auto &v : fValues) {
130 bytesWritten += v.Append();
131 }
132 return bytesWritten;
133 }
134
136 {
137 if (fSchemaId != token.fSchemaId) {
138 throw RException(R__FAIL("invalid token for this entry, "
139 "make sure to use a token from a model with the same schema as this entry."));
140 }
141 }
142
143 /// This function has linear complexity, only use for more helpful error messages!
144 const std::string &FindFieldName(RFieldToken token) const
145 {
146 for (const auto &[fieldName, index] : fFieldName2Token) {
147 if (index == token.fIndex) {
148 return fieldName;
149 }
150 }
151 // Should never happen, but avoid compiler warning about "returning reference to local temporary object".
152 static const std::string empty = "";
153 return empty;
154 }
155
156 template <typename T>
157 void EnsureMatchingType(RFieldToken token [[maybe_unused]]) const
158 {
159 if constexpr (!std::is_void_v<T>) {
160 if (fFieldTypes[token.fIndex] != RField<T>::TypeName()) {
161 throw RException(R__FAIL("type mismatch for field " + FindFieldName(token) + ": " +
162 fFieldTypes[token.fIndex] + " vs. " + RField<T>::TypeName()));
163 }
164 }
165 }
166
167public:
168 using ConstIterator_t = decltype(fValues)::const_iterator;
169
170 REntry(const REntry &other) = delete;
171 REntry &operator=(const REntry &other) = delete;
172 REntry(REntry &&other) = default;
173 REntry &operator=(REntry &&other) = default;
174 ~REntry() = default;
175
176 /// The ordinal of the (sub)field fieldName; can be used in other methods to address the corresponding value
177 RFieldToken GetToken(std::string_view fieldName) const
178 {
179 auto it = fFieldName2Token.find(std::string(fieldName));
180 if (it == fFieldName2Token.end()) {
181 throw RException(R__FAIL("invalid field name: " + std::string(fieldName)));
182 }
183 return RFieldToken(it->second, fSchemaId);
184 }
185
187 {
188 EnsureMatchingModel(token);
189 fValues[token.fIndex].EmplaceNew();
190 }
191
192 void EmplaceNewValue(std::string_view fieldName) { EmplaceNewValue(GetToken(fieldName)); }
193
194 template <typename T>
195 void BindValue(RFieldToken token, std::shared_ptr<T> objPtr)
196 {
197 EnsureMatchingModel(token);
198 EnsureMatchingType<T>(token);
199 fValues[token.fIndex].Bind(objPtr);
200 }
201
202 template <typename T>
203 void BindValue(std::string_view fieldName, std::shared_ptr<T> objPtr)
204 {
205 BindValue<T>(GetToken(fieldName), objPtr);
206 }
207
208 template <typename T>
209 void BindRawPtr(RFieldToken token, T *rawPtr)
210 {
211 EnsureMatchingModel(token);
212 EnsureMatchingType<T>(token);
213 fValues[token.fIndex].BindRawPtr(rawPtr);
214 }
215
216 template <typename T>
217 void BindRawPtr(std::string_view fieldName, T *rawPtr)
218 {
219 BindRawPtr<void>(GetToken(fieldName), rawPtr);
220 }
221
222 template <typename T>
223 std::shared_ptr<T> GetPtr(RFieldToken token) const
224 {
225 EnsureMatchingModel(token);
226 EnsureMatchingType<T>(token);
227 return std::static_pointer_cast<T>(fValues[token.fIndex].GetPtr<void>());
228 }
229
230 template <typename T>
231 std::shared_ptr<T> GetPtr(std::string_view fieldName) const
232 {
233 return GetPtr<T>(GetToken(fieldName));
234 }
235
236 const std::string &GetTypeName(RFieldToken token) const
237 {
238 EnsureMatchingModel(token);
239 return fFieldTypes[token.fIndex];
240 }
241
242 const std::string &GetTypeName(std::string_view fieldName) const { return GetTypeName(GetToken(fieldName)); }
243
244 std::uint64_t GetModelId() const { return fModelId; }
245 std::uint64_t GetSchemaId() const { return fSchemaId; }
246
247 ConstIterator_t begin() const { return fValues.cbegin(); }
248 ConstIterator_t end() const { return fValues.cend(); }
249};
250
251} // namespace Experimental
252} // namespace ROOT
253
254#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
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 field token identifies a (sub)field in this entry.
Definition REntry.hxx:63
std::size_t fIndex
The index in fValues that belongs to the field.
Definition REntry.hxx:67
RFieldToken(std::size_t index, std::uint64_t schemaId)
Definition REntry.hxx:69
std::uint64_t fSchemaId
Safety check to prevent tokens from other models being used.
Definition REntry.hxx:68
The REntry is a collection of values in an ntuple corresponding to a complete row in the data set.
Definition REntry.hxx:51
void EnsureMatchingType(RFieldToken token) const
Definition REntry.hxx:157
const std::string & GetTypeName(RFieldToken token) const
Definition REntry.hxx:236
std::uint64_t fSchemaId
The entry and its tokens are also linked to a specific schema, identified by a schema ID.
Definition REntry.hxx:79
std::uint64_t fModelId
The entry must be linked to a specific model, identified by a model ID.
Definition REntry.hxx:77
void BindValue(RFieldToken token, std::shared_ptr< T > objPtr)
Definition REntry.hxx:195
REntry & operator=(REntry &&other)=default
std::uint64_t GetSchemaId() const
Definition REntry.hxx:245
decltype(fValues)::const_iterator ConstIterator_t
Definition REntry.hxx:168
std::vector< std::string > fFieldTypes
To ensure that the entry is standalone, a copy of all field types.
Definition REntry.hxx:85
void Read(NTupleSize_t index)
Definition REntry.hxx:119
ConstIterator_t begin() const
Definition REntry.hxx:247
REntry & operator=(const REntry &other)=delete
const std::string & GetTypeName(std::string_view fieldName) const
Definition REntry.hxx:242
void EmplaceNewValue(std::string_view fieldName)
Definition REntry.hxx:192
REntry(REntry &&other)=default
std::uint64_t GetModelId() const
Definition REntry.hxx:244
void EmplaceNewValue(RFieldToken token)
Definition REntry.hxx:186
const std::string & FindFieldName(RFieldToken token) const
This function has linear complexity, only use for more helpful error messages!
Definition REntry.hxx:144
void BindRawPtr(RFieldToken token, T *rawPtr)
Definition REntry.hxx:209
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:83
void BindValue(std::string_view fieldName, std::shared_ptr< T > objPtr)
Definition REntry.hxx:203
void UpdateValue(RFieldToken token, RFieldBase::RValue &&value)
Update the RValue for a field in the entry.
Definition REntry.hxx:112
REntry(std::uint64_t modelId, std::uint64_t schemaId)
Definition REntry.hxx:90
RFieldBase::RValue & GetValue(std::string_view fieldName)
Definition REntry.hxx:117
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:177
std::shared_ptr< T > AddValue(RField< T > &field)
While building the entry, adds a new value to the list and return the value's shared pointer.
Definition REntry.hxx:101
RFieldBase::RValue & GetValue(RFieldToken token)
Return the RValue currently bound to the provided field.
Definition REntry.hxx:116
void AddValue(RFieldBase::RValue &&value)
Definition REntry.hxx:92
void UpdateValue(RFieldToken token, RFieldBase::RValue &value)
Definition REntry.hxx:113
std::vector< RFieldBase::RValue > fValues
Corresponds to the fields of the linked model.
Definition REntry.hxx:81
void BindRawPtr(std::string_view fieldName, T *rawPtr)
Definition REntry.hxx:217
ConstIterator_t end() const
Definition REntry.hxx:248
void EnsureMatchingModel(RFieldToken token) const
Definition REntry.hxx:135
REntry(const REntry &other)=delete
std::shared_ptr< T > GetPtr(std::string_view fieldName) const
Definition REntry.hxx:231
std::shared_ptr< T > GetPtr(RFieldToken token) const
Definition REntry.hxx:223
Points to an object with RNTuple I/O support and keeps a pointer to the corresponding field.
const std::string & GetTypeName() const
std::string GetQualifiedFieldName() const
Returns the field name and parent field names separated by dots ("grandparent.parent....
RValue CreateValue()
Generates an object of the field type and wraps the created object in a shared pointer and returns it...
Classes with dictionaries that can be inspected by TClass.
Definition RField.hxx:242
Processor specializiation for vertically concatenated RNTuples (chains).
A context for filling entries (data) into clusters of an RNTuple.
Processor specializiation for horizontally concatenated RNTuples (joins).
The RNTupleModel encapulates the schema of an ntuple.
Interface for iterating over entries of RNTuples and vertically concatenated RNTuples (chains).
An RNTuple that is used to read data from storage.
Processor specializiation for processing a single RNTuple.
Base class for all ROOT issued exceptions.
Definition RError.hxx:79
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...