diff --git a/tree/ntuple/v7/src/RNTupleMerger.cxx b/tree/ntuple/v7/src/RNTupleMerger.cxx index a265dcceb81f8..e30d8fa718440 100644 --- a/tree/ntuple/v7/src/RNTupleMerger.cxx +++ b/tree/ntuple/v7/src/RNTupleMerger.cxx @@ -24,6 +24,8 @@ #include #include +#include + Long64_t ROOT::Experimental::RNTuple::Merge(TCollection *inputs, TFileMergeInfo *mergeInfo) { // Check the inputs @@ -193,6 +195,12 @@ void ROOT::Experimental::Internal::RNTupleMerger::Merge(std::span while (clusterId != ROOT::Experimental::kInvalidDescriptorId) { auto &cluster = descriptor->GetClusterDescriptor(clusterId); + std::vector> buffers; + // We use a std::deque so that references to the contained SealedPageSequence_t, and its iterators, are never + // invalidated. + std::deque sealedPagesV; + std::vector sealedPageGroups; + for (const auto &column : columns) { // See if this cluster contains this column @@ -206,6 +214,8 @@ void ROOT::Experimental::Internal::RNTupleMerger::Merge(std::span const auto &pages = cluster.GetPageRange(columnId); size_t idx{0}; + RPageStorage::SealedPageSequence_t sealedPages; + // Loop over the pages for (const auto &pageInfo : pages.fPageInfos) { @@ -222,17 +232,23 @@ void ROOT::Experimental::Internal::RNTupleMerger::Merge(std::span sealedPage.fBuffer = buffer.get(); source->LoadSealedPage(columnId, clusterIndex, sealedPage); - // Now commit this page to the output - // Can we do this w/ a CommitSealedPageV - destination.CommitSealedPage(column.fColumnOutputId, sealedPage); + buffers.push_back(std::move(buffer)); + sealedPages.push_back(std::move(sealedPage)); // Move on to the next index idx += pageInfo.fNElements; } // end of loop over pages + sealedPagesV.push_back(std::move(sealedPages)); + sealedPageGroups.emplace_back(column.fColumnOutputId, sealedPagesV.back().cbegin(), + sealedPagesV.back().cend()); + } // end of loop over columns + // Now commit all pages to the output + destination.CommitSealedPageV(sealedPageGroups); + // Commit the clusters destination.CommitCluster(cluster.GetNEntries());