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");
58 bool doFilterDHAliases =
true;
59 const std::string svcName = (serviceLocator()->existsService(
"AthenaPoolSharedIOCnvSvc") ?
"AthenaPoolSharedIOCnvSvc" :
"AthenaPoolCnvSvc");
60 SmartIF<IProperty> cnvSvc{service(svcName,
false)};
63 if( cnvSvc->getProperty(&sizeProp).isSuccess() ) {
66 BooleanProperty aliasFilterProp(
"doFilterDHAliases", doFilterDHAliases);
67 if( cnvSvc->getProperty(&aliasFilterProp).isSuccess() ) {
68 doFilterDHAliases = aliasFilterProp.value();
70 BooleanProperty oneDHForm(
"OneDataHeaderForm",
m_oneDHForm);
71 if( cnvSvc->getProperty(&oneDHForm).isSuccess() ) {
76 if( doFilterDHAliases ) {
87 incSvc->addListener(
this, IncidentType::EndInputFile, 0);
88 incSvc->addListener(
this,
"PreFork", 0);
90 incSvc->addListener(
this,
"WriteDataHeaderForms", 0);
97 if( incident.type() ==
"PreFork" ) {
100 if( incident.type() == IncidentType::EndInputFile ) {
102 const std::string& guid =
static_cast<const FileIncident&
>(incident).fileGuid();
105 if( incident.type() ==
"WriteDataHeaderForms" ) {
107 const std::string& fileName =
static_cast<const FileIncident*
>(&incident)->fileName();
109 std::vector<std::string> toWrite;
110 auto pos = fileName.find(
"[OutputCollection=MetaDataHdr]");
111 bool metaDataCommit = (pos != std::string::npos);
112 std::string justFileName = fileName.substr(0, pos);
113 ATH_MSG_DEBUG(
"Handling WriteDataHeaderForms incident for stream: " << fileName);
116 const std::string& placementStr = elem.first;
120 if( formPlacement.
fileName() == justFileName or fileName ==
"*" ) {
122 if( (placementStr.find(
"[CONT=MetaData") != std::string::npos) == metaDataCommit ) {
123 toWrite.push_back( placementStr );
128 for( std::size_t n = 0;
const std::string& placementStr : toWrite ) {
132 if( form_ptr->isModified() ) {
133 static const RootType dhFormType(
typeid( *form_ptr ) );
137 std::string
errmsg = std::format(
"Failed to write {} {}", dhFormType.
Name(), placementStr);
139 throw GaudiException(std::move(
errmsg),
"DataHeaderCnv::WriteDataHeaderForms", StatusCode::FAILURE);
141 ATH_MSG_DEBUG(
"Wrote DatHeaderForm, placeemnt was " << placementStr <<
" token=" << form_token->
toString());
142 form_token->
release(); form_token =
nullptr;
143 bool doCommit = (++n == toWrite.size());
144 const std::string connection = ( fileName!=
"*"? fileName : formPlacement.
fileName() );
146 throw GaudiException(
"WriteDataHeaderForms failed",
"DataHeaderCnv::WriteDataHeaderForms", StatusCode::FAILURE);
159 size_t dbpos = iter->first.find(
"[DB=");
160 if( dbpos != std::string::npos && iter->first.compare(dbpos+4, dbpos+36, dbGuid) == 0 ) {
172 auto start =
str.find(key);
173 if( start == std::string::npos )
176 auto end =
str.find(
"]", start);
177 return str.substr(start, end-start);
186 return std::format(
"[{}={}]", key, val);
198 if( lval != rval )
return lval < rval;
202 if( lval.empty() or rval.empty() )
return false;
203 return std::stoul( lval ) < std::stoul( rval );
217 auto dataHeader =
reinterpret_cast<DataHeader_p6*
>( pObject );
218 const std::string dhRef = pAddress->par()[0];
219 const std::string dhPlacementStr = pAddress->par()[1];
222 dhFormPlacement.
fromString( dataHeader->dhFormToken() );
225 if( !clientN.empty() ) {
229 dataHeader->setDhFormToken( dhFormNewRef );
237 ATH_MSG_ERROR(
"updateRep called but the previous DataHeader was not yet processed."
240 return StatusCode::FAILURE;
245 std::size_t tagBeg = dhPlacementStr.find(
"[KEY=") + 5;
246 std::size_t tagSize = dhPlacementStr.find(
']', tagBeg) - tagBeg;
249 return StatusCode::SUCCESS;
263 std::string dhid = pAddress->par()[1];
268 ATH_MSG_ERROR(
"updateRepRefs called without DataHeaderForm" );
269 return StatusCode::FAILURE;
277 ATH_MSG_ERROR(
"updateRepRefs: missing DataHeaderForm for DH ID=" << dhid );
278 return StatusCode::FAILURE;
291 return(StatusCode::SUCCESS);
297 std::lock_guard<AthenaPoolConverter::CallMutex>
lock(this->
m_conv_mut);
300 ATH_MSG_ERROR(
"Failed to cast DataHeader to transient type" );
301 return(StatusCode::FAILURE);
305 std::string form_placement_str = dhf_placement.
toString();
307 std::unique_ptr<DataHeaderForm_p6>& dhForm =
m_persFormMap[form_placement_str];
308 if (dhForm ==
nullptr) {
310 dhForm = std::make_unique<DataHeaderForm_p6>();
311 dhForm->setProcessTag( obj->getProcessTag() );
317 const std::string connection = dh_placement.
fileName();
322 }
catch (std::exception &e) {
323 ATH_MSG_FATAL(
"Failed to convert DataHeader to persistent type: " << e.what());
324 return(StatusCode::FAILURE);
328 if (dh_token ==
nullptr) {
330 return(StatusCode::FAILURE);
334 m_tpOutConverter.insertDHRef(persObj, obj->getProcessTag(), dh_token->toString(), *dhForm);
337 if( dhForm->isModified() ) {
340 static const RootType dhFormType(
typeid(*dhForm));
342 if (dhf_token ==
nullptr) {
344 return(StatusCode::FAILURE);
347 dhForm->setToken(dhf_token->
toString());
349 ATH_MSG_DEBUG(
"Technology does not support setting DHF token for: " << dh_token->toString());
350 dhForm->setToken(
"");
352 ATH_MSG_DEBUG(
"wrote new DHForm with " << dhForm->sizeObj() <<
" SG object data");
353 dhf_token->
release(); dhf_token =
nullptr;
354 dhForm->clearModified();
362 if( dhForm->getToken().empty() ) {
363 form_placement_str += std::format(
"[DB={}]", dh_token->dbID().toString());
364 dhForm->setToken( form_placement_str );
366 form_placement_str = dhForm->getToken();
369 auto b = form_placement_str.find(
"[FILE=");
370 auto e = form_placement_str.find(
"]", b);
371 form_placement_str.erase(b, e-b+1);
376 const coral::AttributeList* list = obj->getAttributeList();
377 if (list !=
nullptr) {
378 static const std::string attributeListStr{
"AttributeList"};
379 obj->setEvtRefTokenStr(dh_token->toString());
382 obj->getEvtRefTokenStr().c_str(),
384 delete ref_token; ref_token =
nullptr;
385 for (coral::AttributeList::const_iterator iter = list->begin(), last = list->end(); iter != last; ++iter) {
386 attr_placement = this->
setPlacementWithType(attributeListStr, (*iter).specification().name(), *pAddr->par());
388 (*iter).addressOfData(),
389 RootType((*iter).specification().type()) );
390 delete attr_token; attr_token =
nullptr;
394 if (tokAddr !=
nullptr) {
395 tokAddr->
setToken(std::move(dh_token));
397 return(StatusCode::FAILURE);
399 return(StatusCode::SUCCESS);
405 void* voidPtr1 =
nullptr;
407 if (voidPtr1 ==
nullptr) {
408 throw std::runtime_error(
"Could not get object for token = " + token->
toString());
412 void* voidPtr2 =
nullptr;
419 if (voidPtr2 ==
nullptr) {
420 throw std::runtime_error(
"Could not get object for token = " + mapToken.
toString());
434 void* voidPtr1 =
nullptr;
435 std::string error_message;
438 }
catch(
const std::exception& err) {
440 error_message = err.what();
442 if (voidPtr1 ==
nullptr) {
443 throw std::runtime_error(
"Could not get object for token = " + token->
toString() +
", " + error_message);
447 std::string dhFormToken =
header->dhFormToken();
449 if( !dhFormToken.empty() and dhFormToken.find(
"[OID=") == std::string::npos) {
459 std::int64_t oid2 = token->
oid().second;
460 oid2 >>= 32; oid2 <<= 32;
463 if( !swn.empty() ) oid2 += std::stoul( swn ) - 1;
464 formToken.
setOid( {0,oid2} );
467 header->setDhFormToken( dhFormToken );
472 size_t dbpos = dhFormToken.find(
"[DB=");
473 if( dbpos != std::string::npos ) {
474 const std::string dbGuid = dhFormToken.substr(dbpos+4, dbpos+36);
482 void* voidPtr2 =
nullptr;
483 if( dhFormToken.empty() ) {
494 }
catch(
const std::exception& err) {
496 error_message = err.what();
498 if (voidPtr2 ==
nullptr) {
504 void* firstPtr1 =
nullptr;
507 }
catch(
const std::exception& err) {
509 error_message = err.what();
511 if (firstPtr1 ==
nullptr)
throw std::runtime_error(
"Could not get first DataHeader for token = " + firstToken.
toString() +
", " + error_message);
514 std::unique_ptr<DataHeader_p6> firstHeader(
reinterpret_cast<DataHeader_p6*
>(firstPtr1) );
515 dhFormToken = firstHeader->dhFormToken();
522 }
catch(
const std::exception& err) {
524 error_message = err.what();
526 if (voidPtr2 ==
nullptr)
throw std::runtime_error(
"Could not get DataHeaderForm for token = " + formToken.
toString() +
", " + error_message);
529 ATH_MSG_WARNING(
"DataHeaderForm read exception: " << error_message <<
" - reusing the last good DHForm");
532 ATH_MSG_WARNING(
"DataHeaderForm read exception: " << error_message <<
" - reusing the last good DHForm");
537 if (voidPtr2 ==
nullptr) {
538 throw std::runtime_error(
"Could not get object for token = " + formToken.
toString());
558 if( iter->getToken()->dbID() ==
Guid::null() ) {
569 if (token ==
nullptr) {
574 std::string bestPfn, fileType;
580 static const Guid p6_guid(
"4DDBD295-EFCE-472A-9EC8-15CD35A9EB8D");
581 static const Guid p5_guid(
"D82968A1-CF91-4320-B2DD-E0F739CBC7E6");
582 static const Guid p4_guid(
"9630EB7B-CCD7-47D9-A39B-CBBF4133CDF2");
583 static const Guid p3_guid(
"EC1318F0-8E28-45F8-9A2D-2597C1CC87A6");
605 }
catch (std::exception &e) {
607 std::string
error = e.what();
608 throw std::runtime_error(
error);
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_VERBOSE(x,...)
#define ATH_MSG_FATAL(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)
This class provides a encapsulation of a GUID/UUID/CLSID/IID data structure (128 bit number).
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 & 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.
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.
Token & setAuxString(std::string &&auxString)
Set auxiliary string.
bool fromStorable(DataObject *pDObj, T *&pTrans, bool quiet=false, IRegisterTransient *irt=0, bool isConst=true)
static constexpr CLID ID()