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"
46 if (!iomgr->io_register(
this).isSuccess()) {
47 ATH_MSG_FATAL(
"Could not register myself with the IoComponentMgr !");
48 return(StatusCode::FAILURE);
52 if (
auto p = maxFileSizeSpec.find(
'=');
p != std::string::npos) {
53 long long maxFileSize = 0;
54 const char*
start = maxFileSizeSpec.data() + (
p + 1);
55 const char*
end = maxFileSizeSpec.data() + maxFileSizeSpec.size();
56 if (
auto [
ptr, ec] = std::from_chars(
start,
end, maxFileSize); ec != std::errc{}) {
59 std::string databaseName = maxFileSizeSpec.substr(0, maxFileSizeSpec.find_first_of(
" ="));
62 if (
auto [
ptr, ec] = std::from_chars(maxFileSizeSpec.data(), maxFileSizeSpec.data() + maxFileSizeSpec.size(),
m_domainMaxFileSize); ec != std::errc{}) {
71 if (dbType == pool::TEST_StorageType) {
73 return StatusCode::FAILURE;
78 return StatusCode::FAILURE;
81 return StatusCode::FAILURE;
93 incSvc->addListener(
this,
"EndEvent", pri);
94 ATH_MSG_DEBUG(
"Subscribed to EndEvent for printing out input file attributes.");
97 ATH_MSG_DEBUG(
"setInputAttribute failed setting POOL domain attributes.");
102 TClass::GetClass (
"TLeafI");
103 TClass::GetClass (
"TLeafL");
104 TClass::GetClass (
"TLeafD");
105 TClass::GetClass (
"TLeafF");
107 return(StatusCode::SUCCESS);
113 return(StatusCode::SUCCESS);
119 FileIncident incident(
name(),
"WriteDataHeaderForms",
streamName);
120 if( DHCnvListener ) DHCnvListener->handle(incident);
127 return StatusCode::SUCCESS;
144 const std::string msgPrefix{
"PerfStats "};
146 ATH_MSG_INFO(msgPrefix <<
"Timing Measurements for AthenaPoolCnvSvc");
149 ATH_MSG_INFO(msgPrefix <<
"| " << std::left << std::setw(15) <<
key <<
" | "
150 << std::right << std::setw(15) << std::fixed << std::setprecision(0) <<
value <<
" ms |");
155 m_cnvs.shrink_to_fit();
156 return(StatusCode::SUCCESS);
161 return(StatusCode::SUCCESS);
166 std::string objName =
"ALL";
168 if (
m_clidSvc->getTypeNameOfID(pAddress->clID(), objName).isFailure()) {
172 objName += *(pAddress->par() + 1);
179 const unsigned int maxContext =
m_poolSvc->getInputContextMap().size();
182 const std::string contextStr =
std::format(
"[CTXT={:08X}]", auxContext);
183 std::strncpy(
text, contextStr.c_str(),
sizeof(
text) - 1);
185 if (
m_poolSvc->getInputContextMap().size() > maxContext) {
187 ATH_MSG_DEBUG(
"setInputAttribute failed to switch off TTreeCache for id = " << auxContext <<
".");
200 std::string objName =
"ALL";
202 if (
m_clidSvc->getTypeNameOfID(pObject->clID(), objName).isFailure()) {
206 objName += pObject->registry()->name();
211 if (pObject->clID() == 1) {
214 if (
proxy !=
nullptr) {
215 IConverter* cnv = converter(
proxy->clID());
216 status = cnv->createRep(pObject, refpAddress);
222 }
catch(std::runtime_error&
e) {
231 std::string objName =
"ALL";
233 if (
m_clidSvc->getTypeNameOfID(pObject->clID(), objName).isFailure()) {
237 objName += pObject->registry()->name();
242 if (pObject->clID() == 1) {
245 if (
proxy !=
nullptr) {
246 IConverter* cnv = converter(
proxy->clID());
247 status = cnv->fillRepRefs(pAddress, pObject);
253 }
catch(std::runtime_error&
e) {
261 const std::string& ) {
267 std::string outputConnection = outputConnectionSpec.substr(0, outputConnectionSpec.find(
'['));
271 ATH_MSG_ERROR(
"connectOutput FAILED extract file name and technology.");
272 return(StatusCode::FAILURE);
277 ATH_MSG_ERROR(
"connectOutput FAILED to open an UPDATE transaction.");
278 return(StatusCode::FAILURE);
282 return(StatusCode::FAILURE);
287 std::size_t
merge = outputConnection.find(
"?pmerge=");
291 std::vector<std::string> maxFileSize;
292 maxFileSize.push_back(
"TREE_MAX_SIZE");
293 maxFileSize.push_back(
"1099511627776L");
299 const std::string&
opt = dbAttrEntry[0];
300 std::string&
data = dbAttrEntry[1];
301 const std::string&
file = dbAttrEntry[2];
302 const std::string& cont = dbAttrEntry[3];
303 std::size_t
equal = cont.find(
'=');
307 if (colon == std::string::npos) colon = 0;
310 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") {
320 if (
merge != std::string::npos) {
321 ATH_MSG_INFO(
"connectOutput setting auto write for: " << outputConnection <<
" to " <<
flush <<
" events");
326 ATH_MSG_DEBUG(
"connectOutput failed process POOL domain attributes.");
329 ATH_MSG_DEBUG(
"connectOutput failed process POOL database attributes.");
331 return(StatusCode::SUCCESS);
337 std::string outputConnection = outputConnectionSpec.substr(0, outputConnectionSpec.find(
'['));
344 ATH_MSG_ERROR(
"connectOutput FAILED extract file name and technology.");
345 return(StatusCode::FAILURE);
349 ATH_MSG_DEBUG(
"commitOutput failed process POOL domain attributes.");
352 ATH_MSG_DEBUG(
"commitOutput failed process POOL database attributes.");
355 ATH_MSG_DEBUG(
"commitOutput failed process POOL container attributes.");
357 std::size_t
merge = outputConnection.find(
"?pmerge=");
358 const std::string baseOutputConnection = outputConnection.substr(0,
merge);
368 if (!
m_poolSvc->commit(contextId).isSuccess()) {
369 ATH_MSG_ERROR(
"commitOutput FAILED to commit OutputStream.");
370 return(StatusCode::FAILURE);
373 if (!
m_poolSvc->commitAndHold(contextId).isSuccess()) {
374 ATH_MSG_ERROR(
"commitOutput FAILED to commitAndHold OutputStream.");
375 return(StatusCode::FAILURE);
380 return(StatusCode::FAILURE);
382 if (!this->
cleanUp(baseOutputConnection).isSuccess()) {
384 return(StatusCode::FAILURE);
387 long long int currentFileSize =
m_poolSvc->getFileSize(outputConnection, tech, contextId);
391 return(StatusCode::RECOVERABLE);
395 return(StatusCode::RECOVERABLE);
397 return(StatusCode::SUCCESS);
402 std::string outputConnection = outputConnectionSpec.substr(0, outputConnectionSpec.find(
'['));
422 Token* token =
nullptr;
426 std::strncpy(
text, contextStr.c_str(),
sizeof(
text) - 1);
430 token =
m_poolSvc->registerForWrite(placement,
obj, classDesc);
450 const std::string*
par,
451 const unsigned long*
ip,
452 IOpaqueAddress*& refpAddress) {
453 if( svcType != repSvcType() ) {
454 ATH_MSG_ERROR(
"createAddress: svcType != POOL_StorageType " << svcType <<
" " << repSvcType());
455 return(StatusCode::FAILURE);
457 std::unique_ptr<Token> token;
459 token = std::make_unique<Token>();
467 if (token ==
nullptr) {
468 return(StatusCode::RECOVERABLE);
471 return(StatusCode::SUCCESS);
476 const std::string& refAddress,
477 IOpaqueAddress*& refpAddress) {
478 if (svcType != repSvcType()) {
479 ATH_MSG_ERROR(
"createAddress: svcType != POOL_StorageType " << svcType <<
" " << repSvcType());
480 return(StatusCode::FAILURE);
482 refpAddress =
new GenericAddress(repSvcType(), clid, refAddress);
483 return(StatusCode::SUCCESS);
487 std::string& refAddress) {
490 if (tokAddr !=
nullptr && tokAddr->
getToken() !=
nullptr) {
493 refAddress = *pAddress->par();
495 return(StatusCode::SUCCESS);
499 if (fileSpec.starts_with (
"ROOTKEY:")) {
500 outputTech = pool::ROOTKEY_StorageType.
type();
501 fileSpec.erase(0, 8);
502 }
else if (fileSpec.starts_with (
"ROOTTREE:")) {
503 outputTech = pool::ROOTTREE_StorageType.
type();
504 fileSpec.erase(0, 9);
505 }
else if (fileSpec.starts_with (
"ROOTTREEINDEX:")) {
506 outputTech = pool::ROOTTREEINDEX_StorageType.
type();
507 fileSpec.erase(0, 14);
508 }
else if (fileSpec.starts_with (
"ROOTRNTUPLE:")) {
509 outputTech = pool::ROOTRNTUPLE_StorageType.
type();
510 fileSpec.erase(0, 12);
511 }
else if (outputTech == 0) {
514 if (
auto pos = fileSpec.find(
"?pmerge=");
pos != std::string::npos) {
523 outputTech =
it->second;
525 outputTech =
it->second;
527 outputTech = pool::ROOTTREEINDEX_StorageType.
type();
530 return StatusCode::SUCCESS;
534 m_cnvs.push_back(cnv);
535 return(StatusCode::SUCCESS);
539 bool retError =
false;
540 std::size_t cpos = connection.find(
':');
541 std::size_t bpos = connection.find(
'[');
542 if (cpos == std::string::npos) {
547 if (bpos != std::string::npos) bpos = bpos - cpos;
548 const std::string
conn = connection.substr(cpos, bpos);
550 for (
auto converter : m_cnvs) {
551 if (!converter->cleanUp(
conn).isSuccess()) {
556 return(retError ? StatusCode::FAILURE : StatusCode::SUCCESS);
563 ATH_MSG_DEBUG(
"setInputAttribute failed setting POOL database/container attributes.");
566 ATH_MSG_DEBUG(
"setInputAttribute failed getting POOL database/container attributes.");
570 const auto& extraInputContextMap =
m_poolSvc->getInputContextMap();
571 for (
const auto& [
label,
id]: extraInputContextMap) {
573 ATH_MSG_DEBUG(
"setInputAttribute failed to switch off TTreeCache for = " <<
label <<
".");
577 return(StatusCode::SUCCESS);
582 if (incident.type() ==
"EndEvent") {
584 ATH_MSG_DEBUG(
"handle EndEvent failed process POOL database attributes.");
590 base_class(
name, pSvcLocator,
pool::POOL_StorageType.
type()) {
594 std::vector<std::vector<std::string> >* contAttr,
595 std::vector<std::vector<std::string> >* dbAttr,
596 std::vector<std::vector<std::string> >* domAttr)
const {
597 std::vector<std::string>
opt;
598 std::string attributeName, containerName, databaseName, valueString;
599 for (
const auto& propertyValue : property.value()) {
601 attributeName.clear();
602 containerName.clear();
603 databaseName.clear();
605 using Gaudi::Utils::AttribStringParser;
606 for (
const AttribStringParser::Attrib& attrib : AttribStringParser (propertyValue)) {
607 const std::string
tag = attrib.tag;
608 const std::string
val = attrib.value;
609 if (
tag ==
"DatabaseName") {
611 }
else if (
tag ==
"ContainerName") {
612 if (databaseName.empty()) {
615 containerName = std::move(
val);
617 attributeName = std::move(
tag);
618 valueString = std::move(
val);
621 if (!attributeName.empty() && !valueString.empty()) {
622 opt.push_back(attributeName);
623 opt.push_back(valueString);
624 if (!databaseName.empty()) {
625 opt.push_back(databaseName);
626 if (!containerName.empty()) {
627 opt.push_back(containerName);
628 if (containerName.compare(0, 6,
"TTree=") == 0) {
629 dbAttr->push_back(
opt);
631 contAttr->push_back(
opt);
635 dbAttr->push_back(
opt);
637 }
else if (domAttr != 0) {
638 domAttr->push_back(
opt);
642 dbAttr->push_back(
opt);
650 unsigned long contextId,
653 bool doClear)
const {
654 bool retError =
false;
655 for (
auto& attrEntry : attr) {
656 if (attrEntry.size() == 2) {
657 const std::string&
opt = attrEntry[0];
658 std::string
data = attrEntry[1];
659 if (
data ==
"int" ||
data ==
"DbLonglong" ||
data ==
"double" ||
data ==
"string") {
678 if (attrEntry.size() == 4) {
679 const std::string&
opt = attrEntry[0];
680 std::string
data = attrEntry[1];
681 const std::string&
file = attrEntry[2];
682 const std::string& cont = attrEntry[3];
684 || (
file[0] ==
'*' &&
file.find(
"," +
fileName +
",") == std::string::npos))) {
685 if (
data ==
"int" ||
data ==
"DbLonglong" ||
data ==
"double" ||
data ==
"string") {
697 attrEntry[2] +=
"," +
fileName +
",";
710 std::erase_if(attr, [](
const auto&
entry) {
return entry.empty(); });
711 return(retError ? StatusCode::FAILURE : StatusCode::SUCCESS);