ATLAS Offline Software
Loading...
Searching...
No Matches
TrigSerializeConverter.h
Go to the documentation of this file.
1// Dear emacs, this is -*- c++ -*-
2
3/*
4 Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
5*/
6
7// $Id$
8#ifndef TRIGSERIALIZECONVERTER_H
9#define TRIGSERIALIZECONVERTER_H
10
11#include "GaudiKernel/Converter.h"
12#include "GaudiKernel/ToolHandle.h"
13#include "GaudiKernel/ServiceHandle.h"
14
18
22
26
27#include <memory>
28
29
30//fwd
31template< class Cnv >
32class CnvFactory;
33
34/***
35 * @brief TrigSerializeConverter is a templated converter which implements
36 * conversions from transient to persistent representation (and back)
37 * used by TrigSerializeCnvSvc to serialize and deserialize Trigger objects
38 *
39 * @author Jiri Masik Jiri.Masik@cern.ch
40 * @author Lukas Heinrich lukas.heinrich@cern.ch
41 */
42
43namespace SG{class AuxElement;}
44namespace SG{class IAuxStore;}
45
46
47template<typename T>
48 struct isxAOD {
49 template<typename C>
50 constexpr static typename std::enable_if<std::is_base_of<SG::AuxElement,typename std::pointer_traits<typename C::value_type>::element_type>::value,bool>::type isxAODVector(C*){return true;}
51 template<typename C>
52 constexpr static bool isxAODVector(...){return false;}
53 template<typename C>
54 constexpr static typename std::enable_if<std::is_base_of<SG::IAuxStore,C>::value,bool>::type isAuxVector(C*){return true;}
55 template<typename C>
56 constexpr static bool isAuxVector(...){return false;}
57 static const bool value = isxAODVector<T>(0) || isAuxVector<T>(0);
58};
59
60
62
63
71template <class DATA>
72DATA* prepareForWrite (DATA* d, std::unique_ptr<DATA>& /*holder*/)
73{
74 return d;
75}
76
77
88template <class DV>
90 std::unique_ptr<ViewVector<DV> >& holder)
91{
92 holder = std::make_unique<ViewVector<DV> > (*d);
93 holder->setClearOnPersistent();
94 return holder.get();
95}
96
97
104template <class DATA>
105DATA* finishRead (DATA* d)
106{
107 return d;
108}
109
110
118template <class DV>
120{
121 // In the case of schema evolution, we'll actually get a
122 // @c ViewVector for a different _v type.
123 if (typeid(*d) != typeid(ViewVector<DV>)) {
124 auto d2 = std::make_unique<ViewVector<DV> > (*d);
125 delete d;
126 d = d2.release();
127 // root read rule doesn't do anything in this case.
128 d->toTransient();
129 }
130 d->clearPersistent();
131 return d;
132}
133
134
135} // namespace TrigSerialization
136
137
138template< typename DATA >
140
141public:
142 static const bool typeIsxAOD = isxAOD<DATA>::value;
143
144 // per->tran
145 StatusCode createObj( IOpaqueAddress* iAddr, DataObject *& pO ) {
146
147 const std::string clname = ClassID_traits< DATA >::typeName();
148
149 std::string normalized = SG::normalizedTypeinfoName( typeid(DATA) ); // normalized string representation (matching the names used in the root dictionary)
150
151
152 void *ptr( 0 );
153 if( m_log->level() <= MSG::DEBUG ) {
154 *m_log << MSG::DEBUG << "In createObj for : " << clname << " normalized to " << normalized << endmsg;
155 }
156
157 StatusCode sc = m_convHelper->createObj( normalized, iAddr, ptr, typeIsxAOD);
158 if( sc.isFailure() ){
159 *m_log << MSG::WARNING << "m_convHelper->createObj failed for "
160 << clname << endmsg;
161 }
162
163 DATA *nObj = ( DATA* ) ptr;
164 nObj = TrigSerialization::finishRead (nObj);
165 pO = SG::asStorable( nObj );
166
167 if( m_log->level() <= MSG::DEBUG ) {
168 *m_log << MSG::DEBUG << "IOpaq: " << iAddr
169 << " created nObj: " << nObj << endmsg;
170 }
171
172
173
174
175 if( m_sgsvc && nObj ){
176 TrigStreamAddress *addr = dynamic_cast< TrigStreamAddress* >( iAddr );
177 if( addr ) {
178 if( m_sgsvc->contains< DATA >( addr->sgkey() ) ) {
179 *m_log << MSG::WARNING << "TrigSerializeConverter::createObj object "
180 << clname << " / " << addr->sgkey()
181 << " is already in the store; not overwriting"
182 << endmsg;
183 } else {
184 sc = m_sgsvc->record( nObj, addr->sgkey() );
185 }
186 if( sc.isFailure() ) {
187 *m_log << MSG::ERROR << "SG::record failed for " << addr->sgkey()
188 << endmsg;
189 } else if( m_log->level() <= MSG::DEBUG ) {
190 *m_log << MSG::DEBUG << "SG::record key: "
191 << addr->sgkey() << " class: " << clname << endmsg;
192 }
193 } else {
194 *m_log << MSG::WARNING << "createObj cast failed" << endmsg;
195 }
196 } else if( m_log->level() <= MSG::DEBUG ) {
197 *m_log << MSG::DEBUG << "did not put an object into SG" << endmsg;
198 }
199
200 return sc;
201 }
202
203 // tran->per
204 StatusCode createRep( DataObject* pObj, IOpaqueAddress*& pAddr ) {
205
206 // const std::string clname = ClassID_traits<DATA>::typeName(); // old style, does not contain the _vX of the actual class type
207
208 // const std::type_info& typeId = ClassID_traits<DATA>::typeId(); // damn, this line just does not compile
209
210 std::string classname = SG::normalizedTypeinfoName( typeid(DATA) ); // normalized string representation (matching the names used in the root dictionary)
211
212 DATA *d( 0 );
213 SG::fromStorable( pObj, d );
214 if( m_log->level() <= MSG::DEBUG ) {
215 *m_log << MSG::DEBUG << "My createRep for " << classID() << " "
216 << classname << endmsg;
217 }
218
219 std::unique_ptr<DATA> holder;
220 void *serptr = TrigSerialization::prepareForWrite (d, holder);
221 //
222 std::vector< uint32_t > ser;
223
224 StatusCode sc = m_convHelper->createRep( classname, serptr, ser, typeIsxAOD);
225 if( m_log->level() <= MSG::DEBUG ) {
226 *m_log << MSG::DEBUG << "convHelper " << ser.size() << endmsg;
227 }
228
229 TrigStreamAddress *addr = new TrigStreamAddress( classID(), classname, "" );
230 addr->add( ser );
231
232 pAddr = addr;
233
234 return sc;
235 }
236
237 StatusCode initialize(){
238
239 if( m_log ) {
240 m_log->setLevel( msgSvc()->outputLevel( "TrigSerializeConverter" ) );
241 } else {
242 return StatusCode::FAILURE;
243 }
244
245 StatusCode sc = m_convHelper.retrieve();
246 if( ! sc.isSuccess() ) {
247 if( m_log->level() <= MSG::DEBUG ) {
248 *m_log << MSG::DEBUG << m_convHelper << "not retrieved" << endmsg;
249 }
250 } else {
251 if( m_log->level() <= MSG::DEBUG ) {
252 *m_log << MSG::DEBUG << m_convHelper << "m_serializer retrieved"
253 << endmsg;
254 }
255 if( ! m_convHelper->initialize().isSuccess() ) {
256 if( m_log->level() <= MSG::DEBUG ) {
257 *m_log << MSG::DEBUG << m_convHelper << " not initialized"
258 << endmsg;
259 }
260 }
261 }
262
263 StatusCode scsg = m_sgHandle.retrieve();
264 if (scsg.isFailure())
265 *m_log << MSG::ERROR << "cannot access SG" << endmsg;
266 else {
267 m_sgsvc = m_sgHandle.operator->();
268 }
269 return sc;
270 }
271
272 static const CLID& classID() { return ClassID_traits<DATA>::ID(); }
273
274 virtual long int repSvcType() const;
275 static long int storageType();
276
277 TrigSerializeConverter( ISvcLocator* svcloc )
278 : Converter( storageType(), classID(), svcloc ),
279 m_convHelper( "TrigSerializeConvHelper/TrigSerializeConvHelper" ),
280 m_sgHandle( "StoreGateSvc", "TrigSerializeConverter" ),
281 m_log( 0 ), m_sgsvc( 0 ) {
282
283 m_log = new MsgStream( msgSvc(), "TrigSerializeConverter" );
284 }
285
287 delete m_log;
288 }
289
290private:
291 ToolHandle< ITrigSerializeConvHelper > m_convHelper;
293 MsgStream *m_log;
295};
296
297
298template <typename DATA>
302template <typename DATA>
304 return storageType();
305}
306
307
308#endif // TRIGSERIALIZECONVERTER_H
#define endmsg
a traits class that associates a CLID to a type T It also detects whether T inherits from Gaudi DataO...
uint32_t CLID
The Class ID type.
static Double_t sc
convert to and from a SG storable
Identify view containers to be made persistent.
Abstract factory to create the converter.
Base class for elements of a container that can have aux data.
Definition AuxElement.h:483
Interface for non-const operations on an auxiliary store.
Definition IAuxStore.h:48
void setClearOnPersistent()
Set a flag to declare that the vector should be cleared on the next call to toPersistent().
The Athena Transient Store API.
static long int storageType()
ServiceHandle< StoreGateSvc > m_sgHandle
TrigSerializeConverter(ISvcLocator *svcloc)
virtual long int repSvcType() const
StatusCode createRep(DataObject *pObj, IOpaqueAddress *&pAddr)
static const CLID & classID()
ToolHandle< ITrigSerializeConvHelper > m_convHelper
StatusCode createObj(IOpaqueAddress *iAddr, DataObject *&pO)
IOpaqueAddress for TrigSerializenCnvSvc.
void add(const std::vector< uint32_t > &a)
const std::string & sgkey() const
Identify view containers to be made persistent.
Definition ViewVector.h:67
struct color C
Forward declaration.
std::string normalizedTypeinfoName(const std::type_info &info)
Convert a type_info to a normalized string representation (matching the names used in the root dictio...
bool fromStorable(DataObject *pDObj, T *&pTrans, bool quiet=false, IRegisterTransient *irt=0, bool isConst=true)
DataObject * asStorable(SG::DataObjectSharedPtr< T > pObject)
DATA * finishRead(DATA *d)
Called after an object has been read from BS.
DATA * prepareForWrite(DATA *d, std::unique_ptr< DATA > &)
Called before serializing an object to BS.
Helper to disable undefined behavior sanitizer for a function.
#define NO_SANITIZE_UNDEFINED
Convert a type_info to a normalized string representation (matching the names used in the root dictio...
static const bool value
static constexpr bool isAuxVector(...)
static constexpr bool isxAODVector(...)
static constexpr std::enable_if< std::is_base_of< SG::IAuxStore, C >::value, bool >::type isAuxVector(C *)
static constexpr std::enable_if< std::is_base_of< SG::AuxElement, typenamestd::pointer_traits< typenameC::value_type >::element_type >::value, bool >::type isxAODVector(C *)