@@ -646,12 +646,14 @@ static void ExtendDestinationModel(std::span<const ROOT::RFieldDescriptor *> new
646
646
}
647
647
648
648
// Generates default (zero) values for the given columns
649
- static void GenerateZeroPagesForColumns (size_t nEntriesToGenerate, std::span<const RColumnMergeInfo> columns,
650
- RSealedPageMergeData &sealedPageData, ROOT::Internal::RPageAllocator &pageAlloc,
651
- const ROOT::RNTupleDescriptor &dstDescriptor, const RNTupleMergeData &mergeData)
649
+ [[nodiscard]]
650
+ static ROOT::RResult<void >
651
+ GenerateZeroPagesForColumns (size_t nEntriesToGenerate, std::span<const RColumnMergeInfo> columns,
652
+ RSealedPageMergeData &sealedPageData, ROOT::Internal::RPageAllocator &pageAlloc,
653
+ const ROOT::RNTupleDescriptor &dstDescriptor, const RNTupleMergeData &mergeData)
652
654
{
653
655
if (!nEntriesToGenerate)
654
- return ;
656
+ return ROOT::RResult< void >:: Success () ;
655
657
656
658
for (const auto &column : columns) {
657
659
const ROOT::RFieldDescriptor *field = column.fParentFieldDescriptor ;
@@ -681,12 +683,10 @@ static void GenerateZeroPagesForColumns(size_t nEntriesToGenerate, std::span<con
681
683
const auto structure = field->GetStructure ();
682
684
683
685
if (structure == ROOT::ENTupleStructure::kStreamer ) {
684
- R__LOG_FATAL (NTupleMergeLog ())
685
- << " RNTuple::Merge"
686
- " Destination RNTuple contains a streamer field (%s) that is not present in one of the sources. "
687
- " Creating a default value for a streamer field is ill-defined, therefore the merging process will abort."
688
- << field->GetFieldName ();
689
- continue ;
686
+ return R__FAIL (
687
+ " Destination RNTuple contains a streamer field (" + field->GetFieldName () +
688
+ " ) that is not present in one of the sources. "
689
+ " Creating a default value for a streamer field is ill-defined, therefore the merging process will abort." );
690
690
}
691
691
692
692
// NOTE: we cannot have a Record here because it has no associated columns.
@@ -725,21 +725,23 @@ static void GenerateZeroPagesForColumns(size_t nEntriesToGenerate, std::span<con
725
725
sealedPageData.fPagesV .back ().cend ());
726
726
}
727
727
}
728
+ return ROOT::RResult<void >::Success ();
728
729
}
729
730
730
731
// Merges all columns appearing both in the source and destination RNTuples, just copying them if their
731
732
// compression matches ("fast merge") or by unsealing and resealing them with the proper compression.
732
- void RNTupleMerger::MergeCommonColumns (ROOT::Internal::RClusterPool &clusterPool,
733
- const ROOT::RClusterDescriptor &clusterDesc,
734
- std::span<const RColumnMergeInfo> commonColumns,
735
- const RCluster::ColumnSet_t &commonColumnSet,
736
- std::size_t nCommonColumnsInCluster, RSealedPageMergeData &sealedPageData,
737
- const RNTupleMergeData &mergeData, ROOT::Internal::RPageAllocator &pageAlloc)
733
+ ROOT::RResult<void >
734
+ RNTupleMerger::MergeCommonColumns (ROOT::Internal::RClusterPool &clusterPool,
735
+ const ROOT::RClusterDescriptor &clusterDesc,
736
+ std::span<const RColumnMergeInfo> commonColumns,
737
+ const RCluster::ColumnSet_t &commonColumnSet, std::size_t nCommonColumnsInCluster,
738
+ RSealedPageMergeData &sealedPageData, const RNTupleMergeData &mergeData,
739
+ ROOT::Internal::RPageAllocator &pageAlloc)
738
740
{
739
741
assert (nCommonColumnsInCluster == commonColumnSet.size ());
740
742
assert (nCommonColumnsInCluster <= commonColumns.size ());
741
743
if (nCommonColumnsInCluster == 0 )
742
- return ;
744
+ return ROOT::RResult< void >:: Success () ;
743
745
744
746
const RCluster *cluster = clusterPool.GetCluster (clusterDesc.GetId (), commonColumnSet);
745
747
// we expect the cluster pool to contain the requested set of columns, since they were
@@ -794,8 +796,10 @@ void RNTupleMerger::MergeCommonColumns(ROOT::Internal::RClusterPool &clusterPool
794
796
// TODO: also avoid doing this if we added no real page of this column to the destination yet.
795
797
if (columnDesc.GetFirstElementIndex () > clusterDesc.GetFirstEntryIndex () && mergeData.fNumDstEntries > 0 ) {
796
798
const auto nMissingEntries = columnDesc.GetFirstElementIndex () - clusterDesc.GetFirstEntryIndex ();
797
- GenerateZeroPagesForColumns (nMissingEntries, {&column, 1 }, sealedPageData, pageAlloc, mergeData.fDstDescriptor ,
798
- mergeData);
799
+ auto res = GenerateZeroPagesForColumns (nMissingEntries, {&column, 1 }, sealedPageData, pageAlloc,
800
+ mergeData.fDstDescriptor , mergeData);
801
+ if (!res)
802
+ return R__FORWARD_ERROR (res);
799
803
}
800
804
801
805
// Loop over the pages
@@ -843,15 +847,18 @@ void RNTupleMerger::MergeCommonColumns(ROOT::Internal::RClusterPool &clusterPool
843
847
sealedPageData.fGroups .emplace_back (column.fOutputId , sealedPageData.fPagesV .back ().cbegin (),
844
848
sealedPageData.fPagesV .back ().cend ());
845
849
} // end loop over common columns
850
+
851
+ return ROOT::RResult<void >::Success ();
846
852
}
847
853
848
854
// Iterates over all clusters of `source` and merges their pages into `destination`.
849
855
// It is assumed that all columns in `commonColumns` are present (and compatible) in both the source and
850
856
// the destination's schemas.
851
857
// The pages may be "fast-merged" (i.e. simply copied with no decompression/recompression) if the target
852
858
// compression is unspecified or matches the original compression settings.
853
- void RNTupleMerger::MergeSourceClusters (RPageSource &source, std::span<const RColumnMergeInfo> commonColumns,
854
- std::span<const RColumnMergeInfo> extraDstColumns, RNTupleMergeData &mergeData)
859
+ ROOT::RResult<void >
860
+ RNTupleMerger::MergeSourceClusters (RPageSource &source, std::span<const RColumnMergeInfo> commonColumns,
861
+ std::span<const RColumnMergeInfo> extraDstColumns, RNTupleMergeData &mergeData)
855
862
{
856
863
ROOT::Internal::RClusterPool clusterPool{source};
857
864
@@ -893,10 +900,15 @@ void RNTupleMerger::MergeSourceClusters(RPageSource &source, std::span<const RCo
893
900
missingColumns.push_back (commonColumns[i]);
894
901
895
902
RSealedPageMergeData sealedPageData;
896
- MergeCommonColumns (clusterPool, clusterDesc, commonColumns, commonColumnSet, nCommonColumnsInCluster,
897
- sealedPageData, mergeData, *fPageAlloc );
898
- GenerateZeroPagesForColumns (nClusterEntries, missingColumns, sealedPageData, *fPageAlloc ,
899
- mergeData.fDstDescriptor , mergeData);
903
+ auto res = MergeCommonColumns (clusterPool, clusterDesc, commonColumns, commonColumnSet, nCommonColumnsInCluster,
904
+ sealedPageData, mergeData, *fPageAlloc );
905
+ if (!res)
906
+ return R__FORWARD_ERROR (res);
907
+
908
+ res = GenerateZeroPagesForColumns (nClusterEntries, missingColumns, sealedPageData, *fPageAlloc ,
909
+ mergeData.fDstDescriptor , mergeData);
910
+ if (!res)
911
+ return R__FORWARD_ERROR (res);
900
912
901
913
// Commit the pages and the clusters
902
914
mergeData.fDestination .CommitSealedPageV (sealedPageData.fGroups );
@@ -913,6 +925,7 @@ void RNTupleMerger::MergeSourceClusters(RPageSource &source, std::span<const RCo
913
925
// However, as of today, we aren't really handling such huge files, and even relatively big ones
914
926
// such as the CMS dataset have a page list size of about only 2 MB.
915
927
// So currently we simply merge all cluster groups into one.
928
+ return ROOT::RResult<void >::Success ();
916
929
}
917
930
918
931
static std::optional<std::type_index> ColumnInMemoryType (std::string_view fieldType, ENTupleColumnType onDiskType)
@@ -976,7 +989,8 @@ static void AddColumnsFromField(std::vector<RColumnMergeInfo> &columns, const RO
976
989
// 2. when merging a deferred column into an existing column (in which case we need to fill the "hole" with
977
990
// zeroes). For the first case srcFieldDesc and dstFieldDesc are the same (see the calling site of this function),
978
991
// but for the second case they're not, and we need to pick the source field because we will then check the
979
- // column's *input* id inside fParentFieldDescriptor to see if it's a suppressed column (see GenerateZeroPagesForColumns()).
992
+ // column's *input* id inside fParentFieldDescriptor to see if it's a suppressed column (see
993
+ // GenerateZeroPagesForColumns()).
980
994
info.fParentFieldDescriptor = &srcFieldDesc;
981
995
// Save the parent field descriptor since this may be either the source or destination descriptor depending on
982
996
// whether this is an extraDstField or a commonField. We will need this in GenerateZeroPagesForColumns() to
@@ -1182,7 +1196,9 @@ ROOT::RResult<void> RNTupleMerger::Merge(std::span<RPageSource *> sources, const
1182
1196
1183
1197
// handle extra dst fields & common fields
1184
1198
auto columnInfos = GatherColumnInfos (descCmp, srcDescriptor.GetRef (), mergeData);
1185
- MergeSourceClusters (*source, columnInfos.fCommonColumns , columnInfos.fExtraDstColumns , mergeData);
1199
+ auto res = MergeSourceClusters (*source, columnInfos.fCommonColumns , columnInfos.fExtraDstColumns , mergeData);
1200
+ if (!res)
1201
+ return R__FORWARD_ERROR (res);
1186
1202
} // end loop over sources
1187
1203
1188
1204
if (fDestination ->GetNEntries () == 0 )
0 commit comments