The Gaudi Framework  v38r0 (2143aa4c)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
TsDataSvc.cpp
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2022 CERN for the benefit of the LHCb and ATLAS collaborations *
3 * *
4 * This software is distributed under the terms of the Apache version 2 licence, *
5 * copied verbatim in the file "LICENSE". *
6 * *
7 * In applying this licence, CERN does not waive the privileges and immunities *
8 * granted to it by virtue of its status as an Intergovernmental Organization *
9 * or submit itself to any jurisdiction. *
10 \***********************************************************************************/
11 //====================================================================
12 // TsDataSvc.cpp
13 //--------------------------------------------------------------------
14 //
15 // Package : System ( The LHCb Offline System)
16 //
17 // Description: implementation of the Transient data service: TsDataSvc
18 //
19 // Author : M.Frank
20 // History :
21 // +---------+----------------------------------------------+---------
22 // | Date | Comment | Who
23 // +---------+----------------------------------------------+---------
24 // | 29/10/98| Initial version | M.Frank
25 // | 20/2/99 | Automatic data preloading introduced. | M.Frank
26 // | 25/4/13 | Locking for concurrent access introduced. | D.Piparo
27 // +---------+----------------------------------------------+---------
28 //
29 //====================================================================
30 #define TSDATASVC_DATASVC_CPP
31 
32 // Framework include files
34 #include "GaudiKernel/IConverter.h"
36 
37 #include "GaudiKernel/DataObject.h"
39 
43 #include "GaudiKernel/TsDataSvc.h"
44 
45 // Include files
46 #include <algorithm>
47 #include <cassert>
48 #include <cstdlib>
49 #include <mutex>
50 #include <sstream>
51 #include <vector>
52 
53 // Macro to lock a scope
54 #define STD_LOCK_GUARD_MACRO std::scoped_lock lock{ m_accessMutex };
55 
56 namespace {
57  std::string operator+( char c, std::string_view sr ) {
58  std::string s{ c };
59  s.append( sr.data(), sr.size() );
60  return s;
61  }
62 
63  std::string_view::size_type find( std::string_view s, char c, size_t o ) {
64  if ( !s.empty() ) s.remove_prefix( o );
65  auto r = s.find( c );
66  return r == std::string_view::npos ? r : ( r + o );
67  }
68 } // namespace
69 
70 // If you absolutely need optimization: switch off dynamic_cast.
71 // This improves access to the data store roughly by 10 %
72 // for balanced trees.
73 //
74 // M.Frank
75 #define CAST_REGENTRY( x, y ) dynamic_cast<x>( y )
76 // #define CAST_REGENTRY(x,y) (x)(y)
78 
79 #define ON_DEBUG if ( msgLevel( MSG::DEBUG ) )
80 #define ON_VERBOSE if ( msgLevel( MSG::VERBOSE ) )
81 
82 #define DEBMSG ON_DEBUG debug()
83 #define VERMSG ON_VERBOSE verbose()
84 
88 StatusCode TsDataSvc::clearSubTree( std::string_view sub_tree_path ) {
89  DataObject* pObject = nullptr;
90  StatusCode status = findObject( sub_tree_path, pObject );
91  if ( !status.isSuccess() ) return status;
92  RegEntry* node_entry = CAST_REGENTRY( RegEntry*, pObject->registry() );
93  if ( !node_entry ) return Status::INVALID_OBJECT;
94  RegEntry* parent = node_entry->parentEntry();
95  if ( !parent ) return Status::INVALID_PARENT;
96  parent->remove( node_entry );
97  return StatusCode::SUCCESS;
98 }
99 
104  if ( !checkRoot() ) return Status::INVALID_ROOT;
105  RegEntry* entry = CAST_REGENTRY( RegEntry*, pObject->registry() );
106  if ( !entry ) return Status::INVALID_OBJECT;
107  RegEntry* parent = entry->parentEntry();
108  if ( !parent ) return Status::INVALID_PARENT;
109  parent->remove( entry );
110  return StatusCode::SUCCESS;
111 }
112 
115  if ( !checkRoot() ) return Status::INVALID_ROOT;
116  m_root.reset();
117  return StatusCode::SUCCESS;
118 }
119 
123 StatusCode TsDataSvc::traverseSubTree( std::string_view sub_tree_path, IDataStoreAgent* pAgent ) {
124  DataObject* pO = nullptr;
125  StatusCode status = findObject( sub_tree_path, pO );
126  return status.isSuccess() ? traverseSubTree( pO, pAgent ) : status;
127 }
128 
132  if ( !checkRoot() ) return Status::INVALID_ROOT;
133  RegEntry* entry = CAST_REGENTRY( RegEntry*, pObject->registry() );
134  if ( !entry ) return Status::INVALID_OBJECT;
135  return entry->traverseTree( pAgent );
136 }
137 
141  if ( !checkRoot() ) return Status::INVALID_ROOT;
142  return m_root->traverseTree( pAgent );
143 }
144 
150  clearStore().ignore();
151  return i_setRoot( std::move( root_path ), pRootObj );
152 }
153 
160  if ( pRootObj ) {
161  m_root = std::make_unique<RegEntry>( std::move( root_path ) );
162  m_root->makeHard( pRootObj );
163  m_root->setDataSvc( this );
164  // No done with GaudiHive. preLoad().ignore();
165  }
166  return StatusCode::SUCCESS;
167 }
168 
174  clearStore().ignore();
175  return i_setRoot( std::move( root_path ), pRootAddr );
176 }
177 
184  if ( pRootAddr ) {
185  m_root = std::make_unique<RegEntry>( std::move( root_path ) );
186  m_root->makeHard( pRootAddr );
187  m_root->setDataSvc( this );
188  // Not done with GaudiHive. preLoad().ignore();
189  }
190  return StatusCode::SUCCESS;
191 }
192 
195  if ( pDataLoader ) pDataLoader->addRef();
197  if ( pDataLoader ) { pDataLoader->setDataProvider( dpsvc == nullptr ? this : dpsvc ).ignore(); }
198  m_dataLoader = pDataLoader;
199  return StatusCode::SUCCESS;
200 }
201 
203 StatusCode TsDataSvc::objectParent( const DataObject* pObject, IRegistry*& refpParent ) {
204  if ( !pObject ) return Status::INVALID_OBJECT;
205  return objectParent( pObject->registry(), refpParent );
206 }
208 StatusCode TsDataSvc::objectParent( const IRegistry* pRegistry, IRegistry*& refpParent ) {
210  if ( !checkRoot() ) return Status::INVALID_ROOT;
211  const RegEntry* node_entry = CAST_REGENTRY( const RegEntry*, pRegistry );
212  if ( !node_entry ) return Status::INVALID_OBJECT;
213  refpParent = node_entry->parent();
214  return StatusCode::SUCCESS;
215 }
216 
219  if ( !pObject ) return Status::INVALID_OBJECT;
220  return objectLeaves( pObject->registry(), leaves );
221 }
222 
227  if ( !pRegistry ) return Status::INVALID_OBJECT;
228  const RegEntry* node_entry = CAST_REGENTRY( const RegEntry*, pRegistry );
229  if ( !node_entry ) return Status::INVALID_OBJECT;
231  leaves.insert( leaves.end(), node_entry->leaves().begin(), node_entry->leaves().end() );
232  // leaves = node_entry->leaves();
233  return StatusCode::SUCCESS;
234 }
235 
237 StatusCode TsDataSvc::registerAddress( std::string_view fullPath, IOpaqueAddress* pAddress ) {
238  if ( fullPath.empty() ) return Status::INVALID_OBJ_PATH;
239  return registerAddress( fullPath.front() != SEPARATOR ? m_root.get() : nullptr, fullPath, pAddress );
240 }
241 
243 StatusCode TsDataSvc::registerAddress( IRegistry* parentObj, std::string_view objPath, IOpaqueAddress* pAddress ) {
244  if ( !checkRoot() ) return Status::INVALID_ROOT;
245  if ( objPath.empty() ) return Status::INVALID_OBJ_PATH;
246  if ( !parentObj ) {
247  if ( objPath.front() != SEPARATOR ) { return registerAddress( m_root.get(), objPath, pAddress ); }
248  auto sep = find( objPath, SEPARATOR, 1 );
249  if ( sep == std::string_view::npos || objPath.substr( 0, sep ) != m_rootName.value() ) {
250  return Status::INVALID_PARENT;
251  }
252  return registerAddress( m_root.get(), objPath.substr( sep ), pAddress );
253  }
254  if ( objPath.front() != SEPARATOR ) { return registerAddress( parentObj, SEPARATOR + objPath, pAddress ); }
255  RegEntry* par_entry = CAST_REGENTRY( RegEntry*, parentObj );
256  if ( !par_entry ) return Status::INVALID_PARENT;
257  auto sep = objPath.rfind( SEPARATOR );
258  if ( sep > 0 && sep != std::string_view::npos ) {
259  auto p_path = objPath.substr( 0, sep );
260  auto o_path = objPath.substr( sep );
261  RegEntry* p_entry = par_entry->findLeaf( p_path );
262  // Create default object leafs if the
263  // intermediate nodes are not present
264  if ( !p_entry && m_forceLeaves ) {
265  DataObject* pLeaf = createDefaultObject();
266  StatusCode sc = registerObject( par_entry->identifier(), p_path, pLeaf );
267  if ( !sc.isSuccess() ) delete pLeaf;
268  p_entry = par_entry->findLeaf( p_path );
269  }
270  if ( !p_entry ) return Status::INVALID_PARENT;
271  return registerAddress( p_entry, o_path, pAddress );
272  }
273  StatusCode status = par_entry->add( std::string{ objPath }, pAddress );
274  return status.isSuccess() ? status : Status::DOUBL_OBJ_PATH;
275 }
276 
278 StatusCode TsDataSvc::unregisterAddress( std::string_view fullPath ) {
279  if ( fullPath.empty() ) return Status::INVALID_OBJ_PATH;
280  return unregisterAddress( fullPath.front() != SEPARATOR ? m_root.get() : nullptr, fullPath );
281 }
282 
284 StatusCode TsDataSvc::unregisterAddress( IRegistry* pParent, std::string_view objPath ) {
285  if ( !checkRoot() ) return Status::INVALID_ROOT;
286 
287  if ( objPath.empty() ) return Status::INVALID_OBJ_PATH;
288  if ( !pParent ) {
289  if ( objPath.front() != SEPARATOR ) { return unregisterAddress( m_root.get(), objPath ); }
290  auto sep = find( objPath, SEPARATOR, 1 );
291  if ( sep == std::string_view::npos || objPath.substr( 0, sep ) != m_rootName.value() ) {
292  return Status::INVALID_PARENT;
293  }
294  return unregisterAddress( m_root.get(), objPath.substr( sep ) );
295  }
296  if ( objPath.front() != SEPARATOR ) { return unregisterAddress( pParent, SEPARATOR + objPath ); }
297  RegEntry* node_entry = CAST_REGENTRY( RegEntry*, pParent );
298  if ( node_entry ) {
299  RegEntry* leaf_entry = node_entry->findLeaf( objPath );
300  if ( leaf_entry ) {
301  auto sep = objPath.rfind( SEPARATOR );
302  if ( sep > 0 && sep != std::string_view::npos ) {
303  return unregisterAddress( leaf_entry->parent(), objPath.substr( sep ) );
304  }
305  StatusCode status = node_entry->remove( objPath );
306  if ( status.isSuccess() ) return status;
307  }
308  }
309  return Status::INVALID_PARENT;
310 }
311 
313 StatusCode TsDataSvc::registerObject( std::string_view parentPath, std::string_view objPath, DataObject* pObject ) {
314  DataObject* pO = nullptr;
315  StatusCode status = retrieveObject( parentPath, pO );
316  if ( !status.isSuccess() && m_forceLeaves ) {
317  pO = createDefaultObject();
318  status = registerObject( parentPath, pO );
319  if ( !status.isSuccess() ) pO->release();
320  }
321  return status.isSuccess() ? registerObject( pO, objPath, pObject ) : status;
322 }
323 
325 StatusCode TsDataSvc::registerObject( DataObject* parentObj, std::string_view objPath, DataObject* pObject ) {
326  if ( !checkRoot() ) return Status::INVALID_ROOT;
327  if ( !parentObj ) {
328  if ( !objPath.empty() ) {
329  if ( objPath.front() != SEPARATOR ) { return registerObject( m_rootName.value(), objPath, pObject ); }
330  auto sep = find( objPath, SEPARATOR, 1 );
331  if ( sep != std::string_view::npos ) {
332  return registerObject( objPath.substr( 0, sep ), objPath.substr( sep ), pObject );
333  }
334  }
335  return Status::INVALID_OBJ_PATH;
336  }
337  RegEntry* node_entry = CAST_REGENTRY( RegEntry*, parentObj->registry() );
338  if ( node_entry ) {
339  StatusCode status = Status::INVALID_PARENT;
340  auto sep = find( objPath, SEPARATOR, 1 );
341  if ( sep != std::string_view::npos ) {
342  auto p_path = objPath.substr( 0, sep );
343  auto o_path = objPath.substr( sep );
344  RegEntry* par_entry = node_entry->findLeaf( p_path );
345  // Create default object leafs if the
346  // intermediate nodes are not present
347  if ( !par_entry && m_forceLeaves ) {
348  DataObject* pLeaf = createDefaultObject();
349  StatusCode sc = registerObject( parentObj, p_path, pLeaf );
350  if ( !sc.isSuccess() ) delete pLeaf;
351  par_entry = node_entry->findLeaf( p_path );
352  } else if ( par_entry && !par_entry->object() ) {
353  status = retrieveEntry( node_entry, p_path, par_entry );
354  if ( !status.isSuccess() && !par_entry->address() && m_forceLeaves ) {
355  DataObject* pLeaf = createDefaultObject();
356  StatusCode sc = registerObject( parentObj, p_path, pLeaf );
357  if ( !sc.isSuccess() ) delete pLeaf;
358  par_entry = node_entry->findLeaf( p_path );
359  }
360  }
361  node_entry = par_entry;
362  if ( node_entry ) {
363  DataObject* obj = node_entry->object();
364  if ( obj ) status = registerObject( obj, o_path, pObject );
365  }
366  } else {
367  RegEntry* leaf = node_entry->findLeaf( objPath );
368  if ( !leaf ) {
369  status = node_entry->add( std::string{ objPath }, pObject );
370  } else {
371  DataObject* obj = leaf->object();
372  if ( !obj ) {
373  if ( !pObject ) {
374  error() << "registerObject: trying to register null DataObject" << endmsg;
375  return StatusCode::FAILURE;
376  } else {
377  pObject->setRegistry( leaf );
378  }
379  leaf->setAddress( nullptr );
380  leaf->setObject( pObject );
381  status = StatusCode::SUCCESS;
382  } else {
383  status = Status::DOUBL_OBJ_PATH;
384  }
385  }
386  }
387  return status;
388  }
389  return Status::INVALID_PARENT;
390 }
391 
393 StatusCode TsDataSvc::unregisterObject( std::string_view fullPath ) {
394  DataObject* pObject = nullptr;
395  StatusCode status = findObject( fullPath, pObject );
396  if ( status.isFailure() ) return status;
397  RegEntry* pEntry = CAST_REGENTRY( RegEntry*, pObject->registry() );
398  if ( !pEntry ) return Status::INVALID_ROOT;
399  if ( !pEntry->isEmpty() ) return Status::DIR_NOT_EMPTY;
400  RegEntry* pParent = pEntry->parentEntry();
401  if ( !pParent ) return Status::INVALID_PARENT;
402  if ( pObject ) pObject->addRef();
403  pParent->remove( pEntry );
404  return StatusCode::SUCCESS;
405 }
406 
409  if ( !checkRoot() ) return Status::INVALID_ROOT;
410  RegEntry* entry = m_root->findLeaf( pObject );
411  if ( !entry ) return Status::INVALID_OBJECT;
412  RegEntry* parent = entry->parentEntry();
413  if ( !parent ) return Status::INVALID_PARENT;
414  if ( !entry->isEmpty() ) return Status::DIR_NOT_EMPTY;
415  if ( entry->object() ) entry->object()->addRef();
416  if ( parent ) parent->remove( entry );
417  return StatusCode::SUCCESS;
418 }
419 
421 StatusCode TsDataSvc::unregisterObject( DataObject* pParentObj, std::string_view objectPath ) {
422  if ( !checkRoot() ) return Status::INVALID_ROOT;
423  try {
424  RegEntry* parent = CAST_REGENTRY( RegEntry*, pParentObj->registry() );
425  if ( parent ) {
426  RegEntry* entry = parent->findLeaf( objectPath );
427  if ( !entry ) return Status::INVALID_OBJECT;
428  if ( !entry->isEmpty() ) return Status::DIR_NOT_EMPTY;
429  if ( entry->object() ) entry->object()->addRef();
430  parent->remove( entry );
431  return StatusCode::SUCCESS;
432  }
433  } catch ( ... ) {}
434  return Status::INVALID_PARENT;
435 }
436 
440  if ( m_enableFaultHdlr ) {
441  IRegistry* pLeaf = nullptr;
442  if ( pReg && path.empty() ) {
443  DataIncident incident( name(), m_faultName, pReg->identifier() );
444  m_incidentSvc->fireIncident( incident );
445  return pReg->object();
446  } else if ( pReg ) {
447  std::string p = pReg->identifier();
448  if ( path.front() != SEPARATOR ) p += SEPARATOR;
449  p.append( path.data(), path.size() );
450  DataIncident incident( name(), m_faultName, p );
451  m_incidentSvc->fireIncident( incident );
452  pLeaf = m_root->findLeaf( p );
453  } else {
455  if ( path.front() != SEPARATOR ) p += SEPARATOR;
456  p.append( path.data(), path.size() );
457  DataIncident incident( name(), m_faultName, p );
458  m_incidentSvc->fireIncident( incident );
459  pLeaf = m_root->findLeaf( p );
460  }
461  if ( pLeaf ) return pLeaf->object();
462  }
463  return nullptr;
464 }
465 
470  IConversionSvc* pLoader = getDataLoader( pRegistry );
471  return loadObject( pLoader, pRegistry );
472 }
473 
478  StatusCode status = Status::INVALID_OBJ_ADDR;
479  DataObject* pObject = nullptr;
481  if ( !pLoader ) { // Precondition: Data loader must be present
482  if ( handleDataFault( pRegistry ) )
483  return StatusCode::SUCCESS;
484  else
485  return Status::NO_DATA_LOADER;
486  }
487  if ( !pRegistry ) { // Precondition: Directory must be valid
488  if ( handleDataFault( pRegistry ) )
489  return StatusCode::SUCCESS;
490  else
491  return Status::INVALID_OBJ_ADDR;
492  }
493 
494  VERMSG << "Requested object " << pRegistry->identifier() << endmsg;
495 
496  if ( m_enableAccessHdlr ) {
497  // Fire data access incident
498  DataIncident incident( name(), m_accessName, pRegistry->identifier() );
499  m_incidentSvc->fireIncident( incident );
500  }
501  if ( !m_inhibitPathes.empty() ) {
502  const auto& ident = pRegistry->identifier();
503  auto inhibit = std::find( m_inhibitPathes.begin(), m_inhibitPathes.end(), ident );
504  if ( inhibit != m_inhibitPathes.end() ) return Status::NO_ACCESS;
505  }
506  IOpaqueAddress* pAddress = pRegistry->address();
507  if ( !pAddress ) { // Precondition:
508  return Status::INVALID_OBJ_ADDR; // Address must be valid
509  }
510  try {
511  status = pLoader->createObj( pAddress, pObject ); // Call data loader
512  if ( status.isSuccess() ) {
513 
514  VERMSG << "Object " << pRegistry->identifier() << " created" << endmsg;
515 
516  RegEntry* pEntry = CAST_REGENTRY( RegEntry*, pRegistry );
517  pEntry->setObject( pObject );
518 
519  VERMSG << "Filling object " << pRegistry->identifier() << endmsg;
520  status = pLoader->fillObjRefs( pAddress, pObject );
521  }
522  } catch ( const GaudiException& exc ) {
523  if ( handleDataFault( pRegistry ) ) return StatusCode::SUCCESS;
524  throw GaudiException( "GaudiException in loadObject() " + pRegistry->identifier(), name(), StatusCode::FAILURE,
525  exc );
526  } catch ( const std::exception& x ) {
527  if ( handleDataFault( pRegistry ) ) return StatusCode::SUCCESS;
528  throw GaudiException( "std::exception in loadObject() " + pRegistry->identifier() + ": " +
529  System::typeinfoName( typeid( x ) ) + ", " + x.what(),
531  } catch ( ... ) {
532  if ( handleDataFault( pRegistry ) ) return StatusCode::SUCCESS;
533  throw GaudiException( "UNKN exception in loadObject() " + pRegistry->identifier(), name(), StatusCode::FAILURE );
534  }
535  if ( !status.isSuccess() ) {
536  if ( handleDataFault( pRegistry ) ) return StatusCode::SUCCESS;
537  }
538  ON_VERBOSE if ( status.isSuccess() ) {
539  verbose() << "Object " << pRegistry->identifier() << " successfully loaded" << endmsg;
540  }
541  return status;
542 }
543 
545 StatusCode TsDataSvc::retrieveEntry( RegEntry* parentObj, std::string_view path, RegEntry*& pEntry ) {
546  auto sep = find( path, SEPARATOR, 1 );
547  StatusCode status = Status::INVALID_ROOT;
548  pEntry = nullptr;
550  // A.Valassi 16.08.2001 avoid core dump if store is empty
551  if ( checkRoot() ) {
552  if ( !parentObj ) {
553  if ( path.empty() || path == m_rootName ) return retrieveEntry( m_root.get(), "", pEntry );
554  if ( path.front() != SEPARATOR ) return retrieveEntry( m_root.get(), path, pEntry );
555  if ( sep == std::string_view::npos ) return Status::INVALID_OBJ_PATH;
556  if ( !m_root->object() ) {
557  RegEntry* r = nullptr;
558  status = retrieveEntry( m_root.get(), "", r );
559  if ( !status.isSuccess() ) return status;
560  }
561  return retrieveEntry( m_root.get(), path.substr( sep ), pEntry );
562  }
563  if ( sep != std::string_view::npos ) { // the string contains a separator (after pos 0)
564  auto p_path = path.substr( 0, sep );
565  auto o_path = path.substr( sep );
566  if ( !parentObj->object() ) { // if the parent object has not been loaded yet, load it now
567  status = loadObject( parentObj );
568  if ( !status.isSuccess() ) return status;
569  }
570  RegEntry* root_entry = parentObj->findLeaf( p_path );
571  if ( !root_entry && m_enableFaultHdlr ) {
572  // If not even the parent is there, an incident
573  // to load the parent must be fired...
574  handleDataFault( parentObj, p_path );
575  root_entry = parentObj->findLeaf( p_path );
576  }
577  if ( root_entry ) {
578  DataObject* pO = root_entry->object();
579  if ( !pO ) {
580  // Object is not loaded: load the object if at all possible
581  status = loadObject( root_entry );
582  if ( !status.isSuccess() ) return status;
583  }
584  if ( root_entry->isSoft() ) { root_entry = CAST_REGENTRY( RegEntry*, pO->registry() ); }
585  return retrieveEntry( root_entry, o_path, pEntry );
586  }
587  return Status::INVALID_OBJ_PATH;
588  } else if ( path.empty() ) {
589  pEntry = parentObj;
590  } else {
591  if ( !parentObj->object() ) { // if the parent object has not been loaded yet, load it now
592  status = loadObject( parentObj );
593  if ( !status.isSuccess() ) return status;
594  }
595  // last leave in search: find leaf and load
596  pEntry = parentObj->findLeaf( path );
597  // If no registry entry was found, trigger incident for action-on-demand
598  if ( !pEntry && m_enableFaultHdlr ) {
599  handleDataFault( parentObj, path );
600  pEntry = ( path.empty() ? parentObj : parentObj->findLeaf( path ) );
601  }
602  }
603  // Check results and return
604  if ( !pEntry ) {
605  status = Status::INVALID_OBJ_PATH;
606  } else if ( !pEntry->object() ) {
607  status = loadObject( pEntry );
608  } else if ( m_enableAccessHdlr ) {
609  // Fire data access incident
610  // I do not know if this is a good idea....
611  // This fires too often!
612  //
613  // DataIncident incident(name(), m_accessName, pEntry->identifier());
614  // m_incidentSvc->fireIncident(incident);
615  status = StatusCode::SUCCESS;
616  } else {
617  status = StatusCode::SUCCESS;
618  }
619  }
620  return status;
621 }
622 
624 StatusCode TsDataSvc::retrieveObject( IRegistry* pRegistry, std::string_view path, DataObject*& pObject ) {
625  pObject = nullptr;
626  RegEntry * result = nullptr, *parent = CAST_REGENTRY( RegEntry*, pRegistry );
627  StatusCode status = retrieveEntry( parent, path, result );
628  if ( status.isSuccess() ) pObject = result->object();
629  return status;
630 }
631 
633 StatusCode TsDataSvc::findObject( IRegistry* pRegistry, std::string_view path, DataObject*& pObject ) {
635  pObject = nullptr;
636  IRegistry* pReg = ( pRegistry ? pRegistry : m_root.get() );
637  RegEntry* root_entry = CAST_REGENTRY( RegEntry*, pReg );
638  if ( root_entry ) {
639  if ( !path.empty() ) pReg = root_entry->find( path );
640  if ( !pReg ) return Status::INVALID_OBJ_PATH;
641  pObject = pReg->object();
642  }
643  return pObject ? Status::IDataProviderSvc_NO_ERROR : Status::OBJ_NOT_LOADED;
644 }
645 
647 StatusCode TsDataSvc::findObject( std::string_view path, DataObject*& pObject ) {
648  pObject = nullptr;
650  if ( !checkRoot() ) return Status::INVALID_ROOT;
651  if ( path.empty() || path == m_rootName ) {
652  pObject = m_root->object();
653  return !pObject ? Status::OBJ_NOT_LOADED : Status::IDataProviderSvc_NO_ERROR;
654  }
655  return findObject( path.front() != SEPARATOR ? m_root.get() : nullptr, path, pObject );
656 }
657 
660  if ( !pRegistry ) return Status::INVALID_OBJ_ADDR; // Precondition: Addres must be valid
661  DataObject* toUpdate = pRegistry->object();
662  return toUpdate ? updateObject( toUpdate ) : loadObject( pRegistry );
663 }
664 
667  StatusCode status = Status::INVALID_OBJ_ADDR;
668  if ( !toUpdate ) return Status::INVALID_OBJECT; // Precondition: Address must be valid
669  IRegistry* pRegistry = toUpdate->registry();
670  if ( !pRegistry ) return Status::INVALID_OBJECT; // Precondition: Need valid registry
671  IOpaqueAddress* pAddress = pRegistry->address();
672  if ( !pAddress ) return Status::INVALID_OBJ_ADDR; // Precondition: Need valid address
674  IConversionSvc* pLoader = getDataLoader( pRegistry );
675  if ( !pLoader ) return Status::NO_DATA_LOADER; // Precondition: Data loader must be present
676  if ( !m_inhibitPathes.empty() ) {
677  auto& ident = pRegistry->identifier();
678  auto inhibit = std::find( m_inhibitPathes.begin(), m_inhibitPathes.end(), ident );
679  if ( inhibit != m_inhibitPathes.end() ) return Status::NO_ACCESS;
680  }
681  try {
682  status = pLoader->updateObj( pAddress, toUpdate ); // Call data loader
683  if ( status.isSuccess() ) { status = pLoader->updateObjRefs( pAddress, toUpdate ); }
684  } catch ( const GaudiException& exc ) {
685  throw GaudiException( "GaudiException in updateObject() " + pRegistry->name(), name(), StatusCode::FAILURE, exc );
686  } catch ( const std::exception& x ) {
687  throw GaudiException( "std::exception in updateObject() " + pRegistry->name() + ": " +
688  System::typeinfoName( typeid( x ) ) + ", " + x.what(),
690  } catch ( ... ) {
691  throw GaudiException( "UNKN exception in updateObject() " + pRegistry->name(), name(), StatusCode::FAILURE );
692  }
693  return status;
694 }
695 
696 // Link object
697 StatusCode TsDataSvc::linkObject( IRegistry* from, std::string_view objPath, DataObject* to ) {
699  if ( !checkRoot() ) return Status::INVALID_ROOT;
700  try {
701  RegEntry* from_entry = CAST_REGENTRY( RegEntry*, from );
702  if ( from_entry ) {
703  // First check if both objects are already registered to the store
704  RegEntry* to_entry = m_root->findLeaf( to );
705  if ( !to_entry ) return Status::INVALID_OBJECT;
706  auto sep = objPath.rfind( SEPARATOR );
707  if ( sep > 0 && sep != std::string_view::npos ) { // in case the objPath is a sub-directory itself
708  DataObject* pO = nullptr;
709  StatusCode sc = retrieveObject( from, objPath.substr( 0, sep ), pO );
710  return sc.isSuccess() ? linkObject( pO->registry(), objPath.substr( sep ), to ) : sc;
711  }
712  // Now register the soft link
713  StatusCode status = from_entry->add( std::string{ objPath }, to, true );
714  return status.isSuccess() ? Status::IDataProviderSvc_NO_ERROR : Status::DOUBL_OBJ_PATH;
715  }
716  } catch ( ... ) {}
717  return Status::INVALID_PARENT;
718 }
719 
721 StatusCode TsDataSvc::linkObject( std::string_view fullPath, DataObject* to ) {
722  if ( fullPath.empty() ) return Status::INVALID_OBJ_PATH;
723  if ( fullPath.front() == SEPARATOR ) {
724  auto sep = fullPath.rfind( SEPARATOR );
725  return linkObject( fullPath.substr( 0, sep ), fullPath.substr( sep ), to );
726  }
728  return linkObject( m_root.get(), fullPath, to );
729 }
730 
732 StatusCode TsDataSvc::unlinkObject( IRegistry* from, std::string_view objPath ) {
734  if ( !checkRoot() ) return Status::INVALID_ROOT;
735  try {
736  RegEntry* from_entry = CAST_REGENTRY( RegEntry*, from );
737  if ( from_entry ) {
738  auto sep = objPath.rfind( SEPARATOR );
739  if ( sep > 0 && sep != std::string_view::npos ) { // in case the objPath is a sub-directory itself
740  DataObject* pO = nullptr;
741  StatusCode sc = findObject( from, objPath.substr( 0, sep ), pO );
742  return sc.isSuccess() ? unlinkObject( pO->registry(), objPath.substr( sep ) ) : sc;
743  }
744  StatusCode status = from_entry->remove( objPath );
745  return status.isSuccess() ? status : Status::INVALID_OBJ_PATH;
746  }
747  } catch ( ... ) {}
748  return Status::INVALID_PARENT;
749 }
750 
752 StatusCode TsDataSvc::unlinkObject( std::string_view fullPath ) {
753  if ( fullPath.empty() ) return Status::INVALID_OBJ_PATH;
754  if ( fullPath.front() != SEPARATOR ) { return unlinkObject( m_root.get(), fullPath ); }
755  auto sep = fullPath.rfind( SEPARATOR );
756  return unlinkObject( fullPath.substr( 0, sep ), fullPath.substr( sep ) );
757 }
758 
760 StatusCode TsDataSvc::unlinkObject( DataObject* from, std::string_view objPath ) {
761  if ( !checkRoot() ) return Status::INVALID_ROOT;
762  return unlinkObject( m_root->findLeaf( from ), objPath );
763 }
764 
767  auto i = std::find( m_preLoads.begin(), m_preLoads.end(), item );
768  if ( i == m_preLoads.end() ) m_preLoads.push_back( item );
769  return StatusCode::SUCCESS;
770 }
771 
774  auto i = std::remove( m_preLoads.begin(), m_preLoads.end(), item );
775  m_preLoads.erase( i, m_preLoads.end() );
776  return StatusCode::SUCCESS;
777 }
778 
781  m_preLoads.clear();
782  return StatusCode::SUCCESS;
783 }
784 
786 StatusCode TsDataSvc::preLoad( int depth, int load_depth, DataObject* pObject ) {
787  // unused: StatusCode sc = StatusCode::FAILURE;
788  if ( pObject && depth++ < load_depth ) {
789  RegEntry* dir = CAST_REGENTRY( RegEntry*, pObject->registry() );
790  if ( dir ) {
791  for ( const auto& i : *dir ) {
792  DataObject* pObj = nullptr;
793  StatusCode status = retrieveObject( pObject, i->name(), pObj );
794  if ( status.isSuccess() && depth < load_depth ) { preLoad( depth, load_depth, pObj ).ignore(); }
795  }
796  }
797  }
798  return StatusCode::SUCCESS;
799 }
800 
803  DataObject* pObj = nullptr;
804  for ( const auto& i : m_preLoads ) {
805  StatusCode sc = retrieveObject( i.path(), pObj );
806  int load_depth = i.depth();
807  if ( sc.isSuccess() && load_depth > 1 ) { preLoad( 1, load_depth, pObj ).ignore(); }
808  }
809  return StatusCode::SUCCESS;
810 }
811 
814  // Nothing to do: just call base class initialisation
816  if ( !sc.isSuccess() ) return sc;
817  sc = service( "IncidentSvc", m_incidentSvc, true );
818  if ( !sc.isSuccess() ) { error() << "Failed to access incident service." << endmsg; }
819  return sc;
820 }
821 
824  StatusCode sc;
825  // the finalize part is copied here
826  setDataLoader( nullptr ).ignore();
827  resetPreLoad().ignore();
828  clearStore().ignore();
829  if ( m_incidentSvc ) {
831  m_incidentSvc = nullptr;
832  }
833  // re-initialize the base class
834  sc = Service::reinitialize();
835  if ( !sc.isSuccess() ) {
836  error() << "Unable to reinitialize base class" << endmsg;
837  return sc;
838  }
839  // the initialize part is copied here
840  sc = service( "IncidentSvc", m_incidentSvc, true );
841  if ( !sc.isSuccess() ) {
842  error() << "Failed to access incident service." << endmsg;
843  return sc;
844  }
845  // return
846  return StatusCode::SUCCESS;
847 }
848 
851  // Nothing to do: just call base class initialisation
852  setDataLoader( nullptr ).ignore();
853  resetPreLoad().ignore();
854  clearStore().ignore();
855  if ( m_incidentSvc ) {
857  m_incidentSvc = nullptr;
858  }
859  return Service::finalize();
860 }
861 
863 CLID TsDataSvc::rootCLID() const { return ( (CLID)m_rootCLID ); }
864 
866 const std::string& TsDataSvc::rootName() const { return ( m_rootName ); }
867 
870 
TsDataSvc::loadObject
virtual StatusCode loadObject(IRegistry *pNode)
Invoke Persistency service to create transient object from its persistent representation.
Definition: TsDataSvc.cpp:469
TsDataSvc::m_preLoads
std::vector< DataStoreItem > m_preLoads
Items to be pre-loaded.
Definition: TsDataSvc.h:87
TsDataSvc::m_inhibitPathes
Gaudi::Property< std::vector< std::string > > m_inhibitPathes
Definition: TsDataSvc.h:76
CAST_REGENTRY
#define CAST_REGENTRY(x, y)
Definition: TsDataSvc.cpp:75
DataSvcHelpers::RegistryEntry::find
IRegistry * find(const IRegistry *obj) const
Try to find an object identified by its pointer.
Definition: RegistryEntry.h:149
TsDataSvc::m_root
std::unique_ptr< DataSvcHelpers::RegistryEntry > m_root
Pointer to root entry.
Definition: TsDataSvc.h:89
DataObject::setRegistry
void setRegistry(IRegistry *pRegistry)
Set pointer to Registry.
Definition: DataObject.h:80
GaudiPython.Bindings.DataObject
DataObject
Definition: Bindings.py:82
TsDataSvc::removePreLoadItem
StatusCode removePreLoadItem(const DataStoreItem &item) override
Remove an item from the preload list.
Definition: TsDataSvc.cpp:773
Service::initialize
StatusCode initialize() override
Definition: Service.cpp:118
DataSvcHelpers::RegistryEntry::setAddress
void setAddress(IOpaqueAddress *pAddress) override
Set/Update Opaque address.
Definition: RegistryEntry.cpp:119
DataObject::name
const std::string & name() const
Retreive DataObject name. It is the name when registered in the store.
Definition: DataObject.cpp:72
TsDataSvc::setDataLoader
StatusCode setDataLoader(IConversionSvc *svc, IDataProviderSvc *dpsvc=nullptr) override
IDataManagerSvc: IDataManagerSvc: Pass a default data loader to the service and optionally a data pro...
Definition: TsDataSvc.cpp:194
std::string
STL class.
TsDataSvc.h
std::exception
STL class.
std::move
T move(T... args)
DataSvcHelpers::RegistryEntry::findLeaf
RegistryEntry * findLeaf(std::string_view path) const
Find identified leaf in this registry node.
Definition: RegistryEntry.h:103
GaudiAlg.HistoUtils.path
path
Definition: HistoUtils.py:960
StatusCode::isSuccess
bool isSuccess() const
Definition: StatusCode.h:314
TsDataSvc::rootCLID
CLID rootCLID() const override
IDataManagerSvc: Accessor for root event CLID.
Definition: TsDataSvc.cpp:863
DataSvcHelpers::RegistryEntry::isSoft
bool isSoft() const
Is the link soft or hard.
Definition: RegistryEntry.h:137
GaudiException.h
TsDataSvc::linkObject
StatusCode linkObject(IRegistry *from, std::string_view objPath, DataObject *to) override
Add a link to another object.
Definition: TsDataSvc.cpp:697
gaudirun.s
string s
Definition: gaudirun.py:346
IOpaqueAddress
Definition: IOpaqueAddress.h:33
TsDataSvc::preLoad
StatusCode preLoad() override
load all preload items of the list
Definition: TsDataSvc.cpp:802
std::vector< IRegistry * >
std::find
T find(T... args)
DataObject::release
virtual unsigned long release()
release reference to object
Definition: DataObject.cpp:56
GaudiException
Definition: GaudiException.h:31
TsDataSvc::getDataLoader
virtual IConversionSvc * getDataLoader(IRegistry *pReg)
Retrieve customizable data loader according to registry entry to be retrieved.
Definition: TsDataSvc.cpp:874
TsDataSvc::checkRoot
bool checkRoot()
Check if root path is valid.
Definition: TsDataSvc.h:272
STD_LOCK_GUARD_MACRO
#define STD_LOCK_GUARD_MACRO
Definition: TsDataSvc.cpp:54
std::unique_ptr::get
T get(T... args)
TsDataSvc::finalize
StatusCode finalize() override
Service initialization.
Definition: TsDataSvc.cpp:850
DataIncident.h
TsDataSvc::m_enableFaultHdlr
Gaudi::Property< bool > m_enableFaultHdlr
Definition: TsDataSvc.h:78
IConverter::createObj
virtual StatusCode createObj(IOpaqueAddress *pAddress, DataObject *&refpObject)=0
Create the transient representation of an object.
DataSvcHelpers::RegistryEntry::makeHard
void makeHard(DataObject *pObject)
Initialize link as hard link.
Definition: RegistryEntry.cpp:105
TsDataSvc::i_setRoot
virtual StatusCode i_setRoot(std::string root_name, DataObject *pRootObj)
Initialize data store for new event by giving new event path and root object.
Definition: TsDataSvc.cpp:159
gaudirun.c
c
Definition: gaudirun.py:525
IRegistry
Definition: IRegistry.h:32
TsDataSvc::handleDataFault
DataObject * handleDataFault(IRegistry *pReg, std::string_view path={})
Invoke data fault handling if enabled.
Definition: TsDataSvc.cpp:439
System::typeinfoName
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition: System.cpp:313
TsDataSvc::registerObject
StatusCode registerObject(std::string_view parentPath, std::string_view objPath, DataObject *pObject) override
Register object with the data store.
Definition: TsDataSvc.cpp:313
TsDataSvc::initialize
StatusCode initialize() override
Service initialization.
Definition: TsDataSvc.cpp:813
VERMSG
#define VERMSG
Definition: TsDataSvc.cpp:83
TsDataSvc::clearStore
StatusCode clearStore() override
IDataManagerSvc: Remove all data objects in the data store.
Definition: TsDataSvc.cpp:114
std::unique_ptr::reset
T reset(T... args)
IIncidentSvc::fireIncident
virtual void fireIncident(const Incident &incident)=0
Fire an Incident.
Service::finalize
StatusCode finalize() override
Definition: Service.cpp:222
TsDataSvc::m_forceLeaves
Gaudi::Property< bool > m_forceLeaves
Definition: TsDataSvc.h:74
RegistryEntry.h
std::vector::clear
T clear(T... args)
TsDataSvc::setRoot
StatusCode setRoot(std::string root_name, DataObject *pRootObj) override
Initialize data store for new event by giving new event path and root object.
Definition: TsDataSvc.cpp:149
TsDataSvc::createDefaultObject
virtual DataObject * createDefaultObject() const
Create default objects in case forced creation of leaves is requested.
Definition: TsDataSvc.cpp:869
IIncidentSvc.h
std::vector::push_back
T push_back(T... args)
IConverter::setDataProvider
virtual StatusCode setDataProvider(IDataProviderSvc *pService)=0
Set Data provider service.
DataSvcHelpers::RegistryEntry::address
IOpaqueAddress * address() const override
Retrieve opaque storage address.
Definition: RegistryEntry.h:133
IRegistry::name
virtual const name_type & name() const =0
Name of the directory (or key)
TsDataSvc::m_rootName
Gaudi::Property< std::string > m_rootName
Definition: TsDataSvc.h:73
DataSvcHelpers::RegistryEntry::leaves
const Store & leaves() const
Access the leaves of the object.
Definition: RegistryEntry.h:139
DataSvcHelpers::RegistryEntry::object
DataObject * object() const override
Retrive object behind the link.
Definition: RegistryEntry.h:131
TsDataSvc::reinitialize
StatusCode reinitialize() override
Service initialization.
Definition: TsDataSvc.cpp:823
Service::name
const std::string & name() const override
Retrieve name of the service
Definition: Service.cpp:332
StatusCode
Definition: StatusCode.h:65
TsDataSvc::objectParent
StatusCode objectParent(const DataObject *pObject, IRegistry *&refpParent) override
IDataManagerSvc: Explore the object store: retrieve the object's parent.
Definition: TsDataSvc.cpp:203
DataStoreItem
Definition: DataStoreItem.h:27
DataIncident
IOpaqueAddress.h
DataSvcHelpers::RegistryEntry::remove
StatusCode remove(std::string_view name)
Remove an entry from the store.
Definition: RegistryEntry.cpp:152
DataSvcHelpers::RegistryEntry::setObject
void setObject(DataObject *obj)
Set/Update object address.
Definition: RegistryEntry.cpp:129
Gaudi::Property::value
const ValueType & value() const
Definition: Property.h:239
TsDataSvc::traverseSubTree
StatusCode traverseSubTree(std::string_view sub_tree_path, IDataStoreAgent *pAgent) override
IDataManagerSvc: Analyze by traversing all data objects below the sub tree identified by its full pat...
Definition: TsDataSvc.cpp:123
RegEntry
DataSvcHelpers::RegistryEntry RegEntry
Definition: TsDataSvc.cpp:77
TsDataSvc::addPreLoadItem
StatusCode addPreLoadItem(const DataStoreItem &item) override
Add an item to the preload list.
Definition: TsDataSvc.cpp:766
std::vector::erase
T erase(T... args)
DataSvcHelpers::RegistryEntry::isEmpty
bool isEmpty() const
Simple check if the Container is empty.
Definition: RegistryEntry.h:143
CLID
unsigned int CLID
Class ID definition.
Definition: ClassID.h:18
genconfuser.verbose
verbose
Definition: genconfuser.py:28
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:203
TsDataSvc::m_faultName
Gaudi::Property< std::string > m_faultName
Definition: TsDataSvc.h:80
DataSvcHelpers::RegistryEntry::parent
IRegistry * parent() const
Pointer to parent directory entry.
Definition: RegistryEntry.h:135
std::remove
T remove(T... args)
DataSvcHelpers::RegistryEntry::setDataSvc
void setDataSvc(IDataProviderSvc *s)
Set the transient data store.
Definition: RegistryEntry.h:99
std::string::append
T append(T... args)
TsDataSvc::registerAddress
StatusCode registerAddress(std::string_view fullPath, IOpaqueAddress *pAddress) override
IDataManagerSvc: Register object address with the data store.
Definition: TsDataSvc.cpp:237
IConverter.h
TsDataSvc::retrieveEntry
StatusCode retrieveEntry(DataSvcHelpers::RegistryEntry *pNode, std::string_view path, DataSvcHelpers::RegistryEntry *&pEntry)
Retrieve registry entry from store.
Definition: TsDataSvc.cpp:545
StatusCode::ignore
const StatusCode & ignore() const
Allow discarding a StatusCode without warning.
Definition: StatusCode.h:139
TsDataSvc::traverseTree
StatusCode traverseTree(IDataStoreAgent *pAgent) override
IDataManagerSvc: Analyze by traversing all data objects in the data store.
Definition: TsDataSvc.cpp:139
SEPARATOR
constexpr char SEPARATOR
Definition: RegistryEntry.cpp:50
TsDataSvc::rootName
const std::string & rootName() const override
IDataManagerSvc: Accessor for root event name.
Definition: TsDataSvc.cpp:866
IRegistry::address
virtual IOpaqueAddress * address() const =0
Retrieve opaque storage address.
StatusCode::isFailure
bool isFailure() const
Definition: StatusCode.h:129
ON_VERBOSE
#define ON_VERBOSE
Definition: TsDataSvc.cpp:80
TsDataSvc::unregisterAddress
StatusCode unregisterAddress(std::string_view fullPath) override
IDataManagerSvc: Unregister object address from the data store.
Definition: TsDataSvc.cpp:278
TsDataSvc::resetPreLoad
StatusCode resetPreLoad() override
Clear the preload list.
Definition: TsDataSvc.cpp:780
StatusCode::SUCCESS
constexpr static const auto SUCCESS
Definition: StatusCode.h:100
DataObject.h
TsDataSvc::findObject
StatusCode findObject(std::string_view fullPath, DataObject *&pObject) override
Find object identified by its full path in the data store.
Definition: TsDataSvc.cpp:647
TsDataSvc::m_accessName
Gaudi::Property< std::string > m_accessName
Definition: TsDataSvc.h:84
Gaudi::Units::sr
constexpr double sr
Definition: SystemOfUnits.h:132
DataSvcHelpers::RegistryEntry
Definition: RegistryEntry.h:46
TsDataSvc::m_dataLoader
IConversionSvc * m_dataLoader
Pointer to data loader service.
Definition: TsDataSvc.h:68
TsDataSvc::unlinkObject
StatusCode unlinkObject(IRegistry *from, std::string_view objPath) override
Remove a link to another object.
Definition: TsDataSvc.cpp:732
std::vector::begin
T begin(T... args)
std::vector::insert
T insert(T... args)
TsDataSvc::updateObject
StatusCode updateObject(IRegistry *pDirectory) override
Update object identified by its directory entry.
Definition: TsDataSvc.cpp:659
IRegistry::object
virtual DataObject * object() const =0
Retrieve object behind the link.
DataSvcHelpers::RegistryEntry::add
StatusCode add(std::string name, DataObject *pObject, bool is_soft=false)
Add entry to data store.
Definition: RegistryEntry.cpp:198
IRegistry::identifier
virtual const id_type & identifier() const =0
Full identifier (or key)
DataObject
Definition: DataObject.h:40
Service::reinitialize
StatusCode reinitialize() override
Definition: Service.cpp:295
TsDataSvc::m_incidentSvc
IIncidentSvc * m_incidentSvc
Pointer to incident service.
Definition: TsDataSvc.h:70
GaudiConfig2.semantics.ident
ident
Definition: semantics.py:198
TsDataSvc::unregisterObject
StatusCode unregisterObject(std::string_view fullPath) override
Unregister object from the data store.
Definition: TsDataSvc.cpp:393
DataSvcHelpers::RegistryEntry::identifier
const std::string & identifier() const override
Full identifier (or key)
Definition: RegistryEntry.h:127
IConverter::fillObjRefs
virtual StatusCode fillObjRefs(IOpaqueAddress *pAddress, DataObject *pObject)=0
Resolve the references of the created transient object.
std::vector::end
T end(T... args)
IDataProviderSvc
Definition: IDataProviderSvc.h:53
TsDataSvc::objectLeaves
StatusCode objectLeaves(const DataObject *pObject, std::vector< IRegistry * > &refLeaves) override
IDataManagerSvc: Explore the object store: retrieve all leaves attached to the object.
Definition: TsDataSvc.cpp:218
StatusCode::FAILURE
constexpr static const auto FAILURE
Definition: StatusCode.h:101
IConversionSvc.h
IInterface::release
virtual unsigned long release()=0
Release Interface instance.
TsDataSvc::retrieveObject
StatusCode retrieveObject(IRegistry *pDirectory, std::string_view path, DataObject *&pObject) override
Retrieve object from data store.
Definition: TsDataSvc.cpp:624
DataSvcHelpers::RegistryEntry::traverseTree
StatusCode traverseTree(IDataStoreAgent *pAgent, int level=0)
traverse data tree
Definition: RegistryEntry.cpp:281
Gaudi::operator+
decltype(auto) operator+(const T &v, const Property< TP, V, H > &p)
implemantation of (value + property)
Definition: Property.h:443
Service::service
StatusCode service(const std::string &name, const T *&psvc, bool createIf=true) const
Access a service by name, creating it if it doesn't already exist.
Definition: Service.h:88
DataObject::registry
IRegistry * registry() const
Get pointer to Registry.
Definition: DataObject.h:82
IInterface::addRef
virtual unsigned long addRef()=0
Increment the reference count of Interface instance.
DataObject::addRef
virtual unsigned long addRef()
Add reference to object.
Definition: DataObject.cpp:63
std::exception::what
T what(T... args)
TsDataSvc::m_rootCLID
Gaudi::Property< CLID > m_rootCLID
Definition: TsDataSvc.h:72
TsDataSvc::m_enableAccessHdlr
Gaudi::Property< bool > m_enableAccessHdlr
Definition: TsDataSvc.h:82
TsDataSvc::clearSubTree
StatusCode clearSubTree(std::string_view sub_tree_path) override
IDataManagerSvc: Remove all data objects below the sub tree identified by its full path name.
Definition: TsDataSvc.cpp:88
IDataStoreAgent
Definition: IDataStoreAgent.h:27
DataSvcHelpers::RegistryEntry::parentEntry
RegistryEntry * parentEntry()
Pointer to parent registry entry.
Definition: RegistryEntry.h:101
IConversionSvc
Definition: IConversionSvc.h:47