Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RNTupleDescriptor.hxx
Go to the documentation of this file.
1/// \file ROOT/RNTupleDescriptor.hxx
2/// \author Jakob Blomer <jblomer@cern.ch>
3/// \author Javier Lopez-Gomez <javier.lopez.gomez@cern.ch>
4/// \date 2018-07-19
5
6/*************************************************************************
7 * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
8 * All rights reserved. *
9 * *
10 * For the licensing terms see $ROOTSYS/LICENSE. *
11 * For the list of contributors see $ROOTSYS/README/CREDITS. *
12 *************************************************************************/
13
14#ifndef ROOT_RNTupleDescriptor
15#define ROOT_RNTupleDescriptor
16
18#include <ROOT/RError.hxx>
20#include <ROOT/RNTupleTypes.hxx>
21#include <ROOT/RNTupleUtils.hxx>
22#include <ROOT/RSpan.hxx>
23
24#include <TError.h>
25
26#include <algorithm>
27#include <chrono>
28#include <cmath>
29#include <functional>
30#include <iterator>
31#include <map>
32#include <memory>
33#include <optional>
34#include <ostream>
35#include <vector>
36#include <set>
37#include <string>
38#include <string_view>
39#include <unordered_map>
40#include <unordered_set>
41
42namespace ROOT {
43
44class RFieldBase;
45class RNTupleModel;
46
47namespace Internal {
48class RColumnElementBase;
49}
50
51class RNTupleDescriptor;
52class RFieldDescriptor;
53
54namespace Internal {
55class RColumnDescriptorBuilder;
56class RClusterDescriptorBuilder;
57class RClusterGroupDescriptorBuilder;
58class RExtraTypeInfoDescriptorBuilder;
59class RFieldDescriptorBuilder;
60class RNTupleDescriptorBuilder;
61class RNTupleAttrSetDescriptorBuilder;
62
63RNTupleDescriptor CloneDescriptorSchema(const RNTupleDescriptor &desc);
68
69std::vector<ROOT::Internal::RNTupleClusterBoundaries> GetClusterBoundaries(const RNTupleDescriptor &desc);
70} // namespace Internal
71
72// clang-format off
73/**
74\class ROOT::RNTupleAttrSetDescriptor
75\ingroup NTuple
76\brief Metadata stored for every Attribute Set linked to an RNTuple.
77*/
78// clang-format on
81
82 std::uint16_t fSchemaVersionMajor = 0;
83 std::uint16_t fSchemaVersionMinor = 0;
84 std::uint32_t fAnchorLength = 0; ///< uncompressed size of the linked anchor
85 // The locator of the AttributeSet anchor.
86 // In case of kTypeFile, it points to the beginning of the Anchor's payload.
87 // NOTE: Only kTypeFile is supported at the moment.
89 std::string fName;
90
91public:
97
98 bool operator==(const RNTupleAttrSetDescriptor &other) const;
99 bool operator!=(const RNTupleAttrSetDescriptor &other) const { return !(*this == other); }
100
101 const std::string &GetName() const { return fName; }
102 std::uint16_t GetSchemaVersionMajor() const { return fSchemaVersionMajor; }
103 std::uint16_t GetSchemaVersionMinor() const { return fSchemaVersionMinor; }
104 std::uint32_t GetAnchorLength() const { return fAnchorLength; }
106
108};
109
110// clang-format off
111/**
112\class ROOT::RFieldDescriptor
113\ingroup NTuple
114\brief Metadata stored for every field of an RNTuple
115*/
116// clang-format on
117class RFieldDescriptor final {
120
121private:
122 static const std::string &GetEmptyString();
123
125 /// The version of the C++-type-to-column translation mechanics
126 std::uint32_t fFieldVersion = 0;
127 /// The version of the C++ type itself
128 std::uint32_t fTypeVersion = 0;
129 /// Optional string storage for a free-standing field descriptor. If possible, strings come from the surrounding
130 /// RNTupleDescriptor string pool and this member remains unset.
131 std::unique_ptr<Internal::RStringPool> fStringPool;
132 /// The leaf name, not including parent fields
133 const std::string *fFieldName = nullptr;
134 /// Free text set by the user
135 const std::string *fFieldDescription = nullptr;
136 /// The C++ type that was used when writing the field
137 const std::string *fTypeName = nullptr;
138 /// A typedef or using directive that resolved to the type name during field creation
139 const std::string *fTypeAlias = nullptr;
140 /// The number of elements per entry for fixed-size arrays
141 std::uint64_t fNRepetitions = 0;
142 /// Establishes sub field relationships, such as classes and collections
144 /// For projected fields, the source field ID
146 /// The pointers in the other direction from parent to children. They are serialized, too, to keep the
147 /// order of sub fields.
148 std::vector<ROOT::DescriptorId_t> fLinkIds;
149 /// The ordered list of columns attached to this field: first by representation index then by column index.
150 std::vector<ROOT::DescriptorId_t> fLogicalColumnIds;
151 /// The number of columns in the column representations of the field. The column cardinality helps to navigate the
152 /// list of logical column ids. For example, the second column of the third column representation is
153 /// fLogicalColumnIds[2 * fColumnCardinality + 1]
154 std::uint32_t fColumnCardinality = 0;
155 /// The structural information carried by this field in the data model tree
157 /// For custom classes, we store the ROOT TClass reported checksum to facilitate the use of I/O rules that
158 /// identify types by their checksum
159 std::optional<std::uint32_t> fTypeChecksum;
160 /// Indicates if this is a collection that should be represented in memory by a SoA layout.
161 bool fIsSoACollection = false;
162
163 void InitFrom(const RFieldDescriptor &source, Internal::RStringPool &stringPool);
164
165public:
166 RFieldDescriptor() = default;
167 RFieldDescriptor(const RFieldDescriptor &other) = delete;
171
172 bool operator==(const RFieldDescriptor &other) const;
173 /// Get a copy of the descriptor
174 RFieldDescriptor Clone() const;
175
176 /// In general, we create a field simply from the C++ type name. For untyped fields, however, we potentially need
177 /// access to sub fields, which is provided by the RNTupleDescriptor argument.
178 std::unique_ptr<ROOT::RFieldBase>
179 CreateField(const RNTupleDescriptor &ntplDesc, const ROOT::RCreateFieldOptions &options = {}) const;
180
182 std::uint32_t GetFieldVersion() const { return fFieldVersion; }
183 std::uint32_t GetTypeVersion() const { return fTypeVersion; }
184 const std::string &GetFieldName() const { return fFieldName ? *fFieldName : GetEmptyString(); }
185 const std::string &GetFieldDescription() const { return fFieldDescription ? *fFieldDescription : GetEmptyString(); }
186 const std::string &GetTypeName() const { return fTypeName ? *fTypeName : GetEmptyString(); }
187 const std::string &GetTypeAlias() const { return fTypeAlias ? *fTypeAlias : GetEmptyString(); }
188 std::uint64_t GetNRepetitions() const { return fNRepetitions; }
192 const std::vector<ROOT::DescriptorId_t> &GetLinkIds() const { return fLinkIds; }
193 const std::vector<ROOT::DescriptorId_t> &GetLogicalColumnIds() const { return fLogicalColumnIds; }
194 std::uint32_t GetColumnCardinality() const { return fColumnCardinality; }
195 std::optional<std::uint32_t> GetTypeChecksum() const { return fTypeChecksum; }
197 bool IsSoACollection() const { return fIsSoACollection; }
198};
199
200// clang-format off
201/**
202\class ROOT::RColumnDescriptor
203\ingroup NTuple
204\brief Metadata stored for every column of an RNTuple
205*/
206// clang-format on
207class RColumnDescriptor final {
210
211public:
212 struct RValueRange {
213 double fMin = 0, fMax = 0;
214
215 RValueRange() = default;
216 RValueRange(double min, double max) : fMin(min), fMax(max) {}
217 RValueRange(std::pair<double, double> range) : fMin(range.first), fMax(range.second) {}
218
219 bool operator==(RValueRange other) const { return fMin == other.fMin && fMax == other.fMax; }
220 bool operator!=(RValueRange other) const { return !(*this == other); }
221 };
222
223private:
224 /// The actual column identifier, which is the link to the corresponding field
226 /// Usually identical to the logical column ID, except for alias columns where it references the shadowed column
228 /// Every column belongs to one and only one field
230 /// The absolute value specifies the index for the first stored element for this column.
231 /// For deferred columns the absolute value is larger than zero.
232 /// Negative values specify a suppressed and deferred column.
233 std::int64_t fFirstElementIndex = 0U;
234 /// Optional value range (used e.g. by quantized real fields)
235 std::unique_ptr<RValueRange> fValueRange;
236 /// A field can be serialized into several columns, which are numbered from zero to $n$
237 std::uint32_t fIndex = 0;
238 /// A field may use multiple column representations, which are numbered from zero to $m$.
239 /// Every representation has the same number of columns.
240 std::uint16_t fRepresentationIndex = 0;
241 /// The size in bits of elements of this column. Most columns have the size fixed by their type
242 /// but low-precision float columns have variable bit widths.
243 std::uint16_t fBitsOnStorage = 0;
244 /// The on-disk column type
246
247public:
248 RColumnDescriptor() = default;
249 RColumnDescriptor(const RColumnDescriptor &other) = delete;
253
254 bool operator==(const RColumnDescriptor &other) const;
255 /// Get a copy of the descriptor
256 RColumnDescriptor Clone() const;
257
261 std::uint32_t GetIndex() const { return fIndex; }
262 std::uint16_t GetRepresentationIndex() const { return fRepresentationIndex; }
263 std::uint64_t GetFirstElementIndex() const { return std::abs(fFirstElementIndex); }
264 std::uint16_t GetBitsOnStorage() const { return fBitsOnStorage; }
267 bool IsDeferredColumn() const { return fFirstElementIndex != 0; }
269 std::optional<RValueRange> GetValueRange() const
270 {
271 if (fValueRange)
272 return *fValueRange;
273 return std::nullopt;
274 }
275};
276
277// clang-format off
278/**
279\class ROOT::RClusterDescriptor
280\ingroup NTuple
281\brief Metadata for RNTuple clusters
282
283The cluster descriptor is built in two phases. In a first phase, the descriptor has only an ID.
284In a second phase, the event range, column group, page locations and column ranges are added.
285Both phases are populated by the RClusterDescriptorBuilder.
286Clusters span across all available columns in the RNTuple.
287*/
288// clang-format on
291
292public:
293 // clang-format off
294 /**
295 \class ROOT::RClusterDescriptor::RColumnRange
296 \ingroup NTuple
297 \brief The window of element indexes of a particular column in a particular cluster
298 */
299 // clang-format on
300 class RColumnRange final {
302 /// The global index of the first column element in the cluster
304 /// The number of column elements in the cluster
306 /// The usual format for ROOT compression settings (see Compression.h).
307 /// The pages of a particular column in a particular cluster are all compressed with the same settings.
308 /// If unset, the compression settings are undefined (deferred columns, suppressed columns).
309 std::optional<std::uint32_t> fCompressionSettings;
310 /// Suppressed columns have an empty page range and unknown compression settings.
311 /// Their element index range, however, is aligned with the corresponding column of the
312 /// primary column representation (see Section "Suppressed Columns" in the specification)
313 bool fIsSuppressed = false;
314
315 // TODO(jblomer): we perhaps want to store summary information, such as average, min/max, etc.
316 // Should this be done on the field level?
317
318 public:
319 RColumnRange() = default;
320
321 RColumnRange(ROOT::DescriptorId_t physicalColumnId, ROOT::NTupleSize_t firstElementIndex,
322 ROOT::NTupleSize_t nElements, std::optional<std::uint32_t> compressionSettings,
323 bool suppressed = false)
324 : fPhysicalColumnId(physicalColumnId),
325 fFirstElementIndex(firstElementIndex),
326 fNElements(nElements),
327 fCompressionSettings(compressionSettings),
328 fIsSuppressed(suppressed)
329 {
330 }
331
334
338
342
343 std::optional<std::uint32_t> GetCompressionSettings() const { return fCompressionSettings; }
344 void SetCompressionSettings(std::optional<std::uint32_t> comp) { fCompressionSettings = comp; }
345
346 bool IsSuppressed() const { return fIsSuppressed; }
347 void SetIsSuppressed(bool suppressed) { fIsSuppressed = suppressed; }
348
349 bool operator==(const RColumnRange &other) const
350 {
354 }
355
360 };
361
362 // clang-format off
363 /**
364 \class ROOT::RClusterDescriptor::RPageInfo
365 \ingroup NTuple
366 \brief Information about a single page in the context of a cluster's page range.
367 */
368 // clang-format on
369 // NOTE: We do not need to store the element size / uncompressed page size because we know to which column
370 // the page belongs
371 struct RPageInfo {
372 private:
373 /// The meaning of `fLocator` depends on the storage backend.
375 /// The sum of the elements of all the pages must match the corresponding `fNElements` field in `fColumnRanges`
376 std::uint32_t fNElements = std::uint32_t(-1);
377 /// If true, the 8 bytes following the serialized page are an xxhash of the on-disk page data
378 bool fHasChecksum = false;
379
380 public:
381 RPageInfo() = default;
382 RPageInfo(std::uint32_t nElements, const RNTupleLocator &locator, bool hasChecksum)
383 : fLocator(locator), fNElements(nElements), fHasChecksum(hasChecksum)
384 {
385 }
386
387 bool operator==(const RPageInfo &other) const
388 {
389 return fLocator == other.fLocator && fNElements == other.fNElements;
390 }
391
392 const RNTupleLocator &GetLocator() const { return fLocator; }
394 void SetLocator(const RNTupleLocator &locator) { fLocator = locator; }
395
396 std::uint32_t GetNElements() const { return fNElements; }
397 void SetNElements(std::uint32_t n) { fNElements = n; }
398
399 bool HasChecksum() const { return fHasChecksum; }
400 void SetHasChecksum(bool hasChecksum) { fHasChecksum = hasChecksum; }
401 };
402
403 // clang-format off
404 /**
405 \class ROOT::RClusterDescriptor::RPageInfoExtended
406 \ingroup NTuple
407 \brief Additional information about a page in an in-memory RPageRange.
408
409 Used by RPageRange::Find() to return information relative to the RPageRange. This information is not stored on disk
410 and we don't need to keep it in memory because it can be easily recomputed.
411 */
412 // clang-format on
414 private:
415 /// Index (in cluster) of the first element in page.
417 /// Page number in the corresponding RPageRange.
419
420 public:
421 RPageInfoExtended() = default;
422 RPageInfoExtended(const RPageInfo &pageInfo, ROOT::NTupleSize_t firstElementIndex, ROOT::NTupleSize_t pageNumber)
423 : RPageInfo(pageInfo), fFirstElementIndex(firstElementIndex), fPageNumber(pageNumber)
424 {
425 }
426
428 void SetFirstElementIndex(ROOT::NTupleSize_t firstInPage) { fFirstElementIndex = firstInPage; }
429
431 void SetPageNumber(ROOT::NTupleSize_t pageNumber) { fPageNumber = pageNumber; }
432 };
433
434 // clang-format off
435 /**
436 \class ROOT::RClusterDescriptor::RPageRange
437 \ingroup NTuple
438 \brief Records the partition of data into pages for a particular column in a particular cluster
439 */
440 // clang-format on
441 class RPageRange final {
443
444 private:
445 /// \brief Extend this RPageRange to fit the given RColumnRange.
446 ///
447 /// To do so, prepend as many synthetic RPageInfos as needed to cover the range in `columnRange`.
448 /// RPageInfos are constructed to contain as many elements of type `element` given a page size
449 /// limit of `pageSize` (in bytes); the locator for the referenced pages is `kTypePageZero`.
450 /// This function is used to make up RPageRanges for clusters that contain deferred columns.
451 /// \return The number of column elements covered by the synthesized RPageInfos
452 std::size_t ExtendToFitColumnRange(const RColumnRange &columnRange,
453 const ROOT::Internal::RColumnElementBase &element, std::size_t pageSize);
454
455 std::vector<RPageInfo> fPageInfos;
456
457 /// Has the same length than fPageInfos and stores the sum of the number of elements of all the pages
458 /// up to and including a given index. Used for binary search in Find().
459 /// This vector is only created if fPageInfos has at least kLargeRangeThreshold elements.
460 std::unique_ptr<std::vector<ROOT::NTupleSize_t>> fCumulativeNElements;
461
463
464 public:
465 /// Create the fCumulativeNElements only when its needed, i.e. when there are many pages to search through.
466 static constexpr std::size_t kLargeRangeThreshold = 10;
467
468 RPageRange() = default;
469 RPageRange(const RPageRange &other) = delete;
470 RPageRange &operator=(const RPageRange &other) = delete;
471 RPageRange(RPageRange &&other) = default;
472 RPageRange &operator=(RPageRange &&other) = default;
473
475 {
476 RPageRange clone;
478 clone.fPageInfos = fPageInfos;
480 clone.fCumulativeNElements = std::make_unique<std::vector<ROOT::NTupleSize_t>>(*fCumulativeNElements);
481 }
482 return clone;
483 }
484
485 /// Find the page in the RPageRange that contains the given element. The element must exist.
486 RPageInfoExtended Find(ROOT::NTupleSize_t idxInCluster) const;
487
490
491 const std::vector<RPageInfo> &GetPageInfos() const { return fPageInfos; }
492 std::vector<RPageInfo> &GetPageInfos() { return fPageInfos; }
493
494 bool operator==(const RPageRange &other) const
495 {
496 return fPhysicalColumnId == other.fPhysicalColumnId && fPageInfos == other.fPageInfos;
497 }
498 };
499
500private:
502 /// Clusters can be swapped by adjusting the entry offsets of the cluster and all ranges
505
506 std::unordered_map<ROOT::DescriptorId_t, RColumnRange> fColumnRanges;
507 std::unordered_map<ROOT::DescriptorId_t, RPageRange> fPageRanges;
508
509public:
511
517
519
520 bool operator==(const RClusterDescriptor &other) const;
521
525 const RColumnRange &GetColumnRange(ROOT::DescriptorId_t physicalId) const { return fColumnRanges.at(physicalId); }
526 const RPageRange &GetPageRange(ROOT::DescriptorId_t physicalId) const { return fPageRanges.at(physicalId); }
527 /// Returns an iterator over pairs { columnId, columnRange }. The iteration order is unspecified.
528 RColumnRangeIterable GetColumnRangeIterable() const;
530 {
531 return fColumnRanges.find(physicalId) != fColumnRanges.end();
532 }
533 std::uint64_t GetNBytesOnStorage() const;
534};
535
537private:
539
540public:
541 class RIterator final {
542 private:
543 using Iter_t = std::unordered_map<ROOT::DescriptorId_t, RColumnRange>::const_iterator;
544 /// The wrapped map iterator
546
547 public:
548 using iterator_category = std::forward_iterator_tag;
551 using difference_type = std::ptrdiff_t;
552 using pointer = const RColumnRange *;
553 using reference = const RColumnRange &;
554
555 RIterator() = default;
556 explicit RIterator(Iter_t iter) : fIter(iter) {}
557 iterator &operator++() /* prefix */
558 {
559 ++fIter;
560 return *this;
561 }
562 iterator operator++(int) /* postfix */
563 {
564 auto old = *this;
565 operator++();
566 return old;
567 }
568 reference operator*() const { return fIter->second; }
569 pointer operator->() const { return &fIter->second; }
570 bool operator!=(const iterator &rh) const { return fIter != rh.fIter; }
571 bool operator==(const iterator &rh) const { return fIter == rh.fIter; }
572 };
573
574 explicit RColumnRangeIterable(const RClusterDescriptor &desc) : fDesc(desc) {}
575
578 size_t size() { return fDesc.fColumnRanges.size(); }
579};
580
581// clang-format off
582/**
583\class ROOT::RClusterGroupDescriptor
584\ingroup NTuple
585\brief Clusters are bundled in cluster groups.
586
587Very large RNTuples can contain multiple cluster groups to organize cluster metadata.
588Every RNTuple has at least one cluster group. The clusters in a cluster group are ordered
589corresponding to their first entry number.
590*/
591// clang-format on
594
595private:
597 /// The cluster IDs can be empty if the corresponding page list is not loaded.
598 /// Otherwise, cluster ids are sorted by first entry number.
599 std::vector<ROOT::DescriptorId_t> fClusterIds;
600 /// The page list that corresponds to the cluster group
602 /// Uncompressed size of the page list
603 std::uint64_t fPageListLength = 0;
604 /// The minimum first entry number of the clusters in the cluster group
605 std::uint64_t fMinEntry = 0;
606 /// Number of entries that are (partially for sharded clusters) covered by this cluster group.
607 std::uint64_t fEntrySpan = 0;
608 /// Number of clusters is always known even if the cluster IDs are not (yet) populated
609 std::uint32_t fNClusters = 0;
610
611public:
617
619 /// Creates a clone without the cluster IDs
621
622 bool operator==(const RClusterGroupDescriptor &other) const;
623
625 std::uint32_t GetNClusters() const { return fNClusters; }
627 std::uint64_t GetPageListLength() const { return fPageListLength; }
628 const std::vector<ROOT::DescriptorId_t> &GetClusterIds() const { return fClusterIds; }
629 std::uint64_t GetMinEntry() const { return fMinEntry; }
630 std::uint64_t GetEntrySpan() const { return fEntrySpan; }
631 /// A cluster group is loaded in two stages. Stage one loads only the summary information.
632 /// Stage two loads the list of cluster IDs.
633 bool HasClusterDetails() const { return !fClusterIds.empty(); }
634};
635
636/// Used in RExtraTypeInfoDescriptor
638 kInvalid,
640};
641
642// clang-format off
643/**
644\class ROOT::RExtraTypeInfoDescriptor
645\ingroup NTuple
646\brief Field specific extra type information from the header / extenstion header
647
648Currently only used by streamer fields to store RNTuple-wide list of streamer info records.
649*/
650// clang-format on
653
654private:
655 /// Specifies the meaning of the extra information
657 /// Type version the extra type information is bound to
658 std::uint32_t fTypeVersion = 0;
659 /// The type name the extra information refers to; empty for RNTuple-wide extra information
660 std::string fTypeName;
661 /// The content format depends on the content ID and may be binary
662 std::string fContent;
663
664public:
670
671 bool operator==(const RExtraTypeInfoDescriptor &other) const;
672
674
676 std::uint32_t GetTypeVersion() const { return fTypeVersion; }
677 const std::string &GetTypeName() const { return fTypeName; }
678 const std::string &GetContent() const { return fContent; }
679};
680
681// clang-format off
682/**
683\class ROOT::RNTupleDescriptor
684\ingroup NTuple
685\brief The on-storage metadata of an RNTuple
686
687Represents the on-disk (on storage) information about an RNTuple. The metadata consists of a header, a footer, and
688potentially multiple page lists.
689The header carries the RNTuple schema, i.e. the fields and the associated columns and their relationships.
690The footer carries information about one or several cluster groups and links to their page lists.
691For every cluster group, a page list envelope stores cluster summaries and page locations.
692For every cluster, it stores for every column the range of element indexes as well as a list of pages and page
693locations.
694
695The descriptor provides machine-independent (de-)serialization of headers and footers, and it provides lookup routines
696for RNTuple objects (pages, clusters, ...). It is supposed to be usable by all RPageStorage implementations.
697
698The serialization does not use standard ROOT streamers in order to not let it depend on libCore. The serialization uses
699the concept of envelopes and frames: header, footer, and page list envelopes have a preamble with a type ID and length.
700Substructures are serialized in frames and have a size and number of items (for list frames). This allows for forward
701and backward compatibility when the metadata evolves.
702*/
703// clang-format on
704class RNTupleDescriptor final {
707
708public:
709 class RHeaderExtension;
710
711private:
712 /// The RNTuple name needs to be unique in a given storage location (file)
713 std::string fName;
714 /// Free text from the user
715 std::string fDescription;
716
718
719 std::uint64_t fNPhysicalColumns = 0; ///< Updated by the descriptor builder when columns are added
720
721 /// Storage for all the field strings. Shared among descriptor clones.
722 std::shared_ptr<Internal::RStringPool> fStringPool;
723
724 std::set<unsigned int> fFeatureFlags; // needs to be ordered
725 std::unordered_map<ROOT::DescriptorId_t, RFieldDescriptor> fFieldDescriptors;
726 std::unordered_map<ROOT::DescriptorId_t, RColumnDescriptor> fColumnDescriptors;
727
728 std::vector<RExtraTypeInfoDescriptor> fExtraTypeInfoDescriptors;
729 std::unique_ptr<RHeaderExtension> fHeaderExtension;
730
731 //// All fields above are part of the schema and are cloned when creating a new descriptor from a given one
732 //// (see CloneSchema())
733
734 std::uint16_t fVersionEpoch = 0; ///< Set by the descriptor builder when deserialized
735 std::uint16_t fVersionMajor = 0; ///< Set by the descriptor builder when deserialized
736 std::uint16_t fVersionMinor = 0; ///< Set by the descriptor builder when deserialized
737 std::uint16_t fVersionPatch = 0; ///< Set by the descriptor builder when deserialized
738
739 std::uint64_t fOnDiskHeaderSize = 0; ///< Set by the descriptor builder when deserialized
740 std::uint64_t fOnDiskHeaderXxHash3 = 0; ///< Set by the descriptor builder when deserialized
741 std::uint64_t fOnDiskFooterSize = 0; ///< Like fOnDiskHeaderSize, contains both cluster summaries and page locations
742
743 std::uint64_t fNEntries = 0; ///< Updated by the descriptor builder when the cluster groups are added
744 std::uint64_t fNClusters = 0; ///< Updated by the descriptor builder when the cluster groups are added
745
746 /// \brief The generation of the descriptor
747 ///
748 /// Once constructed by an RNTupleDescriptorBuilder, the descriptor is mostly immutable except for the set of
749 /// active page locations. During the lifetime of the descriptor, page location information for clusters
750 /// can be added or removed. When this happens, the generation should be increased, so that users of the
751 /// descriptor know that the information changed. The generation is increased, e.g., by the page source's
752 /// exclusive lock guard around the descriptor. It is used, e.g., by the descriptor cache in RNTupleReader.
753 std::uint64_t fGeneration = 0;
754
755 std::unordered_map<ROOT::DescriptorId_t, RClusterGroupDescriptor> fClusterGroupDescriptors;
756 /// References cluster groups sorted by entry range and thus allows for binary search.
757 /// Note that this list is empty during the descriptor building process and will only be
758 /// created when the final descriptor is extracted from the builder.
759 std::vector<ROOT::DescriptorId_t> fSortedClusterGroupIds;
760 /// Potentially a subset of all the available clusters
761 std::unordered_map<ROOT::DescriptorId_t, RClusterDescriptor> fClusterDescriptors;
762 /// List of AttributeSets linked to this RNTuple
763 std::vector<RNTupleAttrSetDescriptor> fAttributeSets;
764
765 // We don't expose this publicly because when we add sharded clusters, this interface does not make sense anymore
767
768 /// Creates a descriptor containing only the schema information about this RNTuple, i.e. all the information needed
769 /// to create a new RNTuple with the same schema as this one but not necessarily the same clustering. This is used
770 /// when merging two RNTuples.
771 RNTupleDescriptor CloneSchema(bool shareStringPool) const;
772
773 /// ROOT v6.34, with spec versions before 1.0.0.1, did not properly renormalize the type name.
774 /// This function returns true if this descriptor has a version prior to 1.0.0.1 and may therefore contain such
775 /// fields. This is only valid to call after SetVersion() or SetVersionForWriting() has been called on this
776 /// descriptor.
777 bool FieldTypeNamesMayNeedFixup() const;
778
779public:
780 /// All known feature flags.
781 /// Note that the flag values represent the bit _index_, not the already-bitshifted integer.
783 /// Signals that the RNTuple contains at least one deferred column that is part of a collection and was extended
784 /// (i.e. it appears in the footer). This can happen when merging two RNTuples that have the same collection field
785 /// backed by columns with different encoding, e.g. a vector<float> whose elements are represented by SplitReal32
786 /// in the first ntuple and by Real32 in the second.
787 /// Added in version 1.1.0.0 of the binary format.
789 // Insert new feature flags here, with contiguous values. If at any point a "hole" appears in the valid feature
790 // flags values, the check in RNTupleSerialize must be updated.
791
792 // End of regular feature flags
794
795 /// Reserved for forward-compatibility testing
797 };
798
799 class RColumnDescriptorIterable;
800 class RFieldDescriptorIterable;
801 class RClusterGroupDescriptorIterable;
802 class RClusterDescriptorIterable;
803 class RExtraTypeInfoDescriptorIterable;
805
806 /// Modifiers passed to CreateModel()
808 private:
809 /// If set to true, projected fields will be reconstructed as such. This will prevent the model to be used
810 /// with an RNTupleReader, but it is useful, e.g., to accurately merge data.
812 /// By default, creating a model will fail if any of the reconstructed fields contains an unknown column type
813 /// or an unknown field structural role.
814 /// If this option is enabled, the model will be created and all fields containing unknown data (directly
815 /// or indirectly) will be skipped instead.
816 bool fForwardCompatible = false;
817 /// If true, the model will be created without a default entry (bare model).
818 bool fCreateBare = false;
819 /// If true, fields with a user defined type that have no available dictionaries will be reconstructed
820 /// as record fields from the on-disk information; otherwise, they will cause an error.
822
823 public:
824 RCreateModelOptions() {} // Work around compiler bug, see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88165
825
828
831
832 void SetCreateBare(bool v) { fCreateBare = v; }
833 bool GetCreateBare() const { return fCreateBare; }
834
837 };
838
840 RNTupleDescriptor(const RNTupleDescriptor &other) = delete;
844
845 RNTupleDescriptor Clone() const;
846
847 bool operator==(const RNTupleDescriptor &other) const;
848
849 std::uint64_t GetOnDiskHeaderXxHash3() const { return fOnDiskHeaderXxHash3; }
850 std::uint64_t GetOnDiskHeaderSize() const { return fOnDiskHeaderSize; }
851 std::uint64_t GetOnDiskFooterSize() const { return fOnDiskFooterSize; }
852 /// \see ROOT::RNTuple::GetCurrentVersion()
853 std::uint64_t GetVersion() const
854 {
855 return (static_cast<std::uint64_t>(fVersionEpoch) << 48) | (static_cast<std::uint64_t>(fVersionMajor) << 32) |
856 (static_cast<std::uint64_t>(fVersionMinor) << 16) | (static_cast<std::uint64_t>(fVersionPatch));
857 }
858
860 {
861 return fFieldDescriptors.at(fieldId);
862 }
864 {
865 return fColumnDescriptors.at(columnId);
866 }
868 {
869 return fClusterGroupDescriptors.at(clusterGroupId);
870 }
872 {
873 return fClusterDescriptors.at(clusterId);
874 }
875
876 RFieldDescriptorIterable GetFieldIterable(const RFieldDescriptor &fieldDesc) const;
877 RFieldDescriptorIterable
878 GetFieldIterable(const RFieldDescriptor &fieldDesc,
879 const std::function<bool(ROOT::DescriptorId_t, ROOT::DescriptorId_t)> &comparator) const;
880 RFieldDescriptorIterable GetFieldIterable(ROOT::DescriptorId_t fieldId) const;
881 RFieldDescriptorIterable
883 const std::function<bool(ROOT::DescriptorId_t, ROOT::DescriptorId_t)> &comparator) const;
884
885 RFieldDescriptorIterable GetTopLevelFields() const;
886 RFieldDescriptorIterable
887 GetTopLevelFields(const std::function<bool(ROOT::DescriptorId_t, ROOT::DescriptorId_t)> &comparator) const;
888
889 RColumnDescriptorIterable GetColumnIterable() const;
890 RColumnDescriptorIterable GetColumnIterable(const RFieldDescriptor &fieldDesc) const;
891 RColumnDescriptorIterable GetColumnIterable(ROOT::DescriptorId_t fieldId) const;
892
893 RClusterGroupDescriptorIterable GetClusterGroupIterable() const;
894
895 RClusterDescriptorIterable
897 "This function is unsafe to use because, in general, not all cluster "
898 "metadata are available (there may be cluster groups with unloaded cluster group details). Use the "
899 "'GetActiveClusterIterable()' method instead if you are aware of this limitation.")
900 GetClusterIterable() const;
902
904
906
907 const std::string &GetName() const { return fName; }
908 const std::string &GetDescription() const { return fDescription; }
909
910 std::size_t GetNFields() const { return fFieldDescriptors.size(); }
911 std::size_t GetNLogicalColumns() const { return fColumnDescriptors.size(); }
912 std::size_t GetNPhysicalColumns() const { return fNPhysicalColumns; }
913 std::size_t GetNClusterGroups() const { return fClusterGroupDescriptors.size(); }
914 std::size_t GetNClusters() const { return fNClusters; }
915 std::size_t GetNActiveClusters() const { return fClusterDescriptors.size(); }
916 std::size_t GetNExtraTypeInfos() const { return fExtraTypeInfoDescriptors.size(); }
917 std::size_t GetNAttributeSets() const { return fAttributeSets.size(); }
918
919 /// We know the number of entries from adding the cluster summaries
922 R__DEPRECATED(6, 46,
923 "This function is ill-conceived in the descriptor "
924 "as not all cluster descriptors may be present. This interface is no longer publicly exposed.")
925 GetNElements(ROOT::DescriptorId_t physicalColumnId) const;
926
927 /// Returns the logical parent of all top-level RNTuple data fields.
930 ROOT::DescriptorId_t FindFieldId(std::string_view fieldName, ROOT::DescriptorId_t parentId) const;
931 /// Searches for a top-level field
932 ROOT::DescriptorId_t FindFieldId(std::string_view fieldName) const;
933 ROOT::DescriptorId_t FindLogicalColumnId(ROOT::DescriptorId_t fieldId, std::uint32_t columnIndex,
934 std::uint16_t representationIndex) const;
935 ROOT::DescriptorId_t FindPhysicalColumnId(ROOT::DescriptorId_t fieldId, std::uint32_t columnIndex,
936 std::uint16_t representationIndex) const;
938 R__DEPRECATED(6, 46,
939 "This function is ill-defined in the descriptor "
940 "as not all cluster descriptors may be present. This interface is no longer exposed.")
941 FindClusterId(ROOT::DescriptorId_t physicalColumnId, ROOT::NTupleSize_t index) const;
943 R__DEPRECATED(6, 46,
944 "This function is ill-defined in the descriptor "
945 "as not all cluster descriptors may be present. This interface is no longer exposed.")
946 FindNextClusterId(ROOT::DescriptorId_t clusterId) const;
948 R__DEPRECATED(6, 46,
949 "This function is ill-defined in the descriptor "
950 "as not all cluster descriptors may be present. This interface is no longer exposed.")
951 FindPrevClusterId(ROOT::DescriptorId_t clusterId) const;
952
953 /// Walks up the parents of the field ID and returns a field name of the form a.b.c.d
954 /// In case of invalid field ID, an empty string is returned.
955 std::string GetQualifiedFieldName(ROOT::DescriptorId_t fieldId) const;
956
957 /// Adjust the type name of the passed RFieldDescriptor for comparison with another renormalized type name.
958 std::string GetTypeNameForComparison(const RFieldDescriptor &fieldDesc) const;
959
960 bool HasFeature(unsigned int flag) const { return fFeatureFlags.count(flag) > 0; }
961 std::vector<std::uint64_t> GetFeatureFlags() const;
962
963 /// Return header extension information; if the descriptor does not have a header extension, return `nullptr`
964 const RHeaderExtension *GetHeaderExtension() const { return fHeaderExtension.get(); }
965
966 /// Methods to load and drop cluster group details (cluster IDs and page locations)
968 AddClusterGroupDetails(ROOT::DescriptorId_t clusterGroupId, std::vector<RClusterDescriptor> &clusterDescs);
970
971 std::uint64_t GetGeneration() const { return fGeneration; }
973
974 /// Re-create the C++ model from the stored metadata
975 std::unique_ptr<ROOT::RNTupleModel> CreateModel(const RCreateModelOptions &options = RCreateModelOptions()) const;
976 void PrintInfo(std::ostream &output) const;
977};
978
979// clang-format off
980/**
981\class ROOT::RNTupleDescriptor::RColumnDescriptorIterable
982\ingroup NTuple
983\brief Used to loop over a field's associated columns
984*/
985// clang-format on
987private:
988 /// The associated RNTuple for this range.
990 /// The descriptor ids of the columns ordered by field, representation, and column index
991 std::vector<ROOT::DescriptorId_t> fColumns = {};
992
993public:
994 class RIterator final {
995 private:
996 /// The enclosing RColumnDescriptorIterable.
998 std::size_t fIndex;
999
1000 public:
1001 using iterator_category = std::forward_iterator_tag;
1004 using difference_type = std::ptrdiff_t;
1007
1008 explicit RIterator(const RColumnDescriptorIterable *iterable = nullptr, std::size_t index = 0)
1009 : fIterable(iterable), fIndex(index)
1010 {
1011 }
1012 iterator &operator++() /* prefix */
1013 {
1014 ++fIndex;
1015 return *this;
1016 }
1017 iterator operator++(int) /* postfix */
1018 {
1019 auto old = *this;
1020 operator++();
1021 return old;
1022 }
1024 {
1025 if (fIterable)
1027 throw RException(R__FAIL("dereference of RNTupleDescriptor::RColumnDescriptorIterable::RIterator"
1028 " constructed without RNTupleDescriptor::RColumnDescriptorIterable"));
1029 }
1031 {
1033 }
1034 bool operator!=(const iterator &rh) const { return fIndex != rh.fIndex || fIterable != rh.fIterable; }
1035 bool operator==(const iterator &rh) const { return fIndex == rh.fIndex && fIterable == rh.fIterable; }
1036 };
1037
1038 RColumnDescriptorIterable(const RNTupleDescriptor &ntuple, const RFieldDescriptor &fieldDesc);
1040
1041 RIterator begin() { return RIterator(this, 0); }
1042 RIterator end() { return RIterator(this, fColumns.size()); }
1043 size_t size() { return fColumns.size(); }
1044};
1045
1046// clang-format off
1047/**
1048\class ROOT::RNTupleDescriptor::RFieldDescriptorIterable
1049\ingroup NTuple
1050\brief Used to loop over a field's child fields
1051*/
1052// clang-format on
1054private:
1055 /// The associated RNTuple for this range.
1057 /// The descriptor IDs of the child fields. These may be sorted using
1058 /// a comparison function.
1059 std::vector<ROOT::DescriptorId_t> fFieldChildren = {};
1060
1061public:
1062 class RIterator final {
1063 private:
1064 /// The enclosing RFieldDescriptorIterable.
1066 std::size_t fIndex;
1067
1068 public:
1069 using iterator_category = std::forward_iterator_tag;
1072 using difference_type = std::ptrdiff_t;
1073 using pointer = const RFieldDescriptor *;
1075
1076 explicit RIterator(const RFieldDescriptorIterable *iterable = nullptr, std::size_t index = 0)
1077 : fIterable(iterable), fIndex(index)
1078 {
1079 }
1080 iterator &operator++() /* prefix */
1081 {
1082 ++fIndex;
1083 return *this;
1084 }
1085 iterator operator++(int) /* postfix */
1086 {
1087 auto old = *this;
1088 operator++();
1089 return old;
1090 }
1092 {
1093 if (fIterable)
1095 throw RException(R__FAIL("dereference of RNTupleDescriptor::RFieldDescriptorIterable::RIterator"
1096 " constructed without RNTupleDescriptor::RFieldDescriptorIterable"));
1097 }
1099 {
1101 }
1102 bool operator!=(const iterator &rh) const { return fIndex != rh.fIndex || fIterable != rh.fIterable; }
1103 bool operator==(const iterator &rh) const { return fIndex == rh.fIndex && fIterable == rh.fIterable; }
1104 };
1106 : fNTuple(ntuple), fFieldChildren(field.GetLinkIds())
1107 {
1108 }
1109 /// Sort the range using an arbitrary comparison function.
1111 const std::function<bool(ROOT::DescriptorId_t, ROOT::DescriptorId_t)> &comparator)
1112 : fNTuple(ntuple), fFieldChildren(field.GetLinkIds())
1113 {
1114 std::sort(fFieldChildren.begin(), fFieldChildren.end(), comparator);
1115 }
1116 RIterator begin() { return RIterator(this, 0); }
1117 RIterator end() { return RIterator(this, fFieldChildren.size()); }
1118};
1119
1120// clang-format off
1121/**
1122\class ROOT::RNTupleDescriptor::RClusterGroupDescriptorIterable
1123\ingroup NTuple
1124\brief Used to loop over all the cluster groups of an RNTuple in order of entry ranges
1125
1126Enumerate all cluster group IDs from the descriptor. No specific order can be assumed.
1127*/
1128// clang-format on
1130private:
1131 /// The associated RNTuple for this range.
1133
1134public:
1135 class RIterator final {
1137
1138 private:
1139 const RNTupleDescriptor *fNTuple = nullptr;
1140 const std::vector<ROOT::DescriptorId_t> *fSortedClusterGroupIds = nullptr;
1141 std::size_t fIdx = 0;
1142
1143 RIterator(const RNTupleDescriptor *ntuple, const std::vector<ROOT::DescriptorId_t> *sortedClusterGroupIds,
1144 std::size_t idx)
1145 : fNTuple(ntuple), fSortedClusterGroupIds(sortedClusterGroupIds), fIdx(idx)
1146 {
1147 }
1148
1149 public:
1150 using iterator_category = std::forward_iterator_tag;
1153 using difference_type = std::ptrdiff_t;
1156
1157 RIterator() = default;
1158 iterator &operator++() /* prefix */
1159 {
1160 ++fIdx;
1161 return *this;
1162 }
1163 iterator operator++(int) /* postfix */
1164 {
1165 auto old = *this;
1166 fIdx++;
1167 return old;
1168 }
1169 iterator &operator+=(std::size_t n)
1170 {
1171 fIdx += n;
1172 return *this;
1173 }
1174 iterator operator+(std::size_t n) const { return RIterator(fNTuple, fSortedClusterGroupIds, fIdx + n); }
1177 bool operator==(const iterator &rh) const { return (fNTuple == rh.fNTuple) && (fIdx == rh.fIdx); }
1178 bool operator!=(const iterator &rh) const { return !(*this == rh); }
1179 };
1180
1187 std::size_t size() const { return fNTuple.fSortedClusterGroupIds.size(); }
1188 bool empty() const { return fNTuple.fSortedClusterGroupIds.empty(); }
1189};
1190
1191// clang-format off
1192/**
1193\class ROOT::RNTupleDescriptor::RClusterDescriptorIterable
1194\ingroup NTuple
1195\brief Loop over all the clusters of an RNTuple, ordered by first entry number
1196
1197Enumerate all the active cluster IDs from all cluster groups. Iteration is ordered by first entry number.
1198Note that cluster groups without available cluster details (page lists) are silently skipped.
1199*/
1200// clang-format on
1202private:
1203 /// The associated RNTuple for this range.
1205
1206public:
1207 class RIterator final {
1208 private:
1210 using ClusterInGroupContainer_t = std::vector<DescriptorId_t>;
1211 using ClusterInGroupIter_t = ClusterInGroupContainer_t::const_iterator;
1212
1213 const RNTupleDescriptor *fNTuple = nullptr;
1216 std::size_t fClusterInGroupNum = 0; // index into RClusterGroupDescriptor::GetClusterIds()
1217
1218 public:
1219 using iterator_category = std::forward_iterator_tag;
1222 using difference_type = std::ptrdiff_t;
1225
1226 RIterator() = default;
1227 explicit RIterator(const RNTupleDescriptor &ntuple, std::size_t clusterGroupNum)
1228 : fNTuple(&ntuple),
1231 {
1232 }
1233 iterator &operator++() /* prefix */
1234 {
1236 while ((fClusterGroupIter != fClusterGroupEnd) &&
1237 (fClusterInGroupNum >= fClusterGroupIter->GetClusterIds().size())) {
1240 }
1241 return *this;
1242 }
1244 {
1246 }
1248 {
1250 }
1251 bool operator==(const iterator &rh) const
1252 {
1254 }
1255 bool operator!=(const iterator &rh) const { return !(*this == rh); }
1256 };
1257
1261};
1262
1263// clang-format off
1264/**
1265\class ROOT::RNTupleDescriptor::RExtraTypeInfoDescriptorIterable
1266\ingroup NTuple
1267\brief Used to loop over all the extra type info record of an RNTuple (in unspecified order)
1268*/
1269// clang-format on
1271private:
1272 /// The associated RNTuple for this range.
1274
1275public:
1276 class RIterator final {
1277 private:
1278 using Iter_t = std::vector<RExtraTypeInfoDescriptor>::const_iterator;
1279 /// The wrapped vector iterator
1281
1282 public:
1283 using iterator_category = std::forward_iterator_tag;
1286 using difference_type = std::ptrdiff_t;
1289
1290 RIterator() = default;
1291 explicit RIterator(Iter_t iter) : fIter(iter) {}
1292 iterator &operator++() /* prefix */
1293 {
1294 ++fIter;
1295 return *this;
1296 }
1297 iterator operator++(int) /* postfix */
1298 {
1299 auto old = *this;
1300 operator++();
1301 return old;
1302 }
1303 reference operator*() const { return *fIter; }
1304 pointer operator->() const { return fIter.operator->(); }
1305 bool operator!=(const iterator &rh) const { return fIter != rh.fIter; }
1306 bool operator==(const iterator &rh) const { return fIter == rh.fIter; }
1307 };
1308
1312};
1313
1314// clang-format off
1315/**
1316\class ROOT::RNTupleAttrSetDescriptorIterable
1317\ingroup NTuple
1318\brief Used to loop over all the Attribute Sets linked to an RNTuple
1319*/
1320// clang-format on
1321// TODO: move this to RNTupleDescriptor::RNTupleAttrSetDescriptorIterable when it moves out of Experimental.
1323private:
1324 /// The associated RNTuple for this range.
1326
1327public:
1328 class RIterator final {
1329 private:
1330 using Iter_t = std::vector<RNTupleAttrSetDescriptor>::const_iterator;
1331 /// The wrapped vector iterator
1333
1334 public:
1335 using iterator_category = std::forward_iterator_tag;
1338 using difference_type = std::ptrdiff_t;
1339 using pointer = const value_type *;
1340 using reference = const value_type &;
1341
1342 RIterator() = default;
1343 explicit RIterator(Iter_t iter) : fIter(iter) {}
1344 iterator &operator++() /* prefix */
1345 {
1346 ++fIter;
1347 return *this;
1348 }
1349 iterator operator++(int) /* postfix */
1350 {
1351 auto old = *this;
1352 operator++();
1353 return old;
1354 }
1355 reference operator*() const { return *fIter; }
1356 pointer operator->() const { return fIter.operator->(); }
1357 bool operator!=(const iterator &rh) const { return fIter != rh.fIter; }
1358 bool operator==(const iterator &rh) const { return fIter == rh.fIter; }
1359 };
1360
1364};
1365
1366// clang-format off
1367/**
1368\class ROOT::RNTupleDescriptor::RHeaderExtension
1369\ingroup NTuple
1370\brief Summarizes information about fields and the corresponding columns that were added after the header has been serialized
1371*/
1372// clang-format on
1375
1376private:
1377 /// All field IDs of late model extensions, in the order of field addition. This is necessary to serialize the
1378 /// the fields in that order.
1379 std::vector<ROOT::DescriptorId_t> fFieldIdsOrder;
1380 /// All field IDs of late model extensions for efficient lookup. When a column gets added to the extension
1381 /// header, this enables us to determine if the column belongs to a field of the header extension of if it
1382 /// belongs to a field of the regular header that gets extended by additional column representations.
1383 std::unordered_set<ROOT::DescriptorId_t> fFieldIdsLookup;
1384 /// All logical column IDs of columns that extend, with additional column representations, fields of the regular
1385 /// header. During serialization, these columns are not picked up as columns of `fFieldIdsOrder`. But instead
1386 /// these columns need to be serialized in the extension header without re-serializing the field.
1387 std::vector<ROOT::DescriptorId_t> fExtendedColumnRepresentations;
1388 /// Number of logical and physical columns; updated by the descriptor builder when columns are added
1389 std::uint32_t fNLogicalColumns = 0;
1390 std::uint32_t fNPhysicalColumns = 0;
1391
1392 /// Marks `fieldDesc` as an extended field, i.e. a field that appears in the Header Extension (e.g. having been added
1393 /// through late model extension). Note that the field descriptor should also have been added to the RNTuple
1394 /// Descriptor alongside non-extended fields.
1396 {
1397 fFieldIdsOrder.emplace_back(fieldDesc.GetId());
1398 fFieldIdsLookup.insert(fieldDesc.GetId());
1399 }
1400
1401 /// Marks `columnDesc` as an extended column, i.e. a column that appears in the Header Extension (e.g. having been
1402 /// added through late model extension as an additional representation of an existing column). Note that the column
1403 /// descriptor should also have been added to the RNTuple Descriptor alongside non-extended columns.
1405 {
1407 if (!columnDesc.IsAliasColumn())
1409 if (fFieldIdsLookup.count(columnDesc.GetFieldId()) == 0) {
1410 fExtendedColumnRepresentations.emplace_back(columnDesc.GetLogicalId());
1411 }
1412 }
1413
1414public:
1415 std::size_t GetNFields() const { return fFieldIdsOrder.size(); }
1416 std::size_t GetNLogicalColumns() const { return fNLogicalColumns; }
1417 std::size_t GetNPhysicalColumns() const { return fNPhysicalColumns; }
1418 const std::vector<ROOT::DescriptorId_t> &GetExtendedColumnRepresentations() const
1419 {
1421 }
1422 /// Return a vector containing the IDs of the top-level fields defined in the extension header, in the order
1423 /// of their addition. Note that these fields are not necessarily top-level fields in the overall schema.
1424 /// If a nested field is extended, it will return the top-most field of the extended subtree.
1425 /// We cannot create this vector when building the fFields because at the time when AddExtendedField is called,
1426 /// the field is not yet linked into the schema tree.
1427 std::vector<ROOT::DescriptorId_t> GetTopMostFields(const RNTupleDescriptor &desc) const;
1428
1430 {
1431 return fFieldIdsLookup.find(fieldId) != fFieldIdsLookup.end();
1432 }
1434 {
1435 return std::find(fExtendedColumnRepresentations.begin(), fExtendedColumnRepresentations.end(), columnId) !=
1437 }
1438};
1439
1440namespace Internal {
1443
1444public:
1446 {
1447 fDesc.fName = name;
1448 return *this;
1449 }
1450 RNTupleAttrSetDescriptorBuilder &SchemaVersion(std::uint16_t major, std::uint16_t minor)
1451 {
1452 fDesc.fSchemaVersionMajor = major;
1453 fDesc.fSchemaVersionMinor = minor;
1454 return *this;
1455 }
1457 {
1458 fDesc.fAnchorLocator = loc;
1459 return *this;
1460 }
1462 {
1464 return *this;
1465 }
1466
1467 /// Attempt to make an AttributeSet descriptor. This may fail if the builder
1468 /// was not given enough information to make a proper descriptor.
1470};
1471
1472// clang-format off
1473/**
1474\class ROOT::Internal::RColumnDescriptorBuilder
1475\ingroup NTuple
1476\brief A helper class for piece-wise construction of an RColumnDescriptor
1477
1478Dangling column descriptors can become actual descriptors when added to an
1479RNTupleDescriptorBuilder instance and then linked to their fields.
1480*/
1481// clang-format on
1483private:
1485
1486public:
1487 /// Make an empty column descriptor builder.
1489
1491 {
1492 fColumn.fLogicalColumnId = logicalColumnId;
1493 return *this;
1494 }
1496 {
1497 fColumn.fPhysicalColumnId = physicalColumnId;
1498 return *this;
1499 }
1500 RColumnDescriptorBuilder &BitsOnStorage(std::uint16_t bitsOnStorage)
1501 {
1502 fColumn.fBitsOnStorage = bitsOnStorage;
1503 return *this;
1504 }
1506 {
1507 fColumn.fType = type;
1508 return *this;
1509 }
1511 {
1512 fColumn.fFieldId = fieldId;
1513 return *this;
1514 }
1516 {
1518 return *this;
1519 }
1520 RColumnDescriptorBuilder &FirstElementIndex(std::uint64_t firstElementIdx)
1521 {
1522 fColumn.fFirstElementIndex = firstElementIdx;
1523 return *this;
1524 }
1532 RColumnDescriptorBuilder &RepresentationIndex(std::uint16_t representationIndex)
1533 {
1534 fColumn.fRepresentationIndex = representationIndex;
1535 return *this;
1536 }
1537 RColumnDescriptorBuilder &ValueRange(double min, double max)
1538 {
1539 fColumn.fValueRange = std::make_unique<RColumnDescriptor::RValueRange>(min, max);
1540 return *this;
1541 }
1542 RColumnDescriptorBuilder &ValueRange(std::optional<RColumnDescriptor::RValueRange> valueRange)
1543 {
1544 if (valueRange)
1545 fColumn.fValueRange = std::make_unique<RColumnDescriptor::RValueRange>(*valueRange);
1546 return *this;
1547 }
1550 /// Attempt to make a column descriptor. This may fail if the column
1551 /// was not given enough information to make a proper descriptor.
1553};
1554
1555// clang-format off
1556/**
1557\class ROOT::Internal::RFieldDescriptorBuilder
1558\ingroup NTuple
1559\brief A helper class for piece-wise construction of an RFieldDescriptor
1560
1561Dangling field descriptors describe a single field in isolation. They are
1562missing the necessary relationship information (parent field, any child fields)
1563required to describe a real RNTuple field.
1564
1565Dangling field descriptors can only become actual descriptors when added to an
1566RNTupleDescriptorBuilder instance and then linked to other fields.
1567*/
1568// clang-format on
1570private:
1573
1574public:
1576 {
1577 fField.fStringPool = std::make_unique<RStringPool>();
1579 }
1580
1581 // The passed string pool needs to live at least as long as the field descriptor to be moved out of this builder
1582 explicit RFieldDescriptorBuilder(RStringPool &stringPool) : fStringPool(&stringPool) {}
1583
1584 // Takes an existing field descriptor to patch it up. The given string pool must be the one that is already
1585 // being used by the source descriptor.
1587 : fField(std::move(source)), fStringPool(&stringPool)
1588 {
1589 }
1590
1591 // Makes a copy of the given descriptor and assigns the clone's strings to the new string pool
1592 static RFieldDescriptor CloneDescriptor(const RFieldDescriptor &source, RStringPool &stringPool);
1593
1595 {
1596 fField.fFieldId = fieldId;
1597 return *this;
1598 }
1599 RFieldDescriptorBuilder &FieldVersion(std::uint32_t fieldVersion)
1600 {
1601 fField.fFieldVersion = fieldVersion;
1602 return *this;
1603 }
1604 RFieldDescriptorBuilder &TypeVersion(std::uint32_t typeVersion)
1605 {
1606 fField.fTypeVersion = typeVersion;
1607 return *this;
1608 }
1610 {
1612 return *this;
1613 }
1619 RFieldDescriptorBuilder &FieldName(const std::string &fieldName)
1620 {
1621 fField.fFieldName = fStringPool->Intern(fieldName);
1622 return *this;
1623 }
1624 RFieldDescriptorBuilder &FieldDescription(const std::string &fieldDescription)
1625 {
1626 fField.fFieldDescription = fStringPool->Intern(fieldDescription);
1627 return *this;
1628 }
1629 RFieldDescriptorBuilder &TypeName(const std::string &typeName)
1630 {
1631 fField.fTypeName = fStringPool->Intern(typeName);
1632 return *this;
1633 }
1634 RFieldDescriptorBuilder &TypeAlias(const std::string &typeAlias)
1635 {
1636 fField.fTypeAlias = fStringPool->Intern(typeAlias);
1637 return *this;
1638 }
1639 RFieldDescriptorBuilder &NRepetitions(std::uint64_t nRepetitions)
1640 {
1641 fField.fNRepetitions = nRepetitions;
1642 return *this;
1643 }
1645 {
1646 fField.fStructure = structure;
1647 return *this;
1648 }
1649 RFieldDescriptorBuilder &TypeChecksum(const std::optional<std::uint32_t> typeChecksum)
1650 {
1651 fField.fTypeChecksum = typeChecksum;
1652 return *this;
1653 }
1655 {
1657 return *this;
1658 }
1660 /// Attempt to make a field descriptor. This may fail if the dangling field
1661 /// was not given enough information to make a proper descriptor.
1663};
1664
1665// clang-format off
1666/**
1667\class ROOT::Internal::RClusterDescriptorBuilder
1668\ingroup NTuple
1669\brief A helper class for piece-wise construction of an RClusterDescriptor
1670
1671The cluster descriptor builder starts from a summary-only cluster descriptor and allows for the
1672piecewise addition of page locations.
1673*/
1674// clang-format on
1676private:
1678
1679public:
1681 {
1682 fCluster.fClusterId = clusterId;
1683 return *this;
1684 }
1685
1686 RClusterDescriptorBuilder &FirstEntryIndex(std::uint64_t firstEntryIndex)
1687 {
1688 fCluster.fFirstEntryIndex = firstEntryIndex;
1689 return *this;
1690 }
1691
1692 RClusterDescriptorBuilder &NEntries(std::uint64_t nEntries)
1693 {
1694 fCluster.fNEntries = nEntries;
1695 return *this;
1696 }
1697
1698 RResult<void> CommitColumnRange(ROOT::DescriptorId_t physicalId, std::uint64_t firstElementIndex,
1699 std::uint32_t compressionSettings, const RClusterDescriptor::RPageRange &pageRange);
1700
1701 /// Books the given column ID as being suppressed in this cluster. The correct first element index and number of
1702 /// elements need to be set by CommitSuppressedColumnRanges() once all the calls to CommitColumnRange() and
1703 /// MarkSuppressedColumnRange() took place.
1705
1706 /// Sets the first element index and number of elements for all the suppressed column ranges.
1707 /// The information is taken from the corresponding columns from the primary representation.
1708 /// Needs to be called when all the columns (suppressed and regular) where added.
1710
1711 /// Add column and page ranges for columns created during late model extension missing in this cluster. The locator
1712 /// type for the synthesized page ranges is `kTypePageZero`. All the page sources must be able to populate the
1713 /// 'zero' page from such locator. Any call to CommitColumnRange() and CommitSuppressedColumnRanges()
1714 /// should happen before calling this function.
1716
1718 {
1719 return fCluster.GetColumnRange(physicalId);
1720 }
1721
1722 /// Move out the full cluster descriptor including page locations
1724};
1725
1726// clang-format off
1727/**
1728\class ROOT::Internal::RClusterGroupDescriptorBuilder
1729\ingroup NTuple
1730\brief A helper class for piece-wise construction of an RClusterGroupDescriptor
1731*/
1732// clang-format on
1734private:
1736
1737public:
1740
1742 {
1743 fClusterGroup.fClusterGroupId = clusterGroupId;
1744 return *this;
1745 }
1747 {
1748 fClusterGroup.fPageListLocator = pageListLocator;
1749 return *this;
1750 }
1751 RClusterGroupDescriptorBuilder &PageListLength(std::uint64_t pageListLength)
1752 {
1753 fClusterGroup.fPageListLength = pageListLength;
1754 return *this;
1755 }
1757 {
1758 fClusterGroup.fMinEntry = minEntry;
1759 return *this;
1760 }
1762 {
1763 fClusterGroup.fEntrySpan = entrySpan;
1764 return *this;
1765 }
1767 {
1768 fClusterGroup.fNClusters = nClusters;
1769 return *this;
1770 }
1771 void AddSortedClusters(const std::vector<ROOT::DescriptorId_t> &clusterIds)
1772 {
1773 if (clusterIds.size() != fClusterGroup.GetNClusters())
1774 throw RException(R__FAIL("mismatch of number of clusters"));
1775 fClusterGroup.fClusterIds = clusterIds;
1776 }
1777
1779};
1780
1781// clang-format off
1782/**
1783\class ROOT::Internal::RExtraTypeInfoDescriptorBuilder
1784\ingroup NTuple
1785\brief A helper class for piece-wise construction of an RExtraTypeInfoDescriptor
1786*/
1787// clang-format on
1789private:
1791
1792public:
1794
1796 {
1797 fExtraTypeInfo.fContentId = contentId;
1798 return *this;
1799 }
1801 {
1802 fExtraTypeInfo.fTypeVersion = typeVersion;
1803 return *this;
1804 }
1805 RExtraTypeInfoDescriptorBuilder &TypeName(const std::string &typeName)
1806 {
1807 fExtraTypeInfo.fTypeName = typeName;
1808 return *this;
1809 }
1810 RExtraTypeInfoDescriptorBuilder &Content(const std::string &content)
1811 {
1812 fExtraTypeInfo.fContent = content;
1813 return *this;
1814 }
1815
1817};
1818
1819// clang-format off
1820/**
1821\class ROOT::Internal::RNTupleDescriptorBuilder
1822\ingroup NTuple
1823\brief A helper class for piece-wise construction of an RNTupleDescriptor
1824
1825Used by RPageStorage implementations in order to construct the RNTupleDescriptor from the various header parts.
1826*/
1827// clang-format on
1829private:
1832
1833public:
1834 /// Checks whether invariants hold:
1835 /// * RNTuple epoch is valid
1836 /// * RNTuple name is valid
1837 /// * Fields have valid parents
1838 /// * Number of columns is constant across column representations
1843
1844 /// Copies the "schema" part of `descriptor` into the builder's descriptor.
1845 /// This resets the builder's descriptor.
1846 void SetSchemaFromExisting(const RNTupleDescriptor &descriptor);
1847
1848 void SetVersion(std::uint16_t versionEpoch, std::uint16_t versionMajor, std::uint16_t versionMinor,
1849 std::uint16_t versionPatch);
1850 void SetVersionForWriting();
1851
1852 void SetNTuple(std::string_view name, std::string_view description);
1853 /// Sets the `flag`-th bit of the feature flag to 1.
1854 /// Note that `flag` itself is not a bitmask, just the bit index of the flag to enable.
1855 void SetFeature(unsigned int flag);
1856
1857 void SetOnDiskHeaderXxHash3(std::uint64_t xxhash3) { fDescriptor.fOnDiskHeaderXxHash3 = xxhash3; }
1859 /// The real footer size also include the page list envelopes
1861
1862 void AddField(RFieldDescriptor fieldDesc);
1863 void AddField(const ROOT::RFieldBase &field, DescriptorId_t fieldId);
1866
1867 // The field that the column belongs to has to be already available. For fields with multiple columns,
1868 // the columns need to be added in order of the column index
1870
1873
1875 void ReplaceExtraTypeInfo(RExtraTypeInfoDescriptor &&extraTypeInfoDesc);
1876
1878
1879 /// Mark the beginning of the header extension; any fields and columns added after a call to this function are
1880 /// annotated as begin part of the header extension.
1881 void BeginHeaderExtension();
1882
1883 /// \brief Shift column IDs of alias columns by `offset`
1884 ///
1885 /// If the descriptor is constructed in pieces consisting of physical and alias columns
1886 /// (regular and projected fields), the natural column order would be
1887 /// - Physical and alias columns of piece one
1888 /// - Physical and alias columns of piece two
1889 /// - etc.
1890 /// What we want, however, are first all physical column IDs and then all alias column IDs.
1891 /// This method adds `offset` to the logical column IDs of all alias columns and fixes up the corresponding
1892 /// column IDs in the projected field descriptors. In this way, a new piece of physical and alias columns can
1893 /// first shift the existing alias columns by the number of new physical columns, resulting in the following order
1894 /// - Physical columns of piece one
1895 /// - Physical columns of piece two
1896 /// - ...
1897 // - Logical columns of piece one
1898 /// - Logical columns of piece two
1899 /// - ...
1900 void ShiftAliasColumns(std::uint32_t offset);
1901};
1902
1904{
1905 return desc.CloneSchema(false /* shareStringPool */);
1906}
1907
1908/// Tells if the field describes a user-defined enum type.
1909/// The dictionary does not need to be available for this method.
1910/// Needs the full descriptor to look up sub fields.
1911bool IsCustomEnumFieldDesc(const RNTupleDescriptor &desc, const RFieldDescriptor &fieldDesc);
1912
1913/// Tells if the field describes a std::atomic<T> type
1914bool IsStdAtomicFieldDesc(const RFieldDescriptor &fieldDesc);
1915
1916} // namespace Internal
1917
1918} // namespace ROOT
1919
1920#endif // ROOT_RNTupleDescriptor
#define R__DEPRECATED(MAJOR, MINOR, REASON)
Definition RConfig.hxx:486
#define R__FAIL(msg)
Short-hand to return an RResult<T> in an error state; the RError is implicitly converted into RResult...
Definition RError.hxx:322
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
Definition TError.h:139
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h length
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize id
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
char name[80]
Definition TGX11.cxx:142
The available trivial, native content types of a column.
A helper class for piece-wise construction of an RClusterDescriptor.
RResult< void > MarkSuppressedColumnRange(ROOT::DescriptorId_t physicalId)
Books the given column ID as being suppressed in this cluster.
RResult< void > CommitColumnRange(ROOT::DescriptorId_t physicalId, std::uint64_t firstElementIndex, std::uint32_t compressionSettings, const RClusterDescriptor::RPageRange &pageRange)
RClusterDescriptorBuilder & AddExtendedColumnRanges(const RNTupleDescriptor &desc)
Add column and page ranges for columns created during late model extension missing in this cluster.
RClusterDescriptorBuilder & NEntries(std::uint64_t nEntries)
RResult< void > CommitSuppressedColumnRanges(const RNTupleDescriptor &desc)
Sets the first element index and number of elements for all the suppressed column ranges.
RResult< RClusterDescriptor > MoveDescriptor()
Move out the full cluster descriptor including page locations.
const RClusterDescriptor::RColumnRange & GetColumnRange(ROOT::DescriptorId_t physicalId)
RClusterDescriptorBuilder & ClusterId(ROOT::DescriptorId_t clusterId)
RClusterDescriptorBuilder & FirstEntryIndex(std::uint64_t firstEntryIndex)
A helper class for piece-wise construction of an RClusterGroupDescriptor.
RClusterGroupDescriptorBuilder & EntrySpan(std::uint64_t entrySpan)
RClusterGroupDescriptorBuilder & PageListLocator(const RNTupleLocator &pageListLocator)
static RClusterGroupDescriptorBuilder FromSummary(const RClusterGroupDescriptor &clusterGroupDesc)
RClusterGroupDescriptorBuilder & PageListLength(std::uint64_t pageListLength)
RClusterGroupDescriptorBuilder & MinEntry(std::uint64_t minEntry)
void AddSortedClusters(const std::vector< ROOT::DescriptorId_t > &clusterIds)
RResult< RClusterGroupDescriptor > MoveDescriptor()
RClusterGroupDescriptorBuilder & ClusterGroupId(ROOT::DescriptorId_t clusterGroupId)
RClusterGroupDescriptorBuilder & NClusters(std::uint32_t nClusters)
A helper class for piece-wise construction of an RColumnDescriptor.
ROOT::DescriptorId_t GetRepresentationIndex() const
RColumnDescriptorBuilder & SetSuppressedDeferred()
RColumnDescriptorBuilder & LogicalColumnId(ROOT::DescriptorId_t logicalColumnId)
RColumnDescriptorBuilder & FieldId(ROOT::DescriptorId_t fieldId)
RColumnDescriptorBuilder & BitsOnStorage(std::uint16_t bitsOnStorage)
RColumnDescriptorBuilder & ValueRange(double min, double max)
RColumnDescriptorBuilder()=default
Make an empty column descriptor builder.
RColumnDescriptorBuilder & ValueRange(std::optional< RColumnDescriptor::RValueRange > valueRange)
RColumnDescriptorBuilder & Type(ROOT::ENTupleColumnType type)
RColumnDescriptorBuilder & PhysicalColumnId(ROOT::DescriptorId_t physicalColumnId)
RColumnDescriptorBuilder & FirstElementIndex(std::uint64_t firstElementIdx)
RColumnDescriptorBuilder & Index(std::uint32_t index)
RColumnDescriptorBuilder & RepresentationIndex(std::uint16_t representationIndex)
RResult< RColumnDescriptor > MoveDescriptor()
Attempt to make a column descriptor.
A column element encapsulates the translation between basic C++ types and their column representation...
A helper class for piece-wise construction of an RExtraTypeInfoDescriptor.
RResult< RExtraTypeInfoDescriptor > MoveDescriptor()
RExtraTypeInfoDescriptorBuilder & ContentId(EExtraTypeInfoIds contentId)
RExtraTypeInfoDescriptorBuilder & TypeName(const std::string &typeName)
RExtraTypeInfoDescriptorBuilder & Content(const std::string &content)
RExtraTypeInfoDescriptorBuilder & TypeVersion(std::uint32_t typeVersion)
A helper class for piece-wise construction of an RFieldDescriptor.
RResult< RFieldDescriptor > MoveDescriptor()
Attempt to make a field descriptor.
RFieldDescriptorBuilder & NRepetitions(std::uint64_t nRepetitions)
RFieldDescriptorBuilder & Structure(const ROOT::ENTupleStructure &structure)
RFieldDescriptorBuilder & TypeAlias(const std::string &typeAlias)
RFieldDescriptorBuilder & ProjectionSourceId(ROOT::DescriptorId_t id)
static RFieldDescriptor CloneDescriptor(const RFieldDescriptor &source, RStringPool &stringPool)
RFieldDescriptorBuilder & TypeVersion(std::uint32_t typeVersion)
RFieldDescriptorBuilder & IsSoACollection(bool val)
RFieldDescriptorBuilder & TypeChecksum(const std::optional< std::uint32_t > typeChecksum)
RFieldDescriptorBuilder & ParentId(ROOT::DescriptorId_t id)
RFieldDescriptorBuilder & FieldDescription(const std::string &fieldDescription)
RFieldDescriptorBuilder & FieldVersion(std::uint32_t fieldVersion)
RFieldDescriptorBuilder(RFieldDescriptor &&source, RStringPool &stringPool)
RFieldDescriptorBuilder & FieldName(const std::string &fieldName)
RFieldDescriptorBuilder & FieldId(ROOT::DescriptorId_t fieldId)
RFieldDescriptorBuilder & TypeName(const std::string &typeName)
RNTupleAttrSetDescriptorBuilder & Name(std::string_view name)
RNTupleAttrSetDescriptorBuilder & SchemaVersion(std::uint16_t major, std::uint16_t minor)
RResult< ROOT::RNTupleAttrSetDescriptor > MoveDescriptor()
Attempt to make an AttributeSet descriptor.
RNTupleAttrSetDescriptorBuilder & AnchorLocator(const RNTupleLocator &loc)
RNTupleAttrSetDescriptorBuilder & AnchorLength(std::uint32_t length)
A helper class for piece-wise construction of an RNTupleDescriptor.
void SetNTuple(std::string_view name, std::string_view description)
void SetSchemaFromExisting(const RNTupleDescriptor &descriptor)
Copies the "schema" part of descriptor into the builder's descriptor.
RResult< void > AddColumn(RColumnDescriptor &&columnDesc)
void AddField(RFieldDescriptor fieldDesc)
RResult< void > AddFieldProjection(ROOT::DescriptorId_t sourceId, ROOT::DescriptorId_t targetId)
void ReplaceExtraTypeInfo(RExtraTypeInfoDescriptor &&extraTypeInfoDesc)
RResult< void > AddExtraTypeInfo(RExtraTypeInfoDescriptor &&extraTypeInfoDesc)
void ShiftAliasColumns(std::uint32_t offset)
Shift column IDs of alias columns by offset
RResult< void > AddAttributeSet(RNTupleAttrSetDescriptor &&attrSetDesc)
void SetVersion(std::uint16_t versionEpoch, std::uint16_t versionMajor, std::uint16_t versionMinor, std::uint16_t versionPatch)
const RNTupleDescriptor & GetDescriptor() const
void BeginHeaderExtension()
Mark the beginning of the header extension; any fields and columns added after a call to this functio...
RResult< void > AddCluster(RClusterDescriptor &&clusterDesc)
RResult< void > EnsureValidDescriptor() const
Checks whether invariants hold:
RResult< void > AddFieldLink(ROOT::DescriptorId_t fieldId, ROOT::DescriptorId_t linkId)
RResult< void > AddClusterGroup(RClusterGroupDescriptor &&clusterGroup)
void SetOnDiskHeaderXxHash3(std::uint64_t xxhash3)
RResult< void > EnsureFieldExists(ROOT::DescriptorId_t fieldId) const
void SetFeature(unsigned int flag)
Sets the flag-th bit of the feature flag to 1.
void AddToOnDiskFooterSize(std::uint64_t size)
The real footer size also include the page list envelopes.
Used for string interning of repeated type names, field names, etc.
const std::string * Intern(std::string_view str)
Searches for str in the pool.
std::unordered_map< ROOT::DescriptorId_t, RColumnRange >::const_iterator Iter_t
RColumnRangeIterable(const RClusterDescriptor &desc)
The window of element indexes of a particular column in a particular cluster.
void SetCompressionSettings(std::optional< std::uint32_t > comp)
bool fIsSuppressed
Suppressed columns have an empty page range and unknown compression settings.
void SetPhysicalColumnId(ROOT::DescriptorId_t id)
ROOT::DescriptorId_t GetPhysicalColumnId() const
bool operator==(const RColumnRange &other) const
void SetFirstElementIndex(ROOT::NTupleSize_t idx)
ROOT::NTupleSize_t fFirstElementIndex
The global index of the first column element in the cluster.
std::optional< std::uint32_t > GetCompressionSettings() const
std::optional< std::uint32_t > fCompressionSettings
The usual format for ROOT compression settings (see Compression.h).
ROOT::NTupleSize_t GetFirstElementIndex() const
RColumnRange(ROOT::DescriptorId_t physicalColumnId, ROOT::NTupleSize_t firstElementIndex, ROOT::NTupleSize_t nElements, std::optional< std::uint32_t > compressionSettings, bool suppressed=false)
void IncrementFirstElementIndex(ROOT::NTupleSize_t by)
bool Contains(ROOT::NTupleSize_t index) const
ROOT::NTupleSize_t fNElements
The number of column elements in the cluster.
void IncrementNElements(ROOT::NTupleSize_t by)
Records the partition of data into pages for a particular column in a particular cluster.
RPageRange & operator=(const RPageRange &other)=delete
std::unique_ptr< std::vector< ROOT::NTupleSize_t > > fCumulativeNElements
Has the same length than fPageInfos and stores the sum of the number of elements of all the pages up ...
RPageRange(RPageRange &&other)=default
static constexpr std::size_t kLargeRangeThreshold
Create the fCumulativeNElements only when its needed, i.e. when there are many pages to search throug...
RPageRange(const RPageRange &other)=delete
const std::vector< RPageInfo > & GetPageInfos() const
RPageInfoExtended Find(ROOT::NTupleSize_t idxInCluster) const
Find the page in the RPageRange that contains the given element. The element must exist.
bool operator==(const RPageRange &other) const
ROOT::DescriptorId_t GetPhysicalColumnId() const
void SetPhysicalColumnId(ROOT::DescriptorId_t id)
std::size_t ExtendToFitColumnRange(const RColumnRange &columnRange, const ROOT::Internal::RColumnElementBase &element, std::size_t pageSize)
Extend this RPageRange to fit the given RColumnRange.
RPageRange & operator=(RPageRange &&other)=default
std::vector< RPageInfo > & GetPageInfos()
Metadata for RNTuple clusters.
ROOT::NTupleSize_t GetNEntries() const
ROOT::NTupleSize_t fFirstEntryIndex
Clusters can be swapped by adjusting the entry offsets of the cluster and all ranges.
RClusterDescriptor & operator=(const RClusterDescriptor &other)=delete
ROOT::DescriptorId_t GetId() const
const RPageRange & GetPageRange(ROOT::DescriptorId_t physicalId) const
RClusterDescriptor(RClusterDescriptor &&other)=default
std::unordered_map< ROOT::DescriptorId_t, RColumnRange > fColumnRanges
ROOT::DescriptorId_t fClusterId
bool ContainsColumn(ROOT::DescriptorId_t physicalId) const
RClusterDescriptor & operator=(RClusterDescriptor &&other)=default
RClusterDescriptor Clone() const
bool operator==(const RClusterDescriptor &other) const
const RColumnRange & GetColumnRange(ROOT::DescriptorId_t physicalId) const
RColumnRangeIterable GetColumnRangeIterable() const
Returns an iterator over pairs { columnId, columnRange }. The iteration order is unspecified.
ROOT::NTupleSize_t GetFirstEntryIndex() const
std::unordered_map< ROOT::DescriptorId_t, RPageRange > fPageRanges
RClusterDescriptor(const RClusterDescriptor &other)=delete
std::uint64_t GetNBytesOnStorage() const
Clusters are bundled in cluster groups.
RNTupleLocator fPageListLocator
The page list that corresponds to the cluster group.
RClusterGroupDescriptor & operator=(const RClusterGroupDescriptor &other)=delete
RClusterGroupDescriptor Clone() const
std::vector< ROOT::DescriptorId_t > fClusterIds
The cluster IDs can be empty if the corresponding page list is not loaded.
ROOT::DescriptorId_t GetId() const
RClusterGroupDescriptor(RClusterGroupDescriptor &&other)=default
std::uint64_t fMinEntry
The minimum first entry number of the clusters in the cluster group.
bool HasClusterDetails() const
A cluster group is loaded in two stages.
std::uint32_t fNClusters
Number of clusters is always known even if the cluster IDs are not (yet) populated.
RClusterGroupDescriptor & operator=(RClusterGroupDescriptor &&other)=default
const std::vector< ROOT::DescriptorId_t > & GetClusterIds() const
std::uint64_t fPageListLength
Uncompressed size of the page list.
std::uint64_t GetPageListLength() const
RNTupleLocator GetPageListLocator() const
RClusterGroupDescriptor(const RClusterGroupDescriptor &other)=delete
std::uint64_t fEntrySpan
Number of entries that are (partially for sharded clusters) covered by this cluster group.
bool operator==(const RClusterGroupDescriptor &other) const
RClusterGroupDescriptor CloneSummary() const
Creates a clone without the cluster IDs.
Metadata stored for every column of an RNTuple.
std::optional< RValueRange > GetValueRange() const
ROOT::DescriptorId_t fPhysicalColumnId
Usually identical to the logical column ID, except for alias columns where it references the shadowed...
bool operator==(const RColumnDescriptor &other) const
ROOT::DescriptorId_t fLogicalColumnId
The actual column identifier, which is the link to the corresponding field.
std::unique_ptr< RValueRange > fValueRange
Optional value range (used e.g. by quantized real fields)
RColumnDescriptor(const RColumnDescriptor &other)=delete
std::uint64_t GetFirstElementIndex() const
ROOT::DescriptorId_t fFieldId
Every column belongs to one and only one field.
std::int64_t fFirstElementIndex
The absolute value specifies the index for the first stored element for this column.
ROOT::DescriptorId_t GetFieldId() const
RColumnDescriptor(RColumnDescriptor &&other)=default
std::uint32_t fIndex
A field can be serialized into several columns, which are numbered from zero to $n$.
RColumnDescriptor & operator=(RColumnDescriptor &&other)=default
std::uint32_t GetIndex() const
std::uint16_t fBitsOnStorage
The size in bits of elements of this column.
std::uint16_t fRepresentationIndex
A field may use multiple column representations, which are numbered from zero to $m$.
ROOT::ENTupleColumnType fType
The on-disk column type.
ROOT::ENTupleColumnType GetType() const
ROOT::DescriptorId_t GetPhysicalId() const
std::uint16_t GetRepresentationIndex() const
std::uint16_t GetBitsOnStorage() const
RColumnDescriptor Clone() const
Get a copy of the descriptor.
RColumnDescriptor & operator=(const RColumnDescriptor &other)=delete
ROOT::DescriptorId_t GetLogicalId() const
Base class for all ROOT issued exceptions.
Definition RError.hxx:78
Field specific extra type information from the header / extenstion header.
RExtraTypeInfoDescriptor & operator=(RExtraTypeInfoDescriptor &&other)=default
RExtraTypeInfoDescriptor & operator=(const RExtraTypeInfoDescriptor &other)=delete
bool operator==(const RExtraTypeInfoDescriptor &other) const
RExtraTypeInfoDescriptor Clone() const
RExtraTypeInfoDescriptor(const RExtraTypeInfoDescriptor &other)=delete
EExtraTypeInfoIds fContentId
Specifies the meaning of the extra information.
std::string fTypeName
The type name the extra information refers to; empty for RNTuple-wide extra information.
std::string fContent
The content format depends on the content ID and may be binary.
const std::string & GetContent() const
const std::string & GetTypeName() const
RExtraTypeInfoDescriptor(RExtraTypeInfoDescriptor &&other)=default
EExtraTypeInfoIds GetContentId() const
std::uint32_t fTypeVersion
Type version the extra type information is bound to.
A field translates read and write calls from/to underlying columns to/from tree values.
Metadata stored for every field of an RNTuple.
const std::string & GetTypeAlias() const
std::unique_ptr< ROOT::RFieldBase > CreateField(const RNTupleDescriptor &ntplDesc, const ROOT::RCreateFieldOptions &options={}) const
In general, we create a field simply from the C++ type name.
std::uint32_t fFieldVersion
The version of the C++-type-to-column translation mechanics.
ROOT::DescriptorId_t fFieldId
RFieldDescriptor Clone() const
Get a copy of the descriptor.
ROOT::DescriptorId_t GetId() const
std::uint64_t fNRepetitions
The number of elements per entry for fixed-size arrays.
std::uint32_t GetFieldVersion() const
const std::vector< ROOT::DescriptorId_t > & GetLogicalColumnIds() const
std::uint32_t fColumnCardinality
The number of columns in the column representations of the field.
ROOT::DescriptorId_t fProjectionSourceId
For projected fields, the source field ID.
static const std::string & GetEmptyString()
ROOT::ENTupleStructure GetStructure() const
bool operator==(const RFieldDescriptor &other) const
const std::string * fFieldName
The leaf name, not including parent fields.
const std::string * fTypeName
The C++ type that was used when writing the field.
RFieldDescriptor(const RFieldDescriptor &other)=delete
std::uint32_t GetColumnCardinality() const
const std::string * fFieldDescription
Free text set by the user.
RFieldDescriptor & operator=(const RFieldDescriptor &other)=delete
RFieldDescriptor & operator=(RFieldDescriptor &&other)=default
const std::vector< ROOT::DescriptorId_t > & GetLinkIds() const
ROOT::DescriptorId_t fParentId
Establishes sub field relationships, such as classes and collections.
ROOT::DescriptorId_t GetParentId() const
ROOT::ENTupleStructure fStructure
The structural information carried by this field in the data model tree.
const std::string * fTypeAlias
A typedef or using directive that resolved to the type name during field creation.
std::uint64_t GetNRepetitions() const
RFieldDescriptor(RFieldDescriptor &&other)=default
std::vector< ROOT::DescriptorId_t > fLinkIds
The pointers in the other direction from parent to children.
const std::string & GetFieldDescription() const
std::optional< std::uint32_t > GetTypeChecksum() const
ROOT::DescriptorId_t GetProjectionSourceId() const
void InitFrom(const RFieldDescriptor &source, Internal::RStringPool &stringPool)
bool fIsSoACollection
Indicates if this is a collection that should be represented in memory by a SoA layout.
std::uint32_t fTypeVersion
The version of the C++ type itself.
std::uint32_t GetTypeVersion() const
const std::string & GetFieldName() const
std::unique_ptr< Internal::RStringPool > fStringPool
Optional string storage for a free-standing field descriptor.
std::vector< ROOT::DescriptorId_t > fLogicalColumnIds
The ordered list of columns attached to this field: first by representation index then by column inde...
const std::string & GetTypeName() const
std::optional< std::uint32_t > fTypeChecksum
For custom classes, we store the ROOT TClass reported checksum to facilitate the use of I/O rules tha...
Used to loop over all the Attribute Sets linked to an RNTuple.
Metadata stored for every Attribute Set linked to an RNTuple.
std::uint16_t GetSchemaVersionMinor() const
RNTupleAttrSetDescriptor(RNTupleAttrSetDescriptor &&other)=default
bool operator!=(const RNTupleAttrSetDescriptor &other) const
RNTupleAttrSetDescriptor & operator=(RNTupleAttrSetDescriptor &&other)=default
std::uint16_t GetSchemaVersionMajor() const
RNTupleAttrSetDescriptor Clone() const
const std::string & GetName() const
RNTupleAttrSetDescriptor(const RNTupleAttrSetDescriptor &other)=delete
RNTupleAttrSetDescriptor & operator=(const RNTupleAttrSetDescriptor &other)=delete
bool operator==(const RNTupleAttrSetDescriptor &other) const
std::uint32_t fAnchorLength
uncompressed size of the linked anchor
const RNTupleLocator & GetAnchorLocator() const
std::uint32_t GetAnchorLength() const
RIterator(const RNTupleDescriptor &ntuple, std::size_t clusterGroupNum)
Loop over all the clusters of an RNTuple, ordered by first entry number.
const RNTupleDescriptor & fNTuple
The associated RNTuple for this range.
RClusterDescriptorIterable(const RNTupleDescriptor &ntuple)
RIterator(const RNTupleDescriptor *ntuple, const std::vector< ROOT::DescriptorId_t > *sortedClusterGroupIds, std::size_t idx)
Used to loop over all the cluster groups of an RNTuple in order of entry ranges.
const RNTupleDescriptor & fNTuple
The associated RNTuple for this range.
RIterator(const RColumnDescriptorIterable *iterable=nullptr, std::size_t index=0)
const RColumnDescriptorIterable * fIterable
The enclosing RColumnDescriptorIterable.
Used to loop over a field's associated columns.
const RNTupleDescriptor & fNTuple
The associated RNTuple for this range.
std::vector< ROOT::DescriptorId_t > fColumns
The descriptor ids of the columns ordered by field, representation, and column index.
RColumnDescriptorIterable(const RNTupleDescriptor &ntuple, const RFieldDescriptor &fieldDesc)
std::vector< RExtraTypeInfoDescriptor >::const_iterator Iter_t
Used to loop over all the extra type info record of an RNTuple (in unspecified order)
const RNTupleDescriptor & fNTuple
The associated RNTuple for this range.
RIterator(const RFieldDescriptorIterable *iterable=nullptr, std::size_t index=0)
const RFieldDescriptorIterable * fIterable
The enclosing RFieldDescriptorIterable.
Used to loop over a field's child fields.
const RNTupleDescriptor & fNTuple
The associated RNTuple for this range.
RFieldDescriptorIterable(const RNTupleDescriptor &ntuple, const RFieldDescriptor &field, const std::function< bool(ROOT::DescriptorId_t, ROOT::DescriptorId_t)> &comparator)
Sort the range using an arbitrary comparison function.
RFieldDescriptorIterable(const RNTupleDescriptor &ntuple, const RFieldDescriptor &field)
std::vector< ROOT::DescriptorId_t > fFieldChildren
The descriptor IDs of the child fields.
Summarizes information about fields and the corresponding columns that were added after the header ha...
const std::vector< ROOT::DescriptorId_t > & GetExtendedColumnRepresentations() const
std::unordered_set< ROOT::DescriptorId_t > fFieldIdsLookup
All field IDs of late model extensions for efficient lookup.
std::vector< ROOT::DescriptorId_t > GetTopMostFields(const RNTupleDescriptor &desc) const
Return a vector containing the IDs of the top-level fields defined in the extension header,...
std::uint32_t fNLogicalColumns
Number of logical and physical columns; updated by the descriptor builder when columns are added.
std::vector< ROOT::DescriptorId_t > fExtendedColumnRepresentations
All logical column IDs of columns that extend, with additional column representations,...
bool ContainsExtendedColumnRepresentation(ROOT::DescriptorId_t columnId) const
void MarkExtendedField(const RFieldDescriptor &fieldDesc)
Marks fieldDesc as an extended field, i.e.
std::vector< ROOT::DescriptorId_t > fFieldIdsOrder
All field IDs of late model extensions, in the order of field addition.
bool ContainsField(ROOT::DescriptorId_t fieldId) const
void MarkExtendedColumn(const RColumnDescriptor &columnDesc)
Marks columnDesc as an extended column, i.e.
std::vector< RNTupleAttrSetDescriptor >::const_iterator Iter_t
const RNTupleDescriptor & fNTuple
The associated RNTuple for this range.
The on-storage metadata of an RNTuple.
std::uint64_t GetGeneration() const
std::vector< RNTupleAttrSetDescriptor > fAttributeSets
List of AttributeSets linked to this RNTuple.
RNTupleDescriptor(RNTupleDescriptor &&other)=default
const RClusterGroupDescriptor & GetClusterGroupDescriptor(ROOT::DescriptorId_t clusterGroupId) const
const RColumnDescriptor & GetColumnDescriptor(ROOT::DescriptorId_t columnId) const
RFieldDescriptorIterable GetFieldIterable(const RFieldDescriptor &fieldDesc) const
std::set< unsigned int > fFeatureFlags
std::unordered_map< ROOT::DescriptorId_t, RClusterGroupDescriptor > fClusterGroupDescriptors
const RFieldDescriptor & GetFieldDescriptor(ROOT::DescriptorId_t fieldId) const
RNTupleAttrSetDescriptorIterable GetAttrSetIterable() const
RNTupleDescriptor & operator=(RNTupleDescriptor &&other)=default
std::uint64_t fNPhysicalColumns
Updated by the descriptor builder when columns are added.
ROOT::DescriptorId_t fFieldZeroId
Set by the descriptor builder.
std::uint64_t fNEntries
Updated by the descriptor builder when the cluster groups are added.
std::size_t GetNExtraTypeInfos() const
std::uint64_t GetOnDiskFooterSize() const
RClusterDescriptorIterable GetActiveClusterIterable() const
RClusterGroupDescriptorIterable GetClusterGroupIterable() const
std::size_t GetNActiveClusters() const
RColumnDescriptorIterable GetColumnIterable() const
bool operator==(const RNTupleDescriptor &other) const
const std::string & GetName() const
std::uint64_t fOnDiskFooterSize
Like fOnDiskHeaderSize, contains both cluster summaries and page locations.
std::uint16_t fVersionMinor
Set by the descriptor builder when deserialized.
RClusterDescriptorIterable R__DEPRECATED(6, 46, "This function is unsafe to use because, in general, not all cluster " "metadata are available (there may be cluster groups with unloaded cluster group details). Use the " "'GetActiveClusterIterable()' method instead if you are aware of this limitation.") GetClusterIterable() const
ROOT::DescriptorId_t FindClusterId(ROOT::NTupleSize_t entryIdx) const
ROOT::NTupleSize_t R__DEPRECATED(6, 46, "This function is ill-conceived in the descriptor " "as not all cluster descriptors may be present. This interface is no longer publicly exposed.") GetNElements(ROOT ROOT::DescriptorId_t GetFieldZeroId() const
Returns the logical parent of all top-level RNTuple data fields.
std::vector< std::uint64_t > GetFeatureFlags() const
ROOT::NTupleSize_t GetNEntries() const
We know the number of entries from adding the cluster summaries.
std::unique_ptr< ROOT::RNTupleModel > CreateModel(const RCreateModelOptions &options=RCreateModelOptions()) const
Re-create the C++ model from the stored metadata.
std::string GetTypeNameForComparison(const RFieldDescriptor &fieldDesc) const
Adjust the type name of the passed RFieldDescriptor for comparison with another renormalized type nam...
std::unordered_map< ROOT::DescriptorId_t, RClusterDescriptor > fClusterDescriptors
Potentially a subset of all the available clusters.
std::size_t GetNAttributeSets() const
std::size_t GetNClusters() const
ROOT::DescriptorId_t FindPhysicalColumnId(ROOT::DescriptorId_t fieldId, std::uint32_t columnIndex, std::uint16_t representationIndex) const
RExtraTypeInfoDescriptorIterable GetExtraTypeInfoIterable() const
std::size_t GetNPhysicalColumns() const
EFeatureFlags
All known feature flags.
@ kFeatureFlag_Test
Reserved for forward-compatibility testing.
@ kFeatureFlag_NestedDeferredColumns
Signals that the RNTuple contains at least one deferred column that is part of a collection and was e...
std::shared_ptr< Internal::RStringPool > fStringPool
Storage for all the field strings. Shared among descriptor clones.
const RHeaderExtension * GetHeaderExtension() const
Return header extension information; if the descriptor does not have a header extension,...
std::uint64_t GetVersion() const
void PrintInfo(std::ostream &output) const
std::uint64_t fNClusters
Updated by the descriptor builder when the cluster groups are added.
RNTupleDescriptor CloneSchema(bool shareStringPool) const
Creates a descriptor containing only the schema information about this RNTuple, i....
std::uint64_t fOnDiskHeaderXxHash3
Set by the descriptor builder when deserialized.
const RClusterDescriptor & GetClusterDescriptor(ROOT::DescriptorId_t clusterId) const
ROOT::DescriptorId_t FindFieldId(std::string_view fieldName, ROOT::DescriptorId_t parentId) const
std::string fName
The RNTuple name needs to be unique in a given storage location (file)
RNTupleDescriptor(const RNTupleDescriptor &other)=delete
std::uint64_t fOnDiskHeaderSize
Set by the descriptor builder when deserialized.
std::uint64_t GetOnDiskHeaderXxHash3() const
RResult< void > DropClusterGroupDetails(ROOT::DescriptorId_t clusterGroupId)
std::uint16_t fVersionMajor
Set by the descriptor builder when deserialized.
std::vector< ROOT::DescriptorId_t > fSortedClusterGroupIds
References cluster groups sorted by entry range and thus allows for binary search.
std::unordered_map< ROOT::DescriptorId_t, RColumnDescriptor > fColumnDescriptors
ROOT::DescriptorId_t FindLogicalColumnId(ROOT::DescriptorId_t fieldId, std::uint32_t columnIndex, std::uint16_t representationIndex) const
std::unordered_map< ROOT::DescriptorId_t, RFieldDescriptor > fFieldDescriptors
std::size_t GetNFields() const
RResult< void > AddClusterGroupDetails(ROOT::DescriptorId_t clusterGroupId, std::vector< RClusterDescriptor > &clusterDescs)
Methods to load and drop cluster group details (cluster IDs and page locations)
bool HasFeature(unsigned int flag) const
std::uint16_t fVersionPatch
Set by the descriptor builder when deserialized.
std::uint64_t GetOnDiskHeaderSize() const
std::string fDescription
Free text from the user.
RFieldDescriptorIterable GetTopLevelFields() const
std::uint16_t fVersionEpoch
Set by the descriptor builder when deserialized.
std::vector< RExtraTypeInfoDescriptor > fExtraTypeInfoDescriptors
RNTupleDescriptor Clone() const
std::size_t GetNLogicalColumns() const
RNTupleDescriptor & operator=(const RNTupleDescriptor &other)=delete
std::size_t GetNClusterGroups() const
ROOT::DescriptorId_t R__DEPRECATED(6, 46, "This function is ill-defined in the descriptor " "as not all cluster descriptors may be present. This interface is no longer exposed.") FindClusterId(ROOT ROOT::DescriptorId_t R__DEPRECATED(6, 46, "This function is ill-defined in the descriptor " "as not all cluster descriptors may be present. This interface is no longer exposed.") FindNextClusterId(ROOT ROOT::DescriptorId_t R__DEPRECATED(6, 46, "This function is ill-defined in the descriptor " "as not all cluster descriptors may be present. This interface is no longer exposed.") FindPrevClusterId(ROOT std::string GetQualifiedFieldName(ROOT::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 ...
bool FieldTypeNamesMayNeedFixup() const
ROOT v6.34, with spec versions before 1.0.0.1, did not properly renormalize the type name.
const std::string & GetDescription() const
std::uint64_t fGeneration
The generation of the descriptor.
std::unique_ptr< RHeaderExtension > fHeaderExtension
const RFieldDescriptor & GetFieldZero() const
Generic information about the physical location of data.
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:222
const Int_t n
Definition legend1.C:16
RNTupleDescriptor CloneDescriptorSchema(const RNTupleDescriptor &desc)
bool IsCustomEnumFieldDesc(const RNTupleDescriptor &desc, const RFieldDescriptor &fieldDesc)
Tells if the field describes a user-defined enum type.
std::vector< ROOT::Internal::RNTupleClusterBoundaries > GetClusterBoundaries(const RNTupleDescriptor &desc)
Return the cluster boundaries for each cluster in this RNTuple.
bool IsStdAtomicFieldDesc(const RFieldDescriptor &fieldDesc)
Tells if the field describes a std::atomic<T> type.
EExtraTypeInfoIds
Used in RExtraTypeInfoDescriptor.
std::uint64_t DescriptorId_t
Distriniguishes elements of the same type within a descriptor, e.g. different fields.
constexpr NTupleSize_t kInvalidNTupleIndex
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
constexpr DescriptorId_t kInvalidDescriptorId
ENTupleStructure
The fields in the RNTuple data model tree can carry different structural information about the type s...
Additional information about a page in an in-memory RPageRange.
RPageInfoExtended(const RPageInfo &pageInfo, ROOT::NTupleSize_t firstElementIndex, ROOT::NTupleSize_t pageNumber)
void SetFirstElementIndex(ROOT::NTupleSize_t firstInPage)
ROOT::NTupleSize_t fPageNumber
Page number in the corresponding RPageRange.
ROOT::NTupleSize_t fFirstElementIndex
Index (in cluster) of the first element in page.
void SetPageNumber(ROOT::NTupleSize_t pageNumber)
Information about a single page in the context of a cluster's page range.
bool fHasChecksum
If true, the 8 bytes following the serialized page are an xxhash of the on-disk page data.
void SetLocator(const RNTupleLocator &locator)
bool operator==(const RPageInfo &other) const
std::uint32_t fNElements
The sum of the elements of all the pages must match the corresponding fNElements field in fColumnRang...
const RNTupleLocator & GetLocator() const
RNTupleLocator fLocator
The meaning of fLocator depends on the storage backend.
RPageInfo(std::uint32_t nElements, const RNTupleLocator &locator, bool hasChecksum)
bool operator==(RValueRange other) const
RValueRange(std::pair< double, double > range)
bool operator!=(RValueRange other) const
bool fForwardCompatible
By default, creating a model will fail if any of the reconstructed fields contains an unknown column ...
bool fCreateBare
If true, the model will be created without a default entry (bare model).
bool fReconstructProjections
If set to true, projected fields will be reconstructed as such.
bool fEmulateUnknownTypes
If true, fields with a user defined type that have no available dictionaries will be reconstructed as...