Skip to content

Commit 0bc0bcd

Browse files
committed
[ntuple] Add VersionBehavior to merger options
1 parent feb2035 commit 0bc0bcd

3 files changed

Lines changed: 45 additions & 3 deletions

File tree

tree/ntuple/inc/ROOT/RNTupleMerger.hxx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,16 @@ enum class ENTupleMergeErrBehavior {
6262
kSkip
6363
};
6464

65+
enum class ENTupleMergeVersionBehavior {
66+
/// The merger will emit a warning when merging RNTuples with higher version than the latest supported by this
67+
/// ROOT version, but merging will work. Some optional features present in the source(s) may be missing from the
68+
/// merged RNTuple.
69+
kWarnOnHigherVersion,
70+
/// The merger will refuse to merge RNTuples with higher versions than the latest supported by this ROOT version.
71+
/// The merging process will abort as soon as one such source is encountered.
72+
kAbortOnHigherVersion
73+
};
74+
6575
struct RColumnMergeInfo;
6676
struct RNTupleMergeData;
6777
struct RSealedPageMergeData;
@@ -71,6 +81,7 @@ struct RSealedPageMergeData;
7181
/// Here is the mapping for the TFileMerger options:
7282
/// - "rntuple.MergingMode=(Filter|Union|...)" -> sets fMergingMode
7383
/// - "rntuple.ErrBehavior=(Abort|Skip|...)" -> sets fErrBehavior
84+
/// - "rntuple.VersionBehavior=(WarnOnHigherVersion|AbortOnHigherVersion|...)" -> sets fVersionBehavior
7485
/// - "rntuple.ExtraVerbose" -> sets fExtraVerbose to true
7586
/// Rules about the string-based options:
7687
/// 1. there must be no space between the separators (i.e. `.` and `=`)
@@ -84,6 +95,8 @@ struct RNTupleMergeOptions {
8495
ENTupleMergingMode fMergingMode = ENTupleMergingMode::kFilter;
8596
/// Determines how the Merge function behaves upon merging errors
8697
ENTupleMergeErrBehavior fErrBehavior = ENTupleMergeErrBehavior::kAbort;
98+
/// Determines how the Merge function behaves depending on the RNTuple sources' version.
99+
ENTupleMergeVersionBehavior fVersionBehavior = ENTupleMergeVersionBehavior::kWarnOnHigherVersion;
87100
/// If true, the merger will emit further diagnostics and information.
88101
bool fExtraVerbose = false;
89102
};

tree/ntuple/src/RNTupleMerger.cxx

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,16 @@ static std::optional<ENTupleMergeErrBehavior> ParseOptionErrBehavior(const TStri
106106
{"Skip", ENTupleMergeErrBehavior::kSkip},
107107
});
108108
}
109+
110+
static std::optional<ENTupleMergeVersionBehavior> ParseOptionVersionBehavior(const TString &opts)
111+
{
112+
return ParseStringOption<ENTupleMergeVersionBehavior>(
113+
opts, "rntuple.VersionBehavior=",
114+
{
115+
{"WarnOnHigherVersion", ENTupleMergeVersionBehavior::kWarnOnHigherVersion},
116+
{"AbortOnHigherVersion", ENTupleMergeVersionBehavior::kAbortOnHigherVersion},
117+
});
118+
}
109119
// -------------------------------------------------------------------------------------
110120

111121
// Entry point for TFileMerger. Internally calls RNTupleMerger::Merge().
@@ -244,6 +254,9 @@ try {
244254
if (auto errBehavior = ParseOptionErrBehavior(mergeInfo->fOptions)) {
245255
mergerOpts.fErrBehavior = *errBehavior;
246256
}
257+
if (auto versionBehavior = ParseOptionVersionBehavior(mergeInfo->fOptions)) {
258+
mergerOpts.fVersionBehavior = *versionBehavior;
259+
}
247260
merger.Merge(sourcePtrs, mergerOpts).ThrowOnError();
248261

249262
// Provide the caller with a merged anchor object (even though we've already
@@ -1241,9 +1254,16 @@ ROOT::RResult<void> RNTupleMerger::Merge(std::span<RPageSource *> sources, const
12411254
mergeData.fSrcDescriptor = &srcDescriptor.GetRef();
12421255

12431256
if (mergeData.fSrcDescriptor->GetVersion() > ROOT::RNTuple::GetCurrentVersion()) {
1244-
R__LOG_WARNING(NTupleMergeLog()) << "RNTuple '" << mergeData.fSrcDescriptor->GetName()
1245-
<< "' has a higher format version than the latest supported by this version "
1246-
"of ROOT. Merging will work but some features may be dropped.";
1257+
if (mergeOpts.fVersionBehavior == ENTupleMergeVersionBehavior::kWarnOnHigherVersion) {
1258+
R__LOG_WARNING(NTupleMergeLog())
1259+
<< "RNTuple '" << mergeData.fSrcDescriptor->GetName()
1260+
<< "' has a higher format version than the latest supported by this version "
1261+
"of ROOT. Merging will work but some features may be dropped.";
1262+
} else {
1263+
return R__FAIL("RNTuple '" + mergeData.fSrcDescriptor->GetName() +
1264+
"' has a higher format version than the latest supported by this version. Refusing to "
1265+
"merge, since RNTupleMergeOptions::fVersionBehavior is set to AbortOnHigherVersion.");
1266+
}
12471267
}
12481268

12491269
// Create sink from the input model if not initialized

tree/ntuple/test/ntuple_merger.cxx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3892,5 +3892,14 @@ TEST(RNTupleMerger, MergeNewerVersion)
38923892
auto res = merger.Merge(sourcePtrs, opts);
38933893
EXPECT_TRUE(bool(res));
38943894
}
3895+
3896+
// Now merge again but with VersionBehavior set to Abort.
3897+
{
3898+
RNTupleMergeOptions opts;
3899+
opts.fVersionBehavior = ROOT::Experimental::Internal::ENTupleMergeVersionBehavior::kAbortOnHigherVersion;
3900+
auto res = merger.Merge(sourcePtrs, opts);
3901+
EXPECT_FALSE(bool(res));
3902+
EXPECT_THAT(res.GetError()->GetReport(), testing::HasSubstr("has a higher format version"));
3903+
}
38953904
}
38963905
}

0 commit comments

Comments
 (0)