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);
296 std::lock_guard<AthenaPoolConverter::CallMutex>
lock(this->
m_conv_mut);
299 ATH_MSG_ERROR(
"Failed to cast DataHeader to transient type" );
300 return(StatusCode::FAILURE);
304 std::string form_placement_str = dhf_placement.
toString();
306 std::unique_ptr<DataHeaderForm_p6>& dhForm =
m_persFormMap[form_placement_str];
307 if (dhForm ==
nullptr) {
309 dhForm = std::make_unique<DataHeaderForm_p6>();
310 dhForm->setProcessTag( obj->getProcessTag() );
316 const std::string connection = dh_placement.
fileName();
321 }
catch (std::exception &e) {
322 ATH_MSG_FATAL(
"Failed to convert DataHeader to persistent type: " << e.what());
323 return(StatusCode::FAILURE);
327 if (dh_token ==
nullptr) {
329 return(StatusCode::FAILURE);
333 m_tpOutConverter.insertDHRef(persObj, obj->getProcessTag(), dh_token->toString(), *dhForm);
336 if( dhForm->isModified() ) {
339 static const RootType dhFormType(
typeid(*dhForm));
341 if (dhf_token ==
nullptr) {
343 return(StatusCode::FAILURE);
346 dhForm->setToken(dhf_token->
toString());
348 ATH_MSG_DEBUG(
"Technology does not support setting DHF token for: " << dh_token->toString());
349 dhForm->setToken(
"");
351 ATH_MSG_DEBUG(
"wrote new DHForm with " << dhForm->sizeObj() <<
" SG object data");
352 dhf_token->
release(); dhf_token =
nullptr;
353 dhForm->clearModified();
361 if( dhForm->getToken().empty() ) {
362 form_placement_str += std::format(
"[DB={}]", dh_token->dbID().toString());
363 dhForm->setToken( form_placement_str );
365 form_placement_str = dhForm->getToken();
368 auto b = form_placement_str.find(
"[FILE=");
369 auto e = form_placement_str.find(
"]", b);
370 form_placement_str.erase(b, e-b+1);
375 const coral::AttributeList* list = obj->getAttributeList();
376 if (list !=
nullptr) {
377 static const std::string attributeListStr{
"AttributeList"};
378 obj->setEvtRefTokenStr(dh_token->toString());
381 obj->getEvtRefTokenStr().c_str(),
383 delete ref_token; ref_token =
nullptr;
384 for (coral::AttributeList::const_iterator iter = list->begin(), last = list->end(); iter != last; ++iter) {
385 attr_placement = this->
setPlacementWithType(attributeListStr, (*iter).specification().name(), *pAddr->par());
387 (*iter).addressOfData(),
388 RootType((*iter).specification().type()) );
389 delete attr_token; attr_token =
nullptr;
393 if (tokAddr !=
nullptr) {
394 tokAddr->
setToken(std::move(dh_token));
396 return(StatusCode::FAILURE);
398 return(StatusCode::SUCCESS);
404 void* voidPtr1 =
nullptr;
406 if (voidPtr1 ==
nullptr) {
407 throw std::runtime_error(
"Could not get object for token = " + token->
toString());
411 void* voidPtr2 =
nullptr;
418 if (voidPtr2 ==
nullptr) {
419 throw std::runtime_error(
"Could not get object for token = " + mapToken.
toString());
433 void* voidPtr1 =
nullptr;
434 std::string error_message;
437 }
catch(
const std::exception& err) {
439 error_message = err.what();
441 if (voidPtr1 ==
nullptr) {
442 throw std::runtime_error(
"Could not get object for token = " + token->
toString() +
", " + error_message);
446 std::string dhFormToken =
header->dhFormToken();
448 if( !dhFormToken.empty() and dhFormToken.find(
"[OID=") == std::string::npos) {
458 std::int64_t oid2 = token->
oid().second;
459 oid2 >>= 32; oid2 <<= 32;
462 if( !swn.empty() ) oid2 += std::stoul( swn ) - 1;
463 formToken.
setOid( {0,oid2} );
466 header->setDhFormToken( dhFormToken );
471 size_t dbpos = dhFormToken.find(
"[DB=");
472 if( dbpos != std::string::npos ) {
473 const std::string dbGuid = dhFormToken.substr(dbpos+4, dbpos+36);
481 void* voidPtr2 =
nullptr;
482 if( dhFormToken.empty() ) {
493 }
catch(
const std::exception& err) {
495 error_message = err.what();
497 if (voidPtr2 ==
nullptr) {
503 void* firstPtr1 =
nullptr;
506 }
catch(
const std::exception& err) {
508 error_message = err.what();
510 if (firstPtr1 ==
nullptr)
throw std::runtime_error(
"Could not get first DataHeader for token = " + firstToken.
toString() +
", " + error_message);
513 std::unique_ptr<DataHeader_p6> firstHeader(
reinterpret_cast<DataHeader_p6*
>(firstPtr1) );
514 dhFormToken = firstHeader->dhFormToken();
521 }
catch(
const std::exception& err) {
523 error_message = err.what();
525 if (voidPtr2 ==
nullptr)
throw std::runtime_error(
"Could not get DataHeaderForm for token = " + formToken.
toString() +
", " + error_message);
528 ATH_MSG_WARNING(
"DataHeaderForm read exception: " << error_message <<
" - reusing the last good DHForm");
531 ATH_MSG_WARNING(
"DataHeaderForm read exception: " << error_message <<
" - reusing the last good DHForm");
536 if (voidPtr2 ==
nullptr) {
537 throw std::runtime_error(
"Could not get object for token = " + formToken.
toString());
557 if( iter->getToken()->dbID() ==
Guid::null() ) {
568 if (token ==
nullptr) {
573 std::string bestPfn, fileType;
579 static const pool::Guid p6_guid(
"4DDBD295-EFCE-472A-9EC8-15CD35A9EB8D");
580 static const pool::Guid p5_guid(
"D82968A1-CF91-4320-B2DD-E0F739CBC7E6");
581 static const pool::Guid p4_guid(
"9630EB7B-CCD7-47D9-A39B-CBBF4133CDF2");
582 static const pool::Guid p3_guid(
"EC1318F0-8E28-45F8-9A2D-2597C1CC87A6");
604 }
catch (std::exception &e) {
606 std::string
error = e.what();
607 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)
virtual void lock()=0
Interface to allow an object to lock itself when made const in SG.
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 std::ostringstream errmsg
ServiceHandle< IAthenaPoolCnvSvc > m_athenaPoolCnvSvc
virtual Placement setPlacementWithType(const std::string &tname, const std::string &key, const std::string &output)
static const Guid & null() noexcept
NULL-Guid: static class method.
constexpr void toString(std::span< char, StrLen > buf, bool uppercase=true) const noexcept
Automatic conversion to string representation.
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.
const std::string & auxString() const
Access auxiliary string.
Token & setCont(const std::string &cnt)
Set container name.
const Token & setData(Token *pToken) const
Set all the data part of the token.
Token & setAuxString(const std::string &auxString)
Set auxiliary string.
Token & setDb(const Guid &db)
Set database name.
const std::string & contID() const
Access container identifier.
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.
const Guid & dbID() const
Access database identifier.
bool fromStorable(DataObject *pDObj, T *&pTrans, bool quiet=false, IRegisterTransient *irt=0, bool isConst=true)
static constexpr CLID ID()