Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RNTupleDescriptor.hxx
Go to the documentation of this file.
1/// \file ROOT/RNTupleDescriptor.hxx
2/// \ingroup NTuple ROOT7
3/// \author Jakob Blomer <jblomer@cern.ch>
4/// \author Javier Lopez-Gomez <javier.lopez.gomez@cern.ch>
5/// \date 2018-07-19
6/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
7/// is welcome!
8
9/*************************************************************************
10 * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
11 * All rights reserved. *
12 * *
13 * For the licensing terms see $ROOTSYS/LICENSE. *
14 * For the list of contributors see $ROOTSYS/README/CREDITS. *
15 *************************************************************************/
16
17#ifndef ROOT7_RNTupleDescriptor
18#define ROOT7_RNTupleDescriptor
19
20#include <ROOT/RColumnModel.hxx>
21#include <ROOT/RError.hxx>
23#include <ROOT/RNTupleUtil.hxx>
24#include <ROOT/RSpan.hxx>
25#include <ROOT/RStringView.hxx>
26
27#include <algorithm>
28#include <chrono>
29#include <functional>
30#include <iterator>
31#include <map>
32#include <memory>
33#include <ostream>
34#include <vector>
35#include <string>
36#include <unordered_map>
37#include <unordered_set>
38
39namespace ROOT {
40namespace Experimental {
41
42class RFieldDescriptorBuilder;
43class RNTupleDescriptor;
44class RNTupleDescriptorBuilder;
45class RNTupleModel;
46
47namespace Detail {
48class RColumnElementBase;
49class RFieldBase;
50}
51
52
53// clang-format off
54/**
55\class ROOT::Experimental::RFieldDescriptor
56\ingroup NTuple
57\brief Meta-data stored for every field of an ntuple
58*/
59// clang-format on
63
64private:
66 /// The version of the C++-type-to-column translation mechanics
67 std::uint32_t fFieldVersion = 0;
68 /// The version of the C++ type itself
69 std::uint32_t fTypeVersion = 0;
70 /// The leaf name, not including parent fields
71 std::string fFieldName;
72 /// Free text set by the user
73 std::string fFieldDescription;
74 /// The C++ type that was used when writing the field
75 std::string fTypeName;
76 /// A typedef or using directive that resolved to the type name during field creation
77 std::string fTypeAlias;
78 /// The number of elements per entry for fixed-size arrays
79 std::uint64_t fNRepetitions = 0;
80 /// The structural information carried by this field in the data model tree
82 /// Establishes sub field relationships, such as classes and collections
84 /// The pointers in the other direction from parent to children. They are serialized, too, to keep the
85 /// order of sub fields.
86 std::vector<DescriptorId_t> fLinkIds;
87
88public:
89 RFieldDescriptor() = default;
90 RFieldDescriptor(const RFieldDescriptor &other) = delete;
94
95 bool operator==(const RFieldDescriptor &other) const;
96 /// Get a copy of the descriptor
97 RFieldDescriptor Clone() const;
98 /// In general, we create a field simply from the C++ type name. For untyped fields, however, we potentially need
99 /// access to sub fields, which is provided by the ntuple descriptor argument.
100 std::unique_ptr<Detail::RFieldBase> CreateField(const RNTupleDescriptor &ntplDesc) const;
101
102 DescriptorId_t GetId() const { return fFieldId; }
103 std::uint32_t GetFieldVersion() const { return fFieldVersion; }
104 std::uint32_t GetTypeVersion() const { return fTypeVersion; }
105 std::string GetFieldName() const { return fFieldName; }
106 std::string GetFieldDescription() const { return fFieldDescription; }
107 std::string GetTypeName() const { return fTypeName; }
108 std::string GetTypeAlias() const { return fTypeAlias; }
109 std::uint64_t GetNRepetitions() const { return fNRepetitions; }
112 const std::vector<DescriptorId_t> &GetLinkIds() const { return fLinkIds; }
113};
114
115
116// clang-format off
117/**
118\class ROOT::Experimental::RColumnDescriptor
119\ingroup NTuple
120\brief Meta-data stored for every column of an ntuple
121*/
122// clang-format on
126
127private:
128 /// The actual column identifier, which is the link to the corresponding field
130 /// Usually identical to the logical column ID, except for alias columns where it references the shadowed column
132 /// Contains the column type and whether it is sorted
134 /// Every column belongs to one and only one field
136 /// A field can be serialized into several columns, which are numbered from zero to $n$
137 std::uint32_t fIndex;
138 /// Specifies the index for the first stored element for this column. For deferred columns the value is greater
139 /// than 0
140 std::uint64_t fFirstElementIndex = 0U;
141
142public:
143 RColumnDescriptor() = default;
144 RColumnDescriptor(const RColumnDescriptor &other) = delete;
148
149 bool operator==(const RColumnDescriptor &other) const;
150 /// Get a copy of the descriptor
151 RColumnDescriptor Clone() const;
152
155 RColumnModel GetModel() const { return fModel; }
156 std::uint32_t GetIndex() const { return fIndex; }
159 std::uint64_t GetFirstElementIndex() const { return fFirstElementIndex; }
160 bool IsDeferredColumn() const { return fFirstElementIndex > 0; }
161};
162
163// clang-format off
164/**
165\class ROOT::Experimental::RColumnGroupDescriptor
166\ingroup NTuple
167\brief Meta-data for a sets of columns; non-trivial column groups are used for sharded clusters
168
169Clusters can span a subset of columns. Such subsets are described as a column group. An empty column group
170is used to denote the column group of all the columns. Every ntuple has at least one column group.
171*/
172// clang-format on
175
176private:
178 std::unordered_set<DescriptorId_t> fPhysicalColumnIds;
179
180public:
186
187 bool operator==(const RColumnGroupDescriptor &other) const;
188
190 const std::unordered_set<DescriptorId_t> &GetPhysicalColumnIds() const { return fPhysicalColumnIds; }
191 bool Contains(DescriptorId_t physicalId) const
192 {
193 return fPhysicalColumnIds.empty() || fPhysicalColumnIds.count(physicalId) > 0;
194 }
195 bool HasAllColumns() const { return fPhysicalColumnIds.empty(); }
196};
197
198// clang-format off
199/**
200\class ROOT::Experimental::RClusterDescriptor
201\ingroup NTuple
202\brief Meta-data for a set of ntuple clusters
203
204The cluster descriptor is built in two phases. In a first phase, the descriptor has only summary data,
205i.e. the ID and the event range. In a second phase, page locations and column ranges are added.
206Both phases are populated by the RClusterDescriptorBuilder.
207Clusters usually span across all available columns but in some cases they can describe only a subset of the columns,
208for instance when describing friend ntuples.
209*/
210// clang-format on
213
214public:
215 /// The window of element indexes of a particular column in a particular cluster
218 /// A 64bit element index
220 /// The number of column elements in the cluster
222 /// The usual format for ROOT compression settings (see Compression.h).
223 /// The pages of a particular column in a particular cluster are all compressed with the same settings.
224 std::int64_t fCompressionSettings = 0;
225
226 // TODO(jblomer): we perhaps want to store summary information, such as average, min/max, etc.
227 // Should this be done on the field level?
228
229 bool operator==(const RColumnRange &other) const {
232 }
233
236 }
237 };
238
239 /// Records the parition of data into pages for a particular column in a particular cluster
240 struct RPageRange {
241 /// We do not need to store the element size / uncompressed page size because we know to which column
242 /// the page belongs
243 struct RPageInfo {
244 /// The sum of the elements of all the pages must match the corresponding fNElements field in fColumnRanges
245 std::uint32_t fNElements = std::uint32_t(-1);
246 /// The meaning of fLocator depends on the storage backend.
248
249 bool operator==(const RPageInfo &other) const {
250 return fNElements == other.fNElements && fLocator == other.fLocator;
251 }
252 };
254 /// Index (in cluster) of the first element in page.
256 /// Page number in the corresponding RPageRange.
258
259 RPageInfoExtended() = default;
261 : RPageInfo(pi), fFirstInPage(i), fPageNo(n) {}
262 };
263
264 RPageRange() = default;
265 RPageRange(const RPageRange &other) = delete;
266 RPageRange &operator =(const RPageRange &other) = delete;
267 RPageRange(RPageRange &&other) = default;
268 RPageRange &operator =(RPageRange &&other) = default;
269
272 clone.fPhysicalColumnId = fPhysicalColumnId;
273 clone.fPageInfos = fPageInfos;
274 return clone;
275 }
276
277 /// Find the page in the RPageRange that contains the given element. The element must exist.
278 RPageInfoExtended Find(RClusterSize::ValueType idxInCluster) const;
279
281 std::vector<RPageInfo> fPageInfos;
282
283 bool operator==(const RPageRange &other) const {
284 return fPhysicalColumnId == other.fPhysicalColumnId && fPageInfos == other.fPageInfos;
285 }
286
287 /// Extend this RPageRange to fit the given RColumnRange, i.e. prepend as many synthetic RPageInfos as needed to
288 /// cover the range in `columnRange`. `RPageInfo`s are constructed to contain as many elements of type `element`
289 /// given a page size limit of `pageSize` (in bytes); the locator for the referenced pages is `kTypePageZero`.
290 /// This function is used to make up `RPageRange`s for clusters that contain deferred columns.
291 /// \return The number of column elements covered by the synthesized RPageInfos
292 std::size_t ExtendToFitColumnRange(const RColumnRange &columnRange, const Detail::RColumnElementBase &element,
293 std::size_t pageSize);
294 };
295
296private:
298 /// Clusters can be swapped by adjusting the entry offsets
300 // TODO(jblomer): change to std::uint64_t
302 bool fHasPageLocations = false;
303
304 std::unordered_map<DescriptorId_t, RColumnRange> fColumnRanges;
305 std::unordered_map<DescriptorId_t, RPageRange> fPageRanges;
306
307 void EnsureHasPageLocations() const;
308
309public:
311 // Constructor for a summary-only cluster descriptor without page locations
312 RClusterDescriptor(DescriptorId_t clusterId, std::uint64_t firstEntryIndex, std::uint64_t nEntries)
313 : fClusterId(clusterId), fFirstEntryIndex(firstEntryIndex), fNEntries(ClusterSize_t(nEntries))
314 {
315 }
320
322
323 bool operator==(const RClusterDescriptor &other) const;
324
325 DescriptorId_t GetId() const { return fClusterId; }
329 {
331 return fColumnRanges.at(physicalId);
332 }
333 const RPageRange &GetPageRange(DescriptorId_t physicalId) const
334 {
336 return fPageRanges.at(physicalId);
337 }
338 bool ContainsColumn(DescriptorId_t physicalId) const;
339 std::unordered_set<DescriptorId_t> GetColumnIds() const;
340 std::uint64_t GetBytesOnStorage() const;
341 bool HasPageLocations() const { return fHasPageLocations; }
342};
343
344// clang-format off
345/**
346\class ROOT::Experimental::RClusterGroupDescriptor
347\ingroup NTuple
348\brief Clusters are stored in cluster groups. Cluster groups span all the columns of a certain event range.
349
350Very large ntuples or combined ntuples (chains, friends) contain multiple cluster groups. The cluster groups
351may contain sharded clusters. However, a cluster group must contain the clusters spanning all the columns for the
352given event range. Cluster groups must partition the entry range of an ntuple.
353Every ntuple has at least one cluster group. The clusters in a cluster group are ordered corresponding to
354the order of page locations in the page list envelope that belongs to the cluster group (see format specification)
355*/
356// clang-format on
359
360private:
362 std::vector<DescriptorId_t> fClusterIds;
363 /// The page list that corresponds to the cluster group
365 /// Uncompressed size of the page list
366 std::uint32_t fPageListLength = 0;
367
368public:
374
376
377 bool operator==(const RClusterGroupDescriptor &other) const;
378
380 std::uint64_t GetNClusters() const { return fClusterIds.size(); }
382 std::uint32_t GetPageListLength() const { return fPageListLength; }
383 bool Contains(DescriptorId_t clusterId) const
384 {
385 return std::find(fClusterIds.begin(), fClusterIds.end(), clusterId) != fClusterIds.end();
386 }
387 const std::vector<DescriptorId_t> &GetClusterIds() const { return fClusterIds; }
388};
389
390// clang-format off
391/**
392\class ROOT::Experimental::RNTupleDescriptor
393\ingroup NTuple
394\brief The on-storage meta-data of an ntuple
395
396Represents the on-disk (on storage) information about an ntuple. The meta-data consists of a header and one or
397several footers. The header carries the ntuple schema, i.e. the fields and the associated columns and their
398relationships. The footer(s) carry information about one or several clusters. For every cluster, a footer stores
399its location and size, and for every column the range of element indexes as well as a list of pages and page
400locations.
401
402The descriptor provide machine-independent (de-)serialization of headers and footers, and it provides lookup routines
403for ntuple objects (pages, clusters, ...). It is supposed to be usable by all RPageStorage implementations.
404
405The serialization does not use standard ROOT streamers in order to not let it depend on libCore. The serialization uses
406the concept of frames: header, footer, and substructures have a preamble with version numbers and the size of the
407writte struct. This allows for forward and backward compatibility when the meta-data evolves.
408*/
409// clang-format on
412
413public:
414 class RHeaderExtension;
415
416private:
417 /// The ntuple name needs to be unique in a given storage location (file)
418 std::string fName;
419 /// Free text from the user
420 std::string fDescription;
421
422 std::uint64_t fOnDiskHeaderSize = 0; ///< Set by the descriptor builder when deserialized
423 std::uint64_t fOnDiskFooterSize = 0; ///< Like fOnDiskHeaderSize, contains both cluster summaries and page locations
424
425 std::uint64_t fNEntries = 0; ///< Updated by the descriptor builder when the cluster summaries are added
426 std::uint64_t fNPhysicalColumns = 0; ///< Updated by the descriptor builder when columns are added
427
428 /**
429 * Once constructed by an RNTupleDescriptorBuilder, the descriptor is mostly immutable except for set of
430 * active the page locations. During the lifetime of the descriptor, page location information for clusters
431 * can be added or removed. When this happens, the generation should be increased, so that users of the
432 * descriptor know that the information changed. The generation is increased, e.g., by the page source's
433 * exclusive lock guard around the descriptor. It is used, e.g., by the descriptor cache in RNTupleReader.
434 */
435 std::uint64_t fGeneration = 0;
436
437 std::unordered_map<DescriptorId_t, RFieldDescriptor> fFieldDescriptors;
438 std::unordered_map<DescriptorId_t, RColumnDescriptor> fColumnDescriptors;
439 std::unordered_map<DescriptorId_t, RClusterGroupDescriptor> fClusterGroupDescriptors;
440 /// May contain only a subset of all the available clusters, e.g. the clusters of the current file
441 /// from a chain of files
442 std::unordered_map<DescriptorId_t, RClusterDescriptor> fClusterDescriptors;
443 std::unique_ptr<RHeaderExtension> fHeaderExtension;
444
445public:
446 // clang-format off
447 /**
448 \class ROOT::Experimental::RNTupleDescriptor::RHeaderExtension
449 \ingroup NTuple
450 \brief Summarizes information about fields and the corresponding columns that were added after the header has been serialized
451 */
452 // clang-format on
455
456 private:
457 /// Contains the list of field IDs that are part of the header extension; the corresponding columns are
458 /// available via `GetColumnIterable()`.
459 std::vector<DescriptorId_t> fFields;
460 /// Number of logical and physical columns; updated by the descriptor builder when columns are added
461 std::uint64_t fNLogicalColumns = 0;
462 std::uint64_t fNPhysicalColumns = 0;
463
464 void AddFieldId(DescriptorId_t id) { fFields.push_back(id); }
465 void AddColumn(bool isAliasColumn)
466 {
468 if (!isAliasColumn)
470 }
471
472 public:
473 std::size_t GetNFields() const { return fFields.size(); }
474 std::size_t GetNLogicalColumns() const { return fNLogicalColumns; }
475 std::size_t GetNPhysicalColumns() const { return fNPhysicalColumns; }
476 /// Return a vector containing the IDs of the top-level fields defined in the extension header
477 std::vector<DescriptorId_t> GetTopLevelFields(const RNTupleDescriptor &desc) const;
478 };
479
480 // clang-format off
481 /**
482 \class ROOT::Experimental::RNTupleDescriptor::RColumnDescriptorIterable
483 \ingroup NTuple
484 \brief Used to loop over a field's associated columns
485 */
486 // clang-format on
488 private:
489 /// The associated NTuple for this range.
491 /// The descriptor ids of the columns ordered by index id
492 std::vector<DescriptorId_t> fColumns = {};
493
494 void CollectColumnIds(DescriptorId_t fieldId);
495 public:
496 class RIterator {
497 private:
498 /// The enclosing range's NTuple.
500 /// The enclosing range's descriptor id list.
501 const std::vector<DescriptorId_t> &fColumns;
502 std::size_t fIndex = 0;
503 public:
504 using iterator_category = std::forward_iterator_tag;
507 using difference_type = std::ptrdiff_t;
510
511 RIterator(const RNTupleDescriptor &ntuple, const std::vector<DescriptorId_t> &columns, std::size_t index)
512 : fNTuple(ntuple), fColumns(columns), fIndex(index) {}
513 iterator operator++() { ++fIndex; return *this; }
515 bool operator!=(const iterator &rh) const { return fIndex != rh.fIndex; }
516 bool operator==(const iterator &rh) const { return fIndex == rh.fIndex; }
517 };
518
521
524 };
525
526 // clang-format off
527 /**
528 \class ROOT::Experimental::RNTupleDescriptor::RFieldDescriptorIterable
529 \ingroup NTuple
530 \brief Used to loop over a field's child fields
531 */
532 // clang-format on
534 private:
535 /// The associated NTuple for this range.
537 /// The descriptor ids of the child fields. These may be sorted using
538 /// a comparison function.
539 std::vector<DescriptorId_t> fFieldChildren = {};
540
541 public:
542 class RIterator {
543 private:
544 /// The enclosing range's NTuple.
546 /// The enclosing range's descriptor id list.
547 const std::vector<DescriptorId_t>& fFieldChildren;
548 std::size_t fIndex = 0;
549 public:
550 using iterator_category = std::forward_iterator_tag;
553 using difference_type = std::ptrdiff_t;
556
557 RIterator(const RNTupleDescriptor& ntuple, const std::vector<DescriptorId_t>& fieldChildren,
558 std::size_t index) : fNTuple(ntuple), fFieldChildren(fieldChildren), fIndex(index) {}
559 iterator operator++() { ++fIndex; return *this; }
563 );
564 }
565 bool operator!=(const iterator& rh) const { return fIndex != rh.fIndex; }
566 bool operator==(const iterator& rh) const { return fIndex == rh.fIndex; }
567 };
569 : fNTuple(ntuple), fFieldChildren(field.GetLinkIds()) {}
570 /// Sort the range using an arbitrary comparison function.
572 const std::function<bool(DescriptorId_t, DescriptorId_t)>& comparator)
573 : fNTuple(ntuple), fFieldChildren(field.GetLinkIds())
574 {
575 std::sort(fFieldChildren.begin(), fFieldChildren.end(), comparator);
576 }
578 return RIterator(fNTuple, fFieldChildren, 0);
579 }
582 }
583 };
584
585 // clang-format off
586 /**
587 \class ROOT::Experimental::RNTupleDescriptor::RClusterGroupDescriptorIterable
588 \ingroup NTuple
589 \brief Used to loop over all the cluster groups of an ntuple (in unspecified order)
590
591 Enumerate all cluster group IDs from the cluster group descriptor. No specific order can be assumed, use
592 FindNextClusterGroupId and FindPrevClusterGroupId to traverse clusters groups by entry number.
593 */
594 // clang-format on
596 private:
597 /// The associated NTuple for this range.
599
600 public:
601 class RIterator {
602 private:
603 /// The enclosing range's NTuple.
605 std::size_t fIndex = 0;
606
607 public:
608 using iterator_category = std::forward_iterator_tag;
611 using difference_type = std::ptrdiff_t;
614
615 RIterator(const RNTupleDescriptor &ntuple, std::size_t index) : fNTuple(ntuple), fIndex(index) {}
617 {
618 ++fIndex;
619 return *this;
620 }
622 {
623 auto it = fNTuple.fClusterGroupDescriptors.begin();
624 std::advance(it, fIndex);
625 return it->second;
626 }
627 bool operator!=(const iterator &rh) const { return fIndex != rh.fIndex; }
628 bool operator==(const iterator &rh) const { return fIndex == rh.fIndex; }
629 };
630
634 };
635
636 // clang-format off
637 /**
638 \class ROOT::Experimental::RNTupleDescriptor::RClusterDescriptorIterable
639 \ingroup NTuple
640 \brief Used to loop over all the clusters of an ntuple (in unspecified order)
641
642 Enumerate all cluster IDs from the cluster descriptor. No specific order can be assumed, use
643 FindNextClusterId and FindPrevClusterId to travers clusters by entry number.
644 */
645 // clang-format on
647 private:
648 /// The associated NTuple for this range.
650 public:
651 class RIterator {
652 private:
653 /// The enclosing range's NTuple.
655 std::size_t fIndex = 0;
656 public:
657 using iterator_category = std::forward_iterator_tag;
660 using difference_type = std::ptrdiff_t;
663
664 RIterator(const RNTupleDescriptor &ntuple, std::size_t index) : fNTuple(ntuple), fIndex(index) {}
665 iterator operator++() { ++fIndex; return *this; }
667 auto it = fNTuple.fClusterDescriptors.begin();
668 std::advance(it, fIndex);
669 return it->second;
670 }
671 bool operator!=(const iterator &rh) const { return fIndex != rh.fIndex; }
672 bool operator==(const iterator &rh) const { return fIndex == rh.fIndex; }
673 };
674
678 };
679
680 RNTupleDescriptor() = default;
681 RNTupleDescriptor(const RNTupleDescriptor &other) = delete;
685
686 std::unique_ptr<RNTupleDescriptor> Clone() const;
687
688 bool operator ==(const RNTupleDescriptor &other) const;
689
690 std::uint64_t GetOnDiskHeaderSize() const { return fOnDiskHeaderSize; }
691 std::uint64_t GetOnDiskFooterSize() const { return fOnDiskFooterSize; }
692
694 return fFieldDescriptors.at(fieldId);
695 }
697 return fColumnDescriptors.at(columnId);
698 }
700 {
701 return fClusterGroupDescriptors.at(clusterGroupId);
702 }
704 return fClusterDescriptors.at(clusterId);
705 }
706
708 return RFieldDescriptorIterable(*this, fieldDesc);
709 }
711 const std::function<bool(DescriptorId_t, DescriptorId_t)>& comparator) const
712 {
713 return RFieldDescriptorIterable(*this, fieldDesc, comparator);
714 }
716 return GetFieldIterable(GetFieldDescriptor(fieldId));
717 }
719 const std::function<bool(DescriptorId_t, DescriptorId_t)>& comparator) const
720 {
721 return GetFieldIterable(GetFieldDescriptor(fieldId), comparator);
722 }
725 }
727 const std::function<bool(DescriptorId_t, DescriptorId_t)>& comparator) const
728 {
729 return GetFieldIterable(GetFieldZeroId(), comparator);
730 }
731
733 {
734 return RColumnDescriptorIterable(*this);
735 }
737 {
738 return RColumnDescriptorIterable(*this, fieldDesc);
739 }
741 {
742 return RColumnDescriptorIterable(*this, GetFieldDescriptor(fieldId));
743 }
744
746
748 {
749 return RClusterDescriptorIterable(*this);
750 }
751
752 std::string GetName() const { return fName; }
753 std::string GetDescription() const { return fDescription; }
754
755 std::size_t GetNFields() const { return fFieldDescriptors.size(); }
756 std::size_t GetNLogicalColumns() const { return fColumnDescriptors.size(); }
757 std::size_t GetNPhysicalColumns() const { return fNPhysicalColumns; }
758 std::size_t GetNClusterGroups() const { return fClusterGroupDescriptors.size(); }
759 std::size_t GetNClusters() const { return fClusterDescriptors.size(); }
760
761 /// We know the number of entries from adding the cluster summaries
763 NTupleSize_t GetNElements(DescriptorId_t physicalColumnId) const;
764
765 /// Returns the logical parent of all top-level NTuple data fields.
768 DescriptorId_t FindFieldId(std::string_view fieldName, DescriptorId_t parentId) const;
769 /// Searches for a top-level field
770 DescriptorId_t FindFieldId(std::string_view fieldName) const;
771 DescriptorId_t FindLogicalColumnId(DescriptorId_t fieldId, std::uint32_t columnIndex) const;
772 DescriptorId_t FindPhysicalColumnId(DescriptorId_t fieldId, std::uint32_t columnIndex) const;
776
777 /// Walks up the parents of the field ID and returns a field name of the form a.b.c.d
778 /// In case of invalid field ID, an empty string is returned.
779 std::string GetQualifiedFieldName(DescriptorId_t fieldId) const;
780
781 /// Return header extension information; if the descriptor does not have a header extension, return `nullptr`
782 const RHeaderExtension *GetHeaderExtension() const { return fHeaderExtension.get(); }
783
784 /// Methods to load and drop cluster details
787
788 std::uint64_t GetGeneration() const { return fGeneration; }
790
791 /// Re-create the C++ model from the stored meta-data
792 std::unique_ptr<RNTupleModel> GenerateModel() const;
793 void PrintInfo(std::ostream &output) const;
794};
795
796
797// clang-format off
798/**
799\class ROOT::Experimental::RColumnDescriptorBuilder
800\ingroup NTuple
801\brief A helper class for piece-wise construction of an RColumnDescriptor
802
803Dangling column descriptors can become actual descriptors when added to an
804RNTupleDescriptorBuilder instance and then linked to their fields.
805*/
806// clang-format on
808private:
810public:
811 /// Make an empty column descriptor builder.
813
815 {
816 fColumn.fLogicalColumnId = logicalColumnId;
817 return *this;
818 }
820 {
821 fColumn.fPhysicalColumnId = physicalColumnId;
822 return *this;
823 }
825 fColumn.fModel = model;
826 return *this;
827 }
829 fColumn.fFieldId = fieldId;
830 return *this;
831 }
834 return *this;
835 }
836 RColumnDescriptorBuilder &FirstElementIndex(std::uint64_t firstElementIdx)
837 {
838 fColumn.fFirstElementIndex = firstElementIdx;
839 return *this;
840 }
842 /// Attempt to make a column descriptor. This may fail if the column
843 /// was not given enough information to make a proper descriptor.
845};
846
847
848// clang-format off
849/**
850\class ROOT::Experimental::RFieldDescriptorBuilder
851\ingroup NTuple
852\brief A helper class for piece-wise construction of an RFieldDescriptor
853
854Dangling field descriptors describe a single field in isolation. They are
855missing the necessary relationship information (parent field, any child fields)
856required to describe a real NTuple field.
857
858Dangling field descriptors can only become actual descriptors when added to an
859RNTupleDescriptorBuilder instance and then linked to other fields.
860*/
861// clang-format on
863private:
865public:
866 /// Make an empty dangling field descriptor.
868 /// Make a new RFieldDescriptorBuilder based off an existing descriptor.
869 /// Relationship information is lost during the conversion to a
870 /// dangling descriptor:
871 /// * Parent id is reset to an invalid id.
872 /// * Field children ids are forgotten.
873 ///
874 /// These properties must be set using RNTupleDescriptorBuilder::AddFieldLink().
875 explicit RFieldDescriptorBuilder(const RFieldDescriptor& fieldDesc);
876
877 /// Make a new RFieldDescriptorBuilder based off a live NTuple field.
879
881 fField.fFieldId = fieldId;
882 return *this;
883 }
884 RFieldDescriptorBuilder &FieldVersion(std::uint32_t fieldVersion)
885 {
886 fField.fFieldVersion = fieldVersion;
887 return *this;
888 }
889 RFieldDescriptorBuilder &TypeVersion(std::uint32_t typeVersion)
890 {
891 fField.fTypeVersion = typeVersion;
892 return *this;
893 }
896 return *this;
897 }
898 RFieldDescriptorBuilder& FieldName(const std::string& fieldName) {
899 fField.fFieldName = fieldName;
900 return *this;
901 }
902 RFieldDescriptorBuilder& FieldDescription(const std::string& fieldDescription) {
903 fField.fFieldDescription = fieldDescription;
904 return *this;
905 }
906 RFieldDescriptorBuilder& TypeName(const std::string& typeName) {
907 fField.fTypeName = typeName;
908 return *this;
909 }
910 RFieldDescriptorBuilder &TypeAlias(const std::string &typeAlias)
911 {
912 fField.fTypeAlias = typeAlias;
913 return *this;
914 }
915 RFieldDescriptorBuilder& NRepetitions(std::uint64_t nRepetitions) {
916 fField.fNRepetitions = nRepetitions;
917 return *this;
918 }
920 fField.fStructure = structure;
921 return *this;
922 }
924 /// Attempt to make a field descriptor. This may fail if the dangling field
925 /// was not given enough information to make a proper descriptor.
927};
928
929
930// clang-format off
931/**
932\class ROOT::Experimental::RClusterDescriptorBuilder
933\ingroup NTuple
934\brief A helper class for piece-wise construction of an RClusterDescriptor
935
936The cluster descriptor builder starts from a summary-only cluster descriptor and allows for the
937piecewise addition of page locations.
938*/
939// clang-format on
941private:
943
944public:
945 /// Make an empty cluster descriptor builder.
946 RClusterDescriptorBuilder(DescriptorId_t clusterId, std::uint64_t firstEntryIndex, std::uint64_t nEntries)
947 : fCluster(clusterId, firstEntryIndex, nEntries)
948 {
949 }
950
951 RResult<void> CommitColumnRange(DescriptorId_t physicalId, std::uint64_t firstElementIndex,
952 std::uint32_t compressionSettings, const RClusterDescriptor::RPageRange &pageRange);
953
954 /// Add column and page ranges for deferred columns missing in this cluster. The locator type for the synthesized
955 /// page ranges is `kTypePageZero`. All the page sources must be able to populate the 'zero' page from such locator.
956 /// Any call to `CommitColumnRange()` should happen before calling this function.
958
959 /// Move out the full cluster descriptor including page locations
961};
962
963// clang-format off
964/**
965\class ROOT::Experimental::RClusterGroupDescriptorBuilder
966\ingroup NTuple
967\brief A helper class for piece-wise construction of an RClusterGroupDescriptor
968*/
969// clang-format on
971private:
973
974public:
976
978 {
979 fClusterGroup.fClusterGroupId = clusterGroupId;
980 return *this;
981 }
983 {
984 fClusterGroup.fPageListLocator = pageListLocator;
985 return *this;
986 }
987 RClusterGroupDescriptorBuilder &PageListLength(std::uint32_t pageListLength)
988 {
989 fClusterGroup.fPageListLength = pageListLength;
990 return *this;
991 }
992 void AddCluster(DescriptorId_t clusterId) { fClusterGroup.fClusterIds.emplace_back(clusterId); }
993
995
996 /// Used to prepare the cluster descriptor builders when loading the page locations for a certain cluster group
997 static std::vector<RClusterDescriptorBuilder>
998 GetClusterSummaries(const RNTupleDescriptor &ntplDesc, DescriptorId_t clusterGroupId);
999
1001};
1002
1003// clang-format off
1004/**
1005\class ROOT::Experimental::RColumnGroupDescriptorBuilder
1006\ingroup NTuple
1007\brief A helper class for piece-wise construction of an RColumnGroupDescriptor
1008*/
1009// clang-format on
1011private:
1013
1014public:
1016
1018 {
1019 fColumnGroup.fColumnGroupId = columnGroupId;
1020 return *this;
1021 }
1022 void AddColumn(DescriptorId_t physicalId) { fColumnGroup.fPhysicalColumnIds.insert(physicalId); }
1023
1025};
1026
1027// clang-format off
1028/**
1029\class ROOT::Experimental::RNTupleDescriptorBuilder
1030\ingroup NTuple
1031\brief A helper class for piece-wise construction of an RNTupleDescriptor
1032
1033Used by RPageStorage implementations in order to construct the RNTupleDescriptor from the various header parts.
1034*/
1035// clang-format on
1037private:
1039 std::uint32_t fHeaderCRC32 = 0;
1040
1042public:
1043 /// Checks whether invariants hold:
1044 /// * NTuple name is valid
1045 /// * Fields have valid parent and child ids
1049
1050 void SetNTuple(const std::string_view name, const std::string_view description);
1051 void SetHeaderCRC32(std::uint32_t crc32) { fHeaderCRC32 = crc32; }
1052 std::uint32_t GetHeaderCRC32() const { return fHeaderCRC32; }
1053
1055 /// The real footer size also include the page list envelopes
1057
1058 void AddField(const RFieldDescriptor& fieldDesc);
1060
1061 void AddColumn(DescriptorId_t logicalId, DescriptorId_t physicalId, DescriptorId_t fieldId,
1062 const RColumnModel &model, std::uint32_t index, std::uint64_t firstElementIdx = 0U);
1064
1065 RResult<void> AddClusterSummary(DescriptorId_t clusterId, std::uint64_t firstEntry, std::uint64_t nEntries);
1067
1068 /// Used during writing. For reading, cluster summaries are added in the builder and cluster details are added
1069 /// on demand through the RNTupleDescriptor.
1071
1072 /// Clears so-far stored clusters, fields, and columns and return to a pristine ntuple descriptor
1073 void Reset();
1074
1075 /// Mark the beginning of the header extension; any fields and columns added after a call to this function are
1076 /// annotated as begin part of the header extension.
1077 void BeginHeaderExtension();
1078};
1079
1080} // namespace Experimental
1081} // namespace ROOT
1082
1083#endif // ROOT7_RNTupleDescriptor
TObject * clone(const char *newname) const override
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
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 id
char name[80]
Definition TGX11.cxx:110
A column element encapsulates the translation between basic C++ types and their column representation...
A field translates read and write calls from/to underlying columns to/from tree values.
Definition RField.hxx:83
A helper class for piece-wise construction of an RClusterDescriptor.
RClusterDescriptorBuilder & AddDeferredColumnRanges(const RNTupleDescriptor &desc)
Add column and page ranges for deferred columns missing in this cluster.
RClusterDescriptorBuilder(DescriptorId_t clusterId, std::uint64_t firstEntryIndex, std::uint64_t nEntries)
Make an empty cluster descriptor builder.
RResult< void > CommitColumnRange(DescriptorId_t physicalId, std::uint64_t firstElementIndex, std::uint32_t compressionSettings, const RClusterDescriptor::RPageRange &pageRange)
RResult< RClusterDescriptor > MoveDescriptor()
Move out the full cluster descriptor including page locations.
Meta-data for a set of ntuple clusters.
std::unordered_map< DescriptorId_t, RPageRange > fPageRanges
RClusterDescriptor(DescriptorId_t clusterId, std::uint64_t firstEntryIndex, std::uint64_t nEntries)
RClusterDescriptor(RClusterDescriptor &&other)=default
bool ContainsColumn(DescriptorId_t physicalId) const
RClusterDescriptor(const RClusterDescriptor &other)=delete
NTupleSize_t fFirstEntryIndex
Clusters can be swapped by adjusting the entry offsets.
RClusterDescriptor & operator=(const RClusterDescriptor &other)=delete
const RColumnRange & GetColumnRange(DescriptorId_t physicalId) const
std::unordered_set< DescriptorId_t > GetColumnIds() const
std::unordered_map< DescriptorId_t, RColumnRange > fColumnRanges
bool operator==(const RClusterDescriptor &other) const
const RPageRange & GetPageRange(DescriptorId_t physicalId) const
A helper class for piece-wise construction of an RClusterGroupDescriptor.
RClusterGroupDescriptorBuilder & ClusterGroupId(DescriptorId_t clusterGroupId)
RResult< RClusterGroupDescriptor > MoveDescriptor()
RClusterGroupDescriptorBuilder & PageListLength(std::uint32_t pageListLength)
static std::vector< RClusterDescriptorBuilder > GetClusterSummaries(const RNTupleDescriptor &ntplDesc, DescriptorId_t clusterGroupId)
Used to prepare the cluster descriptor builders when loading the page locations for a certain cluster...
RClusterGroupDescriptorBuilder & PageListLocator(const RNTupleLocator &pageListLocator)
Clusters are stored in cluster groups.
RClusterGroupDescriptor(const RClusterGroupDescriptor &other)=delete
RClusterGroupDescriptor & operator=(RClusterGroupDescriptor &&other)=default
const std::vector< DescriptorId_t > & GetClusterIds() const
RClusterGroupDescriptor & operator=(const RClusterGroupDescriptor &other)=delete
std::uint32_t fPageListLength
Uncompressed size of the page list.
RNTupleLocator fPageListLocator
The page list that corresponds to the cluster group.
bool Contains(DescriptorId_t clusterId) const
bool operator==(const RClusterGroupDescriptor &other) const
RClusterGroupDescriptor(RClusterGroupDescriptor &&other)=default
A helper class for piece-wise construction of an RColumnDescriptor.
RColumnDescriptorBuilder & Model(const RColumnModel &model)
RColumnDescriptorBuilder()=default
Make an empty column descriptor builder.
RResult< RColumnDescriptor > MakeDescriptor() const
Attempt to make a column descriptor.
RColumnDescriptorBuilder & FieldId(DescriptorId_t fieldId)
RColumnDescriptorBuilder & FirstElementIndex(std::uint64_t firstElementIdx)
RColumnDescriptorBuilder & Index(std::uint32_t index)
RColumnDescriptorBuilder & LogicalColumnId(DescriptorId_t logicalColumnId)
RColumnDescriptorBuilder & PhysicalColumnId(DescriptorId_t physicalColumnId)
Meta-data stored for every column of an ntuple.
DescriptorId_t fPhysicalColumnId
Usually identical to the logical column ID, except for alias columns where it references the shadowed...
std::uint64_t fFirstElementIndex
Specifies the index for the first stored element for this column.
RColumnDescriptor(const RColumnDescriptor &other)=delete
DescriptorId_t fLogicalColumnId
The actual column identifier, which is the link to the corresponding field.
RColumnDescriptor Clone() const
Get a copy of the descriptor.
RColumnDescriptor(RColumnDescriptor &&other)=default
DescriptorId_t fFieldId
Every column belongs to one and only one field.
RColumnDescriptor & operator=(const RColumnDescriptor &other)=delete
RColumnModel fModel
Contains the column type and whether it is sorted.
std::uint32_t fIndex
A field can be serialized into several columns, which are numbered from zero to $n$.
bool operator==(const RColumnDescriptor &other) const
A helper class for piece-wise construction of an RColumnGroupDescriptor.
RColumnGroupDescriptorBuilder & ColumnGroupId(DescriptorId_t columnGroupId)
RResult< RColumnGroupDescriptor > MoveDescriptor()
Meta-data for a sets of columns; non-trivial column groups are used for sharded clusters.
RColumnGroupDescriptor(const RColumnGroupDescriptor &other)=delete
RColumnGroupDescriptor & operator=(const RColumnGroupDescriptor &other)=delete
std::unordered_set< DescriptorId_t > fPhysicalColumnIds
RColumnGroupDescriptor & operator=(RColumnGroupDescriptor &&other)=default
bool operator==(const RColumnGroupDescriptor &other) const
bool Contains(DescriptorId_t physicalId) const
const std::unordered_set< DescriptorId_t > & GetPhysicalColumnIds() const
RColumnGroupDescriptor(RColumnGroupDescriptor &&other)=default
Holds the static meta-data of an RNTuple column.
A helper class for piece-wise construction of an RFieldDescriptor.
RFieldDescriptorBuilder & FieldName(const std::string &fieldName)
RFieldDescriptorBuilder & NRepetitions(std::uint64_t nRepetitions)
static RFieldDescriptorBuilder FromField(const Detail::RFieldBase &field)
Make a new RFieldDescriptorBuilder based off a live NTuple field.
RFieldDescriptorBuilder & Structure(const ENTupleStructure &structure)
RResult< RFieldDescriptor > MakeDescriptor() const
Attempt to make a field descriptor.
RFieldDescriptorBuilder & TypeName(const std::string &typeName)
RFieldDescriptorBuilder & TypeVersion(std::uint32_t typeVersion)
RFieldDescriptorBuilder & ParentId(DescriptorId_t id)
RFieldDescriptorBuilder & FieldDescription(const std::string &fieldDescription)
RFieldDescriptorBuilder & FieldVersion(std::uint32_t fieldVersion)
RFieldDescriptorBuilder()=default
Make an empty dangling field descriptor.
RFieldDescriptorBuilder & TypeAlias(const std::string &typeAlias)
RFieldDescriptorBuilder & FieldId(DescriptorId_t fieldId)
Meta-data stored for every field of an ntuple.
std::vector< DescriptorId_t > fLinkIds
The pointers in the other direction from parent to children.
std::uint32_t fTypeVersion
The version of the C++ type itself.
std::unique_ptr< Detail::RFieldBase > CreateField(const RNTupleDescriptor &ntplDesc) const
In general, we create a field simply from the C++ type name.
std::string fFieldDescription
Free text set by the user.
std::string fFieldName
The leaf name, not including parent fields.
std::uint32_t fFieldVersion
The version of the C++-type-to-column translation mechanics.
const std::vector< DescriptorId_t > & GetLinkIds() const
RFieldDescriptor(const RFieldDescriptor &other)=delete
DescriptorId_t fParentId
Establishes sub field relationships, such as classes and collections.
RFieldDescriptor Clone() const
Get a copy of the descriptor.
bool operator==(const RFieldDescriptor &other) const
std::string fTypeAlias
A typedef or using directive that resolved to the type name during field creation.
ENTupleStructure fStructure
The structural information carried by this field in the data model tree.
RFieldDescriptor & operator=(const RFieldDescriptor &other)=delete
RFieldDescriptor(RFieldDescriptor &&other)=default
std::string fTypeName
The C++ type that was used when writing the field.
std::uint64_t fNRepetitions
The number of elements per entry for fixed-size arrays.
A helper class for piece-wise construction of an RNTupleDescriptor.
RResult< void > EnsureValidDescriptor() const
Checks whether invariants hold:
void AddToOnDiskFooterSize(std::uint64_t size)
The real footer size also include the page list envelopes.
RResult< void > AddClusterSummary(DescriptorId_t clusterId, std::uint64_t firstEntry, std::uint64_t nEntries)
RResult< void > EnsureFieldExists(DescriptorId_t fieldId) const
void AddColumn(DescriptorId_t logicalId, DescriptorId_t physicalId, DescriptorId_t fieldId, const RColumnModel &model, std::uint32_t index, std::uint64_t firstElementIdx=0U)
RResult< void > AddFieldLink(DescriptorId_t fieldId, DescriptorId_t linkId)
void SetNTuple(const std::string_view name, const std::string_view description)
const RNTupleDescriptor & GetDescriptor() const
void Reset()
Clears so-far stored clusters, fields, and columns and return to a pristine ntuple descriptor.
void AddClusterGroup(RClusterGroupDescriptorBuilder &&clusterGroup)
RResult< void > AddClusterWithDetails(RClusterDescriptor &&clusterDesc)
Used during writing.
void BeginHeaderExtension()
Mark the beginning of the header extension; any fields and columns added after a call to this functio...
void AddField(const RFieldDescriptor &fieldDesc)
Used to loop over all the clusters of an ntuple (in unspecified order)
const RNTupleDescriptor & fNTuple
The associated NTuple for this range.
Used to loop over all the cluster groups of an ntuple (in unspecified order)
const RNTupleDescriptor & fNTuple
The associated NTuple for this range.
RIterator(const RNTupleDescriptor &ntuple, const std::vector< DescriptorId_t > &columns, std::size_t index)
const std::vector< DescriptorId_t > & fColumns
The enclosing range's descriptor id list.
const RNTupleDescriptor & fNTuple
The enclosing range's NTuple.
const RNTupleDescriptor & fNTuple
The associated NTuple for this range.
std::vector< DescriptorId_t > fColumns
The descriptor ids of the columns ordered by index id.
const std::vector< DescriptorId_t > & fFieldChildren
The enclosing range's descriptor id list.
const RNTupleDescriptor & fNTuple
The enclosing range's NTuple.
RIterator(const RNTupleDescriptor &ntuple, const std::vector< DescriptorId_t > &fieldChildren, std::size_t index)
std::vector< DescriptorId_t > fFieldChildren
The descriptor ids of the child fields.
const RNTupleDescriptor & fNTuple
The associated NTuple for this range.
RFieldDescriptorIterable(const RNTupleDescriptor &ntuple, const RFieldDescriptor &field, const std::function< bool(DescriptorId_t, DescriptorId_t)> &comparator)
Sort the range using an arbitrary comparison function.
RFieldDescriptorIterable(const RNTupleDescriptor &ntuple, const RFieldDescriptor &field)
Summarizes information about fields and the corresponding columns that were added after the header ha...
std::vector< DescriptorId_t > fFields
Contains the list of field IDs that are part of the header extension; the corresponding columns are a...
std::uint64_t fNLogicalColumns
Number of logical and physical columns; updated by the descriptor builder when columns are added.
The on-storage meta-data of an ntuple.
std::uint64_t fNPhysicalColumns
Updated by the descriptor builder when columns are added.
std::unordered_map< DescriptorId_t, RClusterDescriptor > fClusterDescriptors
May contain only a subset of all the available clusters, e.g.
std::uint64_t fGeneration
Once constructed by an RNTupleDescriptorBuilder, the descriptor is mostly immutable except for set of...
std::uint64_t fOnDiskFooterSize
Like fOnDiskHeaderSize, contains both cluster summaries and page locations.
std::uint64_t fNEntries
Updated by the descriptor builder when the cluster summaries are added.
DescriptorId_t FindPhysicalColumnId(DescriptorId_t fieldId, std::uint32_t columnIndex) const
NTupleSize_t GetNElements(DescriptorId_t physicalColumnId) const
std::unique_ptr< RNTupleModel > GenerateModel() const
Re-create the C++ model from the stored meta-data.
DescriptorId_t FindLogicalColumnId(DescriptorId_t fieldId, std::uint32_t columnIndex) const
RClusterGroupDescriptorIterable GetClusterGroupIterable() const
std::unordered_map< DescriptorId_t, RClusterGroupDescriptor > fClusterGroupDescriptors
DescriptorId_t FindNextClusterId(DescriptorId_t clusterId) const
DescriptorId_t FindPrevClusterId(DescriptorId_t clusterId) const
RResult< void > DropClusterDetails(DescriptorId_t clusterId)
RFieldDescriptorIterable GetFieldIterable(const RFieldDescriptor &fieldDesc, const std::function< bool(DescriptorId_t, DescriptorId_t)> &comparator) const
DescriptorId_t GetFieldZeroId() const
Returns the logical parent of all top-level NTuple data fields.
RColumnDescriptorIterable GetColumnIterable(const RFieldDescriptor &fieldDesc) const
std::unordered_map< DescriptorId_t, RColumnDescriptor > fColumnDescriptors
std::unique_ptr< RNTupleDescriptor > Clone() const
DescriptorId_t FindClusterId(DescriptorId_t physicalColumnId, NTupleSize_t index) const
RNTupleDescriptor(RNTupleDescriptor &&other)=default
std::string fName
The ntuple name needs to be unique in a given storage location (file)
RFieldDescriptorIterable GetTopLevelFields() const
const RClusterDescriptor & GetClusterDescriptor(DescriptorId_t clusterId) const
RNTupleDescriptor(const RNTupleDescriptor &other)=delete
std::unordered_map< DescriptorId_t, RFieldDescriptor > fFieldDescriptors
RFieldDescriptorIterable GetFieldIterable(const RFieldDescriptor &fieldDesc) const
RNTupleDescriptor & operator=(RNTupleDescriptor &&other)=default
NTupleSize_t GetNEntries() const
We know the number of entries from adding the cluster summaries.
RFieldDescriptorIterable GetTopLevelFields(const std::function< bool(DescriptorId_t, DescriptorId_t)> &comparator) const
RFieldDescriptorIterable GetFieldIterable(DescriptorId_t fieldId) const
bool operator==(const RNTupleDescriptor &other) const
std::string GetQualifiedFieldName(DescriptorId_t fieldId) const
Walks up the parents of the field ID and returns a field name of the form a.b.c.d In case of invalid ...
DescriptorId_t FindFieldId(std::string_view fieldName, DescriptorId_t parentId) const
const RColumnDescriptor & GetColumnDescriptor(DescriptorId_t columnId) const
RClusterDescriptorIterable GetClusterIterable() const
RResult< void > AddClusterDetails(RClusterDescriptor &&clusterDesc)
Methods to load and drop cluster details.
const RFieldDescriptor & GetFieldDescriptor(DescriptorId_t fieldId) const
std::unique_ptr< RHeaderExtension > fHeaderExtension
const RClusterGroupDescriptor & GetClusterGroupDescriptor(DescriptorId_t clusterGroupId) const
RColumnDescriptorIterable GetColumnIterable() const
RNTupleDescriptor & operator=(const RNTupleDescriptor &other)=delete
std::string fDescription
Free text from the user.
RColumnDescriptorIterable GetColumnIterable(DescriptorId_t fieldId) const
const RHeaderExtension * GetHeaderExtension() const
Return header extension information; if the descriptor does not have a header extension,...
std::uint64_t fOnDiskHeaderSize
Set by the descriptor builder when deserialized.
const RFieldDescriptor & GetFieldZero() const
void PrintInfo(std::ostream &output) const
RFieldDescriptorIterable GetFieldIterable(DescriptorId_t fieldId, const std::function< bool(DescriptorId_t, DescriptorId_t)> &comparator) const
The class is used as a return type for operations that can fail; wraps a value of type T or an RError...
Definition RError.hxx:207
const Int_t n
Definition legend1.C:16
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
ENTupleStructure
The fields in the ntuple model tree can carry different structural information about the type system.
std::uint64_t DescriptorId_t
Distriniguishes elements of the same type within a descriptor, e.g. different fields.
constexpr NTupleSize_t kInvalidNTupleIndex
constexpr ClusterSize_t kInvalidClusterIndex(std::uint64_t(-1))
constexpr DescriptorId_t kInvalidDescriptorId
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.
The window of element indexes of a particular column in a particular cluster.
std::int64_t fCompressionSettings
The usual format for ROOT compression settings (see Compression.h).
ClusterSize_t fNElements
The number of column elements in the cluster.
RPageInfoExtended(const RPageInfo &pi, RClusterSize::ValueType i, NTupleSize_t n)
RClusterSize::ValueType fFirstInPage
Index (in cluster) of the first element in page.
NTupleSize_t fPageNo
Page number in the corresponding RPageRange.
We do not need to store the element size / uncompressed page size because we know to which column the...
std::uint32_t fNElements
The sum of the elements of all the pages must match the corresponding fNElements field in fColumnRang...
RNTupleLocator fLocator
The meaning of fLocator depends on the storage backend.
Records the parition of data into pages for a particular column in a particular cluster.
RPageInfoExtended Find(RClusterSize::ValueType idxInCluster) const
Find the page in the RPageRange that contains the given element. The element must exist.
std::size_t ExtendToFitColumnRange(const RColumnRange &columnRange, const Detail::RColumnElementBase &element, std::size_t pageSize)
Extend this RPageRange to fit the given RColumnRange, i.e.
RPageRange(const RPageRange &other)=delete
RPageRange & operator=(const RPageRange &other)=delete
Wrap the integer in a struct in order to avoid template specialization clash with std::uint32_t.
Generic information about the physical location of data.
static void output()