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
32namespace ROOT {
33namespace Experimental {
34
35// clang-format off
36/**
37\class ROOT::Experimental::REntry
38\ingroup NTuple
39\brief The REntry is a collection of values in an ntuple corresponding to a complete row in the data set
40
41The entry provides a memory-managed binder for a set of values. Through shared pointers, the memory locations
42that are associated to values are managed.
43*/
44// clang-format on
45class REntry {
47 friend class RNTupleModel;
48 friend class RNTupleReader;
49 friend class RNTupleFillContext;
50
51public:
52 /// The field token identifies a top-level field in this entry. It can be used for fast indexing in REntry's
53 /// methods, e.g. BindValue. The field token can also be created by the model.
55 friend class REntry;
56 friend class RNTupleModel;
57
58 std::size_t fIndex; ///< the index in fValues that belongs to the top-level field
59 std::uint64_t fModelId; ///< Safety check to prevent tokens from other models being used
60 RFieldToken(std::size_t index, std::uint64_t modelId) : fIndex(index), fModelId(modelId) {}
61 };
62
63private:
64 /// The entry must be linked to a specific model (or one if its clones), identified by a model ID
65 std::uint64_t fModelId = 0;
66 /// Corresponds to the top-level fields of the linked model
67 std::vector<RFieldBase::RValue> fValues;
68
69 // Creation of entries is done by the RNTupleModel class
70
71 REntry() = default;
72 explicit REntry(std::uint64_t modelId) : fModelId(modelId) {}
73
74 void AddValue(RFieldBase::RValue &&value) { fValues.emplace_back(std::move(value)); }
75
76 /// While building the entry, adds a new value to the list and return the value's shared pointer
77 template <typename T, typename... ArgsT>
78 std::shared_ptr<T> AddValue(RField<T> &field, ArgsT &&...args)
79 {
80 auto ptr = std::make_shared<T>(std::forward<ArgsT>(args)...);
81 fValues.emplace_back(field.BindValue(ptr));
82 return ptr;
83 }
84
86 {
87 for (auto &v : fValues) {
88 v.Read(index);
89 }
90 }
91
92 std::size_t Append()
93 {
94 std::size_t bytesWritten = 0;
95 for (auto &v : fValues) {
96 bytesWritten += v.Append();
97 }
98 return bytesWritten;
99 }
100
102 {
103 if (fModelId != token.fModelId) {
104 throw RException(R__FAIL("invalid token for this entry, "
105 "make sure to use a token from the same model as this entry."));
106 }
107 }
108
109 template <typename T>
110 void EnsureMatchingType(RFieldToken token [[maybe_unused]]) const
111 {
112 if constexpr (!std::is_void_v<T>) {
113 const auto &v = fValues[token.fIndex];
114 if (v.GetField().GetTypeName() != RField<T>::TypeName()) {
115 throw RException(R__FAIL("type mismatch for field " + v.GetField().GetFieldName() + ": " +
116 v.GetField().GetTypeName() + " vs. " + RField<T>::TypeName()));
117 }
118 }
119 }
120
121public:
122 using ConstIterator_t = decltype(fValues)::const_iterator;
123
124 REntry(const REntry &other) = delete;
125 REntry &operator=(const REntry &other) = delete;
126 REntry(REntry &&other) = default;
127 REntry &operator=(REntry &&other) = default;
128 ~REntry() = default;
129
130 /// The ordinal of the top-level field fieldName; can be used in other methods to address the corresponding value
131 RFieldToken GetToken(std::string_view fieldName) const
132 {
133 auto it = std::find_if(fValues.begin(), fValues.end(),
134 [&fieldName] (const RFieldBase::RValue &value) { return value.GetField().GetFieldName() == fieldName; });
135
136 if ( it == fValues.end() ) {
137 throw RException(R__FAIL("invalid field name: " + std::string(fieldName)));
138 }
139 return RFieldToken(std::distance(fValues.begin(), it), fModelId);
140 }
141
143 {
144 EnsureMatchingModel(token);
145 fValues[token.fIndex].EmplaceNew();
146 }
147
148 void EmplaceNewValue(std::string_view fieldName) { EmplaceNewValue(GetToken(fieldName)); }
149
150 template <typename T>
151 void BindValue(RFieldToken token, std::shared_ptr<T> objPtr)
152 {
153 EnsureMatchingModel(token);
154 EnsureMatchingType<T>(token);
155 fValues[token.fIndex].Bind(objPtr);
156 }
157
158 template <typename T>
159 void BindValue(std::string_view fieldName, std::shared_ptr<T> objPtr)
160 {
161 BindValue<T>(GetToken(fieldName), objPtr);
162 }
163
164 template <typename T>
165 void BindRawPtr(RFieldToken token, T *rawPtr)
166 {
167 EnsureMatchingModel(token);
168 EnsureMatchingType<T>(token);
169 fValues[token.fIndex].BindRawPtr(rawPtr);
170 }
171
172 template <typename T>
173 void BindRawPtr(std::string_view fieldName, T *rawPtr)
174 {
175 BindRawPtr<void>(GetToken(fieldName), rawPtr);
176 }
177
178 template <typename T>
179 std::shared_ptr<T> GetPtr(RFieldToken token) const
180 {
181 EnsureMatchingModel(token);
182 EnsureMatchingType<T>(token);
183 return std::static_pointer_cast<T>(fValues[token.fIndex].GetPtr<void>());
184 }
185
186 template <typename T>
187 std::shared_ptr<T> GetPtr(std::string_view fieldName) const
188 {
189 return GetPtr<T>(GetToken(fieldName));
190 }
191
192 std::uint64_t GetModelId() const { return fModelId; }
193
194 ConstIterator_t begin() const { return fValues.cbegin(); }
195 ConstIterator_t end() const { return fValues.cend(); }
196};
197
198} // namespace Experimental
199} // namespace ROOT
200
201#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:290
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 top-level field in this entry.
Definition REntry.hxx:54
std::uint64_t fModelId
Safety check to prevent tokens from other models being used.
Definition REntry.hxx:59
std::size_t fIndex
the index in fValues that belongs to the top-level field
Definition REntry.hxx:58
RFieldToken(std::size_t index, std::uint64_t modelId)
Definition REntry.hxx:60
The REntry is a collection of values in an ntuple corresponding to a complete row in the data set.
Definition REntry.hxx:45
void EnsureMatchingType(RFieldToken token) const
Definition REntry.hxx:110
std::uint64_t fModelId
The entry must be linked to a specific model (or one if its clones), identified by a model ID.
Definition REntry.hxx:65
void BindValue(RFieldToken token, std::shared_ptr< T > objPtr)
Definition REntry.hxx:151
REntry & operator=(REntry &&other)=default
decltype(fValues)::const_iterator ConstIterator_t
Definition REntry.hxx:122
void Read(NTupleSize_t index)
Definition REntry.hxx:85
ConstIterator_t begin() const
Definition REntry.hxx:194
REntry & operator=(const REntry &other)=delete
REntry(std::uint64_t modelId)
Definition REntry.hxx:72
void EmplaceNewValue(std::string_view fieldName)
Definition REntry.hxx:148
REntry(REntry &&other)=default
std::uint64_t GetModelId() const
Definition REntry.hxx:192
void EmplaceNewValue(RFieldToken token)
Definition REntry.hxx:142
std::shared_ptr< T > AddValue(RField< T > &field, ArgsT &&...args)
While building the entry, adds a new value to the list and return the value's shared pointer.
Definition REntry.hxx:78
void BindRawPtr(RFieldToken token, T *rawPtr)
Definition REntry.hxx:165
void BindValue(std::string_view fieldName, std::shared_ptr< T > objPtr)
Definition REntry.hxx:159
RFieldToken GetToken(std::string_view fieldName) const
The ordinal of the top-level field fieldName; can be used in other methods to address the correspondi...
Definition REntry.hxx:131
void AddValue(RFieldBase::RValue &&value)
Definition REntry.hxx:74
std::vector< RFieldBase::RValue > fValues
Corresponds to the top-level fields of the linked model.
Definition REntry.hxx:67
void BindRawPtr(std::string_view fieldName, T *rawPtr)
Definition REntry.hxx:173
ConstIterator_t end() const
Definition REntry.hxx:195
void EnsureMatchingModel(RFieldToken token) const
Definition REntry.hxx:101
REntry(const REntry &other)=delete
std::shared_ptr< T > GetPtr(std::string_view fieldName) const
Definition REntry.hxx:187
std::shared_ptr< T > GetPtr(RFieldToken token) const
Definition REntry.hxx:179
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.
Definition RField.hxx:185
RValue BindValue(std::shared_ptr< void > objPtr)
Creates a value from a memory location with an already constructed object.
Definition RField.hxx:640
Classes with dictionaries that can be inspected by TClass.
Definition RField.hxx:1469
static std::string TypeName()
Definition RField.hxx:1482
A virtual ntuple used for writing untyped collections that can be used to some extent like an RNTuple...
A context for filling entries (data) into clusters of an RNTuple.
The RNTupleModel encapulates the schema of an ntuple.
An RNTuple that is used to read data from storage.
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.