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 // Forget its pointer, and delete the holder object:
69 m_names.erase( itr->second->get() );
70 delete itr->second;
71
72 // Now remove this element from the maps:
73 m_objects.erase( itr );
74 m_keys.erase( Utils::hash( key ) );
75
76 // We were successful:
77 return StatusCode::SUCCESS;
78 }
79
80 StatusCode TStore::remove( void* ptr ) {
81
82 // Look for this object:
83 auto itr = m_names.find( ptr );
84 if( itr == m_names.end() ) {
85 ::Warning( "xAOD::TStore::remove",
86 "Couldn't find object with pointer %p",
87 ptr );
88 return StatusCode::RECOVERABLE;
89 }
90
91 // Copy the key, removing the object destroys the string it points to:
92 return remove( std::string( *itr->second ) );
93 }
94
96
97 // Delete all the managed objects:
98 Objects_t::iterator itr = m_objects.begin();
99 Objects_t::iterator end = m_objects.end();
100 for( ; itr != end; ++itr ) {
101 delete itr->second;
102 }
103
104 // And clear the maps:
105 m_objects.clear();
106 m_keys.clear();
107 m_names.clear();
108
109 return;
110 }
111
115 void TStore::print() const {
116
117 ::Info( "xAOD::TStore::print", "Contents of transient store:" );
118 Objects_t::const_iterator itr = m_objects.begin();
119 Objects_t::const_iterator end = m_objects.end();
120 for( ; itr != end; ++itr ) {
121 ::Info( "xAOD::TStore::print", "-----------------------------------" );
122 ::Info( "xAOD::TStore::print", " Name: %s", itr->first.c_str() );
123 const ::TClass* cl = itr->second->getClass();
124 const std::type_info* ti = itr->second->getTypeInfo();
125 ::Info( "xAOD::TStore::print", " Type: %s",
126 ( cl ? cl->GetName() :
127 ( ti ? SG::normalizedTypeinfoName( *ti ).c_str() :
128 "Unknown" ) ) );
129 ::Info( "xAOD::TStore::print", " Pointer: %p",
130 itr->second->get() );
131 ::Info( "xAOD::TStore::print", " IsOwner: %s",
132 ( itr->second->isOwner() ? "Yes" : "No" ) );
133 ::Info( "xAOD::TStore::print", " IsConst: %s",
134 ( itr->second->isConst() ? "Yes" : "No" ) );
135 ::Info( "xAOD::TStore::print", " HasDictionary: %s",
136 ( cl ? "Yes" : "No" ) );
137 }
138 ::Info( "xAOD::TStore::print", "-----------------------------------" );
139
140 return;
141 }
142
143 ::Bool_t TStore::contains( const std::string& key,
144 const std::type_info& ti ) const {
145
146 // Look up this object:
147 Objects_t::const_iterator itr = m_objects.find( key );
148 if( itr == m_objects.end() ) {
149 return kFALSE;
150 }
151
152 // Check if the object is of the right type:
153 return itr->second->getAsConst( ti, kTRUE );
154 }
155
156 ::Bool_t TStore::isConst( const std::string& key,
157 const std::type_info& ti ) const {
158
159 // Look up this object:
160 Objects_t::const_iterator itr = m_objects.find( key );
161 if( itr == m_objects.end() ) {
162 ::Warning( "xAOD::TStore::isConst",
163 "Object with key \"%s\" not available in store",
164 key.c_str() );
165 return kFALSE;
166 }
167
168 // Check if it can even be retrieved as a constant object of this type:
169 if( ! itr->second->getAsConst( ti, kTRUE ) ) {
170 const std::string typeName = SG::normalizedTypeinfoName( ti );
171 ::Warning( "xAOD::TStore::isConst",
172 "Object with key \"%s\" can't be retrieved as type: %s",
173 key.c_str(), typeName.c_str() );
174 return kFALSE;
175 }
176
177 // Now the question is just whether it can be retrieved as a non-const
178 // object as well:
179 return ( ! itr->second->getAs( ti, kTRUE ) );
180 }
181
182 void* TStore::getObject( const std::string& key,
183 const std::type_info& ti ) const {
184
185 // Look up this object:
186 Objects_t::const_iterator itr = m_objects.find( key );
187 if( itr == m_objects.end() ) {
188 return 0;
189 }
190
191 if( itr->second->isConst() ) {
192 ::Error( "xAOD::TStore::getObject",
193 XAOD_MESSAGE( "Cannot retrieve object with key \"%s\" of type %s as non-const" ),
194 key.c_str(), SG::normalizedTypeinfoName( ti ).c_str() );
195 return nullptr;
196 }
197
198 // Try to retrieve it as the requested type:
199 return itr->second->getAs( ti );
200 }
201
202 const void* TStore::getConstObject( const std::string& key,
203 const std::type_info& ti ) const {
204
205 // Look up this object:
206 Objects_t::const_iterator itr = m_objects.find( key );
207 if( itr == m_objects.end() ) {
208 return 0;
209 }
210
211 // Try to retrieve it as the requested type:
212 return itr->second->getAsConst( ti );
213 }
214
225 StatusCode TStore::record( void* obj, const std::string& key,
226 const std::string& classname,
227 ::Bool_t isOwner, ::Bool_t isConst ) {
228
229 // Cache
231 static clCache_t clMap ATLAS_THREAD_SAFE {clCache_t::Updater_t()};
232
233 // First check if we have this dictionary cached already:
234 ::TClass* cl = 0;
235 auto clItr = clMap.find( classname );
236 if( clItr != clMap.end() ) {
237 // If the cached value doesn't work, then bail now:
238 if( ( ! clItr->second ) || ( ! clItr->second->IsLoaded() ) ) {
239 return StatusCode::RECOVERABLE;
240 }
241 // Otherwise we're done:
242 cl = clItr->second;
243 }
244
245 // If it's not cached, ask ROOT for it:
246 if( ! cl ) {
247 cl = ::TClass::GetClass( classname.c_str(), kTRUE, kTRUE );
248 clMap.emplace( classname, cl );
249 }
250 if( ( ! cl ) || ( ! cl->IsLoaded() ) ) {
251 return StatusCode::RECOVERABLE;
252 }
253
254 // Make sure that the key is not yet taken:
255 if( m_objects.find( key ) != m_objects.end() ) {
256 ::Error( "xAOD::TStore::record",
257 XAOD_MESSAGE( "Trying to overwrite object with key \"%s\"" ),
258 key.c_str() );
259 return StatusCode::FAILURE;
260 }
261
262 // Register the new object:
263 if( isConst )
264 return record( new THolder( const_cast<const void*>(obj), cl, isOwner ), key );
265 return record( new THolder( obj, cl, isOwner ), key );
266 }
267
268 StatusCode TStore::record( void* obj, const std::string& key,
269 const std::type_info& ti,
270 ::Bool_t isOwner, ::Bool_t isConst ) {
271
272 // Make sure that the key is not yet taken:
273 if( m_objects.find( key ) != m_objects.end() ) {
274 ::Error( "xAOD::TStore::record",
275 XAOD_MESSAGE( "Trying to overwrite object with key \"%s\"" ),
276 key.c_str() );
277 return StatusCode::FAILURE;
278 }
279
280 // Register the new object:
281 if( isConst )
282 return record( new THolder( const_cast<const void*>(obj), ti, isOwner ), key );
283 return record( new THolder( obj, ti, isOwner ), key );
284 }
285
286 StatusCode TStore::record( THolder* hldr, const std::string& key ) {
287
288 // Make sure that the key is not yet taken:
289 if( m_objects.find( key ) != m_objects.end() ) {
290 ::Error( "xAOD::TStore::record",
291 XAOD_MESSAGE( "Trying to overwrite object with key \"%s\"" ),
292 key.c_str() );
293 // We delete the holder object at this point. It's quite ugly in terms
294 // of code readibility, but it results in fewer characters in the
295 // template code...
296 delete hldr;
297 return StatusCode::FAILURE;
298 }
299
300 // Register the new object:
301 const auto itr = m_objects.emplace( key, hldr ).first;
302 m_keys[ Utils::hash( key ) ] = key;
303 // shortcut: one key per pointer, an object recorded twice (non-owning, from TPyStore) is lost by either remove; index all keys if that is ever used
304 m_names.emplace( hldr->get(), &itr->first );
305 return StatusCode::SUCCESS;
306 }
307
315 ::Bool_t TStore::contains( SG::sgkey_t hash ) const {
316
317 // Do the check quickly:
318 return ( m_keys.find( hash ) != m_keys.end() );
319 }
320
325 ::Bool_t TStore::contains( const void* ptr ) const {
326
327 return m_names.contains( ptr );
328 }
329
337 const std::string& TStore::getName( SG::sgkey_t hash ) const {
338
339 // Try to find the name associated with this key:
340 HashedKeys_t::const_iterator itr = m_keys.find( hash );
341 if( itr != m_keys.end() ) {
342 // We found it:
343 return itr->second;
344 }
345
346 // We didn't find it:
347 ::Warning( "xAOD::TStore::getName", "Key 0x%08x not known by the store",
348 hash );
349 static const std::string dummy( "" );
350 return dummy;
351 }
352
357 const std::string& TStore::getName( const void* ptr ) const {
358
359 auto itr = m_names.find( ptr );
360 if( itr != m_names.end() ) {
361 return *itr->second;
362 }
363
364 // We didn't find the object:
365 ::Warning( "xAOD::TStore::getName", "Object %p is not held by the store",
366 ptr );
367 static const std::string dummy( "" );
368 return dummy;
369 }
370
371 void TStore::getNames( const std::string& targetTypeName,
372 std::vector< std::string >& vkeys ) const {
373 std::set< std::string > keys;
374
375 for ( const auto& pair : m_objects ) {
376 const std::string& key = pair.first;
377 const ::TClass* cl = pair.second->getClass();
378 const std::type_info* ti = pair.second->getTypeInfo();
379 std::string typeName;
380 if (cl)
381 typeName = cl->GetName();
382 else if (ti)
383 typeName = SG::normalizedTypeinfoName( *ti );
384
385 if (!typeName.empty() && typeName == targetTypeName)
386 keys.insert( key );
387 }
388
389 vkeys.insert( vkeys.end(), keys.begin(), keys.end() );
390 }
391
392} // 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
const void * get() const
Return a typeless const pointer to the held object.
Definition THolder.cxx:216
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:115
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:202
void clear()
Clear the store of all of its contents.
Definition TStore.cxx:95
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:371
const std::string & getName(SG::sgkey_t hash) const
Get the name corresponding to a hashed key.
Definition TStore.cxx:337
HashedKeys_t m_keys
The key map.
Definition TStore.h:172
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:182
std::unordered_map< const void *, const std::string * > m_names
Key of each managed object, by object pointer (points into m_objects).
Definition TStore.h:174
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:170
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...