File indexing completed on 2026-09-07 09:25:37
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef ROOT_RNTupleDescriptor
0016 #define ROOT_RNTupleDescriptor
0017
0018 #include <ROOT/RCreateFieldOptions.hxx>
0019 #include <ROOT/RError.hxx>
0020 #include <ROOT/RNTupleSerialize.hxx>
0021 #include <ROOT/RNTupleTypes.hxx>
0022 #include <ROOT/RSpan.hxx>
0023
0024 #include <TError.h>
0025
0026 #include <algorithm>
0027 #include <chrono>
0028 #include <cmath>
0029 #include <functional>
0030 #include <iterator>
0031 #include <map>
0032 #include <memory>
0033 #include <optional>
0034 #include <ostream>
0035 #include <vector>
0036 #include <set>
0037 #include <string>
0038 #include <string_view>
0039 #include <unordered_map>
0040 #include <unordered_set>
0041
0042 namespace ROOT {
0043
0044 class RFieldBase;
0045 class RNTupleModel;
0046
0047 namespace Internal {
0048 class RColumnElementBase;
0049 }
0050
0051 class RNTupleDescriptor;
0052
0053 namespace Internal {
0054 class RColumnDescriptorBuilder;
0055 class RClusterDescriptorBuilder;
0056 class RClusterGroupDescriptorBuilder;
0057 class RExtraTypeInfoDescriptorBuilder;
0058 class RFieldDescriptorBuilder;
0059 class RNTupleDescriptorBuilder;
0060
0061 RNTupleDescriptor CloneDescriptorSchema(const RNTupleDescriptor &desc);
0062 struct RNTupleClusterBoundaries {
0063 ROOT::NTupleSize_t fFirstEntry = kInvalidNTupleIndex;
0064 ROOT::NTupleSize_t fLastEntryPlusOne = kInvalidNTupleIndex;
0065 };
0066
0067 std::vector<ROOT::Internal::RNTupleClusterBoundaries> GetClusterBoundaries(const RNTupleDescriptor &desc);
0068 }
0069
0070 namespace Experimental {
0071
0072
0073
0074
0075
0076
0077
0078
0079 class RNTupleAttrSetDescriptor final {
0080 friend class Experimental::Internal::RNTupleAttrSetDescriptorBuilder;
0081
0082 std::uint16_t fSchemaVersionMajor = 0;
0083 std::uint16_t fSchemaVersionMinor = 0;
0084 std::uint32_t fAnchorLength = 0;
0085
0086
0087
0088 RNTupleLocator fAnchorLocator;
0089 std::string fName;
0090
0091 public:
0092 RNTupleAttrSetDescriptor() = default;
0093 RNTupleAttrSetDescriptor(const RNTupleAttrSetDescriptor &other) = delete;
0094 RNTupleAttrSetDescriptor &operator=(const RNTupleAttrSetDescriptor &other) = delete;
0095 RNTupleAttrSetDescriptor(RNTupleAttrSetDescriptor &&other) = default;
0096 RNTupleAttrSetDescriptor &operator=(RNTupleAttrSetDescriptor &&other) = default;
0097
0098 bool operator==(const RNTupleAttrSetDescriptor &other) const;
0099 bool operator!=(const RNTupleAttrSetDescriptor &other) const { return !(*this == other); }
0100
0101 const std::string &GetName() const { return fName; }
0102 std::uint16_t GetSchemaVersionMajor() const { return fSchemaVersionMajor; }
0103 std::uint16_t GetSchemaVersionMinor() const { return fSchemaVersionMinor; }
0104 std::uint32_t GetAnchorLength() const { return fAnchorLength; }
0105 const RNTupleLocator &GetAnchorLocator() const { return fAnchorLocator; }
0106
0107 RNTupleAttrSetDescriptor Clone() const;
0108 };
0109
0110 class RNTupleAttrSetDescriptorIterable;
0111
0112 }
0113
0114
0115
0116
0117
0118
0119
0120
0121 class RFieldDescriptor final {
0122 friend class Internal::RNTupleDescriptorBuilder;
0123 friend class Internal::RFieldDescriptorBuilder;
0124
0125 private:
0126 ROOT::DescriptorId_t fFieldId = ROOT::kInvalidDescriptorId;
0127
0128 std::uint32_t fFieldVersion = 0;
0129
0130 std::uint32_t fTypeVersion = 0;
0131
0132 std::string fFieldName;
0133
0134 std::string fFieldDescription;
0135
0136 std::string fTypeName;
0137
0138 std::string fTypeAlias;
0139
0140 std::uint64_t fNRepetitions = 0;
0141
0142 ROOT::ENTupleStructure fStructure = ROOT::ENTupleStructure::kInvalid;
0143
0144 ROOT::DescriptorId_t fParentId = ROOT::kInvalidDescriptorId;
0145
0146 ROOT::DescriptorId_t fProjectionSourceId = ROOT::kInvalidDescriptorId;
0147
0148
0149 std::vector<ROOT::DescriptorId_t> fLinkIds;
0150
0151
0152
0153 std::uint32_t fColumnCardinality = 0;
0154
0155 std::vector<ROOT::DescriptorId_t> fLogicalColumnIds;
0156
0157
0158 std::optional<std::uint32_t> fTypeChecksum;
0159
0160 bool fIsSoACollection = false;
0161
0162 public:
0163 RFieldDescriptor() = default;
0164 RFieldDescriptor(const RFieldDescriptor &other) = delete;
0165 RFieldDescriptor &operator=(const RFieldDescriptor &other) = delete;
0166 RFieldDescriptor(RFieldDescriptor &&other) = default;
0167 RFieldDescriptor &operator=(RFieldDescriptor &&other) = default;
0168
0169 bool operator==(const RFieldDescriptor &other) const;
0170
0171 RFieldDescriptor Clone() const;
0172
0173
0174
0175 std::unique_ptr<ROOT::RFieldBase>
0176 CreateField(const RNTupleDescriptor &ntplDesc, const ROOT::RCreateFieldOptions &options = {}) const;
0177
0178 ROOT::DescriptorId_t GetId() const { return fFieldId; }
0179 std::uint32_t GetFieldVersion() const { return fFieldVersion; }
0180 std::uint32_t GetTypeVersion() const { return fTypeVersion; }
0181 const std::string &GetFieldName() const { return fFieldName; }
0182 const std::string &GetFieldDescription() const { return fFieldDescription; }
0183 const std::string &GetTypeName() const { return fTypeName; }
0184 const std::string &GetTypeAlias() const { return fTypeAlias; }
0185 std::uint64_t GetNRepetitions() const { return fNRepetitions; }
0186 ROOT::ENTupleStructure GetStructure() const { return fStructure; }
0187 ROOT::DescriptorId_t GetParentId() const { return fParentId; }
0188 ROOT::DescriptorId_t GetProjectionSourceId() const { return fProjectionSourceId; }
0189 const std::vector<ROOT::DescriptorId_t> &GetLinkIds() const { return fLinkIds; }
0190 const std::vector<ROOT::DescriptorId_t> &GetLogicalColumnIds() const { return fLogicalColumnIds; }
0191 std::uint32_t GetColumnCardinality() const { return fColumnCardinality; }
0192 std::optional<std::uint32_t> GetTypeChecksum() const { return fTypeChecksum; }
0193 bool IsProjectedField() const { return fProjectionSourceId != ROOT::kInvalidDescriptorId; }
0194 bool IsSoACollection() const { return fIsSoACollection; }
0195
0196 bool IsCustomClass() const R__DEPRECATED(6, 42, "removed from public interface");
0197 bool IsCustomEnum(const RNTupleDescriptor &desc) const R__DEPRECATED(6, 42, "removed from public interface");
0198 bool IsStdAtomic() const R__DEPRECATED(6, 42, "removed from public interface");
0199 };
0200
0201
0202
0203
0204
0205
0206
0207
0208 class RColumnDescriptor final {
0209 friend class Internal::RColumnDescriptorBuilder;
0210 friend class Internal::RNTupleDescriptorBuilder;
0211
0212 public:
0213 struct RValueRange {
0214 double fMin = 0, fMax = 0;
0215
0216 RValueRange() = default;
0217 RValueRange(double min, double max) : fMin(min), fMax(max) {}
0218 RValueRange(std::pair<double, double> range) : fMin(range.first), fMax(range.second) {}
0219
0220 bool operator==(RValueRange other) const { return fMin == other.fMin && fMax == other.fMax; }
0221 bool operator!=(RValueRange other) const { return !(*this == other); }
0222 };
0223
0224 private:
0225
0226 ROOT::DescriptorId_t fLogicalColumnId = ROOT::kInvalidDescriptorId;
0227
0228 ROOT::DescriptorId_t fPhysicalColumnId = ROOT::kInvalidDescriptorId;
0229
0230 ROOT::DescriptorId_t fFieldId = ROOT::kInvalidDescriptorId;
0231
0232
0233
0234 std::int64_t fFirstElementIndex = 0U;
0235
0236 std::uint32_t fIndex = 0;
0237
0238
0239 std::uint16_t fRepresentationIndex = 0;
0240
0241
0242 std::uint16_t fBitsOnStorage = 0;
0243
0244 ROOT::ENTupleColumnType fType = ROOT::ENTupleColumnType::kUnknown;
0245
0246 std::optional<RValueRange> fValueRange;
0247
0248 public:
0249 RColumnDescriptor() = default;
0250 RColumnDescriptor(const RColumnDescriptor &other) = delete;
0251 RColumnDescriptor &operator=(const RColumnDescriptor &other) = delete;
0252 RColumnDescriptor(RColumnDescriptor &&other) = default;
0253 RColumnDescriptor &operator=(RColumnDescriptor &&other) = default;
0254
0255 bool operator==(const RColumnDescriptor &other) const;
0256
0257 RColumnDescriptor Clone() const;
0258
0259 ROOT::DescriptorId_t GetLogicalId() const { return fLogicalColumnId; }
0260 ROOT::DescriptorId_t GetPhysicalId() const { return fPhysicalColumnId; }
0261 ROOT::DescriptorId_t GetFieldId() const { return fFieldId; }
0262 std::uint32_t GetIndex() const { return fIndex; }
0263 std::uint16_t GetRepresentationIndex() const { return fRepresentationIndex; }
0264 std::uint64_t GetFirstElementIndex() const { return std::abs(fFirstElementIndex); }
0265 std::uint16_t GetBitsOnStorage() const { return fBitsOnStorage; }
0266 ROOT::ENTupleColumnType GetType() const { return fType; }
0267 std::optional<RValueRange> GetValueRange() const { return fValueRange; }
0268 bool IsAliasColumn() const { return fPhysicalColumnId != fLogicalColumnId; }
0269 bool IsDeferredColumn() const { return fFirstElementIndex != 0; }
0270 bool IsSuppressedDeferredColumn() const { return fFirstElementIndex < 0; }
0271 };
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285 class RClusterDescriptor final {
0286 friend class Internal::RClusterDescriptorBuilder;
0287
0288 public:
0289
0290
0291
0292
0293
0294
0295
0296 class RColumnRange final {
0297 ROOT::DescriptorId_t fPhysicalColumnId = ROOT::kInvalidDescriptorId;
0298
0299 ROOT::NTupleSize_t fFirstElementIndex = ROOT::kInvalidNTupleIndex;
0300
0301 ROOT::NTupleSize_t fNElements = ROOT::kInvalidNTupleIndex;
0302
0303
0304
0305 std::optional<std::uint32_t> fCompressionSettings;
0306
0307
0308
0309 bool fIsSuppressed = false;
0310
0311
0312
0313
0314 public:
0315 RColumnRange() = default;
0316
0317 RColumnRange(ROOT::DescriptorId_t physicalColumnId, ROOT::NTupleSize_t firstElementIndex,
0318 ROOT::NTupleSize_t nElements, std::optional<std::uint32_t> compressionSettings,
0319 bool suppressed = false)
0320 : fPhysicalColumnId(physicalColumnId),
0321 fFirstElementIndex(firstElementIndex),
0322 fNElements(nElements),
0323 fCompressionSettings(compressionSettings),
0324 fIsSuppressed(suppressed)
0325 {
0326 }
0327
0328 ROOT::DescriptorId_t GetPhysicalColumnId() const { return fPhysicalColumnId; }
0329 void SetPhysicalColumnId(ROOT::DescriptorId_t id) { fPhysicalColumnId = id; }
0330
0331 ROOT::NTupleSize_t GetFirstElementIndex() const { return fFirstElementIndex; }
0332 void SetFirstElementIndex(ROOT::NTupleSize_t idx) { fFirstElementIndex = idx; }
0333 void IncrementFirstElementIndex(ROOT::NTupleSize_t by) { fFirstElementIndex += by; }
0334
0335 ROOT::NTupleSize_t GetNElements() const { return fNElements; }
0336 void SetNElements(ROOT::NTupleSize_t n) { fNElements = n; }
0337 void IncrementNElements(ROOT::NTupleSize_t by) { fNElements += by; }
0338
0339 std::optional<std::uint32_t> GetCompressionSettings() const { return fCompressionSettings; }
0340 void SetCompressionSettings(std::optional<std::uint32_t> comp) { fCompressionSettings = comp; }
0341
0342 bool IsSuppressed() const { return fIsSuppressed; }
0343 void SetIsSuppressed(bool suppressed) { fIsSuppressed = suppressed; }
0344
0345 bool operator==(const RColumnRange &other) const
0346 {
0347 return fPhysicalColumnId == other.fPhysicalColumnId && fFirstElementIndex == other.fFirstElementIndex &&
0348 fNElements == other.fNElements && fCompressionSettings == other.fCompressionSettings &&
0349 fIsSuppressed == other.fIsSuppressed;
0350 }
0351
0352 bool Contains(ROOT::NTupleSize_t index) const
0353 {
0354 return (fFirstElementIndex <= index && (fFirstElementIndex + fNElements) > index);
0355 }
0356 };
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367 struct RPageInfo {
0368 private:
0369
0370 RNTupleLocator fLocator;
0371
0372 std::uint32_t fNElements = std::uint32_t(-1);
0373
0374 bool fHasChecksum = false;
0375
0376 public:
0377 RPageInfo() = default;
0378 RPageInfo(std::uint32_t nElements, const RNTupleLocator &locator, bool hasChecksum)
0379 : fLocator(locator), fNElements(nElements), fHasChecksum(hasChecksum)
0380 {
0381 }
0382
0383 bool operator==(const RPageInfo &other) const
0384 {
0385 return fLocator == other.fLocator && fNElements == other.fNElements;
0386 }
0387
0388 const RNTupleLocator &GetLocator() const { return fLocator; }
0389 RNTupleLocator &GetLocator() { return fLocator; }
0390 void SetLocator(const RNTupleLocator &locator) { fLocator = locator; }
0391
0392 std::uint32_t GetNElements() const { return fNElements; }
0393 void SetNElements(std::uint32_t n) { fNElements = n; }
0394
0395 bool HasChecksum() const { return fHasChecksum; }
0396 void SetHasChecksum(bool hasChecksum) { fHasChecksum = hasChecksum; }
0397 };
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409 struct RPageInfoExtended final : RPageInfo {
0410 private:
0411
0412 ROOT::NTupleSize_t fFirstElementIndex = 0;
0413
0414 ROOT::NTupleSize_t fPageNumber = 0;
0415
0416 public:
0417 RPageInfoExtended() = default;
0418 RPageInfoExtended(const RPageInfo &pageInfo, ROOT::NTupleSize_t firstElementIndex, ROOT::NTupleSize_t pageNumber)
0419 : RPageInfo(pageInfo), fFirstElementIndex(firstElementIndex), fPageNumber(pageNumber)
0420 {
0421 }
0422
0423 ROOT::NTupleSize_t GetFirstElementIndex() const { return fFirstElementIndex; }
0424 void SetFirstElementIndex(ROOT::NTupleSize_t firstInPage) { fFirstElementIndex = firstInPage; }
0425
0426 ROOT::NTupleSize_t GetPageNumber() const { return fPageNumber; }
0427 void SetPageNumber(ROOT::NTupleSize_t pageNumber) { fPageNumber = pageNumber; }
0428 };
0429
0430
0431
0432
0433
0434
0435
0436
0437 class RPageRange final {
0438 friend class Internal::RClusterDescriptorBuilder;
0439
0440 private:
0441
0442
0443
0444
0445
0446
0447
0448 std::size_t ExtendToFitColumnRange(const RColumnRange &columnRange,
0449 const ROOT::Internal::RColumnElementBase &element, std::size_t pageSize);
0450
0451 std::vector<RPageInfo> fPageInfos;
0452
0453
0454
0455
0456 std::unique_ptr<std::vector<ROOT::NTupleSize_t>> fCumulativeNElements;
0457
0458 ROOT::DescriptorId_t fPhysicalColumnId = ROOT::kInvalidDescriptorId;
0459
0460 public:
0461
0462 static constexpr std::size_t kLargeRangeThreshold = 10;
0463
0464 RPageRange() = default;
0465 RPageRange(const RPageRange &other) = delete;
0466 RPageRange &operator=(const RPageRange &other) = delete;
0467 RPageRange(RPageRange &&other) = default;
0468 RPageRange &operator=(RPageRange &&other) = default;
0469
0470 RPageRange Clone() const
0471 {
0472 RPageRange clone;
0473 clone.fPhysicalColumnId = fPhysicalColumnId;
0474 clone.fPageInfos = fPageInfos;
0475 if (fCumulativeNElements) {
0476 clone.fCumulativeNElements = std::make_unique<std::vector<ROOT::NTupleSize_t>>(*fCumulativeNElements);
0477 }
0478 return clone;
0479 }
0480
0481
0482 RPageInfoExtended Find(ROOT::NTupleSize_t idxInCluster) const;
0483
0484 ROOT::DescriptorId_t GetPhysicalColumnId() const { return fPhysicalColumnId; }
0485 void SetPhysicalColumnId(ROOT::DescriptorId_t id) { fPhysicalColumnId = id; }
0486
0487 const std::vector<RPageInfo> &GetPageInfos() const { return fPageInfos; }
0488 std::vector<RPageInfo> &GetPageInfos() { return fPageInfos; }
0489
0490 bool operator==(const RPageRange &other) const
0491 {
0492 return fPhysicalColumnId == other.fPhysicalColumnId && fPageInfos == other.fPageInfos;
0493 }
0494 };
0495
0496 private:
0497 ROOT::DescriptorId_t fClusterId = ROOT::kInvalidDescriptorId;
0498
0499 ROOT::NTupleSize_t fFirstEntryIndex = ROOT::kInvalidNTupleIndex;
0500 ROOT::NTupleSize_t fNEntries = ROOT::kInvalidNTupleIndex;
0501
0502 std::unordered_map<ROOT::DescriptorId_t, RColumnRange> fColumnRanges;
0503 std::unordered_map<ROOT::DescriptorId_t, RPageRange> fPageRanges;
0504
0505 public:
0506 class RColumnRangeIterable;
0507
0508 RClusterDescriptor() = default;
0509 RClusterDescriptor(const RClusterDescriptor &other) = delete;
0510 RClusterDescriptor &operator=(const RClusterDescriptor &other) = delete;
0511 RClusterDescriptor(RClusterDescriptor &&other) = default;
0512 RClusterDescriptor &operator=(RClusterDescriptor &&other) = default;
0513
0514 RClusterDescriptor Clone() const;
0515
0516 bool operator==(const RClusterDescriptor &other) const;
0517
0518 ROOT::DescriptorId_t GetId() const { return fClusterId; }
0519 ROOT::NTupleSize_t GetFirstEntryIndex() const { return fFirstEntryIndex; }
0520 ROOT::NTupleSize_t GetNEntries() const { return fNEntries; }
0521 const RColumnRange &GetColumnRange(ROOT::DescriptorId_t physicalId) const { return fColumnRanges.at(physicalId); }
0522 const RPageRange &GetPageRange(ROOT::DescriptorId_t physicalId) const { return fPageRanges.at(physicalId); }
0523
0524 RColumnRangeIterable GetColumnRangeIterable() const;
0525 bool ContainsColumn(ROOT::DescriptorId_t physicalId) const
0526 {
0527 return fColumnRanges.find(physicalId) != fColumnRanges.end();
0528 }
0529 std::uint64_t GetNBytesOnStorage() const;
0530 };
0531
0532 class RClusterDescriptor::RColumnRangeIterable final {
0533 private:
0534 const RClusterDescriptor &fDesc;
0535
0536 public:
0537 class RIterator final {
0538 private:
0539 using Iter_t = std::unordered_map<ROOT::DescriptorId_t, RColumnRange>::const_iterator;
0540
0541 Iter_t fIter;
0542
0543 public:
0544 using iterator_category = std::forward_iterator_tag;
0545 using iterator = RIterator;
0546 using value_type = RColumnRange;
0547 using difference_type = std::ptrdiff_t;
0548 using pointer = const RColumnRange *;
0549 using reference = const RColumnRange &;
0550
0551 RIterator(Iter_t iter) : fIter(iter) {}
0552 iterator &operator++()
0553 {
0554 ++fIter;
0555 return *this;
0556 }
0557 iterator operator++(int)
0558 {
0559 auto old = *this;
0560 operator++();
0561 return old;
0562 }
0563 reference operator*() const { return fIter->second; }
0564 pointer operator->() const { return &fIter->second; }
0565 bool operator!=(const iterator &rh) const { return fIter != rh.fIter; }
0566 bool operator==(const iterator &rh) const { return fIter == rh.fIter; }
0567 };
0568
0569 explicit RColumnRangeIterable(const RClusterDescriptor &desc) : fDesc(desc) {}
0570
0571 RIterator begin() { return RIterator{fDesc.fColumnRanges.cbegin()}; }
0572 RIterator end() { return RIterator{fDesc.fColumnRanges.cend()}; }
0573 size_t size() { return fDesc.fColumnRanges.size(); }
0574 };
0575
0576
0577
0578
0579
0580
0581
0582
0583
0584
0585
0586
0587 class RClusterGroupDescriptor final {
0588 friend class Internal::RClusterGroupDescriptorBuilder;
0589
0590 private:
0591 ROOT::DescriptorId_t fClusterGroupId = ROOT::kInvalidDescriptorId;
0592
0593
0594 std::vector<ROOT::DescriptorId_t> fClusterIds;
0595
0596 RNTupleLocator fPageListLocator;
0597
0598 std::uint64_t fPageListLength = 0;
0599
0600 std::uint64_t fMinEntry = 0;
0601
0602 std::uint64_t fEntrySpan = 0;
0603
0604 std::uint32_t fNClusters = 0;
0605
0606 public:
0607 RClusterGroupDescriptor() = default;
0608 RClusterGroupDescriptor(const RClusterGroupDescriptor &other) = delete;
0609 RClusterGroupDescriptor &operator=(const RClusterGroupDescriptor &other) = delete;
0610 RClusterGroupDescriptor(RClusterGroupDescriptor &&other) = default;
0611 RClusterGroupDescriptor &operator=(RClusterGroupDescriptor &&other) = default;
0612
0613 RClusterGroupDescriptor Clone() const;
0614
0615 RClusterGroupDescriptor CloneSummary() const;
0616
0617 bool operator==(const RClusterGroupDescriptor &other) const;
0618
0619 ROOT::DescriptorId_t GetId() const { return fClusterGroupId; }
0620 std::uint32_t GetNClusters() const { return fNClusters; }
0621 RNTupleLocator GetPageListLocator() const { return fPageListLocator; }
0622 std::uint64_t GetPageListLength() const { return fPageListLength; }
0623 const std::vector<ROOT::DescriptorId_t> &GetClusterIds() const { return fClusterIds; }
0624 std::uint64_t GetMinEntry() const { return fMinEntry; }
0625 std::uint64_t GetEntrySpan() const { return fEntrySpan; }
0626
0627
0628 bool HasClusterDetails() const { return !fClusterIds.empty(); }
0629 };
0630
0631
0632 enum class EExtraTypeInfoIds {
0633 kInvalid,
0634 kStreamerInfo
0635 };
0636
0637
0638
0639
0640
0641
0642
0643
0644
0645
0646 class RExtraTypeInfoDescriptor final {
0647 friend class Internal::RExtraTypeInfoDescriptorBuilder;
0648
0649 private:
0650
0651 EExtraTypeInfoIds fContentId = EExtraTypeInfoIds::kInvalid;
0652
0653 std::uint32_t fTypeVersion = 0;
0654
0655 std::string fTypeName;
0656
0657 std::string fContent;
0658
0659 public:
0660 RExtraTypeInfoDescriptor() = default;
0661 RExtraTypeInfoDescriptor(const RExtraTypeInfoDescriptor &other) = delete;
0662 RExtraTypeInfoDescriptor &operator=(const RExtraTypeInfoDescriptor &other) = delete;
0663 RExtraTypeInfoDescriptor(RExtraTypeInfoDescriptor &&other) = default;
0664 RExtraTypeInfoDescriptor &operator=(RExtraTypeInfoDescriptor &&other) = default;
0665
0666 bool operator==(const RExtraTypeInfoDescriptor &other) const;
0667
0668 RExtraTypeInfoDescriptor Clone() const;
0669
0670 EExtraTypeInfoIds GetContentId() const { return fContentId; }
0671 std::uint32_t GetTypeVersion() const { return fTypeVersion; }
0672 const std::string &GetTypeName() const { return fTypeName; }
0673 const std::string &GetContent() const { return fContent; }
0674 };
0675
0676 namespace Internal {
0677
0678 ROOT::DescriptorId_t CallFindClusterIdOn(const ROOT::RNTupleDescriptor &desc, ROOT::NTupleSize_t entryIdx);
0679 }
0680
0681
0682
0683
0684
0685
0686
0687
0688
0689
0690
0691
0692
0693
0694
0695
0696
0697
0698
0699
0700
0701
0702
0703
0704 class RNTupleDescriptor final {
0705 friend class Internal::RNTupleDescriptorBuilder;
0706 friend RNTupleDescriptor Internal::CloneDescriptorSchema(const RNTupleDescriptor &desc);
0707 friend DescriptorId_t Internal::CallFindClusterIdOn(const RNTupleDescriptor &desc, NTupleSize_t entryIdx);
0708
0709 public:
0710 class RHeaderExtension;
0711
0712 private:
0713
0714 std::string fName;
0715
0716 std::string fDescription;
0717
0718 ROOT::DescriptorId_t fFieldZeroId = ROOT::kInvalidDescriptorId;
0719
0720 std::uint64_t fNPhysicalColumns = 0;
0721
0722 std::set<unsigned int> fFeatureFlags;
0723 std::unordered_map<ROOT::DescriptorId_t, RFieldDescriptor> fFieldDescriptors;
0724 std::unordered_map<ROOT::DescriptorId_t, RColumnDescriptor> fColumnDescriptors;
0725
0726 std::vector<RExtraTypeInfoDescriptor> fExtraTypeInfoDescriptors;
0727 std::unique_ptr<RHeaderExtension> fHeaderExtension;
0728
0729
0730
0731
0732 std::uint16_t fVersionEpoch = 0;
0733 std::uint16_t fVersionMajor = 0;
0734 std::uint16_t fVersionMinor = 0;
0735 std::uint16_t fVersionPatch = 0;
0736
0737 std::uint64_t fOnDiskHeaderSize = 0;
0738 std::uint64_t fOnDiskHeaderXxHash3 = 0;
0739 std::uint64_t fOnDiskFooterSize = 0;
0740
0741 std::uint64_t fNEntries = 0;
0742 std::uint64_t fNClusters = 0;
0743
0744
0745
0746
0747
0748
0749
0750
0751 std::uint64_t fGeneration = 0;
0752
0753 std::unordered_map<ROOT::DescriptorId_t, RClusterGroupDescriptor> fClusterGroupDescriptors;
0754
0755
0756
0757 std::vector<ROOT::DescriptorId_t> fSortedClusterGroupIds;
0758
0759 std::unordered_map<ROOT::DescriptorId_t, RClusterDescriptor> fClusterDescriptors;
0760
0761 std::vector<Experimental::RNTupleAttrSetDescriptor> fAttributeSets;
0762
0763
0764 ROOT::DescriptorId_t FindClusterId(ROOT::NTupleSize_t entryIdx) const;
0765
0766
0767
0768
0769 RNTupleDescriptor CloneSchema() const;
0770
0771 public:
0772
0773
0774 enum EFeatureFlags {
0775
0776
0777
0778
0779
0780 kFeatureFlag_NestedDeferredColumns = 0,
0781
0782
0783
0784
0785 kFeatureFlag_COUNT,
0786
0787
0788 kFeatureFlag_Test = 137
0789 };
0790
0791 class RColumnDescriptorIterable;
0792 class RFieldDescriptorIterable;
0793 class RClusterGroupDescriptorIterable;
0794 class RClusterDescriptorIterable;
0795 class RExtraTypeInfoDescriptorIterable;
0796 friend class Experimental::RNTupleAttrSetDescriptorIterable;
0797
0798
0799 struct RCreateModelOptions {
0800 private:
0801
0802
0803 bool fReconstructProjections = false;
0804
0805
0806
0807
0808 bool fForwardCompatible = false;
0809
0810 bool fCreateBare = false;
0811
0812
0813 bool fEmulateUnknownTypes = false;
0814
0815 public:
0816 RCreateModelOptions() {}
0817
0818 void SetReconstructProjections(bool v) { fReconstructProjections = v; }
0819 bool GetReconstructProjections() const { return fReconstructProjections; }
0820
0821 void SetForwardCompatible(bool v) { fForwardCompatible = v; }
0822 bool GetForwardCompatible() const { return fForwardCompatible; }
0823
0824 void SetCreateBare(bool v) { fCreateBare = v; }
0825 bool GetCreateBare() const { return fCreateBare; }
0826
0827 void SetEmulateUnknownTypes(bool v) { fEmulateUnknownTypes = v; }
0828 bool GetEmulateUnknownTypes() const { return fEmulateUnknownTypes; }
0829 };
0830
0831 RNTupleDescriptor() = default;
0832 RNTupleDescriptor(const RNTupleDescriptor &other) = delete;
0833 RNTupleDescriptor &operator=(const RNTupleDescriptor &other) = delete;
0834 RNTupleDescriptor(RNTupleDescriptor &&other) = default;
0835 RNTupleDescriptor &operator=(RNTupleDescriptor &&other) = default;
0836
0837 RNTupleDescriptor Clone() const;
0838
0839 bool operator==(const RNTupleDescriptor &other) const;
0840
0841 std::uint64_t GetOnDiskHeaderXxHash3() const { return fOnDiskHeaderXxHash3; }
0842 std::uint64_t GetOnDiskHeaderSize() const { return fOnDiskHeaderSize; }
0843 std::uint64_t GetOnDiskFooterSize() const { return fOnDiskFooterSize; }
0844
0845 std::uint64_t GetVersion() const
0846 {
0847 return (static_cast<std::uint64_t>(fVersionEpoch) << 48) | (static_cast<std::uint64_t>(fVersionMajor) << 32) |
0848 (static_cast<std::uint64_t>(fVersionMinor) << 16) | (static_cast<std::uint64_t>(fVersionPatch));
0849 }
0850
0851 const RFieldDescriptor &GetFieldDescriptor(ROOT::DescriptorId_t fieldId) const
0852 {
0853 return fFieldDescriptors.at(fieldId);
0854 }
0855 const RColumnDescriptor &GetColumnDescriptor(ROOT::DescriptorId_t columnId) const
0856 {
0857 return fColumnDescriptors.at(columnId);
0858 }
0859 const RClusterGroupDescriptor &GetClusterGroupDescriptor(ROOT::DescriptorId_t clusterGroupId) const
0860 {
0861 return fClusterGroupDescriptors.at(clusterGroupId);
0862 }
0863 const RClusterDescriptor &GetClusterDescriptor(ROOT::DescriptorId_t clusterId) const
0864 {
0865 return fClusterDescriptors.at(clusterId);
0866 }
0867
0868 RFieldDescriptorIterable GetFieldIterable(const RFieldDescriptor &fieldDesc) const;
0869 RFieldDescriptorIterable
0870 GetFieldIterable(const RFieldDescriptor &fieldDesc,
0871 const std::function<bool(ROOT::DescriptorId_t, ROOT::DescriptorId_t)> &comparator) const;
0872 RFieldDescriptorIterable GetFieldIterable(ROOT::DescriptorId_t fieldId) const;
0873 RFieldDescriptorIterable
0874 GetFieldIterable(ROOT::DescriptorId_t fieldId,
0875 const std::function<bool(ROOT::DescriptorId_t, ROOT::DescriptorId_t)> &comparator) const;
0876
0877 RFieldDescriptorIterable GetTopLevelFields() const;
0878 RFieldDescriptorIterable
0879 GetTopLevelFields(const std::function<bool(ROOT::DescriptorId_t, ROOT::DescriptorId_t)> &comparator) const;
0880
0881 RColumnDescriptorIterable GetColumnIterable() const;
0882 RColumnDescriptorIterable GetColumnIterable(const RFieldDescriptor &fieldDesc) const;
0883 RColumnDescriptorIterable GetColumnIterable(ROOT::DescriptorId_t fieldId) const;
0884
0885 RClusterGroupDescriptorIterable GetClusterGroupIterable() const;
0886
0887 RClusterDescriptorIterable GetClusterIterable() const;
0888
0889 RExtraTypeInfoDescriptorIterable GetExtraTypeInfoIterable() const;
0890
0891 ROOT::Experimental::RNTupleAttrSetDescriptorIterable GetAttrSetIterable() const;
0892
0893 const std::string &GetName() const { return fName; }
0894 const std::string &GetDescription() const { return fDescription; }
0895
0896 std::size_t GetNFields() const { return fFieldDescriptors.size(); }
0897 std::size_t GetNLogicalColumns() const { return fColumnDescriptors.size(); }
0898 std::size_t GetNPhysicalColumns() const { return fNPhysicalColumns; }
0899 std::size_t GetNClusterGroups() const { return fClusterGroupDescriptors.size(); }
0900 std::size_t GetNClusters() const { return fNClusters; }
0901 std::size_t GetNActiveClusters() const { return fClusterDescriptors.size(); }
0902 std::size_t GetNExtraTypeInfos() const { return fExtraTypeInfoDescriptors.size(); }
0903 std::size_t GetNAttributeSets() const { return fAttributeSets.size(); }
0904
0905
0906 ROOT::NTupleSize_t GetNEntries() const { return fNEntries; }
0907 ROOT::NTupleSize_t GetNElements(ROOT::DescriptorId_t physicalColumnId) const;
0908
0909
0910 ROOT::DescriptorId_t GetFieldZeroId() const { return fFieldZeroId; }
0911 const RFieldDescriptor &GetFieldZero() const { return GetFieldDescriptor(GetFieldZeroId()); }
0912 ROOT::DescriptorId_t FindFieldId(std::string_view fieldName, ROOT::DescriptorId_t parentId) const;
0913
0914 ROOT::DescriptorId_t FindFieldId(std::string_view fieldName) const;
0915 ROOT::DescriptorId_t FindLogicalColumnId(ROOT::DescriptorId_t fieldId, std::uint32_t columnIndex,
0916 std::uint16_t representationIndex) const;
0917 ROOT::DescriptorId_t FindPhysicalColumnId(ROOT::DescriptorId_t fieldId, std::uint32_t columnIndex,
0918 std::uint16_t representationIndex) const;
0919 ROOT::DescriptorId_t FindClusterId(ROOT::DescriptorId_t physicalColumnId, ROOT::NTupleSize_t index) const;
0920 ROOT::DescriptorId_t FindNextClusterId(ROOT::DescriptorId_t clusterId) const;
0921 ROOT::DescriptorId_t FindPrevClusterId(ROOT::DescriptorId_t clusterId) const;
0922
0923
0924
0925 std::string GetQualifiedFieldName(ROOT::DescriptorId_t fieldId) const;
0926
0927
0928 std::string GetTypeNameForComparison(const RFieldDescriptor &fieldDesc) const;
0929
0930 bool HasFeature(unsigned int flag) const { return fFeatureFlags.count(flag) > 0; }
0931 std::vector<std::uint64_t> GetFeatureFlags() const;
0932
0933
0934 const RHeaderExtension *GetHeaderExtension() const { return fHeaderExtension.get(); }
0935
0936
0937 RResult<void>
0938 AddClusterGroupDetails(ROOT::DescriptorId_t clusterGroupId, std::vector<RClusterDescriptor> &clusterDescs);
0939 RResult<void> DropClusterGroupDetails(ROOT::DescriptorId_t clusterGroupId);
0940
0941 std::uint64_t GetGeneration() const { return fGeneration; }
0942 void IncGeneration() { fGeneration++; }
0943
0944
0945 std::unique_ptr<ROOT::RNTupleModel> CreateModel(const RCreateModelOptions &options = RCreateModelOptions()) const;
0946 void PrintInfo(std::ostream &output) const;
0947 };
0948
0949
0950
0951
0952
0953
0954
0955
0956 class RNTupleDescriptor::RColumnDescriptorIterable final {
0957 private:
0958
0959 const RNTupleDescriptor &fNTuple;
0960
0961 std::vector<ROOT::DescriptorId_t> fColumns = {};
0962
0963 public:
0964 class RIterator final {
0965 private:
0966
0967 const RNTupleDescriptor &fNTuple;
0968
0969 const std::vector<ROOT::DescriptorId_t> &fColumns;
0970 std::size_t fIndex = 0;
0971
0972 public:
0973 using iterator_category = std::forward_iterator_tag;
0974 using iterator = RIterator;
0975 using value_type = RFieldDescriptor;
0976 using difference_type = std::ptrdiff_t;
0977 using pointer = const RColumnDescriptor *;
0978 using reference = const RColumnDescriptor &;
0979
0980 RIterator(const RNTupleDescriptor &ntuple, const std::vector<ROOT::DescriptorId_t> &columns, std::size_t index)
0981 : fNTuple(ntuple), fColumns(columns), fIndex(index)
0982 {
0983 }
0984 iterator &operator++()
0985 {
0986 ++fIndex;
0987 return *this;
0988 }
0989 iterator operator++(int)
0990 {
0991 auto old = *this;
0992 operator++();
0993 return old;
0994 }
0995 reference operator*() const { return fNTuple.GetColumnDescriptor(fColumns.at(fIndex)); }
0996 pointer operator->() const { return &fNTuple.GetColumnDescriptor(fColumns.at(fIndex)); }
0997 bool operator!=(const iterator &rh) const { return fIndex != rh.fIndex; }
0998 bool operator==(const iterator &rh) const { return fIndex == rh.fIndex; }
0999 };
1000
1001 RColumnDescriptorIterable(const RNTupleDescriptor &ntuple, const RFieldDescriptor &fieldDesc);
1002 RColumnDescriptorIterable(const RNTupleDescriptor &ntuple);
1003
1004 RIterator begin() { return RIterator(fNTuple, fColumns, 0); }
1005 RIterator end() { return RIterator(fNTuple, fColumns, fColumns.size()); }
1006 size_t size() { return fColumns.size(); }
1007 };
1008
1009
1010
1011
1012
1013
1014
1015
1016 class RNTupleDescriptor::RFieldDescriptorIterable final {
1017 private:
1018
1019 const RNTupleDescriptor &fNTuple;
1020
1021
1022 std::vector<ROOT::DescriptorId_t> fFieldChildren = {};
1023
1024 public:
1025 class RIterator final {
1026 private:
1027
1028 const RNTupleDescriptor &fNTuple;
1029
1030 const std::vector<ROOT::DescriptorId_t> &fFieldChildren;
1031 std::size_t fIndex = 0;
1032
1033 public:
1034 using iterator_category = std::forward_iterator_tag;
1035 using iterator = RIterator;
1036 using value_type = RFieldDescriptor;
1037 using difference_type = std::ptrdiff_t;
1038 using pointer = const RFieldDescriptor *;
1039 using reference = const RFieldDescriptor &;
1040
1041 RIterator(const RNTupleDescriptor &ntuple, const std::vector<ROOT::DescriptorId_t> &fieldChildren,
1042 std::size_t index)
1043 : fNTuple(ntuple), fFieldChildren(fieldChildren), fIndex(index)
1044 {
1045 }
1046 iterator &operator++()
1047 {
1048 ++fIndex;
1049 return *this;
1050 }
1051 iterator operator++(int)
1052 {
1053 auto old = *this;
1054 operator++();
1055 return old;
1056 }
1057 reference operator*() const { return fNTuple.GetFieldDescriptor(fFieldChildren.at(fIndex)); }
1058 pointer operator->() const { return &fNTuple.GetFieldDescriptor(fFieldChildren.at(fIndex)); }
1059 bool operator!=(const iterator &rh) const { return fIndex != rh.fIndex; }
1060 bool operator==(const iterator &rh) const { return fIndex == rh.fIndex; }
1061 };
1062 RFieldDescriptorIterable(const RNTupleDescriptor &ntuple, const RFieldDescriptor &field)
1063 : fNTuple(ntuple), fFieldChildren(field.GetLinkIds())
1064 {
1065 }
1066
1067 RFieldDescriptorIterable(const RNTupleDescriptor &ntuple, const RFieldDescriptor &field,
1068 const std::function<bool(ROOT::DescriptorId_t, ROOT::DescriptorId_t)> &comparator)
1069 : fNTuple(ntuple), fFieldChildren(field.GetLinkIds())
1070 {
1071 std::sort(fFieldChildren.begin(), fFieldChildren.end(), comparator);
1072 }
1073 RIterator begin() { return RIterator(fNTuple, fFieldChildren, 0); }
1074 RIterator end() { return RIterator(fNTuple, fFieldChildren, fFieldChildren.size()); }
1075 };
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086 class RNTupleDescriptor::RClusterGroupDescriptorIterable final {
1087 private:
1088
1089 const RNTupleDescriptor &fNTuple;
1090
1091 public:
1092 class RIterator final {
1093 private:
1094 using Iter_t = std::unordered_map<ROOT::DescriptorId_t, RClusterGroupDescriptor>::const_iterator;
1095
1096 Iter_t fIter;
1097
1098 public:
1099 using iterator_category = std::forward_iterator_tag;
1100 using iterator = RIterator;
1101 using value_type = RClusterGroupDescriptor;
1102 using difference_type = std::ptrdiff_t;
1103 using pointer = const RClusterGroupDescriptor *;
1104 using reference = const RClusterGroupDescriptor &;
1105
1106 RIterator(Iter_t iter) : fIter(iter) {}
1107 iterator &operator++()
1108 {
1109 ++fIter;
1110 return *this;
1111 }
1112 iterator operator++(int)
1113 {
1114 auto old = *this;
1115 operator++();
1116 return old;
1117 }
1118 reference operator*() const { return fIter->second; }
1119 pointer operator->() const { return &fIter->second; }
1120 bool operator!=(const iterator &rh) const { return fIter != rh.fIter; }
1121 bool operator==(const iterator &rh) const { return fIter == rh.fIter; }
1122 };
1123
1124 RClusterGroupDescriptorIterable(const RNTupleDescriptor &ntuple) : fNTuple(ntuple) {}
1125 RIterator begin() { return RIterator(fNTuple.fClusterGroupDescriptors.cbegin()); }
1126 RIterator end() { return RIterator(fNTuple.fClusterGroupDescriptors.cend()); }
1127 };
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140 class RNTupleDescriptor::RClusterDescriptorIterable final {
1141 private:
1142
1143 const RNTupleDescriptor &fNTuple;
1144
1145 public:
1146 class RIterator final {
1147 private:
1148 using Iter_t = std::unordered_map<ROOT::DescriptorId_t, RClusterDescriptor>::const_iterator;
1149
1150 Iter_t fIter;
1151
1152 public:
1153 using iterator_category = std::forward_iterator_tag;
1154 using iterator = RIterator;
1155 using value_type = RClusterDescriptor;
1156 using difference_type = std::ptrdiff_t;
1157 using pointer = const RClusterDescriptor *;
1158 using reference = const RClusterDescriptor &;
1159
1160 RIterator(Iter_t iter) : fIter(iter) {}
1161 iterator &operator++()
1162 {
1163 ++fIter;
1164 return *this;
1165 }
1166 iterator operator++(int)
1167 {
1168 auto old = *this;
1169 operator++();
1170 return old;
1171 }
1172 reference operator*() const { return fIter->second; }
1173 pointer operator->() const { return &fIter->second; }
1174 bool operator!=(const iterator &rh) const { return fIter != rh.fIter; }
1175 bool operator==(const iterator &rh) const { return fIter == rh.fIter; }
1176 };
1177
1178 RClusterDescriptorIterable(const RNTupleDescriptor &ntuple) : fNTuple(ntuple) {}
1179 RIterator begin() { return RIterator(fNTuple.fClusterDescriptors.cbegin()); }
1180 RIterator end() { return RIterator(fNTuple.fClusterDescriptors.cend()); }
1181 };
1182
1183
1184
1185
1186
1187
1188
1189
1190 class RNTupleDescriptor::RExtraTypeInfoDescriptorIterable final {
1191 private:
1192
1193 const RNTupleDescriptor &fNTuple;
1194
1195 public:
1196 class RIterator final {
1197 private:
1198 using Iter_t = std::vector<RExtraTypeInfoDescriptor>::const_iterator;
1199
1200 Iter_t fIter;
1201
1202 public:
1203 using iterator_category = std::forward_iterator_tag;
1204 using iterator = RIterator;
1205 using value_type = RExtraTypeInfoDescriptor;
1206 using difference_type = std::ptrdiff_t;
1207 using pointer = const RExtraTypeInfoDescriptor *;
1208 using reference = const RExtraTypeInfoDescriptor &;
1209
1210 RIterator(Iter_t iter) : fIter(iter) {}
1211 iterator &operator++()
1212 {
1213 ++fIter;
1214 return *this;
1215 }
1216 iterator operator++(int)
1217 {
1218 auto old = *this;
1219 operator++();
1220 return old;
1221 }
1222 reference operator*() const { return *fIter; }
1223 pointer operator->() const { return &*fIter; }
1224 bool operator!=(const iterator &rh) const { return fIter != rh.fIter; }
1225 bool operator==(const iterator &rh) const { return fIter == rh.fIter; }
1226 };
1227
1228 RExtraTypeInfoDescriptorIterable(const RNTupleDescriptor &ntuple) : fNTuple(ntuple) {}
1229 RIterator begin() { return RIterator(fNTuple.fExtraTypeInfoDescriptors.cbegin()); }
1230 RIterator end() { return RIterator(fNTuple.fExtraTypeInfoDescriptors.cend()); }
1231 };
1232
1233 namespace Experimental {
1234
1235
1236
1237
1238
1239
1240
1241
1242 class RNTupleAttrSetDescriptorIterable final {
1243 private:
1244
1245 const RNTupleDescriptor &fNTuple;
1246
1247 public:
1248 class RIterator final {
1249 private:
1250 using Iter_t = std::vector<RNTupleAttrSetDescriptor>::const_iterator;
1251
1252 Iter_t fIter;
1253
1254 public:
1255 using iterator_category = std::forward_iterator_tag;
1256 using iterator = RIterator;
1257 using value_type = RNTupleAttrSetDescriptor;
1258 using difference_type = std::ptrdiff_t;
1259 using pointer = const value_type *;
1260 using reference = const value_type &;
1261
1262 RIterator(Iter_t iter) : fIter(iter) {}
1263 iterator &operator++()
1264 {
1265 ++fIter;
1266 return *this;
1267 }
1268 iterator operator++(int)
1269 {
1270 auto old = *this;
1271 operator++();
1272 return old;
1273 }
1274 reference operator*() const { return *fIter; }
1275 pointer operator->() const { return &*fIter; }
1276 bool operator!=(const iterator &rh) const { return fIter != rh.fIter; }
1277 bool operator==(const iterator &rh) const { return fIter == rh.fIter; }
1278 };
1279
1280 RNTupleAttrSetDescriptorIterable(const RNTupleDescriptor &ntuple) : fNTuple(ntuple) {}
1281 RIterator begin() { return RIterator(fNTuple.fAttributeSets.cbegin()); }
1282 RIterator end() { return RIterator(fNTuple.fAttributeSets.cend()); }
1283 };
1284 }
1285
1286
1287
1288
1289
1290
1291
1292
1293 class RNTupleDescriptor::RHeaderExtension final {
1294 friend class Internal::RNTupleDescriptorBuilder;
1295
1296 private:
1297
1298
1299 std::vector<ROOT::DescriptorId_t> fFieldIdsOrder;
1300
1301
1302
1303 std::unordered_set<ROOT::DescriptorId_t> fFieldIdsLookup;
1304
1305
1306
1307 std::vector<ROOT::DescriptorId_t> fExtendedColumnRepresentations;
1308
1309 std::uint32_t fNLogicalColumns = 0;
1310 std::uint32_t fNPhysicalColumns = 0;
1311
1312
1313
1314
1315 void MarkExtendedField(const RFieldDescriptor &fieldDesc)
1316 {
1317 fFieldIdsOrder.emplace_back(fieldDesc.GetId());
1318 fFieldIdsLookup.insert(fieldDesc.GetId());
1319 }
1320
1321
1322
1323
1324 void MarkExtendedColumn(const RColumnDescriptor &columnDesc)
1325 {
1326 fNLogicalColumns++;
1327 if (!columnDesc.IsAliasColumn())
1328 fNPhysicalColumns++;
1329 if (fFieldIdsLookup.count(columnDesc.GetFieldId()) == 0) {
1330 fExtendedColumnRepresentations.emplace_back(columnDesc.GetLogicalId());
1331 }
1332 }
1333
1334 public:
1335 std::size_t GetNFields() const { return fFieldIdsOrder.size(); }
1336 std::size_t GetNLogicalColumns() const { return fNLogicalColumns; }
1337 std::size_t GetNPhysicalColumns() const { return fNPhysicalColumns; }
1338 const std::vector<ROOT::DescriptorId_t> &GetExtendedColumnRepresentations() const
1339 {
1340 return fExtendedColumnRepresentations;
1341 }
1342
1343
1344
1345
1346
1347 std::vector<ROOT::DescriptorId_t> GetTopMostFields(const RNTupleDescriptor &desc) const;
1348
1349 bool ContainsField(ROOT::DescriptorId_t fieldId) const
1350 {
1351 return fFieldIdsLookup.find(fieldId) != fFieldIdsLookup.end();
1352 }
1353 bool ContainsExtendedColumnRepresentation(ROOT::DescriptorId_t columnId) const
1354 {
1355 return std::find(fExtendedColumnRepresentations.begin(), fExtendedColumnRepresentations.end(), columnId) !=
1356 fExtendedColumnRepresentations.end();
1357 }
1358 };
1359
1360 namespace Experimental::Internal {
1361 class RNTupleAttrSetDescriptorBuilder final {
1362 ROOT::Experimental::RNTupleAttrSetDescriptor fDesc;
1363
1364 public:
1365 RNTupleAttrSetDescriptorBuilder &Name(std::string_view name)
1366 {
1367 fDesc.fName = name;
1368 return *this;
1369 }
1370 RNTupleAttrSetDescriptorBuilder &SchemaVersion(std::uint16_t major, std::uint16_t minor)
1371 {
1372 fDesc.fSchemaVersionMajor = major;
1373 fDesc.fSchemaVersionMinor = minor;
1374 return *this;
1375 }
1376 RNTupleAttrSetDescriptorBuilder &AnchorLocator(const RNTupleLocator &loc)
1377 {
1378 fDesc.fAnchorLocator = loc;
1379 return *this;
1380 }
1381 RNTupleAttrSetDescriptorBuilder &AnchorLength(std::uint32_t length)
1382 {
1383 fDesc.fAnchorLength = length;
1384 return *this;
1385 }
1386
1387
1388
1389 RResult<ROOT::Experimental::RNTupleAttrSetDescriptor> MoveDescriptor();
1390 };
1391 }
1392
1393 namespace Internal {
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405 class RColumnDescriptorBuilder final {
1406 private:
1407 RColumnDescriptor fColumn = RColumnDescriptor();
1408
1409 public:
1410
1411 RColumnDescriptorBuilder() = default;
1412
1413 RColumnDescriptorBuilder &LogicalColumnId(ROOT::DescriptorId_t logicalColumnId)
1414 {
1415 fColumn.fLogicalColumnId = logicalColumnId;
1416 return *this;
1417 }
1418 RColumnDescriptorBuilder &PhysicalColumnId(ROOT::DescriptorId_t physicalColumnId)
1419 {
1420 fColumn.fPhysicalColumnId = physicalColumnId;
1421 return *this;
1422 }
1423 RColumnDescriptorBuilder &BitsOnStorage(std::uint16_t bitsOnStorage)
1424 {
1425 fColumn.fBitsOnStorage = bitsOnStorage;
1426 return *this;
1427 }
1428 RColumnDescriptorBuilder &Type(ROOT::ENTupleColumnType type)
1429 {
1430 fColumn.fType = type;
1431 return *this;
1432 }
1433 RColumnDescriptorBuilder &FieldId(ROOT::DescriptorId_t fieldId)
1434 {
1435 fColumn.fFieldId = fieldId;
1436 return *this;
1437 }
1438 RColumnDescriptorBuilder &Index(std::uint32_t index)
1439 {
1440 fColumn.fIndex = index;
1441 return *this;
1442 }
1443 RColumnDescriptorBuilder &FirstElementIndex(std::uint64_t firstElementIdx)
1444 {
1445 fColumn.fFirstElementIndex = firstElementIdx;
1446 return *this;
1447 }
1448 RColumnDescriptorBuilder &SetSuppressedDeferred()
1449 {
1450 R__ASSERT(fColumn.fFirstElementIndex != 0);
1451 if (fColumn.fFirstElementIndex > 0)
1452 fColumn.fFirstElementIndex = -fColumn.fFirstElementIndex;
1453 return *this;
1454 }
1455 RColumnDescriptorBuilder &RepresentationIndex(std::uint16_t representationIndex)
1456 {
1457 fColumn.fRepresentationIndex = representationIndex;
1458 return *this;
1459 }
1460 RColumnDescriptorBuilder &ValueRange(double min, double max)
1461 {
1462 fColumn.fValueRange = {min, max};
1463 return *this;
1464 }
1465 RColumnDescriptorBuilder &ValueRange(std::optional<RColumnDescriptor::RValueRange> valueRange)
1466 {
1467 fColumn.fValueRange = valueRange;
1468 return *this;
1469 }
1470 ROOT::DescriptorId_t GetFieldId() const { return fColumn.fFieldId; }
1471 ROOT::DescriptorId_t GetRepresentationIndex() const { return fColumn.fRepresentationIndex; }
1472
1473
1474 RResult<RColumnDescriptor> MakeDescriptor() const;
1475 };
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491 class RFieldDescriptorBuilder final {
1492 private:
1493 RFieldDescriptor fField = RFieldDescriptor();
1494
1495 public:
1496
1497 RFieldDescriptorBuilder() = default;
1498
1499
1500 static RFieldDescriptorBuilder FromField(const ROOT::RFieldBase &field);
1501
1502 RFieldDescriptorBuilder &FieldId(ROOT::DescriptorId_t fieldId)
1503 {
1504 fField.fFieldId = fieldId;
1505 return *this;
1506 }
1507 RFieldDescriptorBuilder &FieldVersion(std::uint32_t fieldVersion)
1508 {
1509 fField.fFieldVersion = fieldVersion;
1510 return *this;
1511 }
1512 RFieldDescriptorBuilder &TypeVersion(std::uint32_t typeVersion)
1513 {
1514 fField.fTypeVersion = typeVersion;
1515 return *this;
1516 }
1517 RFieldDescriptorBuilder &ParentId(ROOT::DescriptorId_t id)
1518 {
1519 fField.fParentId = id;
1520 return *this;
1521 }
1522 RFieldDescriptorBuilder &ProjectionSourceId(ROOT::DescriptorId_t id)
1523 {
1524 fField.fProjectionSourceId = id;
1525 return *this;
1526 }
1527 RFieldDescriptorBuilder &FieldName(const std::string &fieldName)
1528 {
1529 fField.fFieldName = fieldName;
1530 return *this;
1531 }
1532 RFieldDescriptorBuilder &FieldDescription(const std::string &fieldDescription)
1533 {
1534 fField.fFieldDescription = fieldDescription;
1535 return *this;
1536 }
1537 RFieldDescriptorBuilder &TypeName(const std::string &typeName)
1538 {
1539 fField.fTypeName = typeName;
1540 return *this;
1541 }
1542 RFieldDescriptorBuilder &TypeAlias(const std::string &typeAlias)
1543 {
1544 fField.fTypeAlias = typeAlias;
1545 return *this;
1546 }
1547 RFieldDescriptorBuilder &NRepetitions(std::uint64_t nRepetitions)
1548 {
1549 fField.fNRepetitions = nRepetitions;
1550 return *this;
1551 }
1552 RFieldDescriptorBuilder &Structure(const ROOT::ENTupleStructure &structure)
1553 {
1554 fField.fStructure = structure;
1555 return *this;
1556 }
1557 RFieldDescriptorBuilder &TypeChecksum(const std::optional<std::uint32_t> typeChecksum)
1558 {
1559 fField.fTypeChecksum = typeChecksum;
1560 return *this;
1561 }
1562 RFieldDescriptorBuilder &IsSoACollection(bool val)
1563 {
1564 fField.fIsSoACollection = val;
1565 return *this;
1566 }
1567 ROOT::DescriptorId_t GetParentId() const { return fField.fParentId; }
1568
1569
1570 RResult<RFieldDescriptor> MakeDescriptor() const;
1571 };
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583 class RClusterDescriptorBuilder final {
1584 private:
1585 RClusterDescriptor fCluster;
1586
1587 public:
1588 RClusterDescriptorBuilder &ClusterId(ROOT::DescriptorId_t clusterId)
1589 {
1590 fCluster.fClusterId = clusterId;
1591 return *this;
1592 }
1593
1594 RClusterDescriptorBuilder &FirstEntryIndex(std::uint64_t firstEntryIndex)
1595 {
1596 fCluster.fFirstEntryIndex = firstEntryIndex;
1597 return *this;
1598 }
1599
1600 RClusterDescriptorBuilder &NEntries(std::uint64_t nEntries)
1601 {
1602 fCluster.fNEntries = nEntries;
1603 return *this;
1604 }
1605
1606 RResult<void> CommitColumnRange(ROOT::DescriptorId_t physicalId, std::uint64_t firstElementIndex,
1607 std::uint32_t compressionSettings, const RClusterDescriptor::RPageRange &pageRange);
1608
1609
1610
1611
1612 RResult<void> MarkSuppressedColumnRange(ROOT::DescriptorId_t physicalId);
1613
1614
1615
1616
1617 RResult<void> CommitSuppressedColumnRanges(const RNTupleDescriptor &desc);
1618
1619
1620
1621
1622
1623 RClusterDescriptorBuilder &AddExtendedColumnRanges(const RNTupleDescriptor &desc);
1624
1625 const RClusterDescriptor::RColumnRange &GetColumnRange(ROOT::DescriptorId_t physicalId)
1626 {
1627 return fCluster.GetColumnRange(physicalId);
1628 }
1629
1630
1631 RResult<RClusterDescriptor> MoveDescriptor();
1632 };
1633
1634
1635
1636
1637
1638
1639
1640
1641 class RClusterGroupDescriptorBuilder final {
1642 private:
1643 RClusterGroupDescriptor fClusterGroup;
1644
1645 public:
1646 RClusterGroupDescriptorBuilder() = default;
1647 static RClusterGroupDescriptorBuilder FromSummary(const RClusterGroupDescriptor &clusterGroupDesc);
1648
1649 RClusterGroupDescriptorBuilder &ClusterGroupId(ROOT::DescriptorId_t clusterGroupId)
1650 {
1651 fClusterGroup.fClusterGroupId = clusterGroupId;
1652 return *this;
1653 }
1654 RClusterGroupDescriptorBuilder &PageListLocator(const RNTupleLocator &pageListLocator)
1655 {
1656 fClusterGroup.fPageListLocator = pageListLocator;
1657 return *this;
1658 }
1659 RClusterGroupDescriptorBuilder &PageListLength(std::uint64_t pageListLength)
1660 {
1661 fClusterGroup.fPageListLength = pageListLength;
1662 return *this;
1663 }
1664 RClusterGroupDescriptorBuilder &MinEntry(std::uint64_t minEntry)
1665 {
1666 fClusterGroup.fMinEntry = minEntry;
1667 return *this;
1668 }
1669 RClusterGroupDescriptorBuilder &EntrySpan(std::uint64_t entrySpan)
1670 {
1671 fClusterGroup.fEntrySpan = entrySpan;
1672 return *this;
1673 }
1674 RClusterGroupDescriptorBuilder &NClusters(std::uint32_t nClusters)
1675 {
1676 fClusterGroup.fNClusters = nClusters;
1677 return *this;
1678 }
1679 void AddSortedClusters(const std::vector<ROOT::DescriptorId_t> &clusterIds)
1680 {
1681 if (clusterIds.size() != fClusterGroup.GetNClusters())
1682 throw RException(R__FAIL("mismatch of number of clusters"));
1683 fClusterGroup.fClusterIds = clusterIds;
1684 }
1685
1686 RResult<RClusterGroupDescriptor> MoveDescriptor();
1687 };
1688
1689
1690
1691
1692
1693
1694
1695
1696 class RExtraTypeInfoDescriptorBuilder final {
1697 private:
1698 RExtraTypeInfoDescriptor fExtraTypeInfo;
1699
1700 public:
1701 RExtraTypeInfoDescriptorBuilder() = default;
1702
1703 RExtraTypeInfoDescriptorBuilder &ContentId(EExtraTypeInfoIds contentId)
1704 {
1705 fExtraTypeInfo.fContentId = contentId;
1706 return *this;
1707 }
1708 RExtraTypeInfoDescriptorBuilder &TypeVersion(std::uint32_t typeVersion)
1709 {
1710 fExtraTypeInfo.fTypeVersion = typeVersion;
1711 return *this;
1712 }
1713 RExtraTypeInfoDescriptorBuilder &TypeName(const std::string &typeName)
1714 {
1715 fExtraTypeInfo.fTypeName = typeName;
1716 return *this;
1717 }
1718 RExtraTypeInfoDescriptorBuilder &Content(const std::string &content)
1719 {
1720 fExtraTypeInfo.fContent = content;
1721 return *this;
1722 }
1723
1724 RResult<RExtraTypeInfoDescriptor> MoveDescriptor();
1725 };
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736 class RNTupleDescriptorBuilder final {
1737 private:
1738 RNTupleDescriptor fDescriptor;
1739 RResult<void> EnsureFieldExists(ROOT::DescriptorId_t fieldId) const;
1740
1741 public:
1742
1743
1744
1745
1746
1747 RResult<void> EnsureValidDescriptor() const;
1748 const RNTupleDescriptor &GetDescriptor() const { return fDescriptor; }
1749 RNTupleDescriptor MoveDescriptor();
1750
1751
1752
1753 void SetSchemaFromExisting(const RNTupleDescriptor &descriptor);
1754
1755 void SetVersion(std::uint16_t versionEpoch, std::uint16_t versionMajor, std::uint16_t versionMinor,
1756 std::uint16_t versionPatch);
1757 void SetVersionForWriting();
1758
1759 void SetNTuple(const std::string_view name, const std::string_view description);
1760 void SetFeature(unsigned int flag);
1761
1762 void SetOnDiskHeaderXxHash3(std::uint64_t xxhash3) { fDescriptor.fOnDiskHeaderXxHash3 = xxhash3; }
1763 void SetOnDiskHeaderSize(std::uint64_t size) { fDescriptor.fOnDiskHeaderSize = size; }
1764
1765 void AddToOnDiskFooterSize(std::uint64_t size) { fDescriptor.fOnDiskFooterSize += size; }
1766
1767 void AddField(const RFieldDescriptor &fieldDesc);
1768 RResult<void> AddFieldLink(ROOT::DescriptorId_t fieldId, ROOT::DescriptorId_t linkId);
1769 RResult<void> AddFieldProjection(ROOT::DescriptorId_t sourceId, ROOT::DescriptorId_t targetId);
1770
1771
1772
1773 RResult<void> AddColumn(RColumnDescriptor &&columnDesc);
1774
1775 RResult<void> AddClusterGroup(RClusterGroupDescriptor &&clusterGroup);
1776 RResult<void> AddCluster(RClusterDescriptor &&clusterDesc);
1777
1778 RResult<void> AddExtraTypeInfo(RExtraTypeInfoDescriptor &&extraTypeInfoDesc);
1779 void ReplaceExtraTypeInfo(RExtraTypeInfoDescriptor &&extraTypeInfoDesc);
1780
1781 RResult<void> AddAttributeSet(Experimental::RNTupleAttrSetDescriptor &&attrSetDesc);
1782
1783
1784
1785 void BeginHeaderExtension();
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804 void ShiftAliasColumns(std::uint32_t offset);
1805 };
1806
1807 inline RNTupleDescriptor CloneDescriptorSchema(const RNTupleDescriptor &desc)
1808 {
1809 return desc.CloneSchema();
1810 }
1811
1812
1813
1814
1815 bool IsCustomEnumFieldDesc(const RNTupleDescriptor &desc, const RFieldDescriptor &fieldDesc);
1816
1817
1818 bool IsStdAtomicFieldDesc(const RFieldDescriptor &fieldDesc);
1819
1820 }
1821
1822 }
1823
1824 #endif