ATLAS Offline Software
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):
13 #include "CxxUtils/SimpleUpdater.h"
14 
15 // Local include(s):
16 #include "xAODRootAccess/TStore.h"
21 
22 namespace 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 
45  TActiveStore::setStore( this );
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 
80 
81  // Look for this object:
82  Objects_t::iterator itr = m_objects.begin();
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 
105  void TStore::clear() {
106 
107  // Delete all the managed objects:
108  Objects_t::iterator itr = m_objects.begin();
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
239  using clCache_t = CxxUtils::ConcurrentStrMap<::TClass*, CxxUtils::SimpleUpdater>;
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)
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
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
xAOD::TStore::~TStore
virtual ~TStore()
Destructor.
Definition: TStore.cxx:30
xAOD::TStore::m_keys
HashedKeys_t m_keys
The key map.
Definition: TStore.h:169
xAOD::TStore::holder
const THolder * holder(const std::string &key) const
return holder for key
Definition: TStore.cxx:50
SG::normalizedTypeinfoName
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...
Definition: normalizedTypeinfoName.cxx:120
xAOD::THolder
This class takes care of holding EDM objects in memory.
Definition: THolder.h:35
xAOD::TStore::getName
const std::string & getName(SG::sgkey_t hash) const
Get the name corresponding to a hashed key.
Definition: TStore.cxx:366
ConcurrentStrMap.h
Hash map from strings allowing concurrent, lockless reads.
xAOD::TStore::setActive
void setActive()
Set this as the active transient store in the application.
Definition: TStore.cxx:43
xAOD::TActiveStore::store
static TStore * store()
Access the currently active TStore object.
Definition: TActiveStore.cxx:16
xAOD
ICaloAffectedTool is abstract interface for tools checking if 4 mom is in calo affected region.
Definition: ICaloAffectedTool.h:24
XAOD_MESSAGE
#define XAOD_MESSAGE(MESSAGE)
Simple macro for printing error/verbose messages.
Definition: Control/xAODRootAccess/xAODRootAccess/tools/Message.h:19
Utils.h
dbg::ptr
void * ptr(T *p)
Definition: SGImplSvc.cxx:74
xAOD::TStore::clear
void clear()
Clear the store of all of its contents.
Definition: TStore.cxx:105
xAOD::TStore::contains
::Bool_t contains(const std::string &key) const
Function checking if an object is available from the store.
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:93
xAOD::TStore::isConst
::Bool_t isConst(const std::string &key) const
Function checking if an object with a given type is constant.
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
Message.h
python.xAODType.dummy
dummy
Definition: xAODType.py:4
xAOD::TStore::remove
StatusCode remove(const std::string &key)
Remove an object from the store by name.
Definition: TStore.cxx:57
xAOD::TStore::getObject
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
normalizedTypeinfoName.h
Convert a type_info to a normalized string representation (matching the names used in the root dictio...
xAOD::TStore::m_objects
Objects_t m_objects
The object storage.
Definition: TStore.h:167
SG::sgkey_t
uint32_t sgkey_t
Type used for hashed StoreGate key+CLID pairs.
Definition: CxxUtils/CxxUtils/sgkey_t.h:32
xAOD::TStore::print
void print() const
Print the current contents of the transient store.
Definition: TStore.cxx:124
xAOD::TStore::getConstObject
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
xAOD::TStore::record
StatusCode record(T *obj, const std::string &key)
Add an object to the store.
SimpleUpdater.h
Simple (non-deleting) Updater implementation.
CaloCondBlobAlgs_fillNoiseFromASCII.hash
dictionary hash
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:109
xAOD::TActiveStore::setStore
static void setStore(TStore *ptr)
Set the active store pointer.
Definition: TActiveStore.cxx:21
xAOD::TStore::keys
void keys(std::vector< std::string > &vkeys) const
provide a list of keys associated with a type
THolder.h
xAOD::TStore::getNames
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
ReadCalibFromCool.typeName
typeName
Definition: ReadCalibFromCool.py:477
ATLAS_THREAD_SAFE
#define ATLAS_THREAD_SAFE
Definition: checker_macros.h:211
checker_macros.h
Define macros for attributes used to control the static checker.
python.PyAthena.obj
obj
Definition: PyAthena.py:132
xAOD::Utils::hash
SG::sgkey_t hash(const std::string &name)
This function provides a hashed version of the key (branch) names used in the xAOD file,...
Definition: Control/xAODRootAccess/Root/Utils.cxx:125
xAOD::TStore::TStore
TStore()
Default constructor.
Definition: TStore.cxx:24
dq_make_web_display.cl
cl
print [x.__class__ for x in toList(dqregion.getSubRegions()) ]
Definition: dq_make_web_display.py:26
TActiveStore.h
TStore.h
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37