19#include "CoralBase/AttributeList.h"
20#include "CoralBase/Attribute.h"
22#include "GaudiKernel/IIncidentSvc.h"
23#include "GaudiKernel/FileIncident.h"
44 if( incSvc.retrieve().isSuccess() ) {
46 incSvc->removeListener(
this, IncidentType::EndInputFile);
47 }
catch ( GaudiException & e){
48 ATH_MSG_FATAL(
"Gaudi exception caught in DataHeaderCnv::~DataHeaderCnv");
57 bool doFilterDHAliases =
true;
58 const std::string svcName = (serviceLocator()->existsService(
"AthenaPoolSharedIOCnvSvc") ?
"AthenaPoolSharedIOCnvSvc" :
"AthenaPoolCnvSvc");
59 SmartIF<IProperty> cnvSvc{service(svcName,
false)};
62 if( cnvSvc->getProperty(&sizeProp).isSuccess() ) {
65 BooleanProperty aliasFilterProp(
"doFilterDHAliases", doFilterDHAliases);
66 if( cnvSvc->getProperty(&aliasFilterProp).isSuccess() ) {
67 doFilterDHAliases = aliasFilterProp.value();
69 BooleanProperty oneDHForm(
"OneDataHeaderForm",
m_oneDHForm);
70 if( cnvSvc->getProperty(&oneDHForm).isSuccess() ) {
75 if( doFilterDHAliases ) {
86 incSvc->addListener(
this, IncidentType::EndInputFile, 0);
87 incSvc->addListener(
this,
"PreFork", 0);
89 incSvc->addListener(
this,
"WriteDataHeaderForms", 0);
96 if( incident.type() ==
"PreFork" ) {
99 if( incident.type() == IncidentType::EndInputFile ) {
101 const std::string& guid =
static_cast<const FileIncident&
>(incident).fileGuid();
104 if( incident.type() ==
"WriteDataHeaderForms" ) {
106 const std::string& fileName =
static_cast<const FileIncident*
>(&incident)->fileName();
108 std::vector<std::string> toWrite;
109 auto pos = fileName.find(
"[OutputCollection=MetaDataHdr]");
110 bool metaDataCommit = (pos != std::string::npos);
111 std::string justFileName = fileName.substr(0, pos);
112 ATH_MSG_DEBUG(
"Handling WriteDataHeaderForms incident for stream: " << fileName);
115 const std::string& placementStr = elem.first;
119 if( formPlacement.
fileName() == justFileName or fileName ==
"*" ) {
121 if( (placementStr.find(
"[CONT=MetaData") != std::string::npos) == metaDataCommit ) {
122 toWrite.push_back( placementStr );
127 for( std::size_t n = 0;
const std::string& placementStr : toWrite ) {
131 if( form_ptr->isModified() ) {
132 static const RootType dhFormType(
typeid( *form_ptr ) );
136 std::string
errmsg = std::format(
"Failed to write {} {}", dhFormType.
Name(), placementStr);
138 throw GaudiException(std::move(
errmsg),
"DataHeaderCnv::WriteDataHeaderForms", StatusCode::FAILURE);
140 ATH_MSG_DEBUG(
"Wrote DatHeaderForm, placeemnt was " << placementStr <<
" token=" << form_token->
toString());
141 form_token->
release(); form_token =
nullptr;
142 bool doCommit = (++n == toWrite.size());
143 const std::string connection = ( fileName!=
"*"? fileName : formPlacement.
fileName() );
145 throw GaudiException(
"WriteDataHeaderForms failed",
"DataHeaderCnv::WriteDataHeaderForms", StatusCode::FAILURE);
158 size_t dbpos = iter->first.find(
"[DB=");
159 if( dbpos != std::string::npos && iter->first.compare(dbpos+4, dbpos+36, dbGuid) == 0 ) {
171 auto start =
str.find(key);
172 if( start == std::string::npos )
175 auto end =
str.find(
"]", start);
176 return str.substr(start, end-start);
185 return std::format(
"[{}={}]", key, val);
197 if( lval != rval )
return lval < rval;
201 if( lval.empty() or rval.empty() )
return false;
202 return std::stoul( lval ) < std::stoul( rval );
216 auto dataHeader =
reinterpret_cast<DataHeader_p6*
>( pObject );
217 const std::string dhRef = pAddress->par()[0];
218 const std::string dhPlacementStr = pAddress->par()[1];
221 dhFormPlacement.
fromString( dataHeader->dhFormToken() );
224 if( !clientN.empty() ) {
228 dataHeader->setDhFormToken( dhFormNewRef );
236 ATH_MSG_ERROR(
"updateRep called but the previous DataHeader was not yet processed."
239 return StatusCode::FAILURE;
244 std::size_t tagBeg = dhPlacementStr.find(
"[KEY=") + 5;
245 std::size_t tagSize = dhPlacementStr.find(
']', tagBeg) - tagBeg;
248 return StatusCode::SUCCESS;
262 std::string dhid = pAddress->par()[1];
267 ATH_MSG_ERROR(
"updateRepRefs called without DataHeaderForm" );
268 return StatusCode::FAILURE;
276 ATH_MSG_ERROR(
"updateRepRefs: missing DataHeaderForm for DH ID=" << dhid );
277 return StatusCode::FAILURE;
290 return(StatusCode::SUCCESS);
298 ATH_MSG_ERROR(
"Failed to cast DataHeader to transient type" );
299 return(StatusCode::FAILURE);
303 std::string form_placement_str = dhf_placement.
toString();
305 std::unique_ptr<DataHeaderForm_p6>& dhForm =
m_persFormMap[form_placement_str];
306 if (dhForm ==
nullptr) {
308 dhForm = std::make_unique<DataHeaderForm_p6>();
309 dhForm->setProcessTag( obj->getProcessTag() );
315 const std::string connection = dh_placement.
fileName();
320 }
catch (std::exception &e) {
321 ATH_MSG_FATAL(
"Failed to convert DataHeader to persistent type: " << e.what());
322 return(StatusCode::FAILURE);
326 if (dh_token ==
nullptr) {
328 return(StatusCode::FAILURE);
332 m_tpOutConverter.insertDHRef(persObj, obj->getProcessTag(), dh_token->toString(), *dhForm);
335 if( dhForm->isModified() ) {
338 static const RootType dhFormType(
typeid(*dhForm));
340 if (dhf_token ==
nullptr) {
342 return(StatusCode::FAILURE);
345 dhForm->setToken(dhf_token->
toString());
347 ATH_MSG_DEBUG(
"Technology does not support setting DHF token for: " << dh_token->toString());
348 dhForm->setToken(
"");
350 ATH_MSG_DEBUG(
"wrote new DHForm with " << dhForm->sizeObj() <<
" SG object data");
351 dhf_token->
release(); dhf_token =
nullptr;
352 dhForm->clearModified();
360 if( dhForm->getToken().empty() ) {
361 form_placement_str += std::format(
"[DB={}]", dh_token->dbID().toString());
362 dhForm->setToken( form_placement_str );
364 form_placement_str = dhForm->getToken();
367 auto b = form_placement_str.find(
"[FILE=");
368 auto e = form_placement_str.find(
"]", b);
369 form_placement_str.erase(b, e-b+1);
374 const coral::AttributeList* list = obj->getAttributeList();
375 if (list !=
nullptr) {
376 obj->setEvtRefTokenStr(dh_token->toString());
379 obj->getEvtRefTokenStr().c_str(),
381 delete ref_token; ref_token =
nullptr;
382 for (coral::AttributeList::const_iterator iter = list->begin(), last = list->end(); iter != last; ++iter) {
383 attr_placement = this->
setPlacementWithType(
"AttributeList", (*iter).specification().name(), *pAddr->par());
385 (*iter).addressOfData(),
386 RootType((*iter).specification().type()) );
387 delete attr_token; attr_token =
nullptr;
391 if (tokAddr !=
nullptr) {
392 tokAddr->
setToken(std::move(dh_token));
394 return(StatusCode::FAILURE);
396 return(StatusCode::SUCCESS);
402 void* voidPtr1 =
nullptr;
404 if (voidPtr1 ==
nullptr) {
405 throw std::runtime_error(
"Could not get object for token = " +
m_i_poolToken->toString());
409 void* voidPtr2 =
nullptr;
416 if (voidPtr2 ==
nullptr) {
417 throw std::runtime_error(
"Could not get object for token = " + mapToken.
toString());
431 void* voidPtr1 =
nullptr;
432 std::string error_message;
435 }
catch(
const std::exception& err) {
437 error_message = err.what();
439 if (voidPtr1 ==
nullptr) {
440 throw std::runtime_error(
"Could not get object for token = " +
m_i_poolToken->toString() +
", " + error_message);
444 std::string dhFormToken =
header->dhFormToken();
446 if( !dhFormToken.empty() and dhFormToken.find(
"[OID=") == std::string::npos) {
457 oid2 >>= 32; oid2 <<= 32;
460 if( !swn.empty() ) oid2 += std::stoul( swn ) - 1;
461 formToken.
setOid( {0,oid2} );
464 header->setDhFormToken( dhFormToken );
469 size_t dbpos = dhFormToken.find(
"[DB=");
470 if( dbpos != std::string::npos ) {
471 const std::string dbGuid = dhFormToken.substr(dbpos+4, dbpos+36);
479 void* voidPtr2 =
nullptr;
480 if( dhFormToken.empty() ) {
491 }
catch(
const std::exception& err) {
493 error_message = err.what();
495 if (voidPtr2 ==
nullptr) {
501 void* firstPtr1 =
nullptr;
504 }
catch(
const std::exception& err) {
506 error_message = err.what();
508 if (firstPtr1 ==
nullptr)
throw std::runtime_error(
"Could not get first DataHeader for token = " + firstToken.
toString() +
", " + error_message);
511 std::unique_ptr<DataHeader_p6> firstHeader(
reinterpret_cast<DataHeader_p6*
>(firstPtr1) );
512 dhFormToken = firstHeader->dhFormToken();
519 }
catch(
const std::exception& err) {
521 error_message = err.what();
523 if (voidPtr2 ==
nullptr)
throw std::runtime_error(
"Could not get DataHeaderForm for token = " + formToken.
toString() +
", " + error_message);
526 ATH_MSG_WARNING(
"DataHeaderForm read exception: " << error_message <<
" - reusing the last good DHForm");
529 ATH_MSG_WARNING(
"DataHeaderForm read exception: " << error_message <<
" - reusing the last good DHForm");
534 if (voidPtr2 ==
nullptr) {
535 throw std::runtime_error(
"Could not get object for token = " + formToken.
toString());
555 if( iter->getToken()->dbID() ==
Guid::null() ) {
571 std::string bestPfn, fileType;
577 static const pool::Guid p6_guid(
"4DDBD295-EFCE-472A-9EC8-15CD35A9EB8D");
578 static const pool::Guid p5_guid(
"D82968A1-CF91-4320-B2DD-E0F739CBC7E6");
579 static const pool::Guid p4_guid(
"9630EB7B-CCD7-47D9-A39B-CBBF4133CDF2");
580 static const pool::Guid p3_guid(
"EC1318F0-8E28-45F8-9A2D-2597C1CC87A6");
602 }
catch (std::exception &e) {
604 std::string
error = e.what();
605 throw std::runtime_error(
error);
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
This file contains the class definition for the Placement class (migrated from POOL).
This file contains the class definition for the TokenAddress class.
This file contains the class definition for the Token class (migrated from POOL).
static thread_local std::ostringstream errmsg
ServiceHandle< IAthenaPoolCnvSvc > m_athenaPoolCnvSvc
virtual Placement setPlacementWithType(const std::string &tname, const std::string &key, const std::string &output)
const Token * m_i_poolToken
static const Guid & null() noexcept
NULL-Guid: static class method.
This class holds all the necessary information to guide the writing of an object in a physical place.
const std::string & auxString() const
Access auxiliary string.
const std::string & containerName() const
Access container name.
Placement & setFileName(const std::string &fileName)
Set file name.
const std::string toString() const
Retrieve the string representation of the placement.
const std::string & fileName() const
Access file name.
Placement & fromString(const std::string &from)
Build from the string representation of a placement.
int technology() const
Access technology type.
std::string Name(unsigned int mod=Reflex::SCOPED) const
virtual bool compareClassGuid(const Token *token, const Guid &clid) const
virtual StatusCode initialize()
P * poolReadObject(const Token *token)
void keepPoolObj(DataHeader_p6 *obj, const std::string &output)
This class provides a Generic Transient Address for POOL tokens.
void setToken(std::unique_ptr< Token > token)
This class provides a token that identifies in a unique way objects on the persistent storage.
Token & setCont(const std::string &cnt)
Set container name.
Token & setAuxString(const std::string &auxString)
Set auxiliary string.
Token & setDb(const Guid &db)
Set database name.
const Guid & classID() const
Access database identifier.
Token & setClassID(const Guid &cl_id)
Access database identifier.
virtual const std::string toString() const
Retrieve the string representation of the token.
int technology() const
Access technology type.
int release()
Release token: Decrease reference count and eventually delete.
Token & setOid(const OID_t &oid)
Set object identifier.
Token & setTechnology(int t)
Set technology type.
const OID_t & oid() const
Access object identifier.
Token & fromString(const std::string_view from)
Build from the string representation of a token.
bool fromStorable(DataObject *pDObj, T *&pTrans, bool quiet=false, IRegisterTransient *irt=0, bool isConst=true)