| The Gaudi Framework v32r1 (f65d50dc)

EvtStoreSvc.cpp
Go to the documentation of this file.
1 #include "GaudiKernel/ConcurrencyFlags.h"
2 #include "GaudiKernel/IConversionSvc.h"
3 #include "GaudiKernel/IDataManagerSvc.h"
4 #include "GaudiKernel/IDataProviderSvc.h"
5 #include "GaudiKernel/IHiveWhiteBoard.h"
6 #include "GaudiKernel/IOpaqueAddress.h"
7 #include "GaudiKernel/IRegistry.h"
8 #include "GaudiKernel/Service.h"
9 #include "GaudiKernel/System.h"
10
11 #include "ThreadLocalStorage.h"
12
13 #include "boost/algorithm/string/predicate.hpp"
14
15 #include "tbb/concurrent_queue.h"
16 #include "tbb/mutex.h"
17 #include "tbb/recursive_mutex.h"
18
19 #include <algorithm>
20 #include <iomanip>
21 #include <iterator>
22 #include <map>
23 #include <stdexcept>
24 #include <type_traits>
25 #include <unordered_map>
26 #include <utility>
27 #include <vector>
28
29 namespace {
30
31 class Entry final : public IRegistry {
32 std::unique_ptr<DataObject> m_data;
33 std::unique_ptr<IOpaqueAddress> m_addr;
34 std::string m_identifier;
35 static IDataProviderSvc* s_svc;
36
37 public:
38 static void setDataProviderSvc( IDataProviderSvc* p ) { s_svc = p; }
39
40 Entry( std::string id, std::unique_ptr<DataObject> data, std::unique_ptr<IOpaqueAddress> addr = {} ) noexcept
41 : m_data{std::move( data )}, m_addr{std::move( addr )}, m_identifier{std::move( id )} {
42 if ( m_data ) m_data->setRegistry( this );
43 if ( m_addr ) m_addr->setRegistry( this );
44 }
45 Entry( const Entry& ) = delete;
46 Entry& operator=( const Entry& rhs ) = delete;
47 Entry( Entry&& rhs ) = delete;
48 Entry& operator=( Entry&& rhs ) = delete;
49
50 // required by IRegistry...
51 unsigned long addRef() override { return -1; }
52 unsigned long release() override { return -1; }
53 const name_type& name() const override { return m_identifier; } // should really be from last '/' onward...
54 const id_type& identifier() const override { return m_identifier; }
55 IDataProviderSvc* dataSvc() const override { return s_svc; }
56 DataObject* object() const override { return const_cast<DataObject*>( m_data.get() ); }
57 IOpaqueAddress* address() const override { return m_addr.get(); }
58 void setAddress( IOpaqueAddress* iAddr ) override {
59 m_addr.reset( iAddr );
60 if ( m_addr ) m_addr->setRegistry( this );
61 }
62 };
63 IDataProviderSvc* Entry::s_svc = nullptr;
64
65 using UnorderedMap = std::unordered_map<std::string_view, Entry>;
66 using OrderedMap = std::map<std::string_view, Entry>;
67
68 template <typename Map = UnorderedMap>
69 class Store {
70 Map m_store;
71 static_assert( std::is_same_v<typename Map::key_type, std::string_view> );
72
73 const auto& emplace( std::string_view k, std::unique_ptr<DataObject> d, std::unique_ptr<IOpaqueAddress> a = {} ) {
74 // tricky way to insert a string_view key which points to the
75 // string contained in the mapped type...
76 auto [i, b] = m_store.try_emplace( k, std::string{k}, std::move( d ), std::move( a ) );
77 if ( !b ) throw std::runtime_error( "failed to insert " + std::string{k} );
78 auto nh = m_store.extract( i );
79 nh.key() = nh.mapped().identifier(); // "re-point" key to the string contained in the Entry
80 auto r = m_store.insert( std::move( nh ) );
81 if ( !r.inserted ) throw std::runtime_error( "failed to insert " + std::string{k} );
82 return r.position->second;
83 }
84
85 public:
86 const DataObject* put( std::string_view k, std::unique_ptr<DataObject> data,
87 std::unique_ptr<IOpaqueAddress> addr = {} ) {
88 return emplace( k, std::move( data ), std::move( addr ) ).object();
89 }
90 const DataObject* get( std::string_view k ) const noexcept {
91 const Entry* d = find( k );
92 return d ? d->object() : nullptr;
93 }
94 const Entry* find( std::string_view k ) const noexcept {
95 auto i = m_store.find( k );
96 return i != m_store.end() ? &( i->second ) : nullptr;
97 }
98
99 auto begin() const noexcept { return m_store.begin(); }
100 auto end() const noexcept { return m_store.end(); }
101 void clear() noexcept { m_store.clear(); }
102 auto erase( std::string_view k ) { return m_store.erase( k ); }
103 template <typename Predicate>
104 void erase_if( Predicate p ) {
105 auto i = m_store.begin();
106 auto end = m_store.end();
107 while ( i != end ) {
108 if ( std::invoke( p, std::as_const( *i ) ) )
109 i = m_store.erase( i );
110 else
111 ++i;
112 }
113 }
114 };
115
116 StatusCode dummy( std::string s ) {
117 std::string trace;
118 System::backTrace( trace, 6, 2 );
119 throw std::logic_error{"Unsupported Function Called: " + s + "\n" + trace};
120 return StatusCode::FAILURE;
121 }
122
123 std::string_view normalize_path( std::string_view path, std::string_view prefix ) {
124 if ( path.size() >= prefix.size() && std::equal( prefix.begin(), prefix.end(), path.begin() ) )
125 path.remove_prefix( prefix.size() );
126 if ( !path.empty() && path.front() == '/' ) path.remove_prefix( 1 );
127 return path;
128 }
129
130 std::unique_ptr<DataObject> createObj( IConversionSvc& cnv, IOpaqueAddress& addr ) {
131 DataObject* pObject = nullptr;
132 auto status = cnv.createObj( &addr, pObject ); // Call data loader
133 auto object = std::unique_ptr<DataObject>( pObject );
134 if ( status.isFailure() ) object.reset();
135 return object;
136 }
137
138 // HiveWhiteBoard helpers
139 struct Partition final {
140 Store<> store;
141 int eventNumber = -1;
142 };
143
144 template <typename T, typename Mutex = tbb::recursive_mutex, typename ReadLock = typename Mutex::scoped_lock,
145 typename WriteLock = ReadLock>
146 class Synced {
147 T m_obj;
148 mutable Mutex m_mtx;
149
150 public:
151 template <typename F>
152 decltype( auto ) with_lock( F&& f ) {
153 WriteLock lock{m_mtx};
154 return f( m_obj );
155 }
156 template <typename F>
157 decltype( auto ) with_lock( F&& f ) const {
158 ReadLock lock{m_mtx};
159 return f( m_obj );
160 }
161 };
162 // transform an f(T) into an f(Synced<T>)
163 template <typename Fun>
164 auto with_lock( Fun&& f ) {
165 return [f = std::forward<Fun>( f )]( auto& p ) -> decltype( auto ) { return p.with_lock( f ); };
166 }
167
168 TTHREAD_TLS( Synced<Partition>* ) s_current = nullptr;
169
170 template <typename Fun>
171 StatusCode fwd( Fun&& f ) {
172 return s_current ? s_current->with_lock( std::forward<Fun>( f ) )
173 : StatusCode{IDataProviderSvc::Status::INVALID_ROOT};
174 }
175
176 } // namespace
177
188 class GAUDI_API EvtStoreSvc : public extends<Service, IDataProviderSvc, IDataManagerSvc, IHiveWhiteBoard> {
189 Gaudi::Property<CLID> m_rootCLID{this, "RootCLID", 110 /*CLID_Event*/, "CLID of root entry"};
190 Gaudi::Property<std::string> m_rootName{this, "RootName", "/Event", "name of root entry"};
191 Gaudi::Property<bool> m_forceLeaves{this, "ForceLeaves", false, "force creation of default leaves on registerObject"};
192 Gaudi::Property<std::string> m_loader{this, "DataLoader", "EventPersistencySvc"};
193 Gaudi::Property<size_t> m_slots{this, "EventSlots", 1, "number of event slots"};
194
195 SmartIF<IConversionSvc> m_dataLoader;
196
198 std::vector<DataStoreItem> m_preLoads;
199
201 std::vector<Synced<Partition>> m_partitions;
202
203 tbb::concurrent_queue<size_t> m_freeSlots;
204
205 public:
206 using extends::extends;
207
208 CLID rootCLID() const override;
209 const std::string& rootName() const override;
210 StatusCode setDataLoader( IConversionSvc* svc, IDataProviderSvc* dpsvc ) override;
211
212 size_t allocateStore( int evtnumber ) override;
213 StatusCode freeStore( size_t partition ) override;
214 size_t freeSlots() override { return m_freeSlots.unsafe_size(); }
215 StatusCode selectStore( size_t partition ) override;
216 StatusCode clearStore() override;
217 StatusCode clearStore( size_t partition ) override;
218 StatusCode setNumberOfStores( size_t slots ) override;
219 size_t getNumberOfStores() const override { return m_slots; }
220 size_t getPartitionNumber( int eventnumber ) const override;
221 bool exists( const DataObjID& id ) override {
222 DataObject* pObject{nullptr};
223 return findObject( id.fullKey(), pObject ).isSuccess();
224 }
225
226 StatusCode objectParent( const DataObject*, IRegistry*& ) override { return dummy( __FUNCTION__ ); }
227 StatusCode objectParent( const IRegistry*, IRegistry*& ) override { return dummy( __FUNCTION__ ); }
228 StatusCode objectLeaves( const DataObject*, std::vector<IRegistry*>& ) override { return dummy( __FUNCTION__ ); }
229 StatusCode objectLeaves( const IRegistry*, std::vector<IRegistry*>& ) override { return dummy( __FUNCTION__ ); }
230
231 StatusCode clearSubTree( std::string_view ) override;
232 StatusCode clearSubTree( DataObject* obj ) override {
233 return obj && obj->registry() ? clearSubTree( obj->registry()->identifier() ) : StatusCode::FAILURE;
234 }
235
236 StatusCode traverseSubTree( std::string_view, IDataStoreAgent* ) override;
237 StatusCode traverseSubTree( DataObject* obj, IDataStoreAgent* pAgent ) override {
238 return ( obj && obj->registry() ) ? traverseSubTree( obj->registry()->identifier(), pAgent ) : StatusCode::FAILURE;
239 }
240 StatusCode traverseTree( IDataStoreAgent* pAgent ) override { return traverseSubTree( std::string_view{}, pAgent ); }
241
242 StatusCode setRoot( std::string root_name, DataObject* pObject ) override;
243 StatusCode setRoot( std::string root_path, IOpaqueAddress* pRootAddr ) override;
244
245 StatusCode unregisterAddress( std::string_view ) override { return dummy( __FUNCTION__ ); };
246 StatusCode unregisterAddress( IRegistry*, std::string_view ) override { return dummy( __FUNCTION__ ); };
247
248 StatusCode registerAddress( std::string_view fullPath, IOpaqueAddress* pAddress ) override;
249 StatusCode registerAddress( IRegistry* parentObj, std::string_view objectPath, IOpaqueAddress* pAddress ) override;
250 StatusCode registerObject( std::string_view parentPath, std::string_view objectPath, DataObject* pObject ) override;
251 StatusCode registerObject( DataObject* parentObj, std::string_view objectPath, DataObject* pObject ) override;
252
253 StatusCode unregisterObject( std::string_view ) override;
254 StatusCode unregisterObject( DataObject* obj ) override {
255 return ( obj && obj->registry() ) ? unregisterObject( obj->registry()->identifier() ) : StatusCode::FAILURE;
256 }
257 StatusCode unregisterObject( DataObject* obj, std::string_view sr ) override {
258 return !obj ? unregisterObject( sr )
259 : obj->registry() ? unregisterObject( ( obj->registry()->identifier() + '/' ).append( sr ) )
260 : StatusCode::FAILURE;
261 };
262
263 StatusCode retrieveObject( IRegistry* pDirectory, std::string_view path, DataObject*& pObject ) override;
264
265 StatusCode findObject( IRegistry* pDirectory, std::string_view path, DataObject*& pObject ) override;
266 StatusCode findObject( std::string_view fullPath, DataObject*& pObject ) override;
267
268 StatusCode updateObject( IRegistry* ) override { return dummy( __FUNCTION__ ); }
269 StatusCode updateObject( DataObject* ) override { return dummy( __FUNCTION__ ); }
270
271 StatusCode addPreLoadItem( const DataStoreItem& ) override;
272 StatusCode removePreLoadItem( const DataStoreItem& ) override;
273 StatusCode resetPreLoad() override {
274 m_preLoads.clear();
275 return StatusCode::SUCCESS;
276 }
277 StatusCode preLoad() override;
278
279 StatusCode linkObject( IRegistry*, std::string_view, DataObject* ) override { return dummy( __FUNCTION__ ); }
280 StatusCode linkObject( std::string_view, DataObject* ) override { return dummy( __FUNCTION__ ); }
281 StatusCode unlinkObject( IRegistry*, std::string_view ) override { return dummy( __FUNCTION__ ); }
282 StatusCode unlinkObject( DataObject*, std::string_view ) override { return dummy( __FUNCTION__ ); }
283 StatusCode unlinkObject( std::string_view ) override { return dummy( __FUNCTION__ ); }
284
285 StatusCode initialize() override {
286 Entry::setDataProviderSvc( this );
287 extends::initialize().ignore();
288 if ( !setNumberOfStores( m_slots ).isSuccess() ) {
289 error() << "Cannot set number of slots" << endmsg;
290 return StatusCode::FAILURE;
291 }
292 m_partitions = std::vector<Synced<Partition>>( m_slots );
293 for ( size_t i = 0; i < m_slots; i++ ) { m_freeSlots.push( i ); }
294 selectStore( 0 ).ignore();
295
296 auto loader = serviceLocator()->service( m_loader ).as<IConversionSvc>().get();
297 if ( !loader ) {
298 error() << "Cannot get IConversionSvc " << m_loader.value() << endmsg;
299 return StatusCode::FAILURE;
300 }
301 return setDataLoader( loader, nullptr );
302 }
303 StatusCode finalize() override {
304 setDataLoader( nullptr, nullptr ).ignore(); // release
305 return extends::finalize();
306 }
307 };
308
309 // Instantiation of a static factory class used by clients to create
310 // instances of this service
311 DECLARE_COMPONENT( EvtStoreSvc )
312
313 CLID EvtStoreSvc::rootCLID() const { return m_rootCLID; }
314 const std::string& EvtStoreSvc::rootName() const { return m_rootName; }
315 StatusCode EvtStoreSvc::setDataLoader( IConversionSvc* pDataLoader, IDataProviderSvc* dpsvc ) {
316 m_dataLoader = pDataLoader;
317 if ( m_dataLoader ) m_dataLoader->setDataProvider( dpsvc ? dpsvc : this ).ignore();
318 return StatusCode::SUCCESS;
319 }
321 size_t EvtStoreSvc::allocateStore( int evtnumber ) {
322 // take next free slot in the list
323 size_t slot = std::string::npos;
324 if ( m_freeSlots.try_pop( slot ) ) {
325 assert( slot != std::string::npos );
326 assert( slot < m_partitions.size() );
327 [[maybe_unused]] auto prev = m_partitions[slot].with_lock(
328 [evtnumber]( Partition& p ) { return std::exchange( p.eventNumber, evtnumber ); } );
329 assert( prev == -1 ); // or whatever value represents 'free'
330 }
331 return slot;
332 }
334 StatusCode EvtStoreSvc::setNumberOfStores( size_t slots ) {
335 if ( slots < size_t{1} ) {
336 error() << "Invalid number of slots (" << slots << ")" << endmsg;
337 return StatusCode::FAILURE;
338 }
339 if ( FSMState() == Gaudi::StateMachine::INITIALIZED || FSMState() == Gaudi::StateMachine::RUNNING ) {
340 error() << "Too late to change the number of slots!" << endmsg;
341 return StatusCode::FAILURE;
342 }
343 m_slots = slots;
344 Gaudi::Concurrency::ConcurrencyFlags::setNumConcEvents( slots );
345 return StatusCode::SUCCESS;
346 }
348 size_t EvtStoreSvc::getPartitionNumber( int eventnumber ) const {
349 auto i = std::find_if( begin( m_partitions ), end( m_partitions ),
350 with_lock( [eventnumber]( const Partition& p ) { return p.eventNumber == eventnumber; } ) );
351 return i != end( m_partitions ) ? std::distance( begin( m_partitions ), i ) : std::string::npos;
352 }
354 StatusCode EvtStoreSvc::selectStore( size_t partition ) {
355 s_current = &m_partitions[partition];
356 return StatusCode::SUCCESS;
357 }
359 StatusCode EvtStoreSvc::freeStore( size_t partition ) {
360 assert( partition < m_partitions.size() );
361 auto prev = m_partitions[partition].with_lock( []( Partition& p ) { return std::exchange( p.eventNumber, -1 ); } );
362 if ( UNLIKELY( prev == -1 ) ) return StatusCode::FAILURE; // double free -- should never happen!
363 m_freeSlots.push( partition );
364 return StatusCode::SUCCESS;
365 }
367 StatusCode EvtStoreSvc::clearStore( size_t partition ) {
368 return m_partitions[partition].with_lock( []( Partition& p ) {
369 p.store.clear();
370 return StatusCode::SUCCESS;
371 } );
372 }
373 StatusCode EvtStoreSvc::clearSubTree( std::string_view top ) {
374 top = normalize_path( top, rootName() );
375 return fwd( [&]( Partition& p ) {
376 p.store.erase_if( [top]( const auto& value ) { return boost::algorithm::starts_with( value.first, top ); } );
377 return StatusCode::SUCCESS;
378 } );
379 }
380 StatusCode EvtStoreSvc::clearStore() {
381 return fwd( []( Partition& p ) {
382 p.store.clear();
383 return StatusCode::SUCCESS;
384 } );
385 }
386 StatusCode EvtStoreSvc::traverseSubTree( std::string_view top, IDataStoreAgent* pAgent ) {
387 return fwd( [&]( Partition& p ) {
388 top = normalize_path( top, rootName() );
389 auto cmp = []( const Entry* lhs, const Entry* rhs ) { return lhs->identifier() < rhs->identifier(); };
390 std::set<const Entry*, decltype( cmp )> keys{std::move( cmp )};
391 for ( const auto& v : p.store ) {
392 if ( boost::algorithm::starts_with( v.second.identifier(), top ) ) keys.insert( &v.second );
393 }
394 auto k = keys.begin();
395 while ( k != keys.end() ) {
396 const auto& id = ( *k )->identifier();
397 int level = std::count( id.begin(), id.end(), '/' );
398 bool accept = pAgent->analyse( const_cast<Entry*>( *( k++ ) ), level );
399 if ( !accept ) {
400 k = std::find_if_not( k, keys.end(),
401 [&id]( const auto& e ) { return boost::algorithm::starts_with( e->identifier(), id ); } );
402 }
403 }
404 return StatusCode::SUCCESS;
405 } );
406 }
407 StatusCode EvtStoreSvc::setRoot( std::string root_path, DataObject* pObject ) {
408 if ( msgLevel( MSG::DEBUG ) ) {
409 debug() << "setRoot( " << root_path << ", (DataObject*)" << (void*)pObject << " )" << endmsg;
410 }
411 clearStore().ignore();
412 return registerObject( nullptr, root_path, pObject );
413 }
414 StatusCode EvtStoreSvc::setRoot( std::string root_path, IOpaqueAddress* pRootAddr ) {
415 auto rootAddr = std::unique_ptr<IOpaqueAddress>( pRootAddr );
416 if ( msgLevel( MSG::DEBUG ) ) {
417 debug() << "setRoot( " << root_path << ", (IOpaqueAddress*)" << (void*)rootAddr.get() << " )" << endmsg;
418 }
419 clearStore().ignore();
420 if ( !rootAddr ) return Status::INVALID_OBJ_ADDR; // Precondition: Address must be valid
421 if ( msgLevel( MSG::DEBUG ) ) {
422 const std::string* par = rootAddr->par();
423 debug() << "par[0]=" << par[0] << endmsg;
424 debug() << "par[1]=" << par[1] << endmsg;
425 }
426 auto object = createObj( *m_dataLoader, *rootAddr ); // Call data loader
427 if ( !object ) return Status::INVALID_OBJECT;
428 if ( msgLevel( MSG::DEBUG ) ) { debug() << "Root Object " << root_path << " created " << endmsg; }
429 auto dummy = Entry{root_path, {}, {}};
430 object->setRegistry( &dummy );
431 rootAddr->setRegistry( &dummy );
432 auto status = m_dataLoader->fillObjRefs( rootAddr.get(), object.get() );
433 if ( status.isSuccess() ) {
434 auto pObject = object.get();
435 status = registerObject( nullptr, root_path, object.release() );
436 if ( status.isSuccess() ) pObject->registry()->setAddress( rootAddr.release() );
437 }
438 return status;
439 }
440 StatusCode EvtStoreSvc::registerAddress( std::string_view path, IOpaqueAddress* pAddr ) {
441 return registerAddress( nullptr, path, pAddr );
442 }
443 StatusCode EvtStoreSvc::registerAddress( IRegistry* pReg, std::string_view path, IOpaqueAddress* pAddr ) {
444 auto addr = std::unique_ptr<IOpaqueAddress>( pAddr );
445 if ( msgLevel( MSG::DEBUG ) ) {
446 debug() << "registerAddress( (IRegistry*)" << (void*)pReg << ", " << path << ", (IOpaqueAddress*)" << addr.get()
447 << "[ " << addr->par()[0] << ", " << addr->par()[1] << " ]"
448 << " )" << endmsg;
449 }
450 if ( !addr ) return Status::INVALID_OBJ_ADDR; // Precondition: Address must be valid
451 if ( path.empty() || path[0] != '/' ) return StatusCode::FAILURE;
452 auto object = createObj( *m_dataLoader, *addr ); // Call data loader
453 if ( !object ) return Status::INVALID_OBJECT;
454 auto fullpath = ( pReg ? pReg->identifier() : m_rootName.value() ) + std::string{path};
455 // the data loader expects the path _including_ the root
456 auto dummy = Entry{fullpath, {}, {}};
457 object->setRegistry( &dummy );
458 addr->setRegistry( &dummy );
459 auto status = m_dataLoader->fillObjRefs( addr.get(), object.get() );
460 if ( !status.isSuccess() ) return status;
461 // note: put will overwrite the registry in pObject to point at the
462 // one actually used -- so we do not dangle, pointing at dummy beyond its
463 // lifetime
464 if ( msgLevel( MSG::DEBUG ) ) {
465 debug() << "registerAddress: " << std::quoted( normalize_path( fullpath, rootName() ) ) << " (DataObject*)"
466 << (void*)object.get() << ( object ? " -> " + System::typeinfoName( typeid( *object ) ) : std::string{} )
467 << endmsg;
468 }
469 fwd( [&]( Partition& p ) {
470 p.store.put( normalize_path( fullpath, rootName() ), std::move( object ), std::move( addr ) );
471 return StatusCode::SUCCESS;
472 } ).ignore();
473 return status;
474 }
475 StatusCode EvtStoreSvc::registerObject( std::string_view parentPath, std::string_view objectPath,
476 DataObject* pObject ) {
477 return parentPath.empty()
478 ? registerObject( nullptr, objectPath, pObject )
479 : registerObject( nullptr, std::string{parentPath}.append( "/" ).append( objectPath ), pObject );
480 }
481 StatusCode EvtStoreSvc::registerObject( DataObject* parentObj, std::string_view path, DataObject* pObject ) {
482 if ( parentObj ) return StatusCode::FAILURE;
483 return fwd( [&, object = std::unique_ptr<DataObject>( pObject ),
484 path = normalize_path( path, rootName() )]( Partition& p ) mutable {
485 if ( m_forceLeaves ) {
486 auto dir = path;
487 for ( auto i = dir.rfind( '/' ); i != std::string_view::npos; i = dir.rfind( '/' ) ) {
488 dir = dir.substr( 0, i );
489 if ( !p.store.find( dir ) ) {
490 if ( msgLevel( MSG::DEBUG ) ) {
491 debug() << "registerObject: adding directory " << std::quoted( dir ) << endmsg;
492 }
493 p.store.put( dir, std::unique_ptr<DataObject>{} );
494 }
495 }
496 }
497 if ( msgLevel( MSG::DEBUG ) ) {
498 debug() << "registerObject: " << std::quoted( path ) << " (DataObject*)" << (void*)object.get()
499 << ( object ? " -> " + System::typeinfoName( typeid( *object ) ) : std::string{} ) << endmsg;
500 }
501 p.store.put( path, std::move( object ) );
502 return StatusCode::SUCCESS;
503 } );
504 }
505 StatusCode EvtStoreSvc::retrieveObject( IRegistry* pDirectory, std::string_view path, DataObject*& pObject ) {
506 if ( pDirectory ) return StatusCode::FAILURE;
507 return fwd( [&]( Partition& p ) {
508 path = normalize_path( path, rootName() );
509 pObject = const_cast<DataObject*>( p.store.get( path ) );
510 if ( msgLevel( MSG::DEBUG ) ) {
511 debug() << "retrieveObject: " << std::quoted( path ) << " (DataObject*)" << (void*)pObject
512 << ( pObject ? " -> " + System::typeinfoName( typeid( *pObject ) ) : std::string{} ) << endmsg;
513 }
514 return pObject ? StatusCode::SUCCESS : StatusCode::FAILURE;
515 } );
516 }
517 StatusCode EvtStoreSvc::findObject( IRegistry* pDirectory, std::string_view path, DataObject*& pObject ) {
518 return retrieveObject( pDirectory, path, pObject );
519 }
520 StatusCode EvtStoreSvc::findObject( std::string_view fullPath, DataObject*& pObject ) {
521 return retrieveObject( nullptr, fullPath, pObject );
522 }
523 StatusCode EvtStoreSvc::unregisterObject( std::string_view sr ) {
524 return fwd( [&]( Partition& p ) { return p.store.erase( sr ) != 0 ? StatusCode::SUCCESS : StatusCode::FAILURE; } );
525 }
526 StatusCode EvtStoreSvc::addPreLoadItem( const DataStoreItem& item ) {
527 auto i = std::find( m_preLoads.begin(), m_preLoads.begin(), item );
528 if ( i == m_preLoads.end() ) m_preLoads.push_back( item );
529 return StatusCode::SUCCESS;
530 }
531 StatusCode EvtStoreSvc::removePreLoadItem( const DataStoreItem& item ) {
532 auto i = std::remove( m_preLoads.begin(), m_preLoads.begin(), item );
533 m_preLoads.erase( i, m_preLoads.end() );
534 return StatusCode::SUCCESS;
535 }
536 StatusCode EvtStoreSvc::preLoad() {
537 for ( const auto& i : m_preLoads ) {
538 DataObject* pObj;
539 if ( msgLevel( MSG::DEBUG ) ) debug() << "Preloading " << i.path() << endmsg;
540 retrieveObject( nullptr, i.path(), pObj ).ignore();
541 }
542 return StatusCode::SUCCESS;
543 }
System.h
IOpaqueAddress::par
virtual const std::string * par() const =0
Retrieve String parameters.
UNLIKELY
#define UNLIKELY(x)
Definition: Kernel.h:96
Gaudi::Units::sr
constexpr double sr
Definition: SystemOfUnits.h:114
Gaudi::StateMachine::INITIALIZED
Definition: StateMachine.h:15
EvtStoreSvc::setNumberOfStores
StatusCode setNumberOfStores(size_t slots) override
Set the number of event slots (copies of DataSvc objects).
Definition: EvtStoreSvc.cpp:334
SmartIF< IConversionSvc >
std::distance
T distance(T... args)
EvtStoreSvc::setDataLoader
StatusCode setDataLoader(IConversionSvc *svc, IDataProviderSvc *dpsvc) override
Definition: EvtStoreSvc.cpp:315
DataObject::registry
IRegistry * registry() const
Get pointer to Registry.
Definition: DataObject.h:72
IConverter::createObj
virtual StatusCode createObj(IOpaqueAddress *pAddress, DataObject *&refpObject)=0
Create the transient representation of an object.
GaudiPython.HistoUtils.path
path
Definition: HistoUtils.py:932
IConversionSvc
Definition: IConversionSvc.h:37
Gaudi::Property
Implementation of property with value of concrete type.
Definition: Property.h:352
Service::FSMState
Gaudi::StateMachine::State FSMState() const override
Definition: Service.h:52
DataObjID
Definition: DataObjID.h:37
System::typeinfoName
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition: System.cpp:298
IDataStoreAgent::analyse
virtual bool analyse(IRegistry *pObject, int level)=0
Analyse the data object.
EvtStoreSvc::resetPreLoad
StatusCode resetPreLoad() override
Definition: EvtStoreSvc.cpp:273
EvtStoreSvc::updateObject
StatusCode updateObject(IRegistry *) override
Definition: EvtStoreSvc.cpp:268
EvtStoreSvc::initialize
StatusCode initialize() override
Definition: EvtStoreSvc.cpp:285
EvtStoreSvc::m_dataLoader
SmartIF< IConversionSvc > m_dataLoader
Definition: EvtStoreSvc.cpp:195
MSG::DEBUG
Definition: IMessageSvc.h:15
IConverter::setDataProvider
virtual StatusCode setDataProvider(IDataProviderSvc *pService)=0
Set Data provider service.
StatusCode::SUCCESS
constexpr static const auto SUCCESS
Definition: StatusCode.h:85
EvtStoreSvc::m_preLoads
std::vector< DataStoreItem > m_preLoads
Items to be pre-loaded.
Definition: EvtStoreSvc.cpp:198
EvtStoreSvc::m_rootName
Gaudi::Property< std::string > m_rootName
Definition: EvtStoreSvc.cpp:190
IRegistry::name
virtual const name_type & name() const =0
Name of the directory (or key)
EvtStoreSvc::clearSubTree
StatusCode clearSubTree(DataObject *obj) override
Definition: EvtStoreSvc.cpp:232
EvtStoreSvc::m_freeSlots
tbb::concurrent_queue< size_t > m_freeSlots
Definition: EvtStoreSvc.cpp:203
std::vector::end
T end(T... args)
EvtStoreSvc::removePreLoadItem
StatusCode removePreLoadItem(const DataStoreItem &) override
Definition: EvtStoreSvc.cpp:531
EvtStoreSvc::traverseSubTree
StatusCode traverseSubTree(std::string_view, IDataStoreAgent *) override
Definition: EvtStoreSvc.cpp:386
EvtStoreSvc::retrieveObject
StatusCode retrieveObject(IRegistry *pDirectory, std::string_view path, DataObject *&pObject) override
Definition: EvtStoreSvc.cpp:505
EvtStoreSvc::traverseTree
StatusCode traverseTree(IDataStoreAgent *pAgent) override
Definition: EvtStoreSvc.cpp:240
IDataProviderSvc
Data provider interface definition.
Definition: IDataProviderSvc.h:43
std::remove
T remove(T... args)
DataStoreItem
Description of the DataStoreItem class.
Definition: DataStoreItem.h:17
std::map
STL class.
EvtStoreSvc::m_slots
Gaudi::Property< size_t > m_slots
Definition: EvtStoreSvc.cpp:193
System::backTrace
GAUDI_API int backTrace(void **addresses, const int depth)
EvtStoreSvc::freeSlots
size_t freeSlots() override
Definition: EvtStoreSvc.cpp:214
EvtStoreSvc::exists
bool exists(const DataObjID &id) override
Definition: EvtStoreSvc.cpp:221
EvtStoreSvc::objectParent
StatusCode objectParent(const DataObject *, IRegistry *&) override
Definition: EvtStoreSvc.cpp:226
CommonMessaging< implements< IService, IProperty, IStateful > >::msgLevel
MSG::Level msgLevel() const
get the cached level (originally extracted from the embedded MsgStream)
Definition: CommonMessaging.h:138
IDataProviderSvc::Status::INVALID_ROOT
Invalid root path object cannot be retrieved or stored.
std::string
STL class.
EvtStoreSvc::linkObject
StatusCode linkObject(std::string_view, DataObject *) override
Definition: EvtStoreSvc.cpp:280
DECLARE_COMPONENT
#define DECLARE_COMPONENT(type)
Definition: PluginServiceV1.h:46
Service.h
EvtStoreSvc::m_forceLeaves
Gaudi::Property< bool > m_forceLeaves
Definition: EvtStoreSvc.cpp:191
std::vector::push_back
T push_back(T... args)
CommonMessagingBase::error
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
Definition: CommonMessaging.h:98
IDataManagerSvc.h
compareOutputFiles.par
string par
Definition: compareOutputFiles.py:465
IDataProviderSvc.h
EvtStoreSvc::preLoad
StatusCode preLoad() override
Definition: EvtStoreSvc.cpp:536
EvtStoreSvc::m_partitions
std::vector< Synced< Partition > > m_partitions
The actual store(s)
Definition: EvtStoreSvc.cpp:201
EvtStoreSvc::clearSubTree
StatusCode clearSubTree(std::string_view) override
Definition: EvtStoreSvc.cpp:373
StatusCode
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:50
EvtStoreSvc::updateObject
StatusCode updateObject(DataObject *) override
Definition: EvtStoreSvc.cpp:269
std::string::append
T append(T... args)
EvtStoreSvc::finalize
StatusCode finalize() override
Definition: EvtStoreSvc.cpp:303
IRegistry::addRef
virtual unsigned long addRef()=0
Add reference to object.
std::runtime_error
STL class.
std::vector::erase
T erase(T... args)
EvtStoreSvc::allocateStore
size_t allocateStore(int evtnumber) override
Allocate a store partition for a given event number.
Definition: EvtStoreSvc.cpp:321
std::lock
T lock(T... args)
IRegistry.h
IRegistry
The IRegistry represents the entry door to the environment any data object residing in a transient da...
Definition: IRegistry.h:22
gaudirun.prefix
string prefix
Definition: gaudirun.py:331
EvtStoreSvc::getNumberOfStores
size_t getNumberOfStores() const override
Definition: EvtStoreSvc.cpp:219
CommonMessagingBase::debug
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
Definition: CommonMessaging.h:107
std::unique_ptr::reset
T reset(T... args)
IOTest.end
def end
Definition: IOTest.py:112
CLID
unsigned int CLID
Class ID definition.
Definition: ClassID.h:8
EvtStoreSvc::unlinkObject
StatusCode unlinkObject(DataObject *, std::string_view) override
Definition: EvtStoreSvc.cpp:282
std::vector::clear
T clear(T... args)
EvtStoreSvc::unregisterObject
StatusCode unregisterObject(std::string_view) override
Definition: EvtStoreSvc.cpp:523
IRegistry::address
virtual IOpaqueAddress * address() const =0
Retrieve opaque storage address.
std::move
T move(T... args)
IRegistry::object
virtual DataObject * object() const =0
Retrieve object behind the link.
EvtStoreSvc::objectParent
StatusCode objectParent(const IRegistry *, IRegistry *&) override
Definition: EvtStoreSvc.cpp:227
std::count
T count(T... args)
TTHREAD_TLS
TTHREAD_TLS(Synced< Partition > *) s_current
EvtStoreSvc::unregisterAddress
StatusCode unregisterAddress(IRegistry *, std::string_view) override
Definition: EvtStoreSvc.cpp:246
EvtStoreSvc::objectLeaves
StatusCode objectLeaves(const IRegistry *, std::vector< IRegistry * > &) override
Definition: EvtStoreSvc.cpp:229
IOpaqueAddress.h
EvtStoreSvc::unregisterObject
StatusCode unregisterObject(DataObject *obj, std::string_view sr) override
Definition: EvtStoreSvc.cpp:257
std::unique_ptr::get
T get(T... args)
EvtStoreSvc::unregisterObject
StatusCode unregisterObject(DataObject *obj) override
Definition: EvtStoreSvc.cpp:254
EvtStoreSvc::linkObject
StatusCode linkObject(IRegistry *, std::string_view, DataObject *) override
Definition: EvtStoreSvc.cpp:279
EvtStoreSvc::clearStore
StatusCode clearStore() override
Definition: EvtStoreSvc.cpp:380
std::find
T find(T... args)
std::vector::size
T size(T... args)
StatusCode::ignore
const StatusCode & ignore() const
Ignore/check StatusCode.
Definition: StatusCode.h:153
Gaudi::StateMachine::RUNNING
Definition: StateMachine.h:16
std::set
STL class.
IConverter::fillObjRefs
virtual StatusCode fillObjRefs(IOpaqueAddress *pAddress, DataObject *pObject)=0
Resolve the references of the created transient object.
EvtStoreSvc::selectStore
StatusCode selectStore(size_t partition) override
Activate a partition object. The identifies the partition uniquely.
Definition: EvtStoreSvc.cpp:354
Gaudi::Functional::details::get
auto get(const Handle &handle, const Algo &, const EventContext &) -> decltype(details::deref(handle.get()))
Definition: FunctionalDetails.h:332
std::vector< DataStoreItem >
std::unique_ptr
STL class.
IDataStoreAgent
Generic data agent interface.
Definition: IDataStoreAgent.h:17
EvtStoreSvc::getPartitionNumber
size_t getPartitionNumber(int eventnumber) const override
Get the partition number corresponding to a given event.
Definition: EvtStoreSvc.cpp:348
IConversionSvc.h
IHiveWhiteBoard.h
extends
Base class used to extend a class implementing other interfaces.
Definition: extends.h:10
std::vector::begin
T begin(T... args)
IRegistry::release
virtual unsigned long release()=0
release reference to object
std::logic_error
STL class.
IRegistry::setAddress
virtual void setAddress(IOpaqueAddress *pAddress)=0
Set/Update Opaque storage address.
EvtStoreSvc::freeStore
StatusCode freeStore(size_t partition) override
Free a store partition.
Definition: EvtStoreSvc.cpp:359
Gaudi::Functional::details::put
Out1 * put(const DataObjectHandle< Out1 > &out_handle, Out2 &&out)
Definition: FunctionalDetails.h:121
EvtStoreSvc::registerAddress
StatusCode registerAddress(std::string_view fullPath, IOpaqueAddress *pAddress) override
Definition: EvtStoreSvc.cpp:440
EvtStoreSvc::objectLeaves
StatusCode objectLeaves(const DataObject *, std::vector< IRegistry * > &) override
Definition: EvtStoreSvc.cpp:228
ConcurrencyFlags.h
EvtStoreSvc::unlinkObject
StatusCode unlinkObject(IRegistry *, std::string_view) override
Definition: EvtStoreSvc.cpp:281
gaudirun.s
string s
Definition: gaudirun.py:316
EvtStoreSvc::setRoot
StatusCode setRoot(std::string root_name, DataObject *pObject) override
Definition: EvtStoreSvc.cpp:407
StatusCode::FAILURE
constexpr static const auto FAILURE
Definition: StatusCode.h:86
IRegistry::dataSvc
virtual IDataProviderSvc * dataSvc() const =0
Retrieve pointer to Transient Store.
EvtStoreSvc::unregisterAddress
StatusCode unregisterAddress(std::string_view) override
Definition: EvtStoreSvc.cpp:245
gaudirun.level
level
Definition: gaudirun.py:334
IRegistry::identifier
virtual const id_type & identifier() const =0
Full identifier (or key)
Gaudi::Utils::begin
AttribStringParser::Iterator begin(const AttribStringParser &parser)
Definition: AttribStringParser.h:120
IOpaqueAddress::setRegistry
virtual void setRegistry(IRegistry *r)=0
Update directory pointer.
IOpaqueAddress
Opaque address interface definition.
Definition: IOpaqueAddress.h:23
EvtStoreSvc::registerObject
StatusCode registerObject(std::string_view parentPath, std::string_view objectPath, DataObject *pObject) override
Definition: EvtStoreSvc.cpp:475
ReadAndWriteWhiteBoard.loader
loader
Definition: ReadAndWriteWhiteBoard.py:36
GAUDI_API
#define GAUDI_API
Definition: Kernel.h:71
DataObject
A DataObject is the base class of any identifiable object on any data store.
Definition: DataObject.h:30
std::equal
T equal(T... args)
Containers::Map
KeyedObjectManager< map > Map
Forward declaration of specialized std::map-like object manager.
Definition: KeyedObjectManager.h:95
EvtStoreSvc
Use a minimal event store implementation, and adds everything required to satisfy the IDataProviderSv...
Definition: EvtStoreSvc.cpp:188
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:192
EvtStoreSvc::addPreLoadItem
StatusCode addPreLoadItem(const DataStoreItem &) override
Definition: EvtStoreSvc.cpp:526
EvtStoreSvc::findObject
StatusCode findObject(IRegistry *pDirectory, std::string_view path, DataObject *&pObject) override
Definition: EvtStoreSvc.cpp:517
Gaudi::Concurrency::ConcurrencyFlags::setNumConcEvents
static GAUDI_API void setNumConcEvents(const std::size_t &nE)
Definition: ConcurrencyFlags.h:59
EvtStoreSvc::rootName
const std::string & rootName() const override
Definition: EvtStoreSvc.cpp:314
EvtStoreSvc::traverseSubTree
StatusCode traverseSubTree(DataObject *obj, IDataStoreAgent *pAgent) override
Definition: EvtStoreSvc.cpp:237
EvtStoreSvc::unlinkObject
StatusCode unlinkObject(std::string_view) override
Definition: EvtStoreSvc.cpp:283
std::unordered_map
STL class.