ATLAS Offline Software
Loading...
Searching...
No Matches
TStore.cxx
Go to the documentation of this file.
1// Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
2
3#include <set>
4
5// ROOT include(s):
6#include <TError.h>
7#include <TClass.h>
8
9// EDM include(s):
14
15// Local include(s):
21
22namespace xAOD {
23
25 : m_objects(), m_keys() {
26
27 setActive();
28 }
29
31
32 // Clear the store before being deleted:
33 clear();
34
35 // If this object is set up as the active store at the moment,
36 // notify the active store object that this object will no longer
37 // be available.
38 if( TActiveStore::store() == this ) {
39 TActiveStore::setStore( nullptr );
40 }
41 }
42
44
46 return;
47 }
48
49
50 const THolder* TStore::holder( const std::string& key ) const {
51 // Look up this object:
52 Objects_t::const_iterator itr = m_objects.find( key );
53 return (itr != m_objects.end() ? itr->second : nullptr);
54 }
55
56
57 StatusCode TStore::remove( const std::string& key ) {
58
59 // Look up this object:
60 Objects_t::iterator itr = m_objects.find( key );
61 if( itr == m_objects.end() ) {
62 ::Warning( "xAOD::TStore::remove",
63 "Couldn't find object with key \"%s\"",
64 key.c_str() );
65 return StatusCode::RECOVERABLE;
66 }
67
68 // Delete the hoder object:
69 delete itr->second;
70
71 // Now remove this element from the maps:
72 m_objects.erase( itr );
73 m_keys.erase( Utils::hash( key ) );
74
75 // We were successful:
76 return StatusCode::SUCCESS;
77 }
78
79 StatusCode TStore::remove( void* ptr ) {
80
81 // Look for this object:
82 Objects_t::iterator itr = m_objects.begin();
83 Objects_t::iterator end = m_objects.end();
84 for( ; itr != end; ++itr ) {
85
86 // Check if this is the object in question:
87 if( itr->second->get() != ptr ) {
88 continue;
89 }
90
91 // Yes, it is...
92 delete itr->second;
93 m_keys.erase( Utils::hash( itr->first ) );
94 m_objects.erase( itr );
95 return StatusCode::SUCCESS;
96 }
97
98 // We didn't find the object in the store:
99 ::Warning( "xAOD::TStore::remove",
100 "Couldn't find object with pointer %p",
101 ptr );
102 return StatusCode::RECOVERABLE;
103 }
104
106
107 // Delete all the managed objects:
108 Objects_t::iterator itr = m_objects.begin();
109 Objects_t::iterator end = m_objects.end();
110 for( ; itr != end; ++itr ) {
111 delete itr->second;
112 }
113
114 // And clear the maps:
115 m_objects.clear();
116 m_keys.clear();
117
118 return;
119 }
120
124 void TStore::print() const {
125
126 ::Info( "xAOD::TStore::print", "Contents of transient store:" );
127 Objects_t::const_iterator itr = m_objects.begin();
128 Objects_t::const_iterator end = m_objects.end();
129 for( ; itr != end; ++itr ) {
130 ::Info( "xAOD::TStore::print", "-----------------------------------" );
131 ::Info( "xAOD::TStore::print", " Name: %s", itr->first.c_str() );
132 const ::TClass* cl = itr->second->getClass();
133 const std::type_info* ti = itr->second->getTypeInfo();
134 ::Info( "xAOD::TStore::print", " Type: %s",
135 ( cl ? cl->GetName() :
136 ( ti ? SG::normalizedTypeinfoName( *ti ).c_str() :
137 "Unknown" ) ) );
138 ::Info( "xAOD::TStore::print", " Pointer: %p",
139 itr->second->get() );
140 ::Info( "xAOD::TStore::print", " IsOwner: %s",
141 ( itr->second->isOwner() ? "Yes" : "No" ) );
142 ::Info( "xAOD::TStore::print", " IsConst: %s",
143 ( itr->second->isConst() ? "Yes" : "No" ) );
144 ::Info( "xAOD::TStore::print", " HasDictionary: %s",
145 ( cl ? "Yes" : "No" ) );
146 }
147 ::Info( "xAOD::TStore::print", "-----------------------------------" );
148
149 return;
150 }
151
152 ::Bool_t TStore::contains( const std::string& key,
153 const std::type_info& ti ) const {
154
155 // Look up this object:
156 Objects_t::const_iterator itr = m_objects.find( key );
157 if( itr == m_objects.end() ) {
158 return kFALSE;
159 }
160
161 // Check if the object is of the right type:
162 return itr->second->getAsConst( ti, kTRUE );
163 }
164
165 ::Bool_t TStore::isConst( const std::string& key,
166 const std::type_info& ti ) const {
167
168 // Look up this object:
169 Objects_t::const_iterator itr = m_objects.find( key );
170 if( itr == m_objects.end() ) {
171 ::Warning( "xAOD::TStore::isConst",
172 "Object with key \"%s\" not available in store",
173 key.c_str() );
174 return kFALSE;
175 }
176
177 // Check if it can even be retrieved as a constant object of this type:
178 if( ! itr->second->getAsConst( ti, kTRUE ) ) {
179 const std::string typeName = SG::normalizedTypeinfoName( ti );
180 ::Warning( "xAOD::TStore::isConst",
181 "Object with key \"%s\" can't be retrieved as type: %s",
182 key.c_str(), typeName.c_str() );
183 return kFALSE;
184 }
185
186 // Now the question is just whether it can be retrieved as a non-const
187 // object as well:
188 return ( ! itr->second->getAs( ti, kTRUE ) );
189 }
190
191 void* TStore::getObject( const std::string& key,
192 const std::type_info& ti ) const {
193
194 // Look up this object:
195 Objects_t::const_iterator itr = m_objects.find( key );
196 if( itr == m_objects.end() ) {
197 return 0;
198 }
199
200 if( itr->second->isConst() ) {
201 ::Error( "xAOD::TStore::getObject",
202 XAOD_MESSAGE( "Cannot retrieve object with key \"%s\" of type %s as non-const" ),
203 key.c_str(), SG::normalizedTypeinfoName( ti ).c_str() );
204 return nullptr;
205 }
206
207 // Try to retrieve it as the requested type:
208 return itr->second->getAs( ti );
209 }
210
211 const void* TStore::getConstObject( const std::string& key,
212 const std::type_info& ti ) const {
213
214 // Look up this object:
215 Objects_t::const_iterator itr = m_objects.find( key );
216 if( itr == m_objects.end() ) {
217 return 0;
218 }
219
220 // Try to retrieve it as the requested type:
221 return itr->second->getAsConst( ti );
222 }
223
234 StatusCode TStore::record( void* obj, const std::string& key,
235 const std::string& classname,
236 ::Bool_t isOwner, ::Bool_t isConst ) {
237
238 // Cache
240 static clCache_t clMap ATLAS_THREAD_SAFE {clCache_t::Updater_t()};
241
242 // First check if we have this dictionary cached already:
243 ::TClass* cl = 0;
244 auto clItr = clMap.find( classname );
245 if( clItr != clMap.end() ) {
246 // If the cached value doesn't work, then bail now:
247 if( ( ! clItr->second ) || ( ! clItr->second->IsLoaded() ) ) {
248 return StatusCode::RECOVERABLE;
249 }
250 // Otherwise we're done:
251 cl = clItr->second;
252 }
253
254 // If it's not cached, ask ROOT for it:
255 if( ! cl ) {
256 cl = ::TClass::GetClass( classname.c_str(), kTRUE, kTRUE );
257 clMap.emplace( classname, cl );
258 }
259 if( ( ! cl ) || ( ! cl->IsLoaded() ) ) {
260 return StatusCode::RECOVERABLE;
261 }
262
263 // Make sure that the key is not yet taken:
264 if( m_objects.find( key ) != m_objects.end() ) {
265 ::Error( "xAOD::TStore::record",
266 XAOD_MESSAGE( "Trying to overwrite object with key \"%s\"" ),
267 key.c_str() );
268 return StatusCode::FAILURE;
269 }
270
271 // Register the new object:
272 if( isConst )
273 m_objects[ key ] = new THolder( const_cast<const void*>(obj), cl, isOwner );
274 else
275 m_objects[ key ] = new THolder( obj, cl, isOwner);
276
277 m_keys[ Utils::hash( key ) ] = key;
278 return StatusCode::SUCCESS;
279 }
280
281 StatusCode TStore::record( void* obj, const std::string& key,
282 const std::type_info& ti,
283 ::Bool_t isOwner, ::Bool_t isConst ) {
284
285 // Make sure that the key is not yet taken:
286 if( m_objects.find( key ) != m_objects.end() ) {
287 ::Error( "xAOD::TStore::record",
288 XAOD_MESSAGE( "Trying to overwrite object with key \"%s\"" ),
289 key.c_str() );
290 return StatusCode::FAILURE;
291 }
292
293 // Register the new object:
294 if( isConst )
295 m_objects[ key ] = new THolder( const_cast<const void*>(obj), ti, isOwner );
296 else
297 m_objects[ key ] = new THolder( obj, ti, isOwner );
298
299 m_keys[ Utils::hash( key ) ] = key;
300 return StatusCode::SUCCESS;
301 }
302
303 StatusCode TStore::record( THolder* hldr, const std::string& key ) {
304
305 // Make sure that the key is not yet taken:
306 if( m_objects.find( key ) != m_objects.end() ) {
307 ::Error( "xAOD::TStore::record",
308 XAOD_MESSAGE( "Trying to overwrite object with key \"%s\"" ),
309 key.c_str() );
310 // We delete the holder object at this point. It's quite ugly in terms
311 // of code readibility, but it results in fewer characters in the
312 // template code...
313 delete hldr;
314 return StatusCode::FAILURE;
315 }
316
317 // Register the new object:
318 m_objects[ key ] = hldr;
319 m_keys[ Utils::hash( key ) ] = key;
320 return StatusCode::SUCCESS;
321 }
322
330 ::Bool_t TStore::contains( SG::sgkey_t hash ) const {
331
332 // Do the check quickly:
333 return ( m_keys.find( hash ) != m_keys.end() );
334 }
335
343 ::Bool_t TStore::contains( const void* ptr ) const {
344
345 // Loop over all the managed objects:
346 Objects_t::const_iterator itr = m_objects.begin();
347 Objects_t::const_iterator end = m_objects.end();
348 for( ; itr != end; ++itr ) {
349 // Check if this is the right object:
350 if( itr->second->get() == ptr ) {
351 return kTRUE;
352 }
353 }
354
355 // We didn't find it:
356 return kFALSE;
357 }
358
366 const std::string& TStore::getName( SG::sgkey_t hash ) const {
367
368 // Try to find the name associated with this key:
369 HashedKeys_t::const_iterator itr = m_keys.find( hash );
370 if( itr != m_keys.end() ) {
371 // We found it:
372 return itr->second;
373 }
374
375 // We didn't find it:
376 ::Warning( "xAOD::TStore::getName", "Key 0x%08x not known by the store",
377 hash );
378 static const std::string dummy( "" );
379 return dummy;
380 }
381
390 const std::string& TStore::getName( const void* ptr ) const {
391
392 // Loop over all the managed objects:
393 Objects_t::const_iterator itr = m_objects.begin();
394 Objects_t::const_iterator end = m_objects.end();
395 for( ; itr != end; ++itr ) {
396 // Check if this is the right object:
397 if( itr->second->get() == ptr ) {
398 return itr->first;
399 }
400 }
401
402 // We didn't find the object:
403 ::Warning( "xAOD::TStore::getName", "Object %p is not held by the store",
404 ptr );
405 static const std::string dummy( "" );
406 return dummy;
407 }
408
409 void TStore::getNames( const std::string& targetTypeName,
410 std::vector< std::string >& vkeys ) const {
411 std::set< std::string > keys;
412
413 for ( const auto& pair : m_objects ) {
414 const std::string& key = pair.first;
415 const ::TClass* cl = pair.second->getClass();
416 const std::type_info* ti = pair.second->getTypeInfo();
417 std::string typeName;
418 if (cl)
419 typeName = cl->GetName();
420 else if (ti)
421 typeName = SG::normalizedTypeinfoName( *ti );
422
423 if (!typeName.empty() && typeName == targetTypeName)
424 keys.insert( key );
425 }
426
427 vkeys.insert( vkeys.end(), keys.begin(), keys.end() );
428 }
429
430} // namespace xAOD
Hash map from strings allowing concurrent, lockless reads.
#define XAOD_MESSAGE(MESSAGE)
Simple macro for printing error/verbose messages.
Simple (non-deleting) Updater implementation.
Define macros for attributes used to control the static checker.
#define ATLAS_THREAD_SAFE
Hash map from strings allowing concurrent, lockless reads.
STL class.
static TStore * store()
Access the currently active TStore object.
static void setStore(TStore *ptr)
Set the active store pointer.
This class takes care of holding EDM objects in memory.
Definition THolder.h:35
void keys(std::vector< std::string > &vkeys) const
provide a list of keys associated with a type
StatusCode remove(const std::string &key)
Remove an object from the store by name.
Definition TStore.cxx:57
void setActive()
Set this as the active transient store in the application.
Definition TStore.cxx:43
void print() const
Print the current contents of the transient store.
Definition TStore.cxx:124
const void * getConstObject(const std::string &key, const std::type_info &ti) const
Function retrieving a const object in a non-template way.
Definition TStore.cxx:211
void clear()
Clear the store of all of its contents.
Definition TStore.cxx:105
virtual ~TStore()
Destructor.
Definition TStore.cxx:30
StatusCode record(T *obj, const std::string &key)
Add an object to the store.
void getNames(const std::string &targetClassName, std::vector< std::string > &vkeys) const
Function determining the list keys associated with a type name.
Definition TStore.cxx:409
const std::string & getName(SG::sgkey_t hash) const
Get the name corresponding to a hashed key.
Definition TStore.cxx:366
HashedKeys_t m_keys
The key map.
Definition TStore.h:171
void * getObject(const std::string &key, const std::type_info &ti) const
Function retrieving a non-const object in a non-template way.
Definition TStore.cxx:191
const THolder * holder(const std::string &key) const
return holder for key
Definition TStore.cxx:50
::Bool_t contains(const std::string &key) const
Function checking if an object is available from the store.
Objects_t m_objects
The object storage.
Definition TStore.h:169
TStore()
Default constructor.
Definition TStore.cxx:24
::Bool_t isConst(const std::string &key) const
Function checking if an object with a given type is constant.
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...
uint32_t sgkey_t
Type used for hashed StoreGate key+CLID pairs.
Definition sgkey_t.h:32
SG::sgkey_t hash(const std::string &name)
This function provides a hashed version of the key (branch) names used in the xAOD file,...
ICaloAffectedTool is abstract interface for tools checking if 4 mom is in calo affected region.
Convert a type_info to a normalized string representation (matching the names used in the root dictio...