25 std::string_view ntupleName, std::span<std::unique_ptr<RPageSource>> sources)
27 , fMetrics(std::string(ntupleName))
29 for (
auto &s : sources) {
39 std::size_t originIdx,
42 const std::string &virtualName)
44 auto virtualFieldId = fNextId++;
49 fBuilder.AddField(virtualField);
50 fBuilder.AddFieldLink(virtualParent, virtualFieldId);
51 fIdBiMap.Insert({originIdx, originField.
GetId()}, virtualFieldId);
53 const auto &originDesc = fSources[originIdx]->GetDescriptor();
54 for (
const auto &
f : originDesc.GetFieldIterable(originField))
55 AddVirtualField(originIdx,
f, virtualFieldId,
f.GetFieldName());
57 for (
const auto &
c: originDesc.GetColumnIterable(originField)) {
58 fBuilder.AddColumn(fNextId, virtualFieldId,
c.GetVersion(),
c.GetModel(),
c.GetIndex());
59 fIdBiMap.Insert({originIdx,
c.GetId()}, fNextId);
74 for (std::size_t i = 0; i < fSources.size(); ++i) {
75 fSources[i]->Attach();
76 const auto &desc = fSources[i]->GetDescriptor();
78 if (fSources[i]->GetNEntries() != fSources[0]->GetNEntries()) {
82 throw RException(
R__FAIL(
"mismatch in the number of entries of friend RNTuples"));
84 for (
unsigned j = 0; j < i; ++j) {
85 if (fSources[j]->GetDescriptor().GetName() == desc.GetName()) {
92 AddVirtualField(i, desc.GetFieldZero(), 0, desc.GetName());
94 for (
const auto &
c : desc.GetClusterIterable()) {
95 fBuilder.AddCluster(fNextId,
c.GetVersion(),
c.GetFirstEntryIndex(),
c.GetNEntries());
96 for (
auto originColumnId :
c.GetColumnIds()) {
97 DescriptorId_t virtualColumnId = fIdBiMap.GetVirtualId({i, originColumnId});
99 auto columnRange =
c.GetColumnRange(originColumnId);
100 columnRange.fColumnId = virtualColumnId;
101 fBuilder.AddClusterColumnRange(fNextId, columnRange);
103 auto pageRange =
c.GetPageRange(originColumnId).Clone();
104 pageRange.fColumnId = virtualColumnId;
105 fBuilder.AddClusterPageRange(fNextId, std::move(pageRange));
107 fIdBiMap.Insert({i,
c.GetId()}, fNextId);
112 fBuilder.EnsureValidDescriptor();
113 return fBuilder.MoveDescriptor();
117std::unique_ptr<ROOT::Experimental::Detail::RPageSource>
120 std::vector<std::unique_ptr<RPageSource>> cloneSources;
121 for (
const auto &
f : fSources)
122 cloneSources.emplace_back(
f->Clone());
123 return std::make_unique<RPageSourceFriends>(fNTupleName, cloneSources);
130 auto originFieldId = fIdBiMap.GetOriginId(fieldId);
131 fSources[originFieldId.fSourceIdx]->AddColumn(originFieldId.fId, column);
138 auto originColumnId = fIdBiMap.GetOriginId(columnHandle.
fId);
139 columnHandle.
fId = originColumnId.fId;
140 fSources[originColumnId.fSourceIdx]->DropColumn(columnHandle);
148 auto virtualColumnId = columnHandle.
fId;
149 auto originColumnId = fIdBiMap.GetOriginId(virtualColumnId);
150 columnHandle.
fId = originColumnId.fId;
152 auto page = fSources[originColumnId.fSourceIdx]->PopulatePage(columnHandle, globalIndex);
154 auto virtualClusterId = fIdBiMap.GetVirtualId({originColumnId.fSourceIdx, page.GetClusterInfo().GetId()});
155 page.ChangeIds(virtualColumnId, virtualClusterId);
165 auto virtualColumnId = columnHandle.
fId;
166 auto originColumnId = fIdBiMap.GetOriginId(virtualColumnId);
170 columnHandle.
fId = originColumnId.fId;
172 auto page = fSources[originColumnId.fSourceIdx]->PopulatePage(columnHandle, originClusterIndex);
174 page.ChangeIds(virtualColumnId, clusterIndex.
GetClusterId());
182 auto originColumnId = fIdBiMap.GetOriginId(columnId);
187 fSources[originColumnId.fSourceIdx]->LoadSealedPage(columnId, originClusterIndex, sealedPage);
196 fSources[sourceIdx]->ReleasePage(page);
200std::vector<std::unique_ptr<ROOT::Experimental::Detail::RCluster>>
205 return std::vector<std::unique_ptr<ROOT::Experimental::Detail::RCluster>>(clusterKeys.size());
#define R__FAIL(msg)
Short-hand to return an RResult<T> in an error state; the RError is implicitly converted into RResult...
void ObserveMetrics(RNTupleMetrics &observee)
~RPageSourceFriends() final
std::unique_ptr< RPageSource > Clone() const final
Open the same storage multiple time, e.g. for reading in multiple threads.
void ReleasePage(RPage &page) final
Every page store needs to be able to free pages it handed out.
RNTupleDescriptor AttachImpl() final
void LoadSealedPage(DescriptorId_t columnId, const RClusterIndex &clusterIndex, RSealedPage &sealedPage) final
Read the packed and compressed bytes of a page into the memory buffer provided by selaedPage.
std::vector< std::unique_ptr< RPageSource > > fSources
std::vector< std::unique_ptr< RCluster > > LoadClusters(std::span< RCluster::RKey > clusterKeys) final
Populates all the pages of the given cluster ids and columns; it is possible that some columns do not...
RPage PopulatePage(ColumnHandle_t columnHandle, NTupleSize_t globalIndex) final
Allocates and fills a page that contains the index-th element.
RPageSourceFriends(std::string_view ntupleName, std::span< std::unique_ptr< RPageSource > > sources)
void DropColumn(ColumnHandle_t columnHandle) final
Unregisters a column.
void AddVirtualField(std::size_t originIdx, const RFieldDescriptor &originField, DescriptorId_t virtualParent, const std::string &virtualName)
ColumnHandle_t AddColumn(DescriptorId_t fieldId, const RColumn &column) final
Register a new column.
Abstract interface to read data from an ntuple.
void DropColumn(ColumnHandle_t columnHandle) override
Unregisters a column.
ColumnHandle_t AddColumn(DescriptorId_t fieldId, const RColumn &column) override
Register a new column.
NTupleSize_t GetId() const
A page is a slice of a column that is mapped into memory.
const RClusterInfo & GetClusterInfo() const
Addresses a column element or field item relative to a particular cluster, instead of a global NTuple...
DescriptorId_t GetClusterId() const
ClusterSize_t::ValueType GetIndex() const
Base class for all ROOT issued exceptions.
A helper class for piece-wise construction of an RFieldDescriptor.
RFieldDescriptorBuilder & FieldName(const std::string &fieldName)
RResult< RFieldDescriptor > MakeDescriptor() const
Attempt to make a field descriptor.
RFieldDescriptorBuilder & FieldId(DescriptorId_t fieldId)
Meta-data stored for every field of an ntuple.
DescriptorId_t GetId() const
The on-storage meta-data of an ntuple.
Common user-tunable settings for reading ntuples.
For forward and backward compatibility, attach version information to the consitituents of the file f...
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
std::uint64_t DescriptorId_t
Distriniguishes elements of the same type within a descriptor, e.g. different fields.
std::string RNTupleUuid
Every NTuple is identified by a UUID. TODO(jblomer): should this be a TUUID?
A sealed page contains the bytes of a page as written to storage (packed & compressed).