The Gaudi Framework  v29r0 (ff2e7097)
DataSvc.cpp
Go to the documentation of this file.
1 //====================================================================
2 // DataSvc.cpp
3 //--------------------------------------------------------------------
4 //
5 // Package : System ( The LHCb Offline System)
6 //
7 // Description: implementation of the Transient data service: DataSvc
8 //
9 // Author : M.Frank
10 // History :
11 // +---------+----------------------------------------------+---------
12 // | Date | Comment | Who
13 // +---------+----------------------------------------------+---------
14 // | 29/10/98| Initial version | M.Frank
15 // | 20/2/99 | Automatic data preloading introduced. | M.Frank
16 // +---------+----------------------------------------------+---------
17 //
18 //====================================================================
19 #define DATASVC_DATASVC_CPP
20 
21 // Framework include files
23 #include "GaudiKernel/IConverter.h"
25 
26 #include "GaudiKernel/DataObject.h"
28 
30 #include "GaudiKernel/DataSvc.h"
33 
34 // Include files
35 #include <algorithm>
36 #include <cassert>
37 #include <cstdlib>
38 #include <sstream>
39 #include <vector>
40 
41 #include "boost/utility/string_ref.hpp"
42 
43 namespace
44 {
47  inline std::string itemToPath( int item ) { return '/' + std::to_string( item ); }
48 
49  inline boost::string_ref::size_type find( boost::string_ref s, char c, size_t o )
50  {
51  if ( !s.empty() ) s.remove_prefix( o );
52  auto r = s.find( c );
53  return r == boost::string_ref::npos ? r : ( r + o );
54  }
55 }
56 
57 // If you absolutely need optimization: switch off dynamic_cast.
58 // This improves access to the data store roughly by 10 %
59 // for balanced trees.
60 //
61 // M.Frank
62 #define CAST_REGENTRY( x, y ) dynamic_cast<x>( y )
63 //#define CAST_REGENTRY(x,y) (x)(y)
65 
66 #define ON_DEBUG if ( msgLevel( MSG::DEBUG ) )
67 #define ON_VERBOSE if ( msgLevel( MSG::VERBOSE ) )
68 
69 #define DEBMSG ON_DEBUG debug()
70 #define VERMSG ON_VERBOSE verbose()
71 
76 {
77  DataObject* pObject = nullptr;
78  StatusCode status = findObject( sub_tree_path, pObject );
79  if ( status.isSuccess() ) {
80  RegEntry* node_entry = CAST_REGENTRY( RegEntry*, pObject->registry() );
81  if ( node_entry ) {
82  RegEntry* parent = node_entry->parentEntry();
83  if ( parent ) {
84  parent->remove( node_entry );
85  return StatusCode::SUCCESS;
86  }
87  return INVALID_PARENT;
88  }
89  return INVALID_OBJECT;
90  }
91  return status;
92 }
93 
98 {
99  if ( checkRoot() ) {
100  RegEntry* entry = CAST_REGENTRY( RegEntry*, pObject->registry() );
101  if ( entry ) {
102  RegEntry* parent = entry->parentEntry();
103  if ( parent ) {
104  parent->remove( entry );
105  return SUCCESS;
106  }
107  return INVALID_PARENT;
108  }
109  return INVALID_OBJECT;
110  }
111  return INVALID_ROOT;
112 }
113 
116 {
117  if ( checkRoot() ) {
118  m_root->release();
119  m_root = nullptr;
120  return SUCCESS;
121  }
122  return INVALID_ROOT;
123 }
124 
129 {
130  DataObject* pO = nullptr;
131  StatusCode status = findObject( sub_tree_path, pO );
132  if ( status.isFailure() ) return status;
133  return traverseSubTree( pO, pAgent );
134 }
135 
138 {
139  if ( !checkRoot() ) return INVALID_ROOT;
140  RegEntry* entry = CAST_REGENTRY( RegEntry*, pObject->registry() );
141  if ( !entry ) return INVALID_OBJECT;
142  return entry->traverseTree( pAgent );
143 }
144 
147 {
148  if ( !checkRoot() ) return INVALID_ROOT;
149  return m_root->traverseTree( pAgent );
150 }
151 
157 {
158  clearStore().ignore();
159  return i_setRoot( std::move( root_path ), pRootObj );
160 }
161 
168 {
169  if ( pRootObj ) {
170  m_root = new RegEntry( std::move( root_path ) );
171  m_root->makeHard( pRootObj );
172  m_root->setDataSvc( this );
173  // No done with GaudiHive. preLoad().ignore();
174  }
175  return SUCCESS;
176 }
177 
183 {
184  clearStore().ignore();
185  return i_setRoot( std::move( root_path ), pRootAddr );
186 }
187 
194 {
195  if ( pRootAddr ) {
196  m_root = new RegEntry( std::move( root_path ) );
197  m_root->makeHard( pRootAddr );
198  m_root->setDataSvc( this );
199  // Not done with GaudiHive. preLoad().ignore();
200  }
201  return SUCCESS;
202 }
203 
206 {
207  m_dataLoader = pDataLoader;
208  if ( m_dataLoader ) m_dataLoader->setDataProvider( dpsvc ? dpsvc : this ).ignore();
209  return SUCCESS;
210 }
211 
213 StatusCode DataSvc::objectParent( const DataObject* pObject, IRegistry*& refpParent )
214 {
215  if ( !pObject ) return INVALID_OBJECT;
216  return objectParent( pObject->registry(), refpParent );
217 }
219 StatusCode DataSvc::objectParent( const IRegistry* pRegistry, IRegistry*& refpParent )
220 {
221  if ( !checkRoot() ) return INVALID_ROOT;
222  const RegEntry* node_entry = CAST_REGENTRY( const RegEntry*, pRegistry );
223  if ( !node_entry ) return INVALID_OBJECT;
224  refpParent = node_entry->parent();
225  return StatusCode::SUCCESS;
226 }
227 
230 {
231  if ( !pObject ) return INVALID_OBJECT;
232  return objectLeaves( pObject->registry(), leaves );
233 }
234 
239 {
240  if ( !checkRoot() ) return INVALID_ROOT;
241  const RegEntry* node_entry = CAST_REGENTRY( const RegEntry*, pRegistry );
242  if ( !node_entry ) return INVALID_OBJECT;
243  leaves = node_entry->leaves();
244  return StatusCode::SUCCESS;
245 }
246 
249 {
250  if ( fullPath.empty() ) return INVALID_OBJ_PATH;
251  return registerAddress( fullPath.front() != SEPARATOR ? m_root : nullptr, fullPath, pAddress );
252 }
253 
255 StatusCode DataSvc::registerAddress( DataObject* parentObj, const std::string& objectPath, IOpaqueAddress* pAddress )
256 {
257  IRegistry* pRegistry = ( parentObj ? parentObj->registry() : nullptr );
258  return registerAddress( pRegistry, objectPath, pAddress );
259 }
260 
263 {
264  if ( !checkRoot() ) return INVALID_ROOT;
265  if ( objPath.empty() ) return INVALID_OBJ_PATH;
266 
267  if ( !parentObj ) {
268  if ( objPath.front() != SEPARATOR ) {
269  return registerAddress( m_root, objPath, pAddress );
270  }
271  std::string::size_type sep = objPath.find( SEPARATOR, 1 );
272  if ( sep == std::string::npos ) {
273  return INVALID_PARENT;
274  }
275  if ( objPath.compare( 0, sep, m_rootName ) == 0 ) {
276  return registerAddress( m_root, objPath.substr( sep ), pAddress );
277  }
278  }
279  if ( objPath.front() != SEPARATOR ) {
280  return registerAddress( parentObj, char( SEPARATOR ) + objPath, pAddress );
281  }
282  RegEntry* par_entry = CAST_REGENTRY( RegEntry*, parentObj );
283  if ( !par_entry ) return INVALID_PARENT;
284 
285  std::string::size_type sep = objPath.rfind( SEPARATOR );
286  if ( sep > 0 && sep != std::string::npos ) {
287  auto p_path = objPath.substr( 0, sep );
288  auto o_path = objPath.substr( sep );
289  RegEntry* p_entry = par_entry->findLeaf( p_path );
290  // Create default object leafs if the
291  // intermediate nodes are not present
292  if ( !p_entry && m_forceLeaves ) {
293  DataObject* pLeaf = createDefaultObject();
294  StatusCode sc = registerObject( par_entry->identifier(), p_path, pLeaf );
295  if ( sc.isFailure() ) delete pLeaf;
296  p_entry = par_entry->findLeaf( p_path );
297  }
298  if ( !p_entry ) return INVALID_PARENT;
299  return registerAddress( p_entry, o_path, pAddress );
300  }
301  StatusCode status = par_entry->add( objPath, pAddress );
302  return status.isSuccess() ? status : DOUBL_OBJ_PATH;
303 }
304 
307 {
308  if ( fullPath.empty() ) return INVALID_OBJ_PATH;
309  return unregisterAddress( fullPath.front() != SEPARATOR ? m_root : nullptr, fullPath );
310 }
311 
314 {
315  return unregisterAddress( pParent ? pParent->registry() : nullptr, objPath );
316 }
317 
320 {
321  if ( !checkRoot() ) return INVALID_ROOT;
322  if ( objPath.empty() ) return INVALID_OBJ_PATH;
323 
324  if ( !pParent ) {
325  if ( objPath.front() != SEPARATOR ) {
326  return unregisterAddress( m_root, objPath );
327  }
328  std::string::size_type sep = objPath.find( SEPARATOR, 1 );
329  if ( sep != std::string::npos && objPath.compare( 0, sep, m_rootName ) == 0 ) {
330  return unregisterAddress( m_root, objPath.substr( sep ) );
331  }
332  return INVALID_PARENT;
333  }
334  if ( objPath.front() != SEPARATOR ) {
335  return unregisterAddress( pParent, char( SEPARATOR ) + objPath );
336  }
337  RegEntry* node_entry = CAST_REGENTRY( RegEntry*, pParent );
338  if ( node_entry ) {
339  RegEntry* leaf_entry = node_entry->findLeaf( objPath );
340  if ( leaf_entry ) {
341  std::string::size_type sep = objPath.rfind( SEPARATOR );
342  if ( sep > 0 && sep != std::string::npos ) {
343  return unregisterAddress( leaf_entry->parent(), objPath.substr( sep ) );
344  }
345  StatusCode status = node_entry->remove( objPath );
346  if ( status.isSuccess() ) return status;
347  }
348  }
349  return INVALID_PARENT;
350 }
351 
354 {
355  return registerObject( nullptr, fullPath, pObject );
356 }
357 
359 StatusCode DataSvc::registerObject( const std::string& parentPath, const std::string& objPath, DataObject* pObject )
360 {
361  DataObject* pO = nullptr;
362  StatusCode status = retrieveObject( parentPath, pO );
363  if ( !status.isSuccess() && m_forceLeaves ) {
364  pO = createDefaultObject();
365  status = registerObject( parentPath, pO );
366  if ( !status.isSuccess() ) pO->release();
367  }
368  if ( status.isFailure() ) return status;
369  return registerObject( pO, objPath, pObject );
370 }
371 
373 StatusCode DataSvc::registerObject( const std::string& parentPath, int item, DataObject* pObject )
374 {
375  return registerObject( parentPath, itemToPath( item ), pObject );
376 }
377 
379 StatusCode DataSvc::registerObject( DataObject* parentObj, int item, DataObject* pObject )
380 {
381  return registerObject( parentObj, itemToPath( item ), pObject );
382 }
383 
385 StatusCode DataSvc::registerObject( DataObject* parentObj, const std::string& objPath, DataObject* pObject )
386 {
387  if ( !checkRoot() ) return INVALID_ROOT;
388 
389  if ( !parentObj ) {
390  if ( !objPath.empty() ) {
391  if ( objPath.front() == SEPARATOR ) {
392  auto sep = objPath.find( SEPARATOR, 1 );
393  if ( sep != std::string::npos ) {
394  return registerObject( objPath.substr( 0, sep ), objPath.substr( sep ), pObject );
395  }
396  } else {
397  return registerObject( m_rootName, objPath, pObject );
398  }
399  }
400  return INVALID_OBJ_PATH;
401  }
402  RegEntry* node_entry = CAST_REGENTRY( RegEntry*, parentObj->registry() );
403  if ( node_entry ) {
404  StatusCode status = INVALID_PARENT;
405  auto sep = objPath.find( SEPARATOR, 1 );
406  if ( sep != std::string::npos ) {
407  auto p_path = objPath.substr( 0, sep );
408  auto o_path = objPath.substr( sep );
409  RegEntry* par_entry = node_entry->findLeaf( p_path );
410  // Create default object leafs if the
411  // intermediate nodes are not present
412  if ( !par_entry && m_forceLeaves ) {
413  DataObject* pLeaf = createDefaultObject();
414  StatusCode sc = registerObject( parentObj, p_path, pLeaf );
415  if ( !sc.isSuccess() ) delete pLeaf;
416  par_entry = node_entry->findLeaf( p_path );
417  } else if ( par_entry && !par_entry->object() ) {
418  status = i_retrieveEntry( node_entry, p_path, par_entry );
419  if ( !status.isSuccess() && !par_entry->address() && m_forceLeaves ) {
420  DataObject* pLeaf = createDefaultObject();
421  StatusCode sc = registerObject( parentObj, p_path, pLeaf );
422  if ( !sc.isSuccess() ) delete pLeaf;
423  par_entry = node_entry->findLeaf( p_path );
424  }
425  }
426  node_entry = par_entry;
427  if ( node_entry ) {
428  DataObject* obj = node_entry->object();
429  if ( obj ) {
430  status = registerObject( obj, o_path, pObject );
431  }
432  }
433  } else {
434  RegEntry* leaf = node_entry->findLeaf( objPath );
435  if ( !leaf ) {
436  status = node_entry->add( objPath, pObject );
437  } else {
438  DataObject* obj = leaf->object();
439  if ( !obj ) {
440  if ( !pObject ) {
441  error() << "registerObject: trying to register null DataObject" << endmsg;
442  return StatusCode::FAILURE;
443  }
444  pObject->setRegistry( leaf );
445  leaf->setAddress( nullptr );
446  leaf->setObject( pObject );
447  status = StatusCode::SUCCESS;
448  } else {
449  status = DOUBL_OBJ_PATH;
450  }
451  }
452  }
453  return status;
454  }
455  return INVALID_PARENT;
456 }
457 
460 {
461  DataObject* pObject = nullptr;
462  StatusCode status = findObject( fullPath, pObject );
463  if ( status.isFailure() ) return status;
464  RegEntry* pEntry = CAST_REGENTRY( RegEntry*, pObject->registry() );
465  if ( !pEntry ) return INVALID_ROOT;
466  if ( !pEntry->isEmpty() ) return DIR_NOT_EMPTY;
467  RegEntry* pParent = pEntry->parentEntry();
468  if ( !pParent ) return INVALID_PARENT;
469  if ( pObject ) pObject->addRef();
470  pParent->remove( pEntry );
471  return StatusCode::SUCCESS;
472 }
473 
475 StatusCode DataSvc::unregisterObject( const std::string& parentPath, const std::string& objPath )
476 {
477  DataObject* pO = nullptr;
478  StatusCode status = findObject( parentPath, pO );
479  return status.isSuccess() ? unregisterObject( pO, objPath ) : status;
480 }
481 
483 StatusCode DataSvc::unregisterObject( const std::string& parentPath, int item )
484 {
485  return unregisterObject( parentPath, itemToPath( item ) );
486 }
487 
490 {
491  if ( !checkRoot() ) return INVALID_ROOT;
492  RegEntry* entry = m_root->findLeaf( pObject );
493  if ( !entry ) return INVALID_OBJECT;
494  RegEntry* parent = entry->parentEntry();
495  if ( !parent ) return INVALID_PARENT;
496  if ( !entry->isEmpty() ) return DIR_NOT_EMPTY;
497  if ( entry->object() ) entry->object()->addRef();
498  if ( parent ) parent->remove( entry );
499  return SUCCESS;
500 }
501 
504 {
505  if ( checkRoot() ) {
506  try {
507  RegEntry* parent = CAST_REGENTRY( RegEntry*, pParentObj->registry() );
508  if ( parent ) {
509  RegEntry* entry = parent->findLeaf( objectPath );
510  if ( entry ) {
511  if ( entry->isEmpty() ) {
512  if ( entry->object() ) {
513  entry->object()->addRef();
514  }
515  parent->remove( entry );
516  return SUCCESS;
517  }
518  return DIR_NOT_EMPTY;
519  }
520  return INVALID_OBJECT;
521  }
522  } catch ( ... ) {
523  }
524  return INVALID_PARENT;
525  }
526  return INVALID_ROOT;
527 }
528 
531 {
532  return unregisterObject( pParentObj, itemToPath( item ) );
533 }
534 
538 {
539  return i_handleDataFault( pReg, path );
540 }
541 
543 {
544  if ( m_enableFaultHdlr ) {
545  IRegistry* pLeaf = nullptr;
546  if ( pReg && path.empty() ) {
547  DataIncident incident( name(), m_faultName, pReg->identifier() );
548  m_incidentSvc->fireIncident( incident );
549  return pReg->object();
550  }
551  if ( pReg ) {
552  std::string p = pReg->identifier();
553  if ( path.front() != SEPARATOR ) p += SEPARATOR;
554  p.append( path.data(), path.size() );
555  DataIncident incident( name(), m_faultName, p );
556  m_incidentSvc->fireIncident( incident );
557  pLeaf = m_root->findLeaf( p );
558  } else {
560  if ( path.front() != SEPARATOR ) p += SEPARATOR;
561  p.append( path.data(), path.size() );
562  DataIncident incident( name(), m_faultName, p );
563  m_incidentSvc->fireIncident( incident );
564  pLeaf = m_root->findLeaf( p );
565  }
566  if ( pLeaf ) {
567  return pLeaf->object();
568  }
569  }
570  return nullptr;
571 }
572 
577 {
578  IConversionSvc* pLoader = getDataLoader( pRegistry );
579  return loadObject( pLoader, pRegistry );
580 }
581 
586 {
587  StatusCode status = INVALID_OBJ_ADDR;
588  DataObject* pObject = nullptr;
589  if ( !pLoader ) { // Precondition: Data loader must be present
590  return handleDataFault( pRegistry ) ? StatusCode{SUCCESS} : NO_DATA_LOADER;
591  }
592  if ( !pRegistry ) { // Precondition: Directory must be valid
593  return handleDataFault( pRegistry ) ? StatusCode{SUCCESS} : INVALID_OBJ_ADDR;
594  }
595 
596  VERMSG << "Requested object " << pRegistry->identifier() << endmsg;
597 
598  if ( m_enableAccessHdlr ) {
599  // Fire data access incident
600  DataIncident incident( name(), m_accessName, pRegistry->identifier() );
601  m_incidentSvc->fireIncident( incident );
602  }
603  if ( !m_inhibitPathes.empty() ) {
604  auto inhibit = std::find( m_inhibitPathes.begin(), m_inhibitPathes.end(), pRegistry->identifier() );
605  if ( inhibit != m_inhibitPathes.end() ) {
606  return NO_ACCESS;
607  }
608  }
609  IOpaqueAddress* pAddress = pRegistry->address();
610  if ( !pAddress ) { // Precondition:
611  return INVALID_OBJ_ADDR; // Address must be valid
612  }
613  try {
614  status = pLoader->createObj( pAddress, pObject ); // Call data loader
615  if ( status.isSuccess() ) {
616 
617  VERMSG << "Object " << pRegistry->identifier() << " created" << endmsg;
618 
619  RegEntry* pEntry = CAST_REGENTRY( RegEntry*, pRegistry );
620  pEntry->setObject( pObject );
621 
622  VERMSG << "Filling object " << pRegistry->identifier() << endmsg;
623  status = pLoader->fillObjRefs( pAddress, pObject );
624  }
625  } catch ( const GaudiException& exc ) {
626  if ( handleDataFault( pRegistry ) ) {
627  return SUCCESS;
628  }
629  throw GaudiException( "GaudiException in loadObject() " + pRegistry->identifier(), name(), StatusCode::FAILURE,
630  exc );
631  } catch ( const std::exception& x ) {
632  if ( handleDataFault( pRegistry ) ) {
633  return SUCCESS;
634  }
635  throw GaudiException( "std::exception in loadObject() " + pRegistry->identifier() + ": " +
636  System::typeinfoName( typeid( x ) ) + ", " + x.what(),
638  } catch ( ... ) {
639  if ( handleDataFault( pRegistry ) ) {
640  return SUCCESS;
641  }
642  throw GaudiException( "UNKN exception in loadObject() " + pRegistry->identifier(), name(), StatusCode::FAILURE );
643  }
644  if ( !status.isSuccess() ) {
645  if ( handleDataFault( pRegistry ) ) {
646  return StatusCode::SUCCESS;
647  }
648  }
649  ON_VERBOSE if ( status.isSuccess() )
650  {
651  verbose() << "Object " << pRegistry->identifier() << " successfully loaded" << endmsg;
652  }
653  return status;
654 }
655 
658 {
659  return i_retrieveEntry( parentObj, path, pEntry );
660 }
661 
662 StatusCode DataSvc::i_retrieveEntry( RegEntry* parentObj, boost::string_ref path, RegEntry*& pEntry )
663 {
664  // A.Valassi 16.08.2001 avoid core dump if store is empty
665  if ( !checkRoot() ) return StatusCode( INVALID_ROOT, true );
666 
667  static const auto empty = boost::string_ref{};
668  auto sep = find( path, SEPARATOR, 1 );
669  pEntry = nullptr;
670 
671  if ( !parentObj ) {
672  if ( path.empty() || path == m_rootName ) {
673  parentObj = m_root;
674  path = empty;
675  } else if ( path.front() != SEPARATOR ) {
676  parentObj = m_root;
677  } else if ( sep != boost::string_ref::npos ) {
678  if ( !m_root->object() ) {
679  RegEntry* r = nullptr;
680  auto status = i_retrieveEntry( m_root, empty, r );
681  if ( !status.isSuccess() ) return status;
682  }
683  parentObj = m_root;
684  path = path.substr( sep );
685  } else {
686  return INVALID_OBJ_PATH;
687  }
688  sep = find( path, SEPARATOR, 1 );
689  }
690 
691  StatusCode status = StatusCode( INVALID_ROOT, true );
692  if ( sep != boost::string_ref::npos ) { // the string contains a separator (after pos 0)
693  if ( !parentObj->object() ) { // if the parent object has not been loaded yet, load it now
694  status = loadObject( parentObj );
695  if ( !status.isSuccess() ) return status;
696  }
697  auto p_path = path.substr( 0, sep );
698  RegEntry* root_entry = parentObj->findLeaf( p_path );
699  if ( !root_entry && m_enableFaultHdlr ) {
700  // If not even the parent is there, an incident
701  // to load the parent must be fired...
702  i_handleDataFault( parentObj, p_path );
703  root_entry = parentObj->findLeaf( p_path );
704  }
705  if ( root_entry ) {
706  DataObject* pO = root_entry->object();
707  if ( !pO ) {
708  // Object is not loaded: load the object if at all possible
709  status = loadObject( root_entry );
710  if ( !status.isSuccess() ) return status;
711  }
712  if ( root_entry->isSoft() ) {
713  root_entry = CAST_REGENTRY( RegEntry*, pO->registry() );
714  }
715  return i_retrieveEntry( root_entry, path.substr( sep ), pEntry );
716  }
717  return status;
718  } else if ( path.empty() ) {
719  pEntry = parentObj;
720  } else {
721  if ( !parentObj->object() ) { // if the parent object has not been loaded yet, load it now
722  status = loadObject( parentObj );
723  if ( !status.isSuccess() ) return status;
724  }
725  // last leave in search: find leaf and load
726  pEntry = parentObj->findLeaf( path );
727  // If no registry entry was found, trigger incident for action-on-demand
728  if ( !pEntry && m_enableFaultHdlr ) {
729  i_handleDataFault( parentObj, path );
730  pEntry = ( path.empty() ? parentObj : parentObj->findLeaf( path ) );
731  }
732  }
733 
734  // Check results and return
735  if ( !pEntry ) return INVALID_OBJ_PATH;
736  if ( !pEntry->object() ) return loadObject( pEntry );
737 
738  if ( m_enableAccessHdlr ) {
739  // Fire data access incident
740  // I do not know if this is a good idea....
741  // This fires too often!
742  //
743  // DataIncident incident(name(), m_accessName, pEntry->identifier());
744  // m_incidentSvc->fireIncident(incident);
745  return SUCCESS;
746  }
747  return SUCCESS;
748 }
749 
752 {
753  pObject = nullptr;
754  RegEntry *result = nullptr, *parent = CAST_REGENTRY( RegEntry *, pRegistry );
755  StatusCode status = i_retrieveEntry( parent, path, result );
756  if ( status.isSuccess() ) pObject = result->object();
757  return status;
758 }
759 
762 {
763  IRegistry* nullDir = nullptr;
764  return retrieveObject( nullDir, fullPath, pObject );
765 }
766 
768 StatusCode DataSvc::retrieveObject( const std::string& parentPath, const std::string& objectPath, DataObject*& pObject )
769 {
770  DataObject* parent = nullptr;
771  StatusCode status = retrieveObject( parentPath, parent );
772  return status.isSuccess() ? retrieveObject( parent, objectPath, pObject ) : status;
773 }
774 
776 StatusCode DataSvc::retrieveObject( const std::string& parentPath, int item, DataObject*& pObject )
777 {
778  return retrieveObject( parentPath, itemToPath( item ), pObject );
779 }
780 
783 {
784  IRegistry* pRegistry = ( parentObj ? parentObj->registry() : nullptr );
785  return retrieveObject( pRegistry, path, pObject );
786 }
787 
789 StatusCode DataSvc::retrieveObject( DataObject* parentObj, int item, DataObject*& pObject )
790 {
791  return retrieveObject( parentObj, itemToPath( item ), pObject );
792 }
793 
796 {
797  pObject = nullptr;
798  IRegistry* pReg = ( pRegistry ? pRegistry : m_root );
799  RegEntry* root_entry = CAST_REGENTRY( RegEntry*, pReg );
800  if ( root_entry ) {
801  if ( !path.empty() ) pReg = root_entry->find( path );
802  if ( !pReg ) return INVALID_OBJ_PATH;
803  pObject = pReg->object();
804  }
805  return ( !pObject ) ? OBJ_NOT_LOADED : IDataProviderSvc_NO_ERROR;
806 }
807 
810 {
811  pObject = nullptr;
812  if ( checkRoot() ) {
813  if ( path.empty() || path == m_rootName ) {
814  pObject = m_root->object();
815  return !pObject ? OBJ_NOT_LOADED : IDataProviderSvc_NO_ERROR;
816  } else if ( path.front() != SEPARATOR ) {
817  return findObject( m_rootName, path, pObject );
818  }
819  return findObject( (IRegistry*)nullptr, path, pObject );
820  }
821  return INVALID_ROOT;
822 }
823 
825 StatusCode DataSvc::findObject( const std::string& parentPath, const std::string& objectPath, DataObject*& pObject )
826 {
827  DataObject* parent = nullptr;
828  StatusCode status = findObject( parentPath, parent );
829  return status.isSuccess() ? findObject( parent, objectPath, pObject ) : status;
830 }
831 
833 StatusCode DataSvc::findObject( const std::string& parentPath, int item, DataObject*& pObject )
834 {
835  return findObject( parentPath, itemToPath( item ), pObject );
836 }
837 
839 StatusCode DataSvc::findObject( DataObject* parentObj, int item, DataObject*& pObject )
840 {
841  return findObject( parentObj, itemToPath( item ), pObject );
842 }
843 
846 {
847  IRegistry* pDir = ( parentObj ? parentObj->registry() : nullptr );
848  return findObject( pDir, path, pObject );
849 }
850 
853 {
854  DataObject* pO = nullptr;
855  StatusCode status = findObject( updatePath, pO );
856  return status.isSuccess() ? updateObject( pO ) : retrieveObject( updatePath, pO );
857 }
858 
861 {
862  if ( !pRegistry ) { // Precondition:
863  return INVALID_OBJ_ADDR; // Addres must be valid
864  }
865  DataObject* toUpdate = pRegistry->object();
866  if ( !toUpdate ) { // Try first to load
867  return loadObject( pRegistry );
868  }
869  return updateObject( toUpdate );
870 }
871 
874 {
875  StatusCode status = INVALID_OBJ_ADDR;
876  if ( !toUpdate ) { // Precondition:
877  return INVALID_OBJECT; // Address must be valid
878  }
879  IRegistry* pRegistry = toUpdate->registry(); // Precondition:
880  if ( !pRegistry ) { // Need valid registry
881  return INVALID_OBJECT;
882  }
883  IOpaqueAddress* pAddress = pRegistry->address(); // Precondition:
884  if ( !pAddress ) { // Need valid address
885  return INVALID_OBJ_ADDR;
886  }
887  IConversionSvc* pLoader = getDataLoader( pRegistry );
888  if ( !pLoader ) { // Precondition:
889  return NO_DATA_LOADER; // Data loader must be present
890  }
891  if ( !m_inhibitPathes.empty() ) {
892  auto inhibit = std::find( m_inhibitPathes.begin(), m_inhibitPathes.end(), pRegistry->identifier() );
893  if ( inhibit != m_inhibitPathes.end() ) {
894  return NO_ACCESS;
895  }
896  }
897  try {
898  status = pLoader->updateObj( pAddress, toUpdate ); // Call data loader
899  if ( status.isSuccess() ) {
900  status = pLoader->updateObjRefs( pAddress, toUpdate );
901  }
902  } catch ( const GaudiException& exc ) {
903  throw GaudiException( "GaudiException in updateObject() " + pRegistry->name(), name(), StatusCode::FAILURE, exc );
904  } catch ( const std::exception& x ) {
905  throw GaudiException( "std::exception in updateObject() " + pRegistry->name() + ": " +
906  System::typeinfoName( typeid( x ) ) + ", " + x.what(),
908  } catch ( ... ) {
909  throw GaudiException( "UNKN exception in updateObject() " + pRegistry->name(), name(), StatusCode::FAILURE );
910  }
911  return status;
912 }
913 
915 StatusCode DataSvc::updateObject( const std::string& parentPath, const std::string& updatePath )
916 {
917  DataObject* pParent = nullptr;
918  StatusCode status = findObject( parentPath, pParent );
919  return status.isSuccess() ? updateObject( pParent, updatePath ) : status;
920 }
921 
924 {
925  DataObject* pObject = nullptr;
926  StatusCode status = findObject( parent, updatePath, pObject );
927  return status.isSuccess() ? updateObject( pObject ) : status;
928 }
929 
930 // Link object
932 {
933  if ( checkRoot() ) {
934  try {
935  RegEntry* from_entry = CAST_REGENTRY( RegEntry*, from );
936  if ( from_entry ) {
937  // First check if both objects are already registered to the store
938  RegEntry* to_entry = m_root->findLeaf( to );
939  if ( !to_entry ) {
940  return INVALID_OBJECT;
941  }
942  std::string::size_type sep = objPath.rfind( SEPARATOR );
943  if ( sep > 0 && sep != std::string::npos ) { // in case the objPath is a sub-directory itself
944  DataObject* pO = nullptr;
945  StatusCode sc = retrieveObject( from, objPath.substr( 0, sep ), pO );
946  if ( sc.isSuccess() ) {
947  sc = linkObject( pO->registry(), objPath.substr( sep ), to );
948  }
949  return sc;
950  }
951  // Now register the soft link
952  StatusCode status = from_entry->add( objPath, to, true );
953  return status.isSuccess() ? IDataProviderSvc_NO_ERROR : DOUBL_OBJ_PATH;
954  }
955  } catch ( ... ) {
956  }
957  return INVALID_PARENT;
958  }
959  return INVALID_ROOT;
960 }
961 
964 {
965  if ( !fullPath.empty() ) {
966  if ( fullPath.front() != SEPARATOR ) {
967  return linkObject( m_rootName, fullPath, to );
968  }
969  auto sep = fullPath.rfind( SEPARATOR );
970  return linkObject( fullPath.substr( 0, sep ), fullPath.substr( sep ), to );
971  }
972  return INVALID_OBJ_PATH;
973 }
974 
977 {
978  DataObject* pO = nullptr;
979  StatusCode status = retrieveObject( from, pO );
980  return status.isSuccess() ? linkObject( pO->registry(), objPath, to ) : status;
981 }
982 
985 {
986  if ( from ) {
987  IRegistry* from_entry = from->registry();
988  if ( from_entry ) {
989  return linkObject( from_entry, objPath, to );
990  }
991  }
992  return INVALID_PARENT;
993 }
994 
997 {
998  if ( checkRoot() ) {
999  try {
1000  RegEntry* from_entry = CAST_REGENTRY( RegEntry*, from );
1001  if ( from_entry ) {
1002  std::string::size_type sep = objPath.rfind( SEPARATOR );
1003  if ( sep > 0 && sep != std::string::npos ) { // in case the objPath is a sub-directory itself
1004  DataObject* pO = nullptr;
1005  StatusCode sc = findObject( from, objPath.substr( 0, sep ), pO );
1006  if ( sc.isSuccess() ) {
1007  sc = unlinkObject( pO->registry(), objPath.substr( sep ) );
1008  }
1009  return sc;
1010  }
1011  StatusCode status = from_entry->remove( objPath );
1012  if ( status.isSuccess() ) return status;
1013  return INVALID_OBJ_PATH;
1014  }
1015  } catch ( ... ) {
1016  }
1017  return INVALID_PARENT;
1018  }
1019  return INVALID_ROOT;
1020 }
1021 
1024 {
1025  if ( fullPath.empty() ) return INVALID_OBJ_PATH;
1026  if ( fullPath.front() != SEPARATOR ) {
1027  return unlinkObject( m_rootName, fullPath );
1028  }
1029  auto sep = fullPath.rfind( SEPARATOR );
1030  return unlinkObject( fullPath.substr( 0, sep ), fullPath.substr( sep ) );
1031 }
1032 
1035 {
1036  DataObject* pObject = nullptr;
1037  StatusCode status = findObject( from, pObject );
1038  return status.isSuccess() ? unlinkObject( pObject->registry(), objPath ) : status;
1039 }
1040 
1043 {
1044  if ( !checkRoot() ) return INVALID_ROOT;
1045  IRegistry* from_entry = m_root->findLeaf( from );
1046  return unlinkObject( from_entry, objPath );
1047 }
1048 
1051 {
1052  auto i = std::find( std::begin( m_preLoads ), std::end( m_preLoads ), item );
1053  if ( i == std::end( m_preLoads ) ) {
1054  m_preLoads.push_back( item );
1055  }
1056  return StatusCode::SUCCESS;
1057 }
1058 
1061 {
1062  return addPreLoadItem( DataStoreItem( itemPath, 1 ) );
1063 }
1064 
1067 {
1069  return StatusCode::SUCCESS;
1070 }
1071 
1074 {
1075  return removePreLoadItem( DataStoreItem( itemPath, 1 ) );
1076 }
1077 
1080 {
1082  return StatusCode::SUCCESS;
1083 }
1084 
1086 StatusCode DataSvc::preLoad( int depth, int load_depth, DataObject* pObject )
1087 {
1088  // unused: StatusCode sc = StatusCode::FAILURE;
1089  if ( pObject && depth++ < load_depth ) {
1090  RegEntry* dir = CAST_REGENTRY( RegEntry*, pObject->registry() );
1091  if ( dir ) {
1092  for ( const auto& i : *dir ) {
1093  DataObject* pObj = nullptr;
1094  StatusCode status = retrieveObject( pObject, i->name(), pObj );
1095  if ( status.isSuccess() && depth < load_depth ) {
1096  preLoad( depth, load_depth, pObj ).ignore();
1097  }
1098  }
1099  }
1100  }
1101  return StatusCode::SUCCESS;
1102 }
1103 
1106 {
1107  DataObject* pObj = nullptr;
1108  for ( const auto& i : m_preLoads ) {
1109  StatusCode sc = retrieveObject( i.path(), pObj );
1110  int load_depth = i.depth();
1111  if ( sc.isSuccess() && load_depth > 1 ) {
1112  preLoad( 1, load_depth, pObj ).ignore();
1113  }
1114  }
1115  return StatusCode::SUCCESS;
1116 }
1117 
1120 {
1121  // Nothing to do: just call base class initialisation
1123  if ( UNLIKELY( !sc.isSuccess() ) ) return sc;
1124  m_incidentSvc = service( "IncidentSvc", true );
1125  if ( UNLIKELY( !m_incidentSvc ) ) {
1126  error() << "Failed to access incident service." << endmsg;
1127  }
1128  return sc;
1129 }
1130 
1133 {
1134  // the finalize part is copied here
1135  setDataLoader( nullptr ).ignore();
1136  resetPreLoad().ignore();
1137  clearStore().ignore();
1138  m_incidentSvc.reset();
1139  // re-initialize the base class
1141  if ( UNLIKELY( !sc.isSuccess() ) ) {
1142  error() << "Unable to reinitialize base class" << endmsg;
1143  return sc;
1144  }
1145  // the initialize part is copied here
1146  m_incidentSvc = service( "IncidentSvc", true );
1147  if ( UNLIKELY( !m_incidentSvc ) ) {
1148  error() << "Failed to access incident service." << endmsg;
1149  return StatusCode::FAILURE;
1150  }
1151  // return
1152  return StatusCode::SUCCESS;
1153 }
1154 
1157 {
1158  // Nothing to do: just call base class initialisation
1159  setDataLoader( nullptr ).ignore();
1160  resetPreLoad().ignore();
1161  clearStore().ignore();
1162  m_incidentSvc.reset();
1163  return Service::finalize();
1164 }
1165 
1167 CLID DataSvc::rootCLID() const { return ( (CLID)m_rootCLID ); }
1168 
1170 const std::string& DataSvc::rootName() const { return m_rootName; }
1171 
1174 
1179 
1182 {
1183  setDataLoader( nullptr ).ignore();
1184  resetPreLoad().ignore();
1185  clearStore().ignore();
1186 }
StatusCode unregisterObject(const std::string &fullPath) override
Unregister object from the data store.
Definition: DataSvc.cpp:459
Gaudi::Property< CLID > m_rootCLID
Definition: DataSvc.h:56
StatusCode addPreLoadItem(const DataStoreItem &item) override
Add an item to the preload list.
Definition: DataSvc.cpp:1050
#define VERMSG
Definition: DataSvc.cpp:70
#define UNLIKELY(x)
Definition: Kernel.h:128
StatusCode initialize() override
Definition: Service.cpp:64
T empty(T...args)
RegistryEntry * findLeaf(boost::string_ref path) const
Find identified leaf in this registry node.
Definition: RegistryEntry.h:94
~DataSvc() override
Standard Destructor.
Definition: DataSvc.cpp:1181
Define general base for Gaudi exception.
DataObject * object() const override
Retrive object behind the link.
const std::string & name() const override
Retrieve name of the service.
Definition: Service.cpp:289
StatusCode preLoad() override
load all preload items of the list
Definition: DataSvc.cpp:1105
virtual StatusCode createObj(IOpaqueAddress *pAddress, DataObject *&refpObject)=0
Create the transient representation of an object.
constexpr char SEPARATOR
StatusCode finalize() override
Definition: Service.cpp:174
CLID rootCLID() const override
IDataManagerSvc: Accessor for root event CLID.
Definition: DataSvc.cpp:1167
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition: System.cpp:329
T front(T...args)
Gaudi::Property< std::string > m_accessName
Definition: DataSvc.h:67
bool isSuccess() const
Test for a status code of SUCCESS.
Definition: StatusCode.h:75
StatusCode setRoot(std::string root_name, DataObject *pRootObj) override
Initialize data store for new event by giving new event path and root object.
Definition: DataSvc.cpp:156
StatusCode setDataLoader(IConversionSvc *svc, IDataProviderSvc *dpsvc=nullptr) override
IDataManagerSvc: IDataManagerSvc: Pass a default data loader to the service and optionally a data pro...
Definition: DataSvc.cpp:205
virtual long add(const std::string &name, DataObject *pObject, bool is_soft=false)
Add entry to data store.
T rfind(T...args)
T to_string(T...args)
virtual long traverseTree(IDataStoreAgent *pAgent, int level=0)
traverse data tree
MsgStream & verbose() const
shortcut for the method msgStream(MSG::VERBOSE)
Gaudi::Property< std::string > m_rootName
Definition: DataSvc.h:57
virtual StatusCode setDataProvider(IDataProviderSvc *pService)=0
Set Data provider service.
virtual StatusCode loadObject(IRegistry *pNode)
Invoke Persistency service to create transient object from its persistent representation.
Definition: DataSvc.cpp:576
LoadItems m_preLoads
Items to be pre-loaded.
Definition: DataSvc.h:70
Gaudi::Property< bool > m_forceLeaves
Definition: DataSvc.h:58
void setRegistry(IRegistry *pRegistry)
Set pointer to Registry.
Definition: DataObject.h:70
unsigned long release() override
IInterface implementation: Reference the object.
Gaudi::Property< bool > m_enableFaultHdlr
Definition: DataSvc.h:61
virtual const name_type & name() const =0
Name of the directory (or key)
StatusCode traverseTree(IDataStoreAgent *pAgent) override
IDataManagerSvc: Analyze by traversing all data objects in the data store.
Definition: DataSvc.cpp:146
T end(T...args)
bool checkRoot()
Check if root path is valid.
Definition: DataSvc.h:321
DataObject * i_handleDataFault(IRegistry *pReg, boost::string_ref path=boost::string_ref{})
Definition: DataSvc.cpp:542
StatusCode removePreLoadItem(const DataStoreItem &item) override
Remove an item from the preload list.
Definition: DataSvc.cpp:1066
virtual long remove(const std::string &name)
Remove an entry from the store.
const Store & leaves() const
Access the leaves of the object.
StatusCode registerObject(const std::string &fullPath, DataObject *pObject) override
Register object with the data store.
Definition: DataSvc.cpp:353
Data provider interface definition.
DataSvcHelpers::RegistryEntry * m_root
Pointer to root entry.
Definition: DataSvc.h:72
T remove(T...args)
void setAddress(IOpaqueAddress *pAddress) override
Set/Update Opaque address.
Description of the DataStoreItem class.
Definition: DataStoreItem.h:17
StatusCode registerAddress(const std::string &fullPath, IOpaqueAddress *pAddress) override
IDataManagerSvc: Register object address with the data store.
Definition: DataSvc.cpp:248
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:86
IRegistry * registry() const
Get pointer to Registry.
Definition: DataObject.h:72
virtual StatusCode updateObj(IOpaqueAddress *pAddress, DataObject *refpObject)=0
Update the transient object from the other representation.
virtual RegistryEntry * parentEntry()
Pointer to parent registry entry.
Definition: RegistryEntry.h:92
STL class.
TYPE * get() const
Get interface pointer.
Definition: SmartIF.h:82
virtual bool isSoft() const
Is the link soft or hard.
T push_back(T...args)
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
virtual unsigned long addRef()
Add reference to object.
Definition: DataObject.cpp:59
virtual void fireIncident(const Incident &incident)=0
Fire an Incident.
void setObject(DataObject *obj)
Set/Update object address.
StatusCode i_retrieveEntry(DataSvcHelpers::RegistryEntry *parentObj, boost::string_ref path, DataSvcHelpers::RegistryEntry *&pEntry)
Definition: DataSvc.cpp:662
Gaudi::Property< std::string > m_faultName
Definition: DataSvc.h:63
virtual const id_type & identifier() const =0
Full identifier (or key)
T what(T...args)
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:28
StatusCode retrieveEntry(DataSvcHelpers::RegistryEntry *pNode, const std::string &path, DataSvcHelpers::RegistryEntry *&pEntry)
Retrieve registry entry from store.
Definition: DataSvc.cpp:657
T append(T...args)
virtual StatusCode updateObjRefs(IOpaqueAddress *pAddress, DataObject *pObject)=0
Update the references of an updated transient object.
SmartIF< IIncidentSvc > m_incidentSvc
Pointer to incident service.
Definition: DataSvc.h:54
StatusCode findObject(const std::string &fullPath, DataObject *&pObject) override
Find object identified by its full path in the data store.
Definition: DataSvc.cpp:809
T erase(T...args)
StatusCode objectLeaves(const DataObject *pObject, std::vector< IRegistry * > &refLeaves) override
IDataManagerSvc: Explore the object store: retrieve all leaves attached to the object.
Definition: DataSvc.cpp:229
void setDataSvc(IDataProviderSvc *s)
Set the transient data store.
Definition: RegistryEntry.h:90
StatusCode unregisterAddress(const std::string &fullPath) override
IDataManagerSvc: Unregister object address from the data store.
Definition: DataSvc.cpp:306
The IRegistry represents the entry door to the environment any data object residing in a transient da...
Definition: IRegistry.h:22
StatusCode finalize() override
Service initialization.
Definition: DataSvc.cpp:1156
virtual bool isEmpty() const
Simple check if the Container is empty.
StatusCode reinitialize() override
Definition: Service.cpp:250
unsigned int CLID
Class ID definition.
Definition: ClassID.h:8
StatusCode clearSubTree(const std::string &sub_tree_path) override
IDataManagerSvc: Remove all data objects below the sub tree identified by its full path name...
Definition: DataSvc.cpp:75
IOpaqueAddress * address() const override
Retrieve opaque storage address.
StatusCode retrieveObject(IRegistry *pDirectory, const std::string &path, DataObject *&pObject) override
Retrieve object from data store.
Definition: DataSvc.cpp:751
STL class.
T move(T...args)
StatusCode linkObject(IRegistry *from, const std::string &objPath, DataObject *to) override
Add a link to another object.
Definition: DataSvc.cpp:931
#define CAST_REGENTRY(x, y)
Definition: DataSvc.cpp:62
virtual DataObject * object() const =0
Retrieve object behind the link.
Definition of an entry in the transient data store.
Definition: RegistryEntry.h:36
virtual unsigned long release()
release reference to object
Definition: DataObject.cpp:51
Gaudi::Property< std::vector< std::string > > m_inhibitPathes
Definition: DataSvc.h:59
T find(T...args)
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: DataSvc.cpp:167
DataObject * handleDataFault(IRegistry *pReg, const std::string &path="")
Invoke data fault handling if enabled.
Definition: DataSvc.cpp:537
virtual StatusCode fillObjRefs(IOpaqueAddress *pAddress, DataObject *pObject)=0
Resolve the references of the created transient object.
StatusCode reinitialize() override
Service initialization.
Definition: DataSvc.cpp:1132
SmartIF< IConversionSvc > m_dataLoader
Pointer to data loader service.
Definition: DataSvc.h:52
virtual IRegistry * parent() const
Pointer to parent directory entry.
Generic data agent interface.
StatusCode initialize() override
Service initialization.
Definition: DataSvc.cpp:1119
T begin(T...args)
StatusCode unlinkObject(IRegistry *from, const std::string &objPath) override
Remove a link to another object.
Definition: DataSvc.cpp:996
string s
Definition: gaudirun.py:253
Gaudi::Property< bool > m_enableAccessHdlr
Definition: DataSvc.h:65
const std::string & name() const
Retreive DataObject name. It is the name when registered in the store.
Definition: DataObject.cpp:68
const std::string & rootName() const override
IDataManagerSvc: Accessor for root event name.
Definition: DataSvc.cpp:1170
T substr(T...args)
StatusCode objectParent(const DataObject *pObject, IRegistry *&refpParent) override
IDataManagerSvc: Explore the object store: retrieve the object&#39;s parent.
Definition: DataSvc.cpp:213
StatusCode service(const std::string &name, const T *&psvc, bool createIf=true) const
Access a service by name, creating it if it doesn&#39;t already exist.
Definition: Service.h:85
const std::string & identifier() const override
Full identifier (or key)
void reset(TYPE *ptr=nullptr)
Set the internal pointer to the passed one disposing of the old one.
Definition: SmartIF.h:92
Data service incident class.
Opaque address interface definition.
void ignore() const
Definition: StatusCode.h:109
virtual IConversionSvc * getDataLoader(IRegistry *pReg)
Retrieve customizable data loader according to registry entry to be retrieved.
Definition: DataSvc.cpp:1178
StatusCode traverseSubTree(const std::string &sub_tree_path, IDataStoreAgent *pAgent) override
IDataManagerSvc: Analyze by traversing all data objects below the sub tree identified by its full pat...
Definition: DataSvc.cpp:128
virtual IOpaqueAddress * address() const =0
Retrieve opaque storage address.
StatusCode updateObject(IRegistry *pDirectory) override
Update object identified by its directory entry.
Definition: DataSvc.cpp:860
A DataObject is the base class of any identifiable object on any data store.
Definition: DataObject.h:29
StatusCode resetPreLoad() override
Clear the preload list.
Definition: DataSvc.cpp:1079
#define ON_VERBOSE
Definition: DataSvc.cpp:67
virtual DataObject * createDefaultObject() const
Create default objects in case forced creation of leaves is requested.
Definition: DataSvc.cpp:1173
virtual IRegistry * find(const IRegistry *obj) const
Try to find an object identified by its pointer.
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:209
StatusCode clearStore() override
IDataManagerSvc: Remove all data objects in the data store.
Definition: DataSvc.cpp:115
T compare(T...args)
DataSvcHelpers::RegistryEntry RegEntry
Definition: DataSvc.cpp:64
void makeHard(DataObject *pObject)
Initialize link as hard link.