The Gaudi Framework  master (37c0b60a)
TsDataSvc.cpp
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2024 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 
42 #include <GaudiKernel/TsDataSvc.h>
43 
44 // Include files
45 #include <algorithm>
46 #include <cassert>
47 #include <cstdlib>
48 #include <mutex>
49 #include <sstream>
50 #include <vector>
51 
52 // Macro to lock a scope
53 #define STD_LOCK_GUARD_MACRO std::scoped_lock lock{ m_accessMutex };
54 
55 namespace {
56  std::string operator+( char c, std::string_view sr ) {
57  std::string s{ c };
58  s.append( sr.data(), sr.size() );
59  return s;
60  }
61 
62  std::string_view::size_type find( std::string_view s, char c, size_t o ) {
63  if ( !s.empty() ) s.remove_prefix( o );
64  auto r = s.find( c );
65  return r == std::string_view::npos ? r : ( r + o );
66  }
67 } // namespace
68 
69 // If you absolutely need optimization: switch off dynamic_cast.
70 // This improves access to the data store roughly by 10 %
71 // for balanced trees.
72 //
73 // M.Frank
74 #define CAST_REGENTRY( x, y ) dynamic_cast<x>( y )
75 // #define CAST_REGENTRY(x,y) (x)(y)
77 
78 #define ON_DEBUG if ( msgLevel( MSG::DEBUG ) )
79 #define ON_VERBOSE if ( msgLevel( MSG::VERBOSE ) )
80 
81 #define DEBMSG ON_DEBUG debug()
82 #define VERMSG ON_VERBOSE verbose()
83 
86  : base_class( name, svc ), m_incidentSvc( "IncidentSvc", name ) {}
87 
91 StatusCode TsDataSvc::clearSubTree( std::string_view sub_tree_path ) {
92  DataObject* pObject = nullptr;
93  StatusCode status = findObject( sub_tree_path, pObject );
94  if ( !status.isSuccess() ) return status;
95  RegEntry* node_entry = CAST_REGENTRY( RegEntry*, pObject->registry() );
96  if ( !node_entry ) return Status::INVALID_OBJECT;
97  RegEntry* parent = node_entry->parentEntry();
98  if ( !parent ) return Status::INVALID_PARENT;
99  parent->remove( node_entry );
100  return StatusCode::SUCCESS;
101 }
102 
107  if ( !checkRoot() ) return Status::INVALID_ROOT;
108  RegEntry* entry = CAST_REGENTRY( RegEntry*, pObject->registry() );
109  if ( !entry ) return Status::INVALID_OBJECT;
110  RegEntry* parent = entry->parentEntry();
111  if ( !parent ) return Status::INVALID_PARENT;
112  parent->remove( entry );
113  return StatusCode::SUCCESS;
114 }
115 
118  if ( !checkRoot() ) return Status::INVALID_ROOT;
119  m_root.reset();
120  return StatusCode::SUCCESS;
121 }
122 
126 StatusCode TsDataSvc::traverseSubTree( std::string_view sub_tree_path, IDataStoreAgent* pAgent ) {
127  DataObject* pO = nullptr;
128  StatusCode status = findObject( sub_tree_path, pO );
129  return status.isSuccess() ? traverseSubTree( pO, pAgent ) : status;
130 }
131 
135  if ( !checkRoot() ) return Status::INVALID_ROOT;
136  RegEntry* entry = CAST_REGENTRY( RegEntry*, pObject->registry() );
137  if ( !entry ) return Status::INVALID_OBJECT;
138  return entry->traverseTree( pAgent );
139 }
140 
144  if ( !checkRoot() ) return Status::INVALID_ROOT;
145  return m_root->traverseTree( pAgent );
146 }
147 
153  clearStore().ignore();
154  return i_setRoot( std::move( root_path ), pRootObj );
155 }
156 
163  if ( pRootObj ) {
164  m_root = std::make_unique<RegEntry>( std::move( root_path ) );
165  m_root->makeHard( pRootObj );
166  m_root->setDataSvc( this );
167  // No done with GaudiHive. preLoad().ignore();
168  }
169  return StatusCode::SUCCESS;
170 }
171 
177  clearStore().ignore();
178  return i_setRoot( std::move( root_path ), pRootAddr );
179 }
180 
187  if ( pRootAddr ) {
188  m_root = std::make_unique<RegEntry>( std::move( root_path ) );
189  m_root->makeHard( pRootAddr );
190  m_root->setDataSvc( this );
191  // Not done with GaudiHive. preLoad().ignore();
192  }
193  return StatusCode::SUCCESS;
194 }
195 
198  if ( pDataLoader ) pDataLoader->addRef();
200  if ( pDataLoader ) { pDataLoader->setDataProvider( dpsvc == nullptr ? this : dpsvc ).ignore(); }
201  m_dataLoader = pDataLoader;
202  return StatusCode::SUCCESS;
203 }
204 
206 StatusCode TsDataSvc::objectParent( const DataObject* pObject, IRegistry*& refpParent ) {
207  if ( !pObject ) return Status::INVALID_OBJECT;
208  return objectParent( pObject->registry(), refpParent );
209 }
211 StatusCode TsDataSvc::objectParent( const IRegistry* pRegistry, IRegistry*& refpParent ) {
213  if ( !checkRoot() ) return Status::INVALID_ROOT;
214  const RegEntry* node_entry = CAST_REGENTRY( const RegEntry*, pRegistry );
215  if ( !node_entry ) return Status::INVALID_OBJECT;
216  refpParent = node_entry->parent();
217  return StatusCode::SUCCESS;
218 }
219 
222  if ( !pObject ) return Status::INVALID_OBJECT;
223  return objectLeaves( pObject->registry(), leaves );
224 }
225 
230  if ( !pRegistry ) return Status::INVALID_OBJECT;
231  const RegEntry* node_entry = CAST_REGENTRY( const RegEntry*, pRegistry );
232  if ( !node_entry ) return Status::INVALID_OBJECT;
234  leaves.insert( leaves.end(), node_entry->leaves().begin(), node_entry->leaves().end() );
235  // leaves = node_entry->leaves();
236  return StatusCode::SUCCESS;
237 }
238 
240 StatusCode TsDataSvc::registerAddress( std::string_view fullPath, IOpaqueAddress* pAddress ) {
241  if ( fullPath.empty() ) return Status::INVALID_OBJ_PATH;
242  return registerAddress( fullPath.front() != SEPARATOR ? m_root.get() : nullptr, fullPath, pAddress );
243 }
244 
246 StatusCode TsDataSvc::registerAddress( IRegistry* parentObj, std::string_view objPath, IOpaqueAddress* pAddress ) {
247  if ( !checkRoot() ) return Status::INVALID_ROOT;
248  if ( objPath.empty() ) return Status::INVALID_OBJ_PATH;
249  if ( !parentObj ) {
250  if ( objPath.front() != SEPARATOR ) { return registerAddress( m_root.get(), objPath, pAddress ); }
251  auto sep = find( objPath, SEPARATOR, 1 );
252  if ( sep == std::string_view::npos || objPath.substr( 0, sep ) != m_rootName.value() ) {
253  return Status::INVALID_PARENT;
254  }
255  return registerAddress( m_root.get(), objPath.substr( sep ), pAddress );
256  }
257  if ( objPath.front() != SEPARATOR ) { return registerAddress( parentObj, SEPARATOR + objPath, pAddress ); }
258  RegEntry* par_entry = CAST_REGENTRY( RegEntry*, parentObj );
259  if ( !par_entry ) return Status::INVALID_PARENT;
260  auto sep = objPath.rfind( SEPARATOR );
261  if ( sep > 0 && sep != std::string_view::npos ) {
262  auto p_path = objPath.substr( 0, sep );
263  auto o_path = objPath.substr( sep );
264  RegEntry* p_entry = par_entry->findLeaf( p_path );
265  // Create default object leafs if the
266  // intermediate nodes are not present
267  if ( !p_entry && m_forceLeaves ) {
268  DataObject* pLeaf = createDefaultObject();
269  StatusCode sc = registerObject( par_entry->identifier(), p_path, pLeaf );
270  if ( !sc.isSuccess() ) delete pLeaf;
271  p_entry = par_entry->findLeaf( p_path );
272  }
273  if ( !p_entry ) return Status::INVALID_PARENT;
274  return registerAddress( p_entry, o_path, pAddress );
275  }
276  StatusCode status = par_entry->add( std::string{ objPath }, pAddress );
277  return status.isSuccess() ? status : Status::DOUBL_OBJ_PATH;
278 }
279 
281 StatusCode TsDataSvc::unregisterAddress( std::string_view fullPath ) {
282  if ( fullPath.empty() ) return Status::INVALID_OBJ_PATH;
283  return unregisterAddress( fullPath.front() != SEPARATOR ? m_root.get() : nullptr, fullPath );
284 }
285 
287 StatusCode TsDataSvc::unregisterAddress( IRegistry* pParent, std::string_view objPath ) {
288  if ( !checkRoot() ) return Status::INVALID_ROOT;
289 
290  if ( objPath.empty() ) return Status::INVALID_OBJ_PATH;
291  if ( !pParent ) {
292  if ( objPath.front() != SEPARATOR ) { return unregisterAddress( m_root.get(), objPath ); }
293  auto sep = find( objPath, SEPARATOR, 1 );
294  if ( sep == std::string_view::npos || objPath.substr( 0, sep ) != m_rootName.value() ) {
295  return Status::INVALID_PARENT;
296  }
297  return unregisterAddress( m_root.get(), objPath.substr( sep ) );
298  }
299  if ( objPath.front() != SEPARATOR ) { return unregisterAddress( pParent, SEPARATOR + objPath ); }
300  RegEntry* node_entry = CAST_REGENTRY( RegEntry*, pParent );
301  if ( node_entry ) {
302  RegEntry* leaf_entry = node_entry->findLeaf( objPath );
303  if ( leaf_entry ) {
304  auto sep = objPath.rfind( SEPARATOR );
305  if ( sep > 0 && sep != std::string_view::npos ) {
306  return unregisterAddress( leaf_entry->parent(), objPath.substr( sep ) );
307  }
308  StatusCode status = node_entry->remove( objPath );
309  if ( status.isSuccess() ) return status;
310  }
311  }
312  return Status::INVALID_PARENT;
313 }
314 
316 StatusCode TsDataSvc::registerObject( std::string_view parentPath, std::string_view objPath, DataObject* pObject ) {
317  DataObject* pO = nullptr;
318  StatusCode status = retrieveObject( parentPath, pO );
319  if ( !status.isSuccess() && m_forceLeaves ) {
320  pO = createDefaultObject();
321  status = registerObject( parentPath, pO );
322  if ( !status.isSuccess() ) pO->release();
323  }
324  return status.isSuccess() ? registerObject( pO, objPath, pObject ) : status;
325 }
326 
328 StatusCode TsDataSvc::registerObject( DataObject* parentObj, std::string_view objPath, DataObject* pObject ) {
329  if ( !checkRoot() ) return Status::INVALID_ROOT;
330  if ( !parentObj ) {
331  if ( !objPath.empty() ) {
332  if ( objPath.front() != SEPARATOR ) { return registerObject( m_rootName.value(), objPath, pObject ); }
333  auto sep = find( objPath, SEPARATOR, 1 );
334  if ( sep != std::string_view::npos ) {
335  return registerObject( objPath.substr( 0, sep ), objPath.substr( sep ), pObject );
336  }
337  }
338  return Status::INVALID_OBJ_PATH;
339  }
340  RegEntry* node_entry = CAST_REGENTRY( RegEntry*, parentObj->registry() );
341  if ( node_entry ) {
342  StatusCode status = Status::INVALID_PARENT;
343  auto sep = find( objPath, SEPARATOR, 1 );
344  if ( sep != std::string_view::npos ) {
345  auto p_path = objPath.substr( 0, sep );
346  auto o_path = objPath.substr( sep );
347  RegEntry* par_entry = node_entry->findLeaf( p_path );
348  // Create default object leafs if the
349  // intermediate nodes are not present
350  if ( !par_entry && m_forceLeaves ) {
351  DataObject* pLeaf = createDefaultObject();
352  StatusCode sc = registerObject( parentObj, p_path, pLeaf );
353  if ( !sc.isSuccess() ) delete pLeaf;
354  par_entry = node_entry->findLeaf( p_path );
355  } else if ( par_entry && !par_entry->object() ) {
356  status = retrieveEntry( node_entry, p_path, par_entry );
357  if ( !status.isSuccess() && !par_entry->address() && m_forceLeaves ) {
358  DataObject* pLeaf = createDefaultObject();
359  StatusCode sc = registerObject( parentObj, p_path, pLeaf );
360  if ( !sc.isSuccess() ) delete pLeaf;
361  par_entry = node_entry->findLeaf( p_path );
362  }
363  }
364  node_entry = par_entry;
365  if ( node_entry ) {
366  DataObject* obj = node_entry->object();
367  if ( obj ) status = registerObject( obj, o_path, pObject );
368  }
369  } else {
370  RegEntry* leaf = node_entry->findLeaf( objPath );
371  if ( !leaf ) {
372  status = node_entry->add( std::string{ objPath }, pObject );
373  } else {
374  DataObject* obj = leaf->object();
375  if ( !obj ) {
376  if ( !pObject ) {
377  error() << "registerObject: trying to register null DataObject" << endmsg;
378  return StatusCode::FAILURE;
379  } else {
380  pObject->setRegistry( leaf );
381  }
382  leaf->setAddress( nullptr );
383  leaf->setObject( pObject );
384  status = StatusCode::SUCCESS;
385  } else {
386  status = Status::DOUBL_OBJ_PATH;
387  }
388  }
389  }
390  return status;
391  }
392  return Status::INVALID_PARENT;
393 }
394 
396 StatusCode TsDataSvc::unregisterObject( std::string_view fullPath ) {
397  DataObject* pObject = nullptr;
398  StatusCode status = findObject( fullPath, pObject );
399  if ( status.isFailure() ) return status;
400  RegEntry* pEntry = CAST_REGENTRY( RegEntry*, pObject->registry() );
401  if ( !pEntry ) return Status::INVALID_ROOT;
402  if ( !pEntry->isEmpty() ) return Status::DIR_NOT_EMPTY;
403  RegEntry* pParent = pEntry->parentEntry();
404  if ( !pParent ) return Status::INVALID_PARENT;
405  pObject->addRef();
406  pParent->remove( pEntry );
407  return StatusCode::SUCCESS;
408 }
409 
412  if ( !checkRoot() ) return Status::INVALID_ROOT;
413  RegEntry* entry = m_root->findLeaf( pObject );
414  if ( !entry ) return Status::INVALID_OBJECT;
415  RegEntry* parent = entry->parentEntry();
416  if ( !parent ) return Status::INVALID_PARENT;
417  if ( !entry->isEmpty() ) return Status::DIR_NOT_EMPTY;
418  if ( entry->object() ) entry->object()->addRef();
419  if ( parent ) parent->remove( entry );
420  return StatusCode::SUCCESS;
421 }
422 
424 StatusCode TsDataSvc::unregisterObject( DataObject* pParentObj, std::string_view objectPath ) {
425  if ( !checkRoot() ) return Status::INVALID_ROOT;
426  try {
427  RegEntry* parent = CAST_REGENTRY( RegEntry*, pParentObj->registry() );
428  if ( parent ) {
429  RegEntry* entry = parent->findLeaf( objectPath );
430  if ( !entry ) return Status::INVALID_OBJECT;
431  if ( !entry->isEmpty() ) return Status::DIR_NOT_EMPTY;
432  if ( entry->object() ) entry->object()->addRef();
433  parent->remove( entry );
434  return StatusCode::SUCCESS;
435  }
436  } catch ( ... ) {}
437  return Status::INVALID_PARENT;
438 }
439 
443  if ( m_enableFaultHdlr ) {
444  IRegistry* pLeaf = nullptr;
445  if ( pReg && path.empty() ) {
446  DataIncident incident( name(), m_faultName, pReg->identifier() );
447  m_incidentSvc->fireIncident( incident );
448  return pReg->object();
449  } else if ( pReg ) {
450  std::string p = pReg->identifier();
451  if ( path.front() != SEPARATOR ) p += SEPARATOR;
452  p.append( path.data(), path.size() );
453  DataIncident incident( name(), m_faultName, p );
454  m_incidentSvc->fireIncident( incident );
455  pLeaf = m_root->findLeaf( p );
456  } else {
458  if ( path.front() != SEPARATOR ) p += SEPARATOR;
459  p.append( path.data(), path.size() );
460  DataIncident incident( name(), m_faultName, p );
461  m_incidentSvc->fireIncident( incident );
462  pLeaf = m_root->findLeaf( p );
463  }
464  if ( pLeaf ) return pLeaf->object();
465  }
466  return nullptr;
467 }
468 
473  IConversionSvc* pLoader = getDataLoader( pRegistry );
474  return loadObject( pLoader, pRegistry );
475 }
476 
481  StatusCode status = Status::INVALID_OBJ_ADDR;
482  DataObject* pObject = nullptr;
484  if ( !pLoader ) { // Precondition: Data loader must be present
485  if ( handleDataFault( pRegistry ) )
486  return StatusCode::SUCCESS;
487  else
488  return Status::NO_DATA_LOADER;
489  }
490  if ( !pRegistry ) { // Precondition: Directory must be valid
491  if ( handleDataFault( pRegistry ) )
492  return StatusCode::SUCCESS;
493  else
494  return Status::INVALID_OBJ_ADDR;
495  }
496 
497  VERMSG << "Requested object " << pRegistry->identifier() << endmsg;
498 
499  if ( m_enableAccessHdlr ) {
500  // Fire data access incident
501  DataIncident incident( name(), m_accessName, pRegistry->identifier() );
502  m_incidentSvc->fireIncident( incident );
503  }
504  if ( !m_inhibitPathes.empty() ) {
505  const auto& ident = pRegistry->identifier();
506  auto inhibit = std::find( m_inhibitPathes.begin(), m_inhibitPathes.end(), ident );
507  if ( inhibit != m_inhibitPathes.end() ) return Status::NO_ACCESS;
508  }
509  IOpaqueAddress* pAddress = pRegistry->address();
510  if ( !pAddress ) { // Precondition:
511  return Status::INVALID_OBJ_ADDR; // Address must be valid
512  }
513  try {
514  status = pLoader->createObj( pAddress, pObject ); // Call data loader
515  if ( status.isSuccess() ) {
516 
517  VERMSG << "Object " << pRegistry->identifier() << " created" << endmsg;
518 
519  RegEntry* pEntry = CAST_REGENTRY( RegEntry*, pRegistry );
520  pEntry->setObject( pObject );
521 
522  VERMSG << "Filling object " << pRegistry->identifier() << endmsg;
523  status = pLoader->fillObjRefs( pAddress, pObject );
524  }
525  } catch ( const GaudiException& exc ) {
526  if ( handleDataFault( pRegistry ) ) return StatusCode::SUCCESS;
527  throw GaudiException( "GaudiException in loadObject() " + pRegistry->identifier(), name(), StatusCode::FAILURE,
528  exc );
529  } catch ( const std::exception& x ) {
530  if ( handleDataFault( pRegistry ) ) return StatusCode::SUCCESS;
531  throw GaudiException( "std::exception in loadObject() " + pRegistry->identifier() + ": " +
532  System::typeinfoName( typeid( x ) ) + ", " + x.what(),
534  } catch ( ... ) {
535  if ( handleDataFault( pRegistry ) ) return StatusCode::SUCCESS;
536  throw GaudiException( "UNKN exception in loadObject() " + pRegistry->identifier(), name(), StatusCode::FAILURE );
537  }
538  if ( !status.isSuccess() ) {
539  if ( handleDataFault( pRegistry ) ) return StatusCode::SUCCESS;
540  }
541  ON_VERBOSE if ( status.isSuccess() ) {
542  verbose() << "Object " << pRegistry->identifier() << " successfully loaded" << endmsg;
543  }
544  return status;
545 }
546 
548 StatusCode TsDataSvc::retrieveEntry( RegEntry* parentObj, std::string_view path, RegEntry*& pEntry ) {
549  auto sep = find( path, SEPARATOR, 1 );
550  StatusCode status = Status::INVALID_ROOT;
551  pEntry = nullptr;
553  // A.Valassi 16.08.2001 avoid core dump if store is empty
554  if ( checkRoot() ) {
555  if ( !parentObj ) {
556  if ( path.empty() || path == m_rootName ) return retrieveEntry( m_root.get(), "", pEntry );
557  if ( path.front() != SEPARATOR ) return retrieveEntry( m_root.get(), path, pEntry );
558  if ( sep == std::string_view::npos ) return Status::INVALID_OBJ_PATH;
559  if ( !m_root->object() ) {
560  RegEntry* r = nullptr;
561  status = retrieveEntry( m_root.get(), "", r );
562  if ( !status.isSuccess() ) return status;
563  }
564  return retrieveEntry( m_root.get(), path.substr( sep ), pEntry );
565  }
566  if ( sep != std::string_view::npos ) { // the string contains a separator (after pos 0)
567  auto p_path = path.substr( 0, sep );
568  auto o_path = path.substr( sep );
569  if ( !parentObj->object() ) { // if the parent object has not been loaded yet, load it now
570  status = loadObject( parentObj );
571  if ( !status.isSuccess() ) return status;
572  }
573  RegEntry* root_entry = parentObj->findLeaf( p_path );
574  if ( !root_entry && m_enableFaultHdlr ) {
575  // If not even the parent is there, an incident
576  // to load the parent must be fired...
577  handleDataFault( parentObj, p_path );
578  root_entry = parentObj->findLeaf( p_path );
579  }
580  if ( root_entry ) {
581  DataObject* pO = root_entry->object();
582  if ( !pO ) {
583  // Object is not loaded: load the object if at all possible
584  status = loadObject( root_entry );
585  if ( !status.isSuccess() ) return status;
586  }
587  if ( root_entry->isSoft() ) { root_entry = CAST_REGENTRY( RegEntry*, pO->registry() ); }
588  return retrieveEntry( root_entry, o_path, pEntry );
589  }
590  return Status::INVALID_OBJ_PATH;
591  } else if ( path.empty() ) {
592  pEntry = parentObj;
593  } else {
594  if ( !parentObj->object() ) { // if the parent object has not been loaded yet, load it now
595  status = loadObject( parentObj );
596  if ( !status.isSuccess() ) return status;
597  }
598  // last leave in search: find leaf and load
599  pEntry = parentObj->findLeaf( path );
600  // If no registry entry was found, trigger incident for action-on-demand
601  if ( !pEntry && m_enableFaultHdlr ) {
602  handleDataFault( parentObj, path );
603  pEntry = ( path.empty() ? parentObj : parentObj->findLeaf( path ) );
604  }
605  }
606  // Check results and return
607  if ( !pEntry ) {
608  status = Status::INVALID_OBJ_PATH;
609  } else if ( !pEntry->object() ) {
610  status = loadObject( pEntry );
611  } else if ( m_enableAccessHdlr ) {
612  // Fire data access incident
613  // I do not know if this is a good idea....
614  // This fires too often!
615  //
616  // DataIncident incident(name(), m_accessName, pEntry->identifier());
617  // m_incidentSvc->fireIncident(incident);
618  status = StatusCode::SUCCESS;
619  } else {
620  status = StatusCode::SUCCESS;
621  }
622  }
623  return status;
624 }
625 
627 StatusCode TsDataSvc::retrieveObject( IRegistry* pRegistry, std::string_view path, DataObject*& pObject ) {
628  pObject = nullptr;
629  RegEntry * result = nullptr, *parent = CAST_REGENTRY( RegEntry*, pRegistry );
630  StatusCode status = retrieveEntry( parent, path, result );
631  if ( status.isSuccess() ) pObject = result->object();
632  return status;
633 }
634 
636 StatusCode TsDataSvc::findObject( IRegistry* pRegistry, std::string_view path, DataObject*& pObject ) {
638  pObject = nullptr;
639  IRegistry* pReg = ( pRegistry ? pRegistry : m_root.get() );
640  RegEntry* root_entry = CAST_REGENTRY( RegEntry*, pReg );
641  if ( root_entry ) {
642  if ( !path.empty() ) pReg = root_entry->find( path );
643  if ( !pReg ) return Status::INVALID_OBJ_PATH;
644  pObject = pReg->object();
645  }
646  return pObject ? Status::IDataProviderSvc_NO_ERROR : Status::OBJ_NOT_LOADED;
647 }
648 
650 StatusCode TsDataSvc::findObject( std::string_view path, DataObject*& pObject ) {
651  pObject = nullptr;
653  if ( !checkRoot() ) return Status::INVALID_ROOT;
654  if ( path.empty() || path == m_rootName ) {
655  pObject = m_root->object();
656  return !pObject ? Status::OBJ_NOT_LOADED : Status::IDataProviderSvc_NO_ERROR;
657  }
658  return findObject( path.front() != SEPARATOR ? m_root.get() : nullptr, path, pObject );
659 }
660 
663  if ( !pRegistry ) return Status::INVALID_OBJ_ADDR; // Precondition: Addres must be valid
664  DataObject* toUpdate = pRegistry->object();
665  return toUpdate ? updateObject( toUpdate ) : loadObject( pRegistry );
666 }
667 
670  StatusCode status = Status::INVALID_OBJ_ADDR;
671  if ( !toUpdate ) return Status::INVALID_OBJECT; // Precondition: Address must be valid
672  IRegistry* pRegistry = toUpdate->registry();
673  if ( !pRegistry ) return Status::INVALID_OBJECT; // Precondition: Need valid registry
674  IOpaqueAddress* pAddress = pRegistry->address();
675  if ( !pAddress ) return Status::INVALID_OBJ_ADDR; // Precondition: Need valid address
677  IConversionSvc* pLoader = getDataLoader( pRegistry );
678  if ( !pLoader ) return Status::NO_DATA_LOADER; // Precondition: Data loader must be present
679  if ( !m_inhibitPathes.empty() ) {
680  auto& ident = pRegistry->identifier();
681  auto inhibit = std::find( m_inhibitPathes.begin(), m_inhibitPathes.end(), ident );
682  if ( inhibit != m_inhibitPathes.end() ) return Status::NO_ACCESS;
683  }
684  try {
685  status = pLoader->updateObj( pAddress, toUpdate ); // Call data loader
686  if ( status.isSuccess() ) { status = pLoader->updateObjRefs( pAddress, toUpdate ); }
687  } catch ( const GaudiException& exc ) {
688  throw GaudiException( "GaudiException in updateObject() " + pRegistry->name(), name(), StatusCode::FAILURE, exc );
689  } catch ( const std::exception& x ) {
690  throw GaudiException( "std::exception in updateObject() " + pRegistry->name() + ": " +
691  System::typeinfoName( typeid( x ) ) + ", " + x.what(),
693  } catch ( ... ) {
694  throw GaudiException( "UNKN exception in updateObject() " + pRegistry->name(), name(), StatusCode::FAILURE );
695  }
696  return status;
697 }
698 
699 // Link object
700 StatusCode TsDataSvc::linkObject( IRegistry* from, std::string_view objPath, DataObject* to ) {
702  if ( !checkRoot() ) return Status::INVALID_ROOT;
703  try {
704  RegEntry* from_entry = CAST_REGENTRY( RegEntry*, from );
705  if ( from_entry ) {
706  // First check if both objects are already registered to the store
707  RegEntry* to_entry = m_root->findLeaf( to );
708  if ( !to_entry ) return Status::INVALID_OBJECT;
709  auto sep = objPath.rfind( SEPARATOR );
710  if ( sep > 0 && sep != std::string_view::npos ) { // in case the objPath is a sub-directory itself
711  DataObject* pO = nullptr;
712  StatusCode sc = retrieveObject( from, objPath.substr( 0, sep ), pO );
713  return sc.isSuccess() ? linkObject( pO->registry(), objPath.substr( sep ), to ) : sc;
714  }
715  // Now register the soft link
716  StatusCode status = from_entry->add( std::string{ objPath }, to, true );
717  return status.isSuccess() ? Status::IDataProviderSvc_NO_ERROR : Status::DOUBL_OBJ_PATH;
718  }
719  } catch ( ... ) {}
720  return Status::INVALID_PARENT;
721 }
722 
724 StatusCode TsDataSvc::linkObject( std::string_view fullPath, DataObject* to ) {
725  if ( fullPath.empty() ) return Status::INVALID_OBJ_PATH;
726  if ( fullPath.front() == SEPARATOR ) {
727  auto sep = fullPath.rfind( SEPARATOR );
728  return linkObject( fullPath.substr( 0, sep ), fullPath.substr( sep ), to );
729  }
731  return linkObject( m_root.get(), fullPath, to );
732 }
733 
735 StatusCode TsDataSvc::unlinkObject( IRegistry* from, std::string_view objPath ) {
737  if ( !checkRoot() ) return Status::INVALID_ROOT;
738  try {
739  RegEntry* from_entry = CAST_REGENTRY( RegEntry*, from );
740  if ( from_entry ) {
741  auto sep = objPath.rfind( SEPARATOR );
742  if ( sep > 0 && sep != std::string_view::npos ) { // in case the objPath is a sub-directory itself
743  DataObject* pO = nullptr;
744  StatusCode sc = findObject( from, objPath.substr( 0, sep ), pO );
745  return sc.isSuccess() ? unlinkObject( pO->registry(), objPath.substr( sep ) ) : sc;
746  }
747  StatusCode status = from_entry->remove( objPath );
748  return status.isSuccess() ? status : Status::INVALID_OBJ_PATH;
749  }
750  } catch ( ... ) {}
751  return Status::INVALID_PARENT;
752 }
753 
755 StatusCode TsDataSvc::unlinkObject( std::string_view fullPath ) {
756  if ( fullPath.empty() ) return Status::INVALID_OBJ_PATH;
757  if ( fullPath.front() != SEPARATOR ) { return unlinkObject( m_root.get(), fullPath ); }
758  auto sep = fullPath.rfind( SEPARATOR );
759  return unlinkObject( fullPath.substr( 0, sep ), fullPath.substr( sep ) );
760 }
761 
763 StatusCode TsDataSvc::unlinkObject( DataObject* from, std::string_view objPath ) {
764  if ( !checkRoot() ) return Status::INVALID_ROOT;
765  return unlinkObject( m_root->findLeaf( from ), objPath );
766 }
767 
770  auto i = std::find( m_preLoads.begin(), m_preLoads.end(), item );
771  if ( i == m_preLoads.end() ) m_preLoads.push_back( item );
772  return StatusCode::SUCCESS;
773 }
774 
777  auto i = std::remove( m_preLoads.begin(), m_preLoads.end(), item );
778  m_preLoads.erase( i, m_preLoads.end() );
779  return StatusCode::SUCCESS;
780 }
781 
784  m_preLoads.clear();
785  return StatusCode::SUCCESS;
786 }
787 
789 StatusCode TsDataSvc::preLoad( int depth, int load_depth, DataObject* pObject ) {
790  // unused: StatusCode sc = StatusCode::FAILURE;
791  if ( pObject && depth++ < load_depth ) {
792  RegEntry* dir = CAST_REGENTRY( RegEntry*, pObject->registry() );
793  if ( dir ) {
794  for ( const auto& i : *dir ) {
795  DataObject* pObj = nullptr;
796  StatusCode status = retrieveObject( pObject, i->name(), pObj );
797  if ( status.isSuccess() && depth < load_depth ) { preLoad( depth, load_depth, pObj ).ignore(); }
798  }
799  }
800  }
801  return StatusCode::SUCCESS;
802 }
803 
806  DataObject* pObj = nullptr;
807  for ( const auto& i : m_preLoads ) {
808  StatusCode sc = retrieveObject( i.path(), pObj );
809  int load_depth = i.depth();
810  if ( sc.isSuccess() && load_depth > 1 ) { preLoad( 1, load_depth, pObj ).ignore(); }
811  }
812  return StatusCode::SUCCESS;
813 }
814 
817  // Nothing to do: just call base class initialisation
819  if ( !sc.isSuccess() ) return sc;
820  sc = m_incidentSvc.retrieve();
821  if ( !sc.isSuccess() ) { error() << "Failed to access incident service." << endmsg; }
822  return sc;
823 }
824 
827  StatusCode sc;
828  // the finalize part is copied here
829  setDataLoader( nullptr ).ignore();
830  resetPreLoad().ignore();
831  clearStore().ignore();
832  // re-initialize the base class
833  sc = Service::reinitialize();
834  if ( !sc.isSuccess() ) {
835  error() << "Unable to reinitialize base class" << endmsg;
836  return sc;
837  }
838  // the initialize part is copied here
839  sc = m_incidentSvc.retrieve();
840  if ( !sc.isSuccess() ) {
841  error() << "Failed to access incident service." << endmsg;
842  return sc;
843  }
844  // return
845  return StatusCode::SUCCESS;
846 }
847 
850  // Nothing to do: just call base class initialisation
851  setDataLoader( nullptr ).ignore();
852  resetPreLoad().ignore();
853  clearStore().ignore();
854  return Service::finalize();
855 }
856 
858 CLID TsDataSvc::rootCLID() const { return ( (CLID)m_rootCLID ); }
859 
861 const std::string& TsDataSvc::rootName() const { return ( m_rootName ); }
862 
865 
TsDataSvc::loadObject
virtual StatusCode loadObject(IRegistry *pNode)
Invoke Persistency service to create transient object from its persistent representation.
Definition: TsDataSvc.cpp:472
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:74
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:76
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:776
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:197
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
AtlasMCRecoFullPrecedenceDump.path
path
Definition: AtlasMCRecoFullPrecedenceDump.py:49
StatusCode::isSuccess
bool isSuccess() const
Definition: StatusCode.h:314
TsDataSvc::rootCLID
CLID rootCLID() const override
IDataManagerSvc: Accessor for root event CLID.
Definition: TsDataSvc.cpp:858
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:700
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:805
std::vector< IRegistry * >
std::find
T find(T... args)
DataObject::release
virtual unsigned long release()
release reference to object
Definition: DataObject.cpp:56
ISvcLocator
Definition: ISvcLocator.h:46
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:869
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:53
std::unique_ptr::get
T get(T... args)
TsDataSvc::finalize
StatusCode finalize() override
Service initialization.
Definition: TsDataSvc.cpp:849
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:162
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:442
System::typeinfoName
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition: System.cpp:315
TsDataSvc::registerObject
StatusCode registerObject(std::string_view parentPath, std::string_view objPath, DataObject *pObject) override
Register object with the data store.
Definition: TsDataSvc.cpp:316
TsDataSvc::initialize
StatusCode initialize() override
Service initialization.
Definition: TsDataSvc.cpp:816
VERMSG
#define VERMSG
Definition: TsDataSvc.cpp:82
TsDataSvc::clearStore
StatusCode clearStore() override
IDataManagerSvc: Remove all data objects in the data store.
Definition: TsDataSvc.cpp:117
std::unique_ptr::reset
T reset(T... args)
IIncidentSvc::fireIncident
virtual void fireIncident(const Incident &incident)=0
Fire an Incident.
TsDataSvc::m_incidentSvc
ServiceHandle< IIncidentSvc > m_incidentSvc
Handle to incident service.
Definition: TsDataSvc.h:70
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:152
TsDataSvc::createDefaultObject
virtual DataObject * createDefaultObject() const
Create default objects in case forced creation of leaves is requested.
Definition: TsDataSvc.cpp:864
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:826
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:206
DataStoreItem
Definition: DataStoreItem.h:27
DataIncident
IOpaqueAddress.h
CommonMessaging
Definition: CommonMessaging.h:66
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:237
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:126
RegEntry
DataSvcHelpers::RegistryEntry RegEntry
Definition: TsDataSvc.cpp:76
TsDataSvc::addPreLoadItem
StatusCode addPreLoadItem(const DataStoreItem &item) override
Add an item to the preload list.
Definition: TsDataSvc.cpp:769
std::vector::erase
T erase(T... args)
DataSvcHelpers::RegistryEntry::isEmpty
bool isEmpty() const
Simple check if the Container is empty.
Definition: RegistryEntry.h:143
TsDataSvc::TsDataSvc
TsDataSvc(const std::string &name, ISvcLocator *svc)
constructor
Definition: TsDataSvc.cpp:85
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:202
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
ServiceHandle::retrieve
StatusCode retrieve(T *&service) const override
Do the real retrieval of the Service.
Definition: ServiceHandle.h:97
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:240
IConverter.h
TsDataSvc::retrieveEntry
StatusCode retrieveEntry(DataSvcHelpers::RegistryEntry *pNode, std::string_view path, DataSvcHelpers::RegistryEntry *&pEntry)
Retrieve registry entry from store.
Definition: TsDataSvc.cpp:548
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:142
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:861
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:79
TsDataSvc::unregisterAddress
StatusCode unregisterAddress(std::string_view fullPath) override
IDataManagerSvc: Unregister object address from the data store.
Definition: TsDataSvc.cpp:281
TsDataSvc::resetPreLoad
StatusCode resetPreLoad() override
Clear the preload list.
Definition: TsDataSvc.cpp:783
StatusCode::SUCCESS
constexpr static const auto SUCCESS
Definition: StatusCode.h:100
ConditionsStallTest.name
name
Definition: ConditionsStallTest.py:77
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:650
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:735
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:662
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:36
Service::reinitialize
StatusCode reinitialize() override
Definition: Service.cpp:295
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:396
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:221
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:627
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:441
DataObject::registry
IRegistry * registry() const
Get pointer to Registry.
Definition: DataObject.h:78
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:91
IDataStoreAgent
Definition: IDataStoreAgent.h:27
DataSvcHelpers::RegistryEntry::parentEntry
RegistryEntry * parentEntry()
Pointer to parent registry entry.
Definition: RegistryEntry.h:101
IConversionSvc
Definition: IConversionSvc.h:47