25   std::string_view ntupleName, std::span<std::unique_ptr<RPageSource>> sources)
 
   27   , fMetrics(std::string(ntupleName))
 
   29   for (
auto &s : sources) {
 
   38                                                                     std::size_t originIdx,
 
   41                                                                     const std::string &virtualName)
 
   43   auto virtualFieldId = fNextId++;
 
   48   fBuilder.AddField(virtualField);
 
   49   fBuilder.AddFieldLink(virtualParent, virtualFieldId);
 
   50   fIdBiMap.Insert({originIdx, originField.
GetId()}, virtualFieldId);
 
   53      AddVirtualField(originDesc, originIdx, 
f, virtualFieldId, 
f.GetFieldName());
 
   56      fBuilder.AddColumn(fNextId, virtualFieldId, 
c.GetModel(), 
c.GetIndex());
 
   57      fIdBiMap.Insert({originIdx, 
c.GetId()}, fNextId);
 
   65   fBuilder.SetNTuple(fNTupleName, 
"");
 
   72   for (std::size_t i = 0; i < fSources.size(); ++i) {
 
   73      fSources[i]->Attach();
 
   75      if (fSources[i]->GetNEntries() != fSources[0]->GetNEntries()) {
 
   79         throw RException(
R__FAIL(
"mismatch in the number of entries of friend RNTuples"));
 
   82      auto descriptorGuard = fSources[i]->GetSharedDescriptorGuard();
 
   83      for (
unsigned j = 0; j < i; ++j) {
 
   84         if (fSources[j]->GetSharedDescriptorGuard()->GetName() == descriptorGuard->GetName()) {
 
   91      AddVirtualField(descriptorGuard.GetRef(), i, descriptorGuard->GetFieldZero(), 0, descriptorGuard->GetName());
 
   93      for (
const auto &
c : descriptorGuard->GetClusterIterable()) {
 
   95         for (
auto originColumnId : 
c.GetColumnIds()) {
 
   96            DescriptorId_t virtualColumnId = fIdBiMap.GetVirtualId({i, originColumnId});
 
   98            auto pageRange = 
c.GetPageRange(originColumnId).Clone();
 
   99            pageRange.fColumnId = virtualColumnId;
 
  101            auto firstElementIndex = 
c.GetColumnRange(originColumnId).fFirstElementIndex;
 
  102            auto compressionSettings = 
c.GetColumnRange(originColumnId).fCompressionSettings;
 
  104            clusterBuilder.
CommitColumnRange(virtualColumnId, firstElementIndex, compressionSettings, pageRange);
 
  106         fBuilder.AddClusterWithDetails(clusterBuilder.
MoveDescriptor().Unwrap());
 
  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...
 
void AddVirtualField(const RNTupleDescriptor &originDesc, std::size_t originIdx, const RFieldDescriptor &originField, DescriptorId_t virtualParent, const std::string &virtualName)
 
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.
 
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
 
A helper class for piece-wise construction of an RClusterDescriptor.
 
RResult< void > CommitColumnRange(DescriptorId_t columnId, std::uint64_t firstElementIndex, std::uint32_t compressionSettings, const RClusterDescriptor::RPageRange &pageRange)
 
RResult< RClusterDescriptor > MoveDescriptor()
Move out the full cluster descriptor including page locations.
 
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.
 
RColumnDescriptorIterable GetColumnIterable(const RFieldDescriptor &fieldDesc) const
 
RFieldDescriptorIterable GetFieldIterable(const RFieldDescriptor &fieldDesc) const
 
Common user-tunable settings for reading ntuples.
 
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.
 
A sealed page contains the bytes of a page as written to storage (packed & compressed).