Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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 {
46 private:
48 public:
50 using iterator_category = std::forward_iterator_tag;
55
56 RIterator() = default;
57 explicit RIterator(NTupleSize_t index) : fIndex(index) {}
58 ~RIterator() = default;
59
60 iterator operator++(int) /* postfix */ { auto r = *this; fIndex++; return r; }
61 iterator& operator++() /* prefix */ { ++fIndex; return *this; }
63 pointer operator->() { return &fIndex; }
64 bool operator==(const iterator& rh) const { return fIndex == rh.fIndex; }
65 bool operator!=(const iterator& rh) const { return fIndex != rh.fIndex; }
66 };
67
70 RIterator end() { return RIterator(fEnd); }
71};
72
73
74// clang-format off
75/**
76\class ROOT::Experimental::RNTupleClusterRange
77\ingroup NTuple
78\brief Used to loop over entries of collections in a single cluster
79*/
80// clang-format on
82private:
86public:
87 class RIterator {
88 private:
90 public:
92 using iterator_category = std::forward_iterator_tag;
97
98 RIterator() = default;
99 explicit RIterator(const RClusterIndex &index) : fIndex(index) {}
100 ~RIterator() = default;
101
102 iterator operator++(int) /* postfix */ { auto r = *this; fIndex++; return r; }
103 iterator& operator++() /* prefix */ { fIndex++; return *this; }
105 pointer operator->() { return &fIndex; }
106 bool operator==(const iterator& rh) const { return fIndex == rh.fIndex; }
107 bool operator!=(const iterator& rh) const { return fIndex != rh.fIndex; }
108 };
109
111 : fClusterId(clusterId), fStart(start), fEnd(end) {}
114};
115
116
117namespace Internal {
118
119template <class FieldT>
121public:
122 using RSuccess = char;
123 struct RFailure { char x[2]; };
124
125 template<class C, typename ... ArgsT>
126 using MapOverloadT = decltype(std::declval<C>().Map(std::declval<ArgsT>() ...)) (C::*)(ArgsT ...);
127
128 template <class C> static RSuccess Test(MapOverloadT<C, NTupleSize_t>);
129 template <class C> static RFailure Test(...);
130
131public:
132 static constexpr bool value = sizeof(Test<FieldT>(0)) == sizeof(RSuccess);
133};
134
135} // namespace Internal
136
137
138// clang-format off
139/**
140\class ROOT::Experimental::RNTupleView
141\ingroup NTuple
142\brief An RNTupleView provides read-only access to a single field of the ntuple
143
144The view owns a field and its underlying columns in order to fill an ntuple value object with data. Data can be
145accessed by index. For top-level fields, the index refers to the entry number. Fields that are part of
146nested collections have global index numbers that are derived from their parent indexes.
147
148Fields of simple types with a Map() method will use that and thus expose zero-copy access.
149*/
150// clang-format on
151template <typename T>
153 friend class RNTupleReader;
155
157
158private:
159 /// fFieldId has fParent always set to null; views access nested fields without looking at the parent
161 /// Used as a Read() destination for fields that are not mappable
163
165 : fField(pageSource->GetDescriptor().GetFieldDescriptor(fieldId).GetFieldName()), fValue(fField.GenerateValue())
166 {
167 Detail::RFieldFuse::ConnectRecursively(fieldId, *pageSource, fField);
168 }
169
170public:
171 RNTupleView(const RNTupleView& other) = delete;
172 RNTupleView(RNTupleView&& other) = default;
173 RNTupleView& operator=(const RNTupleView& other) = delete;
174 RNTupleView& operator=(RNTupleView&& other) = default;
175 ~RNTupleView() { fField.DestroyValue(fValue); }
176
177 RNTupleGlobalRange GetFieldRange() const { return RNTupleGlobalRange(0, fField.GetNElements()); }
178
179 template <typename C = T>
180 typename std::enable_if_t<Internal::IsMappable<FieldT>::value, const C&>
181 operator()(NTupleSize_t globalIndex) { return *fField.Map(globalIndex); }
182
183 template <typename C = T>
184 typename std::enable_if_t<!Internal::IsMappable<FieldT>::value, const C&>
186 fField.Read(globalIndex, &fValue);
187 return *fValue.Get<T>();
188 }
189
190 template <typename C = T>
191 typename std::enable_if_t<Internal::IsMappable<FieldT>::value, const C&>
192 operator()(const RClusterIndex &clusterIndex) { return *fField.Map(clusterIndex); }
193
194 template <typename C = T>
195 typename std::enable_if_t<!Internal::IsMappable<FieldT>::value, const C&>
196 operator()(const RClusterIndex &clusterIndex) {
197 fField.Read(clusterIndex, &fValue);
198 return *fValue.Get<T>();
199 }
200};
201
202
203// clang-format off
204/**
205\class ROOT::Experimental::RNTupleViewCollection
206\ingroup NTuple
207\brief A view for a collection, that can itself generate new ntuple views for its nested fields.
208*/
209// clang-format on
210class RNTupleViewCollection : public RNTupleView<ClusterSize_t> {
211 friend class RNTupleReader;
212
213private:
216
218 : RNTupleView<ClusterSize_t>(fieldId, source)
219 , fSource(source)
220 , fCollectionFieldId(fieldId)
221 {}
222
223public:
229
231 ClusterSize_t size;
232 RClusterIndex collectionStart;
233 fField.GetCollectionInfo(globalIndex, &collectionStart, &size);
234 return RNTupleClusterRange(collectionStart.GetClusterId(), collectionStart.GetIndex(),
235 collectionStart.GetIndex() + size);
236 }
238 ClusterSize_t size;
239 RClusterIndex collectionStart;
240 fField.GetCollectionInfo(clusterIndex, &collectionStart, &size);
241 return RNTupleClusterRange(collectionStart.GetClusterId(), collectionStart.GetIndex(),
242 collectionStart.GetIndex() + size);
243 }
244
245 template <typename T>
246 RNTupleView<T> GetView(std::string_view fieldName) {
247 auto fieldId = fSource->GetDescriptor().FindFieldId(fieldName, fCollectionFieldId);
248 return RNTupleView<T>(fieldId, fSource);
249 }
250 RNTupleViewCollection GetViewCollection(std::string_view fieldName) {
251 auto fieldId = fSource->GetDescriptor().FindFieldId(fieldName, fCollectionFieldId);
252 return RNTupleViewCollection(fieldId, fSource);
253 }
254
256 ClusterSize_t size;
257 RClusterIndex collectionStart;
258 fField.GetCollectionInfo(globalIndex, &collectionStart, &size);
259 return size;
260 }
262 ClusterSize_t size;
263 RClusterIndex collectionStart;
264 fField.GetCollectionInfo(clusterIndex, &collectionStart, &size);
265 return size;
266 }
267};
268
269} // namespace Experimental
270} // namespace ROOT
271
272#endif
ROOT::R::TRInterface & r
Definition Object.C:4
static void ConnectRecursively(DescriptorId_t fieldId, RPageSource &pageSource, RFieldBase &field)
Connect the field columns and all sub field columns.
Definition RField.cxx:127
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...
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:504
Classes with dictionaries that can be inspected by TClass.
Definition RField.hxx:412
Used to loop over entries of collections in a single cluster.
const ClusterSize_t::ValueType fStart
RNTupleClusterRange(DescriptorId_t clusterId, ClusterSize_t::ValueType start, ClusterSize_t::ValueType end)
const ClusterSize_t::ValueType fEnd
DescriptorId_t FindFieldId(std::string_view fieldName, DescriptorId_t parentId) const
Used to loop over indexes (entries or collections) between start and end.
RNTupleGlobalRange(NTupleSize_t start, NTupleSize_t end)
An RNTuple that is used to read data from storage.
Definition RNTuple.hxx:90
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
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
std::uint64_t DescriptorId_t
Distriniguishes elements of the same type within a descriptor, e.g. different fields.
constexpr NTupleSize_t kInvalidNTupleIndex
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
Wrap the 32bit integer in a struct in order to avoid template specialization clash with std::uint32_t...