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];
264 this->
setToken( pAddress->par()[0] );
266 ATH_MSG_ERROR(
"updateRepRefs called without DataHeaderForm" );
267 return StatusCode::FAILURE;
275 ATH_MSG_ERROR(
"updateRepRefs: missing DataHeaderForm for DH ID=" << dhid );
276 return StatusCode::FAILURE;
289 return(StatusCode::SUCCESS);
297 ATH_MSG_ERROR(
"Failed to cast DataHeader to transient type" );
298 return(StatusCode::FAILURE);
302 std::string form_placement_str = dhf_placement.
toString();
304 std::unique_ptr<DataHeaderForm_p6>& dhForm =
m_persFormMap[form_placement_str];
305 if (dhForm ==
nullptr) {
307 dhForm = std::make_unique<DataHeaderForm_p6>();
308 dhForm->setProcessTag( obj->getProcessTag() );
314 const std::string connection = dh_placement.
fileName();
319 }
catch (std::exception &e) {
320 ATH_MSG_FATAL(
"Failed to convert DataHeader to persistent type: " << e.what());
321 return(StatusCode::FAILURE);
325 if (dh_token ==
nullptr) {
327 return(StatusCode::FAILURE);
331 m_tpOutConverter.insertDHRef(persObj, obj->getProcessTag(), dh_token->toString(), *dhForm);
334 if( dhForm->isModified() ) {
337 static const RootType dhFormType(
typeid(*dhForm));
339 if (dhf_token ==
nullptr) {
341 return(StatusCode::FAILURE);
344 dhForm->setToken(dhf_token->
toString());
346 ATH_MSG_DEBUG(
"Technology does not support setting DHF token for: " << dh_token->toString());
347 dhForm->setToken(
"");
349 ATH_MSG_DEBUG(
"wrote new DHForm with " << dhForm->sizeObj() <<
" SG object data");
350 dhf_token->
release(); dhf_token =
nullptr;
351 dhForm->clearModified();
359 if( dhForm->getToken().empty() ) {
360 form_placement_str += std::format(
"[DB={}]", dh_token->dbID().toString());
361 dhForm->setToken( form_placement_str );
363 form_placement_str = dhForm->getToken();
366 auto b = form_placement_str.find(
"[FILE=");
367 auto e = form_placement_str.find(
"]", b);
368 form_placement_str.erase(b, e-b+1);
373 const coral::AttributeList* list = obj->getAttributeList();
374 if (list !=
nullptr) {
375 obj->setEvtRefTokenStr(dh_token->toString());
378 obj->getEvtRefTokenStr().c_str(),
380 delete ref_token; ref_token =
nullptr;
381 for (coral::AttributeList::const_iterator iter = list->begin(), last = list->end(); iter != last; ++iter) {
382 attr_placement = this->
setPlacementWithType(
"AttributeList", (*iter).specification().name(), *pAddr->par());
384 (*iter).addressOfData(),
385 RootType((*iter).specification().type()) );
386 delete attr_token; attr_token =
nullptr;
390 if (tokAddr !=
nullptr) {
391 tokAddr->
setToken(std::move(dh_token));
393 return(StatusCode::FAILURE);
395 return(StatusCode::SUCCESS);
401 void* voidPtr1 =
nullptr;
403 if (voidPtr1 ==
nullptr) {
404 throw std::runtime_error(
"Could not get object for token = " +
m_i_poolToken->toString());
408 void* voidPtr2 =
nullptr;
415 if (voidPtr2 ==
nullptr) {
416 throw std::runtime_error(
"Could not get object for token = " + mapToken.
toString());
430 void* voidPtr1 =
nullptr;
431 std::string error_message;
434 }
catch(
const std::exception& err) {
436 error_message = err.what();
438 if (voidPtr1 ==
nullptr) {
439 throw std::runtime_error(
"Could not get object for token = " +
m_i_poolToken->toString() +
", " + error_message);
443 std::string dhFormToken =
header->dhFormToken();
445 if( !dhFormToken.empty() and dhFormToken.find(
"[OID=") == std::string::npos) {
456 oid2 >>= 32; oid2 <<= 32;
459 if( !swn.empty() ) oid2 += std::stoul( swn ) - 1;
460 formToken.
setOid( {0,oid2} );
463 header->setDhFormToken( dhFormToken );
468 size_t dbpos = dhFormToken.find(
"[DB=");
469 if( dbpos != std::string::npos ) {
470 const std::string dbGuid = dhFormToken.substr(dbpos+4, dbpos+36);
478 void* voidPtr2 =
nullptr;
479 if( dhFormToken.empty() ) {
490 }
catch(
const std::exception& err) {
492 error_message = err.what();
494 if (voidPtr2 ==
nullptr) {
500 void* firstPtr1 =
nullptr;
503 }
catch(
const std::exception& err) {
505 error_message = err.what();
507 if (firstPtr1 ==
nullptr)
throw std::runtime_error(
"Could not get first DataHeader for token = " + firstToken.
toString() +
", " + error_message);
510 std::unique_ptr<DataHeader_p6> firstHeader(
reinterpret_cast<DataHeader_p6*
>(firstPtr1) );
511 dhFormToken = firstHeader->dhFormToken();
518 }
catch(
const std::exception& err) {
520 error_message = err.what();
522 if (voidPtr2 ==
nullptr)
throw std::runtime_error(
"Could not get DataHeaderForm for token = " + formToken.
toString() +
", " + error_message);
525 ATH_MSG_WARNING(
"DataHeaderForm read exception: " << error_message <<
" - reusing the last good DHForm");
528 ATH_MSG_WARNING(
"DataHeaderForm read exception: " << error_message <<
" - reusing the last good DHForm");
533 if (voidPtr2 ==
nullptr) {
534 throw std::runtime_error(
"Could not get object for token = " + formToken.
toString());
552 auto iter = dh->m_inputDataHeader.begin();
553 while( iter != dh->m_inputDataHeader.end() ) {
554 if( iter->getToken()->dbID() ==
Guid::null() ) {
556 iter = dh->m_inputDataHeader.erase(iter);
570 std::string bestPfn, fileType;
576 static const pool::Guid p6_guid(
"4DDBD295-EFCE-472A-9EC8-15CD35A9EB8D");
577 static const pool::Guid p5_guid(
"D82968A1-CF91-4320-B2DD-E0F739CBC7E6");
578 static const pool::Guid p4_guid(
"9630EB7B-CCD7-47D9-A39B-CBBF4133CDF2");
579 static const pool::Guid p3_guid(
"EC1318F0-8E28-45F8-9A2D-2597C1CC87A6");
601 }
catch (std::exception &e) {
603 std::string
error = e.what();
604 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 Guid &clid) const
virtual void setToken(const std::string &token)
virtual StatusCode initialize()
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)