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 
29 namespace ROOT {
30 namespace 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
40 class RNTupleGlobalRange {
41 private:
42  const NTupleSize_t fStart;
43  const NTupleSize_t fEnd;
44 public:
45  class RIterator {
46  private:
48  public:
49  using iterator = RIterator;
50  using iterator_category = std::forward_iterator_tag;
51  using value_type = NTupleSize_t;
53  using pointer = NTupleSize_t*;
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; }
62  reference operator* () { return fIndex; }
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
82 private:
86 public:
87  class RIterator {
88  private:
90  public:
91  using iterator = RIterator;
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) {}
113  RIterator end() { return RIterator(RClusterIndex(fClusterId, fEnd)); }
114 };
115 
116 
117 namespace Internal {
118 
119 template <class FieldT>
120 class IsMappable {
121 public:
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 
131 public:
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 
144 The view owns a field and its underlying columns in order to fill an ntuple value object with data. Data can be
145 accessed by index. For top-level fields, the index refers to the entry number. Fields that are part of
146 nested collections have global index numbers that are derived from their parent indexes.
147 
148 Fields of simple types with a Map() method will use that and thus expose zero-copy access.
149 */
150 // clang-format on
151 template <typename T>
152 class RNTupleView {
153  friend class RNTupleReader;
154  friend class RNTupleViewCollection;
155 
156  using FieldT = RField<T>;
157 
158 private:
159  /// fFieldId has fParent always set to null; views access nested fields without looking at the parent
160  FieldT fField;
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::Connect(fieldId, *pageSource, fField);
168  std::unordered_map<const Detail::RFieldBase *, DescriptorId_t> field2Id;
169  field2Id[&fField] = fieldId;
170  for (auto &f : fField) {
171  auto subFieldId = pageSource->GetDescriptor().FindFieldId(f.GetName(), field2Id[f.GetParent()]);
172  Detail::RFieldFuse::Connect(subFieldId, *pageSource, f);
173  field2Id[&f] = subFieldId;
174  }
175  }
176 
177 public:
178  RNTupleView(const RNTupleView& other) = delete;
179  RNTupleView(RNTupleView&& other) = default;
180  RNTupleView& operator=(const RNTupleView& other) = delete;
181  RNTupleView& operator=(RNTupleView&& other) = default;
183 
185 
186  template <typename C = T>
187  typename std::enable_if_t<Internal::IsMappable<FieldT>::value, const C&>
188  operator()(NTupleSize_t globalIndex) { return *fField.Map(globalIndex); }
189 
190  template <typename C = T>
191  typename std::enable_if_t<!Internal::IsMappable<FieldT>::value, const C&>
192  operator()(NTupleSize_t globalIndex) {
193  fField.Read(globalIndex, &fValue);
194  return *fValue.Get<T>();
195  }
196 
197  template <typename C = T>
198  typename std::enable_if_t<Internal::IsMappable<FieldT>::value, const C&>
199  operator()(const RClusterIndex &clusterIndex) { return *fField.Map(clusterIndex); }
200 
201  template <typename C = T>
202  typename std::enable_if_t<!Internal::IsMappable<FieldT>::value, const C&>
203  operator()(const RClusterIndex &clusterIndex) {
204  fField.Read(clusterIndex, &fValue);
205  return *fValue.Get<T>();
206  }
207 };
208 
209 
210 // clang-format off
211 /**
212 \class ROOT::Experimental::RNTupleViewCollection
213 \ingroup NTuple
214 \brief A view for a collection, that can itself generate new ntuple views for its nested fields.
215 */
216 // clang-format on
217 class RNTupleViewCollection : public RNTupleView<ClusterSize_t> {
218  friend class RNTupleReader;
219 
220 private:
223 
225  : RNTupleView<ClusterSize_t>(fieldId, source)
226  , fSource(source)
227  , fCollectionFieldId(fieldId)
228  {}
229 
230 public:
231  RNTupleViewCollection(const RNTupleViewCollection& other) = delete;
232  RNTupleViewCollection(RNTupleViewCollection&& other) = default;
235  ~RNTupleViewCollection() = default;
236 
238  ClusterSize_t size;
239  RClusterIndex collectionStart;
240  fField.GetCollectionInfo(globalIndex, &collectionStart, &size);
241  return RNTupleClusterRange(collectionStart.GetClusterId(), collectionStart.GetIndex(),
242  collectionStart.GetIndex() + size);
243  }
245  ClusterSize_t size;
246  RClusterIndex collectionStart;
247  fField.GetCollectionInfo(clusterIndex, &collectionStart, &size);
248  return RNTupleClusterRange(collectionStart.GetClusterId(), collectionStart.GetIndex(),
249  collectionStart.GetIndex() + size);
250  }
251 
252  template <typename T>
254  auto fieldId = fSource->GetDescriptor().FindFieldId(fieldName, fCollectionFieldId);
255  return RNTupleView<T>(fieldId, fSource);
256  }
258  auto fieldId = fSource->GetDescriptor().FindFieldId(fieldName, fCollectionFieldId);
259  return RNTupleViewCollection(fieldId, fSource);
260  }
261 
262  ClusterSize_t operator()(NTupleSize_t globalIndex) {
263  ClusterSize_t size;
264  RClusterIndex collectionStart;
265  fField.GetCollectionInfo(globalIndex, &collectionStart, &size);
266  return size;
267  }
268  ClusterSize_t operator()(const RClusterIndex &clusterIndex) {
270  RClusterIndex collectionStart;
271  fField.GetCollectionInfo(clusterIndex, &collectionStart, &size);
272  return size;
273  }
274 };
275 
276 } // namespace Experimental
277 } // namespace ROOT
278 
279 #endif
ROOT::Experimental::RNTupleClusterRange::RIterator::operator->
pointer operator->()
Definition: RNTupleView.hxx:117
ROOT::Experimental::RNTupleView::operator=
RNTupleView & operator=(const RNTupleView &other)=delete
ROOT::Experimental::Detail::RFieldValue::Get
T * Get() const
Definition: RFieldValue.hxx:97
ROOT::Experimental::RNTupleClusterRange::RNTupleClusterRange
RNTupleClusterRange(DescriptorId_t clusterId, ClusterSize_t::ValueType start, ClusterSize_t::ValueType end)
Definition: RNTupleView.hxx:122
ROOT::Experimental::RNTupleGlobalRange::RIterator::operator!=
bool operator!=(const iterator &rh) const
Definition: RNTupleView.hxx:77
f
#define f(i)
Definition: RSha256.hxx:122
ROOT::Experimental::RNTupleGlobalRange::RIterator
Definition: RNTupleView.hxx:57
ROOT::Experimental::RNTupleGlobalRange::RIterator::fIndex
NTupleSize_t fIndex
Definition: RNTupleView.hxx:59
ROOT::Experimental::RNTupleView< ClusterSize_t >::RNTupleViewCollection
friend class RNTupleViewCollection
Definition: RNTupleView.hxx:166
ROOT::Experimental::RNTupleClusterRange::begin
RIterator begin()
Definition: RNTupleView.hxx:124
ROOT::Experimental::RNTupleClusterRange::fStart
const ClusterSize_t::ValueType fStart
Definition: RNTupleView.hxx:96
ROOT::Experimental::RNTupleView::operator()
std::enable_if_t< Internal::IsMappable< FieldT >::value, const C & > operator()(NTupleSize_t globalIndex)
Definition: RNTupleView.hxx:200
ROOT::Experimental::RNTupleViewCollection::~RNTupleViewCollection
~RNTupleViewCollection()=default
ROOT::Experimental::RNTupleViewCollection::GetViewCollection
RNTupleViewCollection GetViewCollection(std::string_view fieldName)
Definition: RNTupleView.hxx:269
ROOT::Experimental::Detail::RFieldBase::GetNElements
NTupleSize_t GetNElements() const
Definition: RField.hxx:222
ROOT::Experimental::Internal::IsMappable::Test
static RSuccess Test(MapOverloadT< C, NTupleSize_t >)
ROOT::Experimental::DescriptorId_t
std::uint64_t DescriptorId_t
Distriniguishes elements of the same type within a descriptor, e.g. different fields.
Definition: RNTupleUtil.hxx:97
r
ROOT::R::TRInterface & r
Definition: Object.C:4
RField.hxx
ROOT::Experimental::RNTupleViewCollection::GetCollectionRange
RNTupleClusterRange GetCollectionRange(NTupleSize_t globalIndex)
Definition: RNTupleView.hxx:249
string_view
basic_string_view< char > string_view
Definition: libcpp_string_view.h:785
ROOT::Experimental::RNTupleGlobalRange::RIterator::operator==
bool operator==(const iterator &rh) const
Definition: RNTupleView.hxx:76
ROOT::Experimental::NTupleSize_t
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
Definition: RNTupleUtil.hxx:61
ROOT::Experimental::Detail::RPageSource
Abstract interface to read data from an ntuple.
Definition: RPageStorage.hxx:180
ROOT::Experimental::RClassField::DestroyValue
void DestroyValue(const Detail::RFieldValue &value, bool dtorOnly=false) final
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
Definition: RField.cxx:576
ROOT::Experimental::RNTupleViewCollection::operator()
ClusterSize_t operator()(NTupleSize_t globalIndex)
Definition: RNTupleView.hxx:274
ROOT::Experimental::RNTupleGlobalRange::RIterator::RIterator
RIterator(NTupleSize_t index)
Definition: RNTupleView.hxx:69
ROOT::Experimental::RNTupleView
An RNTupleView provides read-only access to a single field of the ntuple.
Definition: RNTupleView.hxx:164
ROOT::Experimental::Detail::RFieldValue
Definition: RFieldValue.hxx:59
ROOT::Experimental::RNTupleClusterRange::RIterator
Definition: RNTupleView.hxx:99
ROOT::Experimental::RNTupleViewCollection::operator=
RNTupleViewCollection & operator=(const RNTupleViewCollection &other)=delete
ROOT::Experimental::RNTupleGlobalRange::RIterator::iterator
RIterator iterator
Definition: RNTupleView.hxx:61
ROOT::Experimental::RNTupleGlobalRange::fStart
const NTupleSize_t fStart
Definition: RNTupleView.hxx:54
ROOT::Experimental::RNTupleClusterRange
Used to loop over entries of collections in a single cluster.
Definition: RNTupleView.hxx:93
ROOT::Experimental::RClusterIndex::GetIndex
ClusterSize_t::ValueType GetIndex() const
Definition: RNTupleUtil.hxx:122
ROOT::Experimental::RNTupleGlobalRange::RIterator::operator->
pointer operator->()
Definition: RNTupleView.hxx:75
ROOT::Experimental::RNTupleGlobalRange::RIterator::pointer
NTupleSize_t * pointer
Definition: RNTupleView.hxx:65
ROOT::Math::Cephes::C
static double C[]
Definition: SpecFuncCephes.cxx:187
ROOT::Experimental::RNTupleViewCollection::GetView
RNTupleView< T > GetView(std::string_view fieldName)
Definition: RNTupleView.hxx:265
ROOT::Experimental::RNTupleView::fField
FieldT fField
fFieldId has fParent always set to null; views access nested fields without looking at the parent
Definition: RNTupleView.hxx:172
ROOT::Experimental::RNTupleClusterRange::RIterator::value_type
RClusterIndex value_type
Definition: RNTupleView.hxx:105
ROOT::Experimental::RNTupleClusterRange::end
RIterator end()
Definition: RNTupleView.hxx:125
ROOT::Experimental::RClusterSize::ValueType
std::uint32_t ValueType
Definition: RNTupleUtil.hxx:65
ROOT::Experimental::Internal::IsMappable::value
static constexpr bool value
Definition: RNTupleView.hxx:144
ROOT::Experimental::RNTupleClusterRange::RIterator::~RIterator
~RIterator()=default
ROOT::Experimental::RNTupleClusterRange::fEnd
const ClusterSize_t::ValueType fEnd
Definition: RNTupleView.hxx:97
ROOT::Experimental::Internal::IsMappable::RSuccess
char RSuccess
Definition: RNTupleView.hxx:134
ROOT::Experimental::RNTupleGlobalRange::end
RIterator end()
Definition: RNTupleView.hxx:82
RStringView.hxx
ROOT::Experimental::kInvalidNTupleIndex
constexpr NTupleSize_t kInvalidNTupleIndex
Definition: RNTupleUtil.hxx:62
ROOT::Experimental::RClusterIndex::GetClusterId
DescriptorId_t GetClusterId() const
Definition: RNTupleUtil.hxx:121
ROOT::Experimental::RNTupleViewCollection
A view for a collection, that can itself generate new ntuple views for its nested fields.
Definition: RNTupleView.hxx:229
ROOT::Experimental::RNTupleDescriptor::FindFieldId
DescriptorId_t FindFieldId(std::string_view fieldName, DescriptorId_t parentId) const
Definition: RNTupleDescriptor.cxx:668
ROOT::Experimental::Internal::IsMappable::MapOverloadT
decltype(std::declval< C >().Map(std::declval< ArgsT >() ...))(C::*)(ArgsT ...) MapOverloadT
Definition: RNTupleView.hxx:138
ROOT::Experimental::Detail::RPageSource::GetDescriptor
const RNTupleDescriptor & GetDescriptor() const
Definition: RPageStorage.hxx:203
ROOT::Experimental::RNTupleView::RNTupleView
RNTupleView(DescriptorId_t fieldId, Detail::RPageSource *pageSource)
Definition: RNTupleView.hxx:176
ROOT::Experimental::RNTupleGlobalRange::RIterator::difference_type
NTupleSize_t difference_type
Definition: RNTupleView.hxx:64
ROOT::Experimental::RNTupleClusterRange::RIterator::pointer
RClusterIndex * pointer
Definition: RNTupleView.hxx:107
ROOT::Experimental::RNTupleView::FieldT
RField< T > FieldT
Definition: RNTupleView.hxx:168
ROOT::Experimental::Detail::RFieldFuse::Connect
static void Connect(DescriptorId_t fieldId, RPageStorage &pageStorage, RFieldBase &field)
Definition: RField.cxx:116
ROOT::Experimental::RNTupleClusterRange::RIterator::fIndex
RClusterIndex fIndex
Definition: RNTupleView.hxx:101
ROOT::Experimental::RNTupleClusterRange::RIterator::operator++
iterator & operator++()
Definition: RNTupleView.hxx:115
ROOT::Experimental::RNTupleView::GetFieldRange
RNTupleGlobalRange GetFieldRange() const
Definition: RNTupleView.hxx:196
RNTupleUtil.hxx
ROOT::Experimental::RNTupleClusterRange::RIterator::iterator_category
std::forward_iterator_tag iterator_category
Definition: RNTupleView.hxx:104
ROOT::Experimental::RNTupleGlobalRange::RIterator::RIterator
RIterator()=default
ROOT::Experimental::RNTupleGlobalRange
Used to loop over indexes (entries or collections) between start and end.
Definition: RNTupleView.hxx:52
ROOT::Experimental::RClusterIndex
Addresses a column element or field item relative to a particular cluster, instead of a global NTuple...
Definition: RNTupleUtil.hxx:101
ROOT::Experimental::RNTupleGlobalRange::fEnd
const NTupleSize_t fEnd
Definition: RNTupleView.hxx:55
ROOT::Experimental::RClusterSize
Wrap the 32bit integer in a struct in order to avoid template specialization clash with std::uint32_t...
Definition: RNTupleUtil.hxx:64
ROOT::Experimental::RNTupleClusterRange::RIterator::iterator
RIterator iterator
Definition: RNTupleView.hxx:103
ROOT::Experimental::RNTupleClusterRange::RIterator::operator!=
bool operator!=(const iterator &rh) const
Definition: RNTupleView.hxx:119
ROOT::Experimental::Internal::IsMappable::RFailure::x
char x[2]
Definition: RNTupleView.hxx:135
ROOT::Experimental::RNTupleView::fValue
Detail::RFieldValue fValue
Used as a Read() destination for fields that are not mappable.
Definition: RNTupleView.hxx:174
ROOT::Experimental::RNTupleClusterRange::fClusterId
const DescriptorId_t fClusterId
Definition: RNTupleView.hxx:95
ROOT::Experimental::RNTupleClusterRange::RIterator::difference_type
RClusterIndex difference_type
Definition: RNTupleView.hxx:106
ROOT::Experimental::ClusterSize_t
RClusterSize ClusterSize_t
Definition: RNTupleUtil.hxx:76
ROOT::Experimental::RNTupleGlobalRange::RIterator::operator*
reference operator*()
Definition: RNTupleView.hxx:74
ROOT::Experimental::RNTupleGlobalRange::RIterator::operator++
iterator & operator++()
Definition: RNTupleView.hxx:73
ROOT::Math::Chebyshev::T
double T(double x)
Definition: ChebyshevPol.h:52
ROOT::Experimental::RNTupleGlobalRange::RIterator::iterator_category
std::forward_iterator_tag iterator_category
Definition: RNTupleView.hxx:62
ROOT::Experimental::RNTupleClusterRange::RIterator::RIterator
RIterator()=default
ROOT::Experimental::RField< ClusterSize_t >::GetCollectionInfo
void GetCollectionInfo(NTupleSize_t globalIndex, RClusterIndex *collectionStart, ClusterSize_t *size)
Special help for offset fields.
Definition: RField.hxx:500
ROOT::Experimental::RNTupleViewCollection::fSource
Detail::RPageSource * fSource
Definition: RNTupleView.hxx:233
ROOT::Experimental::RNTupleView::~RNTupleView
~RNTupleView()
Definition: RNTupleView.hxx:194
ROOT::Experimental::Detail::RFieldBase::Read
void Read(NTupleSize_t globalIndex, RFieldValue *value)
Populate a single value with data from the tree, which needs to be of the fitting type.
Definition: RField.hxx:194
ROOT::Experimental::RNTupleViewCollection::fCollectionFieldId
DescriptorId_t fCollectionFieldId
Definition: RNTupleView.hxx:234
ROOT::Experimental::RNTupleClusterRange::RIterator::operator==
bool operator==(const iterator &rh) const
Definition: RNTupleView.hxx:118
ROOT::Experimental::RNTupleGlobalRange::RIterator::reference
NTupleSize_t & reference
Definition: RNTupleView.hxx:66
ROOT::Experimental::RNTupleClusterRange::RIterator::reference
RClusterIndex & reference
Definition: RNTupleView.hxx:108
ROOT::VecOps::Map
auto Map(Args &&... args) -> decltype(ROOT::Detail::VecOps::MapFromTuple(std::forward_as_tuple(args...), std::make_index_sequence< sizeof...(args) - 1 >()))
Create new collection applying a callable to the elements of the input collection.
Definition: RVec.hxx:909
ROOT::Experimental::RNTupleGlobalRange::RIterator::~RIterator
~RIterator()=default
ROOT
VSD Structures.
Definition: StringConv.hxx:21
ROOT::Experimental::RNTupleGlobalRange::RNTupleGlobalRange
RNTupleGlobalRange(NTupleSize_t start, NTupleSize_t end)
Definition: RNTupleView.hxx:80
ROOT::Experimental::RNTupleGlobalRange::RIterator::value_type
NTupleSize_t value_type
Definition: RNTupleView.hxx:63
ROOT::Experimental::RNTupleClusterRange::RIterator::operator*
reference operator*()
Definition: RNTupleView.hxx:116
ROOT::Experimental::RNTupleReader
An RNTuple that is used to read data from storage.
Definition: RNTuple.hxx:87
ROOT::Experimental::RField< T >
ROOT::Experimental::RNTupleGlobalRange::begin
RIterator begin()
Definition: RNTupleView.hxx:81