Logo ROOT  
Reference Guide
RNTupleView.hxx
Go to the documentation of this file.
1/// \file ROOT/RNTupleView.hxx
2/// \ingroup NTuple ROOT7
3/// \author Jakob Blomer <jblomer@cern.ch>
4/// \date 2018-10-05
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_RNTupleView
17#define ROOT7_RNTupleView
18
19#include <ROOT/RField.hxx>
20#include <ROOT/RNTupleUtil.hxx>
21#include <ROOT/RStringView.hxx>
22
23#include <iterator>
24#include <memory>
25#include <type_traits>
26#include <utility>
27#include <unordered_map>
28
29namespace ROOT {
30namespace Experimental {
31
32
33// clang-format off
34/**
35\class ROOT::Experimental::RNTupleGlobalRange
36\ingroup NTuple
37\brief Used to loop over indexes (entries or collections) between start and end
38*/
39// clang-format on
41private:
44public:
45 class RIterator : public std::iterator<std::forward_iterator_tag, NTupleSize_t> {
46 private:
49 public:
50 RIterator() = default;
51 explicit RIterator(NTupleSize_t index) : fIndex(index) {}
52 ~RIterator() = default;
53
54 iterator operator++(int) /* postfix */ { auto r = *this; fIndex++; return r; }
55 iterator& operator++() /* prefix */ { ++fIndex; return *this; }
56 reference operator* () { return fIndex; }
57 pointer operator->() { return &fIndex; }
58 bool operator==(const iterator& rh) const { return fIndex == rh.fIndex; }
59 bool operator!=(const iterator& rh) const { return fIndex != rh.fIndex; }
60 };
61
64 RIterator end() { return RIterator(fEnd); }
65};
66
67
68// clang-format off
69/**
70\class ROOT::Experimental::RNTupleClusterRange
71\ingroup NTuple
72\brief Used to loop over entries of collections in a single cluster
73*/
74// clang-format on
76private:
80public:
81 class RIterator : public std::iterator<std::forward_iterator_tag, RClusterIndex> {
82 private:
85 public:
86 RIterator() = default;
87 explicit RIterator(const RClusterIndex &index) : fIndex(index) {}
88 ~RIterator() = default;
89
90 iterator operator++(int) /* postfix */ { auto r = *this; fIndex++; return r; }
91 iterator& operator++() /* prefix */ { fIndex++; return *this; }
92 reference operator* () { return fIndex; }
93 pointer operator->() { return &fIndex; }
94 bool operator==(const iterator& rh) const { return fIndex == rh.fIndex; }
95 bool operator!=(const iterator& rh) const { return fIndex != rh.fIndex; }
96 };
97
99 : fClusterId(clusterId), fStart(start), fEnd(end) {}
102};
103
104
105namespace Internal {
106
107template <class FieldT>
109public:
110 using RSuccess = char;
111 struct RFailure { char x[2]; };
112
113 template<class C, typename ... ArgsT>
114 using MapOverloadT = decltype(std::declval<C>().Map(std::declval<ArgsT>() ...)) (C::*)(ArgsT ...);
115
116 template <class C> static RSuccess Test(MapOverloadT<C, NTupleSize_t>);
117 template <class C> static RFailure Test(...);
118
119public:
120 static constexpr bool value = sizeof(Test<FieldT>(0)) == sizeof(RSuccess);
121};
122
123} // namespace Internal
124
125
126// clang-format off
127/**
128\class ROOT::Experimental::RNTupleView
129\ingroup NTuple
130\brief An RNTupleView provides read-only access to a single field of the ntuple
131
132The view owns a field and its underlying columns in order to fill an ntuple value object with data. Data can be
133accessed by index. For top level fields, the index refers to the entry number. Fields that are part of
134nested collections have global index numbers that are derived from their parent indexes.
135
136Fields of simple types with a Map() method will use that and thus expose zero-copy access.
137*/
138// clang-format on
139template <typename T>
141 friend class RNTupleReader;
143
145
146private:
147 /// fFieldId has fParent always set to null; views access nested fields without looking at the parent
149 /// Used as a Read() destination for fields that are not mappable
151
153 : fField(pageSource->GetDescriptor().GetFieldDescriptor(fieldId).GetFieldName()), fValue(fField.GenerateValue())
154 {
155 Detail::RFieldFuse::Connect(fieldId, *pageSource, fField);
156 std::unordered_map<const Detail::RFieldBase *, DescriptorId_t> field2Id;
157 field2Id[&fField] = fieldId;
158 for (auto &f : fField) {
159 auto subFieldId = pageSource->GetDescriptor().FindFieldId(f.GetName(), field2Id[f.GetParent()]);
160 Detail::RFieldFuse::Connect(subFieldId, *pageSource, f);
161 field2Id[&f] = subFieldId;
162 }
163 }
164
165public:
166 RNTupleView(const RNTupleView& other) = delete;
167 RNTupleView(RNTupleView&& other) = default;
168 RNTupleView& operator=(const RNTupleView& other) = delete;
169 RNTupleView& operator=(RNTupleView&& other) = default;
170 ~RNTupleView() { fField.DestroyValue(fValue); }
171
172 RNTupleGlobalRange GetFieldRange() const { return RNTupleGlobalRange(0, fField.GetNElements()); }
173
174 template <typename C = T>
175 typename std::enable_if_t<Internal::IsMappable<FieldT>::value, const C&>
176 operator()(NTupleSize_t globalIndex) { return *fField.Map(globalIndex); }
177
178 template <typename C = T>
179 typename std::enable_if_t<!Internal::IsMappable<FieldT>::value, const C&>
181 fField.Read(globalIndex, &fValue);
182 return *fValue.Get<T>();
183 }
184
185 template <typename C = T>
186 typename std::enable_if_t<Internal::IsMappable<FieldT>::value, const C&>
187 operator()(const RClusterIndex &clusterIndex) { return *fField.Map(clusterIndex); }
188
189 template <typename C = T>
190 typename std::enable_if_t<!Internal::IsMappable<FieldT>::value, const C&>
191 operator()(const RClusterIndex &clusterIndex) {
192 fField.Read(clusterIndex, &fValue);
193 return *fValue.Get<T>();
194 }
195};
196
197
198// clang-format off
199/**
200\class ROOT::Experimental::RNTupleViewCollection
201\ingroup NTuple
202\brief A view for a collection, that can itself generate new ntuple views for its nested fields.
203*/
204// clang-format on
205class RNTupleViewCollection : public RNTupleView<ClusterSize_t> {
206 friend class RNTupleReader;
207
208private:
211
213 : RNTupleView<ClusterSize_t>(fieldId, source)
214 , fSource(source)
215 , fCollectionFieldId(fieldId)
216 {}
217
218public:
224
226 ClusterSize_t size;
227 RClusterIndex collectionStart;
228 fField.GetCollectionInfo(globalIndex, &collectionStart, &size);
229 return RNTupleClusterRange(collectionStart.GetClusterId(), collectionStart.GetIndex(),
230 collectionStart.GetIndex() + size);
231 }
233 ClusterSize_t size;
234 RClusterIndex collectionStart;
235 fField.GetCollectionInfo(clusterIndex, &collectionStart, &size);
236 return RNTupleClusterRange(collectionStart.GetClusterId(), collectionStart.GetIndex(),
237 collectionStart.GetIndex() + size);
238 }
239
240 template <typename T>
242 auto fieldId = fSource->GetDescriptor().FindFieldId(fieldName, fCollectionFieldId);
243 return RNTupleView<T>(fieldId, fSource);
244 }
246 auto fieldId = fSource->GetDescriptor().FindFieldId(fieldName, fCollectionFieldId);
247 return RNTupleViewCollection(fieldId, fSource);
248 }
249
251 ClusterSize_t size;
252 RClusterIndex collectionStart;
253 fField.GetCollectionInfo(globalIndex, &collectionStart, &size);
254 return size;
255 }
257 ClusterSize_t size;
258 RClusterIndex collectionStart;
259 fField.GetCollectionInfo(clusterIndex, &collectionStart, &size);
260 return size;
261 }
262};
263
264} // namespace Experimental
265} // namespace ROOT
266
267#endif
ROOT::R::TRInterface & r
Definition: Object.C:4
#define f(i)
Definition: RSha256.hxx:104
static void Connect(DescriptorId_t fieldId, RPageStorage &pageStorage, RFieldBase &field)
Definition: RField.cxx:115
Abstract interface to read data from an ntuple.
const RNTupleDescriptor & GetDescriptor() const
decltype(std::declval< C >().Map(std::declval< ArgsT >() ...))(C::*)(ArgsT ...) MapOverloadT
static RSuccess Test(MapOverloadT< C, NTupleSize_t >)
Addresses a column element or field item relative to a particular cluster, instead of a global NTuple...
Definition: RNTupleUtil.hxx:82
DescriptorId_t GetClusterId() const
ClusterSize_t::ValueType GetIndex() const
void GetCollectionInfo(NTupleSize_t globalIndex, RClusterIndex *collectionStart, ClusterSize_t *size)
Special help for offset fields.
Definition: RField.hxx:493
Classes with dictionaries that can be inspected by TClass.
Definition: RField.hxx:403
Used to loop over entries of collections in a single cluster.
Definition: RNTupleView.hxx:75
const ClusterSize_t::ValueType fStart
Definition: RNTupleView.hxx:78
RNTupleClusterRange(DescriptorId_t clusterId, ClusterSize_t::ValueType start, ClusterSize_t::ValueType end)
Definition: RNTupleView.hxx:98
const ClusterSize_t::ValueType fEnd
Definition: RNTupleView.hxx:79
DescriptorId_t FindFieldId(std::string_view fieldName, DescriptorId_t parentId) const
bool operator==(const iterator &rh) const
Definition: RNTupleView.hxx:58
bool operator!=(const iterator &rh) const
Definition: RNTupleView.hxx:59
Used to loop over indexes (entries or collections) between start and end.
Definition: RNTupleView.hxx:40
RNTupleGlobalRange(NTupleSize_t start, NTupleSize_t end)
Definition: RNTupleView.hxx:62
An RNTuple that is used to read data from storage.
Definition: RNTuple.hxx:73
A view for a collection, that can itself generate new ntuple views for its nested fields.
RNTupleClusterRange GetCollectionRange(const RClusterIndex &clusterIndex)
RNTupleViewCollection GetViewCollection(std::string_view fieldName)
RNTupleViewCollection(RNTupleViewCollection &&other)=default
RNTupleViewCollection & operator=(RNTupleViewCollection &&other)=default
RNTupleViewCollection & operator=(const RNTupleViewCollection &other)=delete
RNTupleViewCollection(DescriptorId_t fieldId, Detail::RPageSource *source)
ClusterSize_t operator()(const RClusterIndex &clusterIndex)
ClusterSize_t operator()(NTupleSize_t globalIndex)
RNTupleView< T > GetView(std::string_view fieldName)
RNTupleClusterRange GetCollectionRange(NTupleSize_t globalIndex)
RNTupleViewCollection(const RNTupleViewCollection &other)=delete
An RNTupleView provides read-only access to a single field of the ntuple.
Detail::RFieldValue fValue
Used as a Read() destination for fields that are not mappable.
RNTupleView & operator=(RNTupleView &&other)=default
std::enable_if_t< Internal::IsMappable< FieldT >::value, const C & > operator()(NTupleSize_t globalIndex)
std::enable_if_t<!Internal::IsMappable< FieldT >::value, const C & > operator()(const RClusterIndex &clusterIndex)
RNTupleView & operator=(const RNTupleView &other)=delete
RNTupleView(RNTupleView &&other)=default
RNTupleView(const RNTupleView &other)=delete
RNTupleView(DescriptorId_t fieldId, Detail::RPageSource *pageSource)
std::enable_if_t< Internal::IsMappable< FieldT >::value, const C & > operator()(const RClusterIndex &clusterIndex)
std::enable_if_t<!Internal::IsMappable< FieldT >::value, const C & > operator()(NTupleSize_t globalIndex)
FieldT fField
fFieldId has fParent always set to null; views access nested fields without looking at the parent
RNTupleGlobalRange GetFieldRange() const
basic_string_view< char > string_view
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
Definition: RNTupleUtil.hxx:42
std::uint64_t DescriptorId_t
Distriniguishes elements of the same type within a descriptor, e.g. different fields.
Definition: RNTupleUtil.hxx:78
constexpr NTupleSize_t kInvalidNTupleIndex
Definition: RNTupleUtil.hxx:43
static double C[]
double T(double x)
Definition: ChebyshevPol.h:34
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
Definition: StringConv.hxx:21
Wrap the 32bit integer in a struct in order to avoid template specialization clash with std::uint32_t...
Definition: RNTupleUtil.hxx:45