Skip to content

Commit d2c0d90

Browse files
authored
Mergers: add postDeserialization() callback and prioritize MergeInterface (AliceO2Group#6811)
This lets the children of MergeInterface to perform any cleanups after ROOT deserializes the object. The main use-case is setting the valid ownership, which cannot be propely set while serializing it for any reason. We also prioritize MergeInterface over TObject when a class inherits both.
1 parent a61d717 commit d2c0d90

4 files changed

Lines changed: 21 additions & 13 deletions

File tree

Utilities/Mergers/include/Mergers/MergeInterface.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,10 @@ class MergeInterface
3636
/// \brief Custom merge method.
3737
virtual void merge(MergeInterface* const other) = 0; // const argument
3838

39-
ClassDef(MergeInterface, 0);
39+
/// \brief Lets the child perform any routines after the object was deserialized (e.g. setting the correct ownership)
40+
virtual void postDeserialization(){};
41+
42+
ClassDef(MergeInterface, 1);
4043
};
4144

4245
} // namespace o2::mergers

Utilities/Mergers/src/IntegratingMerger.cxx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,19 +49,19 @@ void IntegratingMerger::run(framework::ProcessingContext& ctx)
4949

5050
for (const DataRef& ref : InputRecordWalker(ctx.inputs())) {
5151
if (ref.header != timerHeader) {
52+
auto other = object_store_helpers::extractObjectFrom(ref);
5253
if (std::holds_alternative<std::monostate>(mMergedObject)) {
53-
mMergedObject = object_store_helpers::extractObjectFrom(ref);
54-
54+
mMergedObject = std::move(object_store_helpers::extractObjectFrom(ref));
5555
} else if (std::holds_alternative<TObjectPtr>(mMergedObject)) {
5656
// We expect that if the first object was TObject, then all should.
57-
auto other = TObjectPtr(framework::DataRefUtils::as<TObject>(ref).release(), algorithm::deleteTCollections);
58-
auto target = std::get<TObjectPtr>(mMergedObject);
59-
algorithm::merge(target.get(), other.get());
57+
auto targetAsTObject = std::get<TObjectPtr>(mMergedObject);
58+
auto otherAsTObject = std::get<TObjectPtr>(other);
59+
algorithm::merge(targetAsTObject.get(), otherAsTObject.get());
6060

6161
} else if (std::holds_alternative<MergeInterfacePtr>(mMergedObject)) {
6262
// We expect that if the first object inherited MergeInterface, then all should.
63-
auto other = framework::DataRefUtils::as<MergeInterface>(ref);
64-
std::get<MergeInterfacePtr>(mMergedObject)->merge(other.get());
63+
auto otherAsMergeInterface = std::get<MergeInterfacePtr>(other);
64+
std::get<MergeInterfacePtr>(mMergedObject)->merge(otherAsMergeInterface.get());
6565
} else {
6666
throw std::runtime_error("mMergedObject' variant has no value.");
6767
}

Utilities/Mergers/src/ObjectStore.cxx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,15 @@ ObjectStore extractObjectFrom(const framework::DataRef& ref)
6565
errorPrefix + "Failed to read object with name '" + storedClass->GetName() + "' from message using ROOT serialization.");
6666
}
6767

68-
if (inheritsFromTObject) {
69-
return TObjectPtr(static_cast<TObject*>(object), algorithm::deleteTCollections);
68+
if (inheritsFromMergeInterface) {
69+
MergeInterface* objectAsMergeInterface = inheritsFromTObject ? dynamic_cast<MergeInterface*>(static_cast<TObject*>(object)) : static_cast<MergeInterface*>(object);
70+
if (objectAsMergeInterface == nullptr) {
71+
throw std::runtime_error(errorPrefix + "Could not cast '" + storedClass->GetName() + "' to MergeInterface");
72+
}
73+
objectAsMergeInterface->postDeserialization();
74+
return MergeInterfacePtr(objectAsMergeInterface);
7075
} else {
71-
return MergeInterfacePtr(static_cast<MergeInterface*>(object));
76+
return TObjectPtr(static_cast<TObject*>(object), algorithm::deleteTCollections);
7277
}
7378
}
7479

Utilities/Mergers/test/test_ObjectStore.cxx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,9 @@ BOOST_AUTO_TEST_CASE(TestObjectExtraction)
5151
DataRef ref = makeDataRef(obj);
5252

5353
auto objStore = object_store_helpers::extractObjectFrom(ref);
54-
BOOST_REQUIRE(std::holds_alternative<TObjectPtr>(objStore));
54+
BOOST_REQUIRE(std::holds_alternative<MergeInterfacePtr>(objStore));
5555

56-
auto objExtractedCustom = dynamic_cast<CustomMergeableTObject*>(std::get<TObjectPtr>(objStore).get());
56+
auto objExtractedCustom = dynamic_cast<CustomMergeableTObject*>(std::get<MergeInterfacePtr>(objStore).get());
5757
BOOST_REQUIRE(objExtractedCustom != nullptr);
5858
BOOST_CHECK_EQUAL(objExtractedCustom->getSecret(), 123);
5959

0 commit comments

Comments
 (0)