15 #include "TBufferFile.h"
16 #include "TVirtualCollectionProxy.h"
29 #include "TStreamerInfo.h"
32 #include <sys/resource.h>
44 if (!clidsvc.retrieve()){
48 if (!clidsvc->getTypeNameOfID(clid,
name).isSuccess()) {
51 (void)TClass::GetClass(
name.c_str());
71 const std::type_info* getElementType (
const std::string& tname,
72 std::string& elementTypeName ) {
73 TClass*
cls = TClass::GetClass( tname.c_str() );
74 if (
cls ==
nullptr )
return nullptr;
75 TVirtualCollectionProxy* prox =
cls->GetCollectionProxy();
76 if ( prox ==
nullptr )
return nullptr;
77 if ( prox->GetValueClass() !=
nullptr ) {
78 elementTypeName = prox->GetValueClass()->GetName();
79 return prox->GetValueClass()->GetTypeInfo();
82 elementTypeName =
type.getTypeName();
83 return type.getTypeInfo();
89 std::string stripStdVec (
const std::string& s_in) {
91 std::string::size_type
pos{0};
92 while ((
pos =
s.find (
"std::vector<")) != std::string::npos) {
105 bool versionChange(
const std::string& type1,
const std::string& type2) {
108 return ( std::regex_match(type1,
m1,
re) and
109 std::regex_match(type2,
m2,
re) and
110 m1.str(1) !=
m2.str(1) );
118 using Payload = std::vector<uint32_t>;
120 bool operator()(
int level,
bool ,
const char* location,
const char* ) {
121 if (
level >=
kError && location && strstr(location,
"TBufferFile::ReadClass")) {
123 struct rlimit core_limit;
124 getrlimit(RLIMIT_CORE, &core_limit);
125 core_limit.rlim_cur = core_limit.rlim_max;
126 setrlimit(RLIMIT_CORE, &core_limit);
128 std::cout <<
"TriggerEDMDeserialiserAlg: Raising core dump soft size limit to " << core_limit.rlim_cur
129 <<
" and trying to dump core file..." << std::endl;
133 if (
level >=
kError && location && strstr(location,
"TClass::Load")) {
134 std::cout <<
"TriggerEDMDeserialiserAlg: buff dump; start " <<
m_start <<
"\n";
136 std::cout <<
"TriggerEDMDeserialiserAlg: payload dump\n";
137 CxxUtils::hexdump (std::cout, m_payload->data(), m_payload->size() *
sizeof(Payload::value_type));
143 handleError (
const char* buf,
size_t bufsize,
const Payload*
payload,
151 const Payload* m_payload;
169 #if __cpp_lib_array_constexpr >= 201811L
177 #if __cpp_lib_array_constexpr >= 201811L
185 #if __cpp_lib_array_constexpr >= 201811L
197 #if __cpp_lib_array_constexpr >= 201811L
201 return start + (*start);
207 std::vector<std::string>
labels;
221 std::unique_ptr<TList> TriggerEDMDeserialiserAlg::s_streamerInfoList{};
233 return StatusCode::SUCCESS;
238 s_streamerInfoList.reset();
239 return StatusCode::SUCCESS;
246 if ( not resultHandle.isValid() ) {
248 return StatusCode::FAILURE;
252 const Payload* dataptr =
nullptr;
253 if ( resultHandle->getSerialisedData(
m_moduleID, dataptr ).isFailure() ) {
256 return StatusCode::SUCCESS;
259 return StatusCode::FAILURE;
263 return StatusCode::SUCCESS;
269 std::unique_ptr<char[]>
buff = std::make_unique<char[]>(buffSize);
272 auto resize = [&buffSize, &
buff](
const size_t neededSize ) ->
void {
273 if ( neededSize > buffSize ) {
274 buffSize = neededSize;
275 buff = std::make_unique<char[]>(buffSize);
289 std::string previousKey;
290 while (
start != dataptr->end() ) {
293 std::string transientTypeName, transientTypeInfoName;
299 std::string persistentTypeName{
descr[0] };
311 " type: "<< transientTypeName <<
" (" << transientTypeInfoName <<
")" <<
312 " persistent type: " << persistentTypeName <<
" key: " <<
key <<
" size: " << bsize );
327 CxxUtils::FPControl fpcontrol;
328 if (persistentTypeName ==
"xAOD::BTaggingTrigAuxContainer_v1") {
329 fpcontrol.holdExceptions();
332 size_t usedBytes{ bsize };
333 void*
obj{
nullptr };
340 ATH_MSG_DEBUG(
"Deserialised object of ptr: " <<
obj <<
" which used: " << usedBytes <<
341 " bytes from available: " << bsize );
342 if (
obj ==
nullptr ) {
343 ATH_MSG_ERROR(
"Deserialisation of object of CLID " << clid <<
" and transientTypeName " <<
344 transientTypeName <<
" # " <<
key <<
" failed" );
345 return StatusCode::FAILURE;
347 const bool isxAODInterfaceContainer = (transientTypeName.rfind(
"xAOD", 0) != std::string::npos and
348 transientTypeName.find(
"Aux") == std::string::npos and
349 transientTypeName.find(
"ElementLink") == std::string::npos);
350 const bool isxAODAuxContainer = (transientTypeName.rfind(
"xAOD", 0) != std::string::npos and
351 transientTypeName.find(
"Aux") != std::string::npos);
352 const bool isxAODDecoration = transientTypeName.find(
"vector") != std::string::npos;
353 const bool isTPContainer = persistentTypeName.find(
"_p") != std::string::npos;
354 const bool isVersionChange = versionChange(persistentTypeName, transientTypeInfoName);
357 isxAODAuxContainer, isxAODDecoration, isTPContainer ) );
359 if ( isTPContainer or isVersionChange ) {
360 if ( isVersionChange )
ATH_MSG_DEBUG(
"Version change detected from " << persistentTypeName <<
" to "
361 << transientTypeInfoName <<
". Will invoke PT converter." );
363 std::string decodedTransientName;
374 if ( isxAODInterfaceContainer or isxAODAuxContainer or isTPContainer ) {
379 if ( proxyPtr ==
nullptr ) {
383 if ( isxAODInterfaceContainer ) {
387 if (xAODInterfaceContainer!=
nullptr &&
388 xAODInterfaceContainer->
trackIndices() && currentAuxStore==
nullptr) {
389 ATH_MSG_DEBUG(
"Container with key " << previousKey <<
" is missing its Aux store");
392 currentAuxStore =
nullptr;
397 xAODInterfaceContainer =
402 }
else if (isxAODAuxContainer) {
405 ATH_CHECK( currentAuxStore ==
nullptr and xAODInterfaceContainer !=
nullptr );
411 xAODInterfaceContainer->
setStore(auxHolder);
415 currentAuxStore =
nullptr;
416 xAODInterfaceContainer =
nullptr;
419 }
else if ( isxAODDecoration ) {
420 if(
m_skipDuplicates and (currentAuxStore ==
nullptr || xAODInterfaceContainer ==
nullptr)) {
421 ATH_MSG_DEBUG(
"Decoration " <<
key <<
" encountered with no active container. Assume this was already handled.");
423 ATH_CHECK( currentAuxStore !=
nullptr and xAODInterfaceContainer !=
nullptr );
425 currentAuxStore, xAODInterfaceContainer ) );
430 return StatusCode::SUCCESS;
437 const bool isPacked = persistentTypeName.find(
"SG::PackedContainer") != std::string::npos;
441 if (
id != SG::null_auxid ) {
442 std::string regTypeName = stripStdVec(
registry.getVecTypeName(
id) );
443 if ( regTypeName != stripStdVec(transientTypeName) and transientTypeName.find(
"ElementLink") == std::string::npos )
447 if ( regTypeName != stripStdVec(tname.
getTypeName()) ) {
448 ATH_MSG_INFO(
"Schema evolution required for decoration \"" << decorationName <<
"\" from " << transientTypeName <<
" to " <<
registry.getVecTypeName(
id ) <<
" not handled yet");
449 return StatusCode::SUCCESS;
453 std::string elementTypeName;
454 const std::type_info* elt_tinfo = getElementType( transientTypeName, elementTypeName );
456 ATH_MSG_DEBUG(
"Dynamic decoration: \"" << decorationName <<
"\" of type " << transientTypeName <<
" will create a dynamic ID, stored type" << elementTypeName );
457 id =
SG::getDynamicAuxID ( *elt_tinfo, decorationName, elementTypeName, transientTypeName,
false, SG::null_auxid );
459 ATH_MSG_DEBUG(
"Unstreaming decoration \"" << decorationName <<
"\" of type " << transientTypeName <<
" aux ID " <<
id <<
" class " << persistentTypeName <<
" packed " << isPacked );
460 std::unique_ptr<SG::IAuxTypeVector>
vec(
registry.makeVectorFromData (
id,
obj,
nullptr, isPacked,
true) );
462 ATH_MSG_DEBUG(
"Size for \"" << decorationName <<
"\" " <<
vec->size() <<
" interface " << interfaceContainer->
size_v() );
464 if (
vec->size() != 0 ) {
469 accessor.getDataArray( *interfaceContainer );
471 return StatusCode::SUCCESS;
475 ATH_MSG_DEBUG(
"Recognised type " << transientTypeName <<
" as: "
476 << (isxAODInterfaceContainer ?
"xAOD Interface Container":
"" )
477 << (isxAODAuxContainer ?
"xAOD Aux Container ":
"" )
478 << ( isDecoration ?
"xAOD Decoration" :
"")
479 << ( isTPContainer ?
"T/P Container " :
"") );
481 const std::vector<bool> typeOfContainer( { isxAODInterfaceContainer, isxAODAuxContainer, isDecoration, isTPContainer } );
482 const size_t count =
std::count( typeOfContainer.begin(), typeOfContainer.end(),
true );
484 ATH_MSG_ERROR(
"Could not recognise the kind of container " << transientTypeName );
485 return StatusCode::FAILURE;
488 ATH_MSG_ERROR(
"Ambiguous container kind deduced from the transient type name " << transientTypeName );
490 << (isxAODInterfaceContainer ?
"xAOD Interface Context":
"" )
491 << (isxAODAuxContainer ?
" xAOD Aux Container ":
"" )
492 << ( isDecoration ?
"xAOD Decoration" :
"")
493 << ( isTPContainer ?
"T/P Container " :
"") );
494 return StatusCode::FAILURE;
496 return StatusCode::SUCCESS;
501 std::lock_guard<std::mutex> lock(
s_mutex);
503 if (s_streamerInfoList) {
507 std::string extStreamerInfos =
"bs-streamerinfos.root";
510 TFile extFile(extFilePath.c_str());
512 s_streamerInfoList = std::unique_ptr<TList>(extFile.GetStreamerInfoList());
513 for(
const auto&& infObj: *s_streamerInfoList) {
514 TString t_name=infObj->GetName();
515 if (t_name.BeginsWith(
"listOfRules")){
520 TStreamerInfo*
inf =
dynamic_cast<TStreamerInfo*
>(infObj);
522 TClass *
cl =
inf->GetClass();
525 " checksum: " << std::hex <<
inf->GetCheckSum() << std::dec );