-
Notifications
You must be signed in to change notification settings - Fork 494
Expand file tree
/
Copy pathObjectStore.cxx
More file actions
82 lines (68 loc) · 3.29 KB
/
ObjectStore.cxx
File metadata and controls
82 lines (68 loc) · 3.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
// All rights not expressly granted are reserved.
//
// This software is distributed under the terms of the GNU General Public
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
//
// In applying this license CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.
/// \file ObjectStore.cxx
/// \brief Implementation of ObjectStore for Mergers, v0.1
///
/// \author Piotr Konopka, piotr.jan.konopka@cern.ch
#include "Mergers/ObjectStore.h"
#include "Framework/DataRefUtils.h"
#include "Mergers/MergeInterface.h"
#include "Mergers/MergerAlgorithm.h"
#include <TObject.h>
namespace o2::mergers
{
namespace object_store_helpers
{
ObjectStore extractObjectFrom(const framework::DataRef& ref)
{
// We do extraction on the low level to efficiently determine if the message
// contains an object inheriting MergeInterface or TObject. If we did it the
// the following way and catch an exception:
// framework::DataRefUtils::as<MergeInterface>(ref)
// it could cause a memory leak if `ref` contained a non-owning TCollection.
// This way we also avoid doing most of the checks twice.
const static std::string errorPrefix = "Could not extract object to be merged: ";
using DataHeader = o2::header::DataHeader;
auto header = framework::DataRefUtils::getHeader<const DataHeader*>(ref);
if (header->payloadSerializationMethod != o2::header::gSerializationMethodROOT) {
throw std::runtime_error(errorPrefix + "It is not ROOT-serialized");
}
o2::framework::FairTMessage ftm(const_cast<char*>(ref.payload), o2::framework::DataRefUtils::getPayloadSize(ref));
auto* storedClass = ftm.GetClass();
if (storedClass == nullptr) {
throw std::runtime_error(errorPrefix + "Unknown stored class");
}
auto* mergeInterfaceClass = TClass::GetClass(typeid(MergeInterface));
auto* tObjectClass = TClass::GetClass(typeid(TObject));
bool inheritsFromMergeInterface = storedClass->InheritsFrom(mergeInterfaceClass);
bool inheritsFromTObject = storedClass->InheritsFrom(tObjectClass);
if (!inheritsFromMergeInterface && !inheritsFromTObject) {
throw std::runtime_error(
errorPrefix + "Class '" + storedClass->GetName() + "'does not inherit from MergeInterface nor TObject");
}
auto* object = ftm.ReadObjectAny(storedClass);
if (object == nullptr) {
throw std::runtime_error(
errorPrefix + "Failed to read object with name '" + storedClass->GetName() + "' from message using ROOT serialization.");
}
if (inheritsFromMergeInterface) {
MergeInterface* objectAsMergeInterface = inheritsFromTObject ? dynamic_cast<MergeInterface*>(static_cast<TObject*>(object)) : static_cast<MergeInterface*>(object);
if (objectAsMergeInterface == nullptr) {
throw std::runtime_error(errorPrefix + "Could not cast '" + storedClass->GetName() + "' to MergeInterface");
}
objectAsMergeInterface->postDeserialization();
return MergeInterfacePtr(objectAsMergeInterface);
} else {
return TObjectPtr(static_cast<TObject*>(object), algorithm::deleteTCollections);
}
}
} // namespace object_store_helpers
} // namespace o2::mergers