Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RNTupleAttrReading.cxx
Go to the documentation of this file.
1/// \file RNTupleAttrReading.cxx
2/// \ingroup NTuple
3/// \author Giacomo Parolini <giacomo.parolini@cern.ch>
4/// \date 2026-04-01
5/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
6/// is welcome!
7
11#include <ROOT/RNTupleModel.hxx>
12#include <ROOT/RLogger.hxx>
13
14#include <algorithm>
15#include <cstddef>
16#include <utility>
17
19
21 std::uint16_t vSchemaMajor)
22 : fReader(std::move(reader))
23{
24 // Changes in major version imply forward incompatibility
26 throw ROOT::RException(R__FAIL("unsupported attribute schema version: " + std::to_string(vSchemaMajor)));
27
28 // Initialize user model
30
31 // Validate meta model format
32 const auto &metaDesc = fReader->GetDescriptor();
33 const auto &metaFieldIds = metaDesc.GetFieldZero().GetLinkIds();
34 if (metaFieldIds.size() != kMetaFieldIndex_Count) {
35 throw ROOT::RException(R__FAIL("invalid number of attribute meta-fields: expected " +
36 std::to_string(kMetaFieldIndex_Count) + ", got " +
37 std::to_string(metaFieldIds.size())));
38 }
39 for (std::size_t i = 0; i < kMetaFieldIndex_Count; ++i) {
40 const auto fieldId = metaFieldIds[i];
41 const auto &metaField = metaDesc.GetFieldDescriptor(fieldId);
42 if (metaField.GetFieldName() != kMetaFieldNames[i]) {
43 throw ROOT::RException(R__FAIL(std::string("invalid attribute meta-field name: expected '") +
44 kMetaFieldNames[i] + "', got '" + metaField.GetFieldName() + "'"));
45 }
46 }
47
48 const auto &userFieldRoot = metaDesc.GetFieldDescriptor(metaFieldIds[kMetaFieldIndex_UserData]);
49 for (const auto fieldId : userFieldRoot.GetLinkIds()) {
50 const auto &fdesc = metaDesc.GetFieldDescriptor(fieldId);
51 auto userField = RFieldBase::Create(fdesc.GetFieldName(), fdesc.GetTypeName()).Unwrap();
52 fUserModel->AddField(std::move(userField));
53 }
54 fUserModel->Freeze();
55
56 // Collect all entry ranges
59 fEntryRanges.reserve(fReader->GetNEntries());
60 for (auto i : fReader->GetEntryRange()) {
61 auto start = entryRangeStartView(i);
62 auto len = entryRangeLenView(i);
64 }
65
66 std::stable_sort(fEntryRanges.begin(), fEntryRanges.end(),
67 [](const auto &a, const auto &b) { return a.first.GetStart() < b.first.GetStart(); });
68
69 R__LOG_INFO(ROOT::Internal::NTupleLog()) << "Loaded " << fEntryRanges.size() << " attribute entries.";
70}
71
73{
74 return fReader->GetDescriptor();
75}
76
79{
80 // TODO(gparolini): find a way to avoid this const_cast
81 auto &metaModel = const_cast<ROOT::RNTupleModel &>(fReader->GetModel());
82 auto &metaEntry = metaModel.GetDefaultEntry();
83
84 if (R__unlikely(entry.GetModelId() != fUserModel->GetModelId()))
85 throw RException(R__FAIL("mismatch between entry and model"));
86
87 // Load the meta fields
90
91 // Load the user fields into `entry`
93 const auto userFields = userRootField->GetMutableSubfields();
94 assert(entry.fValues.size() == userFields.size());
95 for (std::size_t i = 0; i < userFields.size(); ++i) {
96 auto *field = userFields[i];
97 field->Read(index, entry.fValues[i].GetPtr<void>().get());
98 }
99
101 auto pLen = metaEntry.fValues[kMetaFieldIndex_RangeLen].GetPtr<NTupleSize_t>();
102
104}
105
111
113{
114 return fUserModel->CreateEntry();
115}
116
119{
121 if (endEntry <= startEntry) {
123 << "empty range given when getting attributes from Attribute Set '" << GetDescriptor().GetName()
124 << "' (range given: [" << startEntry << ", " << endEntry << ")).";
125 // Make sure we find 0 entries
127 } else {
129 }
130 RNTupleAttrEntryIterable::RFilter filter{range, /*fIsContained=*/false};
131 return RNTupleAttrEntryIterable{*this, filter};
132}
133
136{
138 if (endEntry <= startEntry) {
140 << "empty range given when getting attributes from Attribute Set '" << GetDescriptor().GetName()
141 << "' (range given: [" << startEntry << ", " << endEntry << ")).";
142 // Make sure we find 0 entries
144 } else {
146 }
147 RNTupleAttrEntryIterable::RFilter filter{range, /*fIsContained=*/true};
148 return RNTupleAttrEntryIterable{*this, filter};
149}
150
158
163
164//
165// RNTupleAttrEntryIterable
166//
168{
169 assert(fFilter);
170 if (fFilter->fIsContained) {
171 return fFilter->fRange.GetStart() <= range.GetStart() && range.GetEnd() <= fFilter->fRange.GetEnd();
172 } else {
173 return range.GetStart() <= fFilter->fRange.GetStart() && fFilter->fRange.GetEnd() <= range.GetEnd();
174 }
175}
176
179{
180 // If we have no filter, every entry is valid.
181 if (!fFilter)
182 return fCur;
183
184 // TODO: consider using binary search, since fEntryRanges is sorted
185 // (maybe it should be done only if the size of the list is bigger than a threshold).
186 for (auto it = fCur; it != fEnd; ++it) {
187 const auto &[range, index] = *it;
188 const auto &firstLast = range.GetFirstLast();
189 // If this is nullopt it means this is a zero-length entry: we always skip those except
190 // for the "catch-all" GetAttributes() (which is when fFilter is also nullopt).
191 if (!firstLast)
192 continue;
193
194 const auto &[first, last] = *firstLast;
195 if (first >= fFilter->fRange.GetEnd()) {
196 // Since fEntryRanges is sorted we know we are at the end of the iteration
197 // TODO: tweak fEnd to directly pass the last entry?
198 return fEnd;
199 }
200
201 if (FullyContained(RNTupleAttrRange::FromStartEnd(first, last + 1)))
202 return it;
203 }
204 return fEnd;
205}
#define R__unlikely(expr)
Definition RConfig.hxx:592
#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:300
#define R__LOG_WARNING(...)
Definition RLogger.hxx:358
#define R__LOG_INFO(...)
Definition RLogger.hxx:359
#define b(i)
Definition RSha256.hxx:100
#define a(i)
Definition RSha256.hxx:99
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
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 Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
decltype(std::declval< RNTupleAttrSetReader >().fEntryRanges.begin()) Iter_t
Iterable class used to loop over attribute entries.
A range of main entries referred to by an attribute entry.
static RNTupleAttrRange FromStartLength(ROOT::NTupleSize_t start, ROOT::NTupleSize_t length)
static RNTupleAttrRange FromStartEnd(ROOT::NTupleSize_t start, ROOT::NTupleSize_t end)
Creates an AttributeRange from [start, end), where end is one past the last valid entry of the range ...
RNTupleAttrEntryIterable GetAttributesInRange(NTupleSize_t startEntry, NTupleSize_t endEntry)
Returns all the attributes whose range is fully contained in [startEntry, endEntry)
std::unique_ptr< ROOT::RNTupleModel > fUserModel
The reconstructed user model.
const ROOT::RNTupleDescriptor & GetDescriptor() const
Returns the read-only descriptor of this attribute set.
std::unique_ptr< RNTupleReader > fReader
The internal Reader used to read the AttributeSet RNTuple.
RNTupleAttrSetReader(std::unique_ptr< RNTupleReader > reader, std::uint16_t vSchemaMajor)
RNTupleAttrEntryIterable GetAttributes()
Returns all the attributes in this Set. The returned attributes are sorted by entry range start.
std::vector< std::pair< RNTupleAttrRange, NTupleSize_t > > fEntryRanges
List containing pairs { entryRange, entryIndex }, used to quickly find out which entries in the Attri...
std::unique_ptr< REntry > CreateEntry()
Creates an entry suitable for use with LoadEntry.
RNTupleAttrEntryIterable GetAttributesContainingRange(NTupleSize_t startEntry, NTupleSize_t endEntry)
Returns all the attributes whose range fully contains [startEntry, endEntry)
RNTupleAttrRange LoadEntry(NTupleSize_t index)
Loads the attribute entry at position index into the default entry.
The REntry is a collection of values in an RNTuple corresponding to a complete row in the data set.
Definition REntry.hxx:55
Base class for all ROOT issued exceptions.
Definition RError.hxx:79
std::vector< RFieldBase * > GetMutableSubfields()
static RResult< std::unique_ptr< RFieldBase > > Create(const std::string &fieldName, const std::string &typeName, const ROOT::RCreateFieldOptions &options, const ROOT::RNTupleDescriptor *desc, ROOT::DescriptorId_t fieldId)
Factory method to resurrect a field from the stored on-disk type information.
The on-storage metadata of an RNTuple.
The RNTupleModel encapulates the schema of an RNTuple.
static std::unique_ptr< RNTupleModel > Create()
ROOT::RFieldZero & GetFieldZeroOfModel(RNTupleModel &model)
ROOT::RLogChannel & NTupleLog()
Log channel for RNTuple diagnostics.
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.