12 #include "GaudiKernel/AttribStringParser.h"
13 #include "GaudiKernel/ClassID.h"
14 #include "GaudiKernel/FileIncident.h"
15 #include "GaudiKernel/IIncidentSvc.h"
16 #include "GaudiKernel/IIoComponentMgr.h"
17 #include "GaudiKernel/IOpaqueAddress.h"
41 StringProperty defContainerType(
"DefaultContainerType",
"ROOTTREEINDEX");
42 if(IProperty* propertyServer =
dynamic_cast<IProperty*
>(
m_poolSvc.get())) {
43 propertyServer->getProperty(&defContainerType).ignore();
51 if (!iomgr->io_register(
this).isSuccess()) {
52 ATH_MSG_FATAL(
"Could not register myself with the IoComponentMgr !");
53 return(StatusCode::FAILURE);
57 if (
auto p = maxFileSizeSpec.find(
'=');
p != std::string::npos) {
58 long long maxFileSize = 0;
59 const char*
start = maxFileSizeSpec.data() + (
p + 1);
60 const char*
end = maxFileSizeSpec.data() + maxFileSizeSpec.size();
61 if (
auto [
ptr, ec] = std::from_chars(
start,
end, maxFileSize); ec != std::errc{}) {
64 std::string databaseName = maxFileSizeSpec.substr(0, maxFileSizeSpec.find_first_of(
" ="));
67 if (
auto [
ptr, ec] = std::from_chars(maxFileSizeSpec.data(), maxFileSizeSpec.data() + maxFileSizeSpec.size(),
m_domainMaxFileSize); ec != std::errc{}) {
76 if (dbType == pool::TEST_StorageType) {
78 return StatusCode::FAILURE;
83 return StatusCode::FAILURE;
86 return StatusCode::FAILURE;
98 incSvc->addListener(
this,
"EndEvent", pri);
99 ATH_MSG_DEBUG(
"Subscribed to EndEvent for printing out input file attributes.");
102 ATH_MSG_DEBUG(
"setInputAttribute failed setting POOL domain attributes.");
107 TClass::GetClass (
"TLeafI");
108 TClass::GetClass (
"TLeafL");
109 TClass::GetClass (
"TLeafD");
110 TClass::GetClass (
"TLeafF");
112 return(StatusCode::SUCCESS);
118 return(StatusCode::SUCCESS);
124 FileIncident incident(
name(),
"WriteDataHeaderForms",
streamName);
125 if( DHCnvListener ) DHCnvListener->handle(incident);
132 return StatusCode::SUCCESS;
149 const std::string msgPrefix{
"PerfStats "};
151 ATH_MSG_INFO(msgPrefix <<
"Timing Measurements for AthenaPoolCnvSvc");
154 ATH_MSG_INFO(msgPrefix <<
"| " << std::left << std::setw(15) <<
key <<
" | "
155 << std::right << std::setw(15) << std::fixed << std::setprecision(0) <<
value <<
" ms |");
160 m_cnvs.shrink_to_fit();
161 return(StatusCode::SUCCESS);
166 return(StatusCode::SUCCESS);
171 std::string objName =
"ALL";
173 if (
m_clidSvc->getTypeNameOfID(pAddress->clID(), objName).isFailure()) {
177 objName += *(pAddress->par() + 1);
184 const unsigned int maxContext =
m_poolSvc->getInputContextMap().size();
187 const std::string contextStr =
std::format(
"[CTXT={:08X}]", auxContext);
188 std::strncpy(
text, contextStr.c_str(),
sizeof(
text) - 1);
190 if (
m_poolSvc->getInputContextMap().size() > maxContext) {
192 ATH_MSG_DEBUG(
"setInputAttribute failed to switch off TTreeCache for id = " << auxContext <<
".");
205 std::string objName =
"ALL";
207 if (
m_clidSvc->getTypeNameOfID(pObject->clID(), objName).isFailure()) {
211 objName += pObject->registry()->name();
216 if (pObject->clID() == 1) {
219 if (
proxy !=
nullptr) {
220 IConverter* cnv = converter(
proxy->clID());
221 status = cnv->createRep(pObject, refpAddress);
227 }
catch(std::runtime_error&
e) {
236 std::string objName =
"ALL";
238 if (
m_clidSvc->getTypeNameOfID(pObject->clID(), objName).isFailure()) {
242 objName += pObject->registry()->name();
247 if (pObject->clID() == 1) {
250 if (
proxy !=
nullptr) {
251 IConverter* cnv = converter(
proxy->clID());
252 status = cnv->fillRepRefs(pAddress, pObject);
258 }
catch(std::runtime_error&
e) {
266 const std::string& ) {
272 std::string outputConnection = outputConnectionSpec.substr(0, outputConnectionSpec.find(
'['));
276 ATH_MSG_ERROR(
"connectOutput FAILED extract file name and technology.");
277 return(StatusCode::FAILURE);
282 ATH_MSG_ERROR(
"connectOutput FAILED to open an UPDATE transaction.");
283 return(StatusCode::FAILURE);
287 return(StatusCode::FAILURE);
292 std::size_t
merge = outputConnection.find(
"?pmerge=");
296 std::vector<std::string> maxFileSize;
297 maxFileSize.push_back(
"TREE_MAX_SIZE");
298 maxFileSize.push_back(
"1099511627776L");
304 const std::string&
opt = dbAttrEntry[0];
305 std::string&
data = dbAttrEntry[1];
306 const std::string&
file = dbAttrEntry[2];
307 const std::string& cont = dbAttrEntry[3];
308 std::size_t
equal = cont.find(
'=');
312 std::size_t colon =
prefix.find(
':');
313 if (colon == std::string::npos) colon = 0;
316 const auto& strProp = (
prefix ==
"Default") ? defaultContName :
prefix;
317 if (
merge != std::string::npos &&
opt ==
"TREE_AUTO_FLUSH" && 0 == outputConnection.compare(0,
merge,
file) &&cont.compare(
equal, std::string::npos, strProp, colon) == 0 &&
data !=
"int" &&
data !=
"DbLonglong" &&
data !=
"double" &&
data !=
"string") {
327 if (
merge != std::string::npos) {
328 ATH_MSG_INFO(
"connectOutput setting auto write for: " << outputConnection <<
" to " <<
flush <<
" events");
333 ATH_MSG_DEBUG(
"connectOutput failed process POOL domain attributes.");
336 ATH_MSG_DEBUG(
"connectOutput failed process POOL database attributes.");
338 return(StatusCode::SUCCESS);
344 std::string outputConnection = outputConnectionSpec.substr(0, outputConnectionSpec.find(
'['));
351 ATH_MSG_ERROR(
"connectOutput FAILED extract file name and technology.");
352 return(StatusCode::FAILURE);
356 ATH_MSG_DEBUG(
"commitOutput failed process POOL domain attributes.");
359 ATH_MSG_DEBUG(
"commitOutput failed process POOL database attributes.");
362 ATH_MSG_DEBUG(
"commitOutput failed process POOL container attributes.");
364 std::size_t
merge = outputConnection.find(
"?pmerge=");
365 const std::string baseOutputConnection = outputConnection.substr(0,
merge);
375 if (!
m_poolSvc->commit(contextId).isSuccess()) {
376 ATH_MSG_ERROR(
"commitOutput FAILED to commit OutputStream.");
377 return(StatusCode::FAILURE);
380 if (!
m_poolSvc->commitAndHold(contextId).isSuccess()) {
381 ATH_MSG_ERROR(
"commitOutput FAILED to commitAndHold OutputStream.");
382 return(StatusCode::FAILURE);
387 return(StatusCode::FAILURE);
389 if (!this->
cleanUp(baseOutputConnection).isSuccess()) {
391 return(StatusCode::FAILURE);
394 long long int currentFileSize =
m_poolSvc->getFileSize(outputConnection, tech, contextId);
398 return(StatusCode::RECOVERABLE);
402 return(StatusCode::RECOVERABLE);
404 return(StatusCode::SUCCESS);
409 std::string outputConnection = outputConnectionSpec.substr(0, outputConnectionSpec.find(
'['));
429 Token* token =
nullptr;
433 std::strncpy(
text, contextStr.c_str(),
sizeof(
text) - 1);
437 token =
m_poolSvc->registerForWrite(placement,
obj, classDesc);
457 const std::string*
par,
458 const unsigned long*
ip,
459 IOpaqueAddress*& refpAddress) {
460 if( svcType != repSvcType() ) {
461 ATH_MSG_ERROR(
"createAddress: svcType != POOL_StorageType " << svcType <<
" " << repSvcType());
462 return(StatusCode::FAILURE);
464 std::unique_ptr<Token> token;
466 token = std::make_unique<Token>();
474 if (token ==
nullptr) {
475 return(StatusCode::RECOVERABLE);
478 return(StatusCode::SUCCESS);
483 const std::string& refAddress,
484 IOpaqueAddress*& refpAddress) {
485 if (svcType != repSvcType()) {
486 ATH_MSG_ERROR(
"createAddress: svcType != POOL_StorageType " << svcType <<
" " << repSvcType());
487 return(StatusCode::FAILURE);
489 refpAddress =
new GenericAddress(repSvcType(), clid, refAddress);
490 return(StatusCode::SUCCESS);
494 std::string& refAddress) {
497 if (tokAddr !=
nullptr && tokAddr->
getToken() !=
nullptr) {
500 refAddress = *pAddress->par();
502 return(StatusCode::SUCCESS);
506 if (fileSpec.starts_with (
"ROOTKEY:")) {
507 outputTech = pool::ROOTKEY_StorageType.
type();
508 fileSpec.erase(0, 8);
509 }
else if (fileSpec.starts_with (
"ROOTTREE:")) {
510 outputTech = pool::ROOTTREE_StorageType.
type();
511 fileSpec.erase(0, 9);
512 }
else if (fileSpec.starts_with (
"ROOTTREEINDEX:")) {
513 outputTech = pool::ROOTTREEINDEX_StorageType.
type();
514 fileSpec.erase(0, 14);
515 }
else if (fileSpec.starts_with (
"ROOTRNTUPLE:")) {
516 outputTech = pool::ROOTRNTUPLE_StorageType.
type();
517 fileSpec.erase(0, 12);
518 }
else if (outputTech == 0) {
521 if (
auto pos = fileSpec.find(
"?pmerge=");
pos != std::string::npos) {
530 outputTech =
it->second;
532 outputTech =
it->second;
537 return StatusCode::SUCCESS;
541 m_cnvs.push_back(cnv);
542 return(StatusCode::SUCCESS);
546 bool retError =
false;
547 std::size_t cpos = connection.find(
':');
548 std::size_t bpos = connection.find(
'[');
549 if (cpos == std::string::npos) {
554 if (bpos != std::string::npos) bpos = bpos - cpos;
555 const std::string
conn = connection.substr(cpos, bpos);
557 for (
auto converter : m_cnvs) {
558 if (!converter->cleanUp(
conn).isSuccess()) {
563 return(retError ? StatusCode::FAILURE : StatusCode::SUCCESS);
570 ATH_MSG_DEBUG(
"setInputAttribute failed setting POOL database/container attributes.");
573 ATH_MSG_DEBUG(
"setInputAttribute failed getting POOL database/container attributes.");
577 const auto& extraInputContextMap =
m_poolSvc->getInputContextMap();
578 for (
const auto& [
label,
id]: extraInputContextMap) {
580 ATH_MSG_DEBUG(
"setInputAttribute failed to switch off TTreeCache for = " <<
label <<
".");
584 return(StatusCode::SUCCESS);
589 if (incident.type() ==
"EndEvent") {
591 ATH_MSG_DEBUG(
"handle EndEvent failed process POOL database attributes.");
597 base_class(
name, pSvcLocator,
pool::POOL_StorageType.
type()) {
601 std::vector<std::vector<std::string> >* contAttr,
602 std::vector<std::vector<std::string> >* dbAttr,
603 std::vector<std::vector<std::string> >* domAttr)
const {
604 std::vector<std::string>
opt;
605 std::string attributeName, containerName, databaseName, valueString;
606 for (
const auto& propertyValue : property.value()) {
608 attributeName.clear();
609 containerName.clear();
610 databaseName.clear();
612 using Gaudi::Utils::AttribStringParser;
613 for (
const AttribStringParser::Attrib& attrib : AttribStringParser (propertyValue)) {
614 const std::string
tag = attrib.tag;
615 const std::string
val = attrib.value;
616 if (
tag ==
"DatabaseName") {
617 databaseName = std::move(
val);
618 }
else if (
tag ==
"ContainerName") {
619 if (databaseName.empty()) {
622 containerName = std::move(
val);
624 attributeName = std::move(
tag);
625 valueString = std::move(
val);
628 if (!attributeName.empty() && !valueString.empty()) {
629 opt.push_back(attributeName);
630 opt.push_back(valueString);
631 if (!databaseName.empty()) {
632 opt.push_back(databaseName);
633 if (!containerName.empty()) {
634 opt.push_back(containerName);
635 if (containerName.compare(0, 6,
"TTree=") == 0) {
636 dbAttr->push_back(
opt);
638 contAttr->push_back(
opt);
642 dbAttr->push_back(
opt);
644 }
else if (domAttr != 0) {
645 domAttr->push_back(
opt);
649 dbAttr->push_back(
opt);
657 unsigned long contextId,
660 bool doClear)
const {
661 bool retError =
false;
662 for (
auto& attrEntry : attr) {
663 if (attrEntry.size() == 2) {
664 const std::string&
opt = attrEntry[0];
665 std::string
data = attrEntry[1];
666 if (
data ==
"int" ||
data ==
"DbLonglong" ||
data ==
"double" ||
data ==
"string") {
685 if (attrEntry.size() == 4) {
686 const std::string&
opt = attrEntry[0];
687 std::string
data = attrEntry[1];
688 const std::string&
file = attrEntry[2];
689 const std::string& cont = attrEntry[3];
691 || (
file[0] ==
'*' &&
file.find(
"," +
fileName +
",") == std::string::npos))) {
692 if (
data ==
"int" ||
data ==
"DbLonglong" ||
data ==
"double" ||
data ==
"string") {
704 attrEntry[2] +=
"," +
fileName +
",";
717 std::erase_if(attr, [](
const auto&
entry) {
return entry.empty(); });
718 return(retError ? StatusCode::FAILURE : StatusCode::SUCCESS);