File indexing completed on 2026-08-16 09:21:19
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef ROOT7_RNTuple_Attr_Reading
0009 #define ROOT7_RNTuple_Attr_Reading
0010
0011 #include <memory>
0012 #include <optional>
0013 #include <utility>
0014 #include <vector>
0015
0016 #include <ROOT/RNTupleFillContext.hxx>
0017 #include <ROOT/RNTupleAttrUtils.hxx>
0018 #include <ROOT/RNTupleUtils.hxx>
0019
0020 namespace ROOT {
0021
0022 class REntry;
0023 class RNTupleDescriptor;
0024 class RNTupleModel;
0025
0026 namespace Experimental {
0027
0028 class RNTupleAttrEntryIterable;
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040 class RNTupleAttrRange final {
0041 ROOT::NTupleSize_t fStart = 0;
0042 ROOT::NTupleSize_t fLength = 0;
0043
0044 RNTupleAttrRange(ROOT::NTupleSize_t start, ROOT::NTupleSize_t length) : fStart(start), fLength(length) {}
0045
0046 public:
0047 static RNTupleAttrRange FromStartLength(ROOT::NTupleSize_t start, ROOT::NTupleSize_t length)
0048 {
0049 return RNTupleAttrRange{start, length};
0050 }
0051
0052
0053
0054 static RNTupleAttrRange FromStartEnd(ROOT::NTupleSize_t start, ROOT::NTupleSize_t end)
0055 {
0056 R__ASSERT(end >= start);
0057 return RNTupleAttrRange{start, end - start};
0058 }
0059
0060 RNTupleAttrRange() = default;
0061
0062
0063 std::optional<ROOT::NTupleSize_t> GetFirst() const { return fLength ? std::make_optional(fStart) : std::nullopt; }
0064
0065
0066 ROOT::NTupleSize_t GetStart() const { return fStart; }
0067
0068 std::optional<ROOT::NTupleSize_t> GetLast() const
0069 {
0070 return fLength ? std::make_optional(fStart + fLength - 1) : std::nullopt;
0071 }
0072
0073 ROOT::NTupleSize_t GetEnd() const { return fStart + fLength; }
0074 ROOT::NTupleSize_t GetLength() const { return fLength; }
0075
0076
0077 std::optional<std::pair<ROOT::NTupleSize_t, ROOT::NTupleSize_t>> GetFirstLast() const
0078 {
0079 return fLength ? std::make_optional(std::make_pair(fStart, fStart + fLength - 1)) : std::nullopt;
0080 }
0081
0082 std::pair<ROOT::NTupleSize_t, ROOT::NTupleSize_t> GetStartLength() const { return {fStart, fLength}; }
0083 };
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114 class RNTupleAttrSetReader final {
0115 friend class ROOT::RNTupleReader;
0116 friend class RNTupleAttrEntryIterable;
0117
0118
0119
0120
0121 std::vector<std::pair<RNTupleAttrRange, NTupleSize_t>> fEntryRanges;
0122
0123 std::unique_ptr<RNTupleReader> fReader;
0124
0125 std::unique_ptr<ROOT::RNTupleModel> fUserModel;
0126
0127 RNTupleAttrSetReader(std::unique_ptr<RNTupleReader> reader, std::uint16_t vSchemaMajor);
0128
0129 public:
0130 RNTupleAttrSetReader(const RNTupleAttrSetReader &) = delete;
0131 RNTupleAttrSetReader &operator=(const RNTupleAttrSetReader &) = delete;
0132 RNTupleAttrSetReader(RNTupleAttrSetReader &&) = default;
0133 RNTupleAttrSetReader &operator=(RNTupleAttrSetReader &&) = default;
0134 ~RNTupleAttrSetReader() = default;
0135
0136
0137 const ROOT::RNTupleDescriptor &GetDescriptor() const;
0138
0139 const ROOT::RNTupleModel &GetModel() const { return *fUserModel; }
0140
0141
0142
0143 std::unique_ptr<REntry> CreateEntry();
0144
0145
0146
0147 RNTupleAttrRange LoadEntry(NTupleSize_t index);
0148
0149
0150 RNTupleAttrRange LoadEntry(NTupleSize_t index, REntry &entry);
0151
0152
0153 std::size_t GetNEntries() const { return fEntryRanges.size(); }
0154
0155
0156 RNTupleAttrEntryIterable GetAttributes();
0157
0158 RNTupleAttrEntryIterable GetAttributes(NTupleSize_t entryIndex);
0159
0160 RNTupleAttrEntryIterable GetAttributesContainingRange(NTupleSize_t startEntry, NTupleSize_t endEntry);
0161
0162 RNTupleAttrEntryIterable GetAttributesInRange(NTupleSize_t startEntry, NTupleSize_t endEntry);
0163 };
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177 class RNTupleAttrEntryIterable final {
0178 public:
0179 struct RFilter {
0180 RNTupleAttrRange fRange;
0181 bool fIsContained;
0182 };
0183
0184 private:
0185 RNTupleAttrSetReader *fReader = nullptr;
0186 std::optional<RFilter> fFilter;
0187
0188 public:
0189 class RIterator final {
0190 private:
0191 using Iter_t = decltype(std::declval<RNTupleAttrSetReader>().fEntryRanges.begin());
0192 Iter_t fCur, fEnd;
0193 std::optional<RFilter> fFilter;
0194
0195 Iter_t SkipFiltered() const;
0196 bool FullyContained(RNTupleAttrRange range) const;
0197
0198 public:
0199 using iterator_category = std::forward_iterator_tag;
0200 using iterator = RIterator;
0201 using value_type = NTupleSize_t;
0202 using difference_type = std::ptrdiff_t;
0203 using pointer = const value_type *;
0204 using reference = const value_type &;
0205
0206 RIterator(Iter_t iter, Iter_t end, std::optional<RFilter> filter) : fCur(iter), fEnd(end), fFilter(filter)
0207 {
0208 if (fFilter) {
0209 if (fFilter->fRange.GetLength() == 0)
0210 fCur = end;
0211 else
0212 fCur = SkipFiltered();
0213 }
0214 }
0215 iterator operator++()
0216 {
0217 ++fCur;
0218 fCur = SkipFiltered();
0219 return *this;
0220 }
0221 iterator operator++(int)
0222 {
0223 iterator it = *this;
0224 operator++();
0225 return it;
0226 }
0227 reference operator*() { return fCur->second; }
0228 bool operator!=(const iterator &rh) const { return !operator==(rh); }
0229 bool operator==(const iterator &rh) const { return fCur == rh.fCur; }
0230 };
0231
0232 explicit RNTupleAttrEntryIterable(RNTupleAttrSetReader &reader, std::optional<RFilter> filter = {})
0233 : fReader(&reader), fFilter(filter)
0234 {
0235 }
0236
0237 RIterator begin() { return RIterator{fReader->fEntryRanges.begin(), fReader->fEntryRanges.end(), fFilter}; }
0238 RIterator end() { return RIterator{fReader->fEntryRanges.end(), fReader->fEntryRanges.end(), fFilter}; }
0239 };
0240
0241 }
0242 }
0243
0244 #endif