ATLAS Offline Software
Loading...
Searching...
No Matches
T_AthenaPoolCustomCnv.icc
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5/** @file T_AthenaPoolCustomCnv.icc
6 * @brief This file contains the implementation for the templated T_AthenaPoolCustomCnv class.
7 * @author Marcin.Nowak@cern.ch
8 **/
9
10#include "GaudiKernel/StatusCode.h"
11#include "GaudiKernel/DataObject.h"
12#include "GaudiKernel/IOpaqueAddress.h"
13#include "GaudiKernel/IRegistry.h"
14
15#include "StorageSvc/DbReflex.h"
16
17#include "AthenaKernel/StorableConversions.h"
18
19#include "AthenaPoolCnvSvc/exceptions.h"
20#include "AthenaPoolCnvTPExtension.h"
21
22#include <sstream>
23#include <stdexcept>
24#include <format>
25
26template <class TRANS, class PERS>
27T_AthenaPoolCustomCnvWithKey<TRANS, PERS>::T_AthenaPoolCustomCnvWithKey(ISvcLocator* pSvcLocator,
28 const char* name /*= nullptr*/) : BaseType(pSvcLocator, name) {
29}
30
31template <class TRANS, class PERS>
32StatusCode T_AthenaPoolCustomCnvWithKey<TRANS, PERS>::DataObjectToPers(DataObject* pObj, IOpaqueAddress*& /*pAddr*/) {
33 ATH_MSG_VERBOSE("In DataObjectToPers() for key = " << pObj->name());
34 return(StatusCode::SUCCESS);
35}
36
37template <class TRANS, class PERS>
38StatusCode T_AthenaPoolCustomCnvWithKey<TRANS, PERS>::DataObjectToPool(IOpaqueAddress* pAddr, DataObject* pObj) {
39 ATH_MSG_VERBOSE("In DataObjectToPool() for key = " << pObj->name());
40 TRANS* obj = nullptr;
41 PERS* persObj = nullptr;
42 bool success = SG::fromStorable(pObj, obj);
43 if (!success || obj == nullptr) {
44 ATH_MSG_ERROR("Failed to cast DataObject to transient type");
45 return(StatusCode::FAILURE);
46 }
47 try {
48 persObj = createPersistentWithKey(obj, pObj->name());
49 }
50 catch (const std::exception& ex) {
51 AthenaPoolCnvSvc::throwExcCaughtException (__PRETTY_FUNCTION__,
52 "creating persistent object",
53 ex,
54 typeid(TRANS),
55 pObj->name());
56 }
57 std::unique_ptr<Token> token;
58 StatusCode status = this->objectToPool(persObj, token, pObj->name(), *pAddr->par());
59 // Null/empty token means ERROR
60 if (token == nullptr || token->classID() == Guid::null()) {
61 ATH_MSG_ERROR("failed to get Token for " << pObj->name());
62 return(StatusCode::FAILURE);
63 }
64 std::size_t cpos = pAddr->par()->find(':');
65 std::size_t bpos = pAddr->par()->find('[');
66 if (cpos == std::string::npos) {
67 cpos = 0;
68 } else {
69 cpos++;
70 }
71 if (bpos != std::string::npos) bpos = bpos - cpos;
72 keepPoolObj(persObj, pAddr->par()->substr(cpos, bpos));
73 // Update IOpaqueAddress for this object.
74 TokenAddress* tokAddr = dynamic_cast<TokenAddress*>(pAddr);
75 if (tokAddr != nullptr) {
76 tokAddr->setToken(std::move(token));
77 } else {
78 return(StatusCode::FAILURE);
79 }
80 return(status);
81}
82
83template <class TRANS, class PERS>
84StatusCode
85T_AthenaPoolCustomCnvWithKey<TRANS, PERS>::PoolToDataObject(DataObject*& pObj,
86 const Token* token,
87 const std::string& key)
88{
89 if (token != nullptr) {
90 this->m_classID = token->classID();
91 }
92 TRANS* transObj = nullptr;
93 AthenaConverterTLPExtension *extCnv = dynamic_cast<AthenaConverterTLPExtension*>(this);
94 // reset the TP converter used for reading, so old value is not used
95 if (extCnv != nullptr) {
96 extCnv->resetTPCnvForReading();
97 }
98 try {
99 transObj = createTransientWithKey(key);
100 }
101 catch(const std::exception& ex) {
102 AthenaPoolCnvSvc::throwExcCaughtException (__PRETTY_FUNCTION__,
103 "creating transient object",
104 ex,
105 typeid(TRANS),
106 key);
107 }
108 if (extCnv != nullptr) {
109 extCnv->deletePersistentObjects();
110 }
111 pObj = SG::asStorable(transObj);
112 return(StatusCode::SUCCESS);
113}
114
115// Read object of type P. This is an exception-throwing version of poolToObject()
116// plus reading of all extending objects
117template <class TRANS, class PERS>
118template <class P>
119inline P* T_AthenaPoolCustomCnvWithKey<TRANS, PERS>::poolReadObject() {
120 P* persObj = nullptr;
121 if (this->poolToObject(this->m_i_poolToken, persObj).isFailure()) {
122 std::string error("POOL read failed. Token = ");
123 throw std::runtime_error(error + (this->m_i_poolToken != nullptr ? this->m_i_poolToken->toString() : ""));
124 }
125 AthenaConverterTLPExtension *extCnv = dynamic_cast<AthenaConverterTLPExtension*>(this);
126 if (extCnv != nullptr) {
127 extCnv->readExtendingObjects(persObj);
128 }
129 return(persObj);
130}
131
132// Read object of type P (plus all extending objects)
133// using the indicated top-level TP converter
134template <class TRANS, class PERS>
135template <class P>
136inline void T_AthenaPoolCustomCnvWithKey<TRANS, PERS>::poolReadObject(TopLevelTPCnvBase& tlp_converter) {
137 AthenaPoolCnvTPExtension *extCnv = dynamic_cast<AthenaPoolCnvTPExtension*>(this);
138 // set which Top level TP concerter will by used for reading
139 // only matters for extended converters
140 if (extCnv != nullptr) {
141 extCnv->usingTPCnvForReading(tlp_converter);
142 }
143 // read the object
144 P* persObj = poolReadObject<P>();
145 // remember the object we just read
146 tlp_converter.setTLPersObject(persObj);
147 // not returning the object - the TLP converter owns it now
148 // and it will delete it automatically in createTransient()!
149}
150
151// Remember the POOL object until commit (then delete it)
152template <class TRANS, class PERS>
153inline void T_AthenaPoolCustomCnvWithKey<TRANS, PERS>::keepPoolObj(PERS* obj, const std::string& output) {
154 std::lock_guard lock(m_pListMutex);
155 m_persObjLists[std::format("{}:{}", output, Gaudi::Hive::currentContext().slot())].emplace_back(obj);
156}
157
158// callback from the CleanupSvc to delete persistent objects after commit
159template <class TRANS, class PERS>
160StatusCode T_AthenaPoolCustomCnvWithKey<TRANS, PERS>::cleanUp(const std::string& output) {
161 std::lock_guard lock(m_pListMutex);
162 m_persObjLists[std::format("{}:{}", output, Gaudi::Hive::currentContext().slot())].clear();
163 return(StatusCode::SUCCESS);
164}
165
166
167template <class TRANS, class PERS>
168PERS* T_AthenaPoolCustomCnv<TRANS, PERS>::createPersistentWithKey
169 (TRANS* obj, const std::string& /*key*/)
170{
171 return createPersistent(obj);
172}
173
174
175template <class TRANS, class PERS>
176TRANS* T_AthenaPoolCustomCnv<TRANS, PERS>::createTransientWithKey
177 (const std::string& /*key*/)
178{
179 return createTransient();
180}