16 #include "ThreadLocalStorage.h" 17 #include "boost/callable_traits.hpp" 18 #include "tbb/concurrent_queue.h" 19 #include "tbb/mutex.h" 20 #include "tbb/recursive_mutex.h" 36 struct Partition final {
47 return dataProvider.get();
51 return dataManager.get();
57 template <
typename T,
typename Mutex = tbb::recursive_mutex,
typename ReadLock =
typename Mutex::scoped_lock,
58 typename WriteLock = ReadLock>
65 decltype(
auto ) with_lock( F&& f ) {
66 WriteLock
lock{m_mtx};
70 decltype(
auto ) with_lock( F&& f )
const {
76 template <
typename Fun>
77 auto with_lock( Fun&& f ) {
78 return [f = std::forward<Fun>( f )](
auto& p ) -> decltype(
auto ) {
return p.with_lock( f ); };
81 template <
typename ContainerOfSynced,
typename Fun>
82 void for_( ContainerOfSynced&
c, Fun&& f ) {
87 TTHREAD_TLS( Synced<Partition>* ) s_current =
nullptr;
94 using argument_t = std::tuple_element_t<0, boost::callable_traits::args_t<F>>;
97 template <
typename Fun>
100 return s_current->with_lock( [&]( Partition& p ) {
101 auto* svc = p.get<std::decay_t<detail::argument_t<Fun>>>();
125 Gaudi::Property<bool> m_forceLeaves{
this,
"ForceLeaves",
false,
"force creation of default leaves on registerObject"};
127 "enable incidents on data creation requests"};
140 using extends::extends;
144 setDataLoader( 0 ).ignore();
145 resetPreLoad().ignore();
146 clearStore().ignore();
147 for_( m_partitions, []( Partition& p ) {
148 p.dataManager->release();
149 p.dataProvider->release();
151 m_partitions.
clear();
155 size_t freeSlots()
override {
return m_freeSlots.unsafe_size(); }
204 for_( m_partitions, []( Partition& p ) { p.dataManager->clearStore().ignore(); } );
240 if ( pDataLoader ) pDataLoader->
addRef();
241 if ( m_dataLoader ) m_dataLoader->
release();
243 m_dataLoader = pDataLoader;
244 for_( m_partitions, [&]( Partition& p ) { p.dataManager->setDataLoader( m_dataLoader,
this ).ignore(); } );
249 for_( m_partitions, [&]( Partition& p ) { p.dataProvider->addPreLoadItem( item ); } );
254 for_( m_partitions, [&]( Partition& p ) { p.dataProvider->removePreLoadItem( item ); } );
259 for_( m_partitions, [&]( Partition& p ) { p.dataProvider->resetPreLoad(); } );
333 return m_partitions[partition].with_lock( []( Partition& p ) {
return p.dataManager->clearStore(); } );
338 s_current = &m_partitions[partition];
345 warning() <<
"Too late to change the number of slots!" <<
endmsg;
359 return findObject(
id.fullKey(), pObject ).isSuccess();
365 size_t slot = std::string::npos;
366 if ( m_freeSlots.try_pop( slot ) ) {
367 assert( slot != std::string::npos );
368 assert( slot < m_partitions.
size() );
369 m_partitions[slot].with_lock( [evtnumber]( Partition& p ) {
370 assert( p.eventNumber == -1 );
371 p.eventNumber = evtnumber;
379 assert( partition < m_partitions.
size() );
380 auto prev = m_partitions[partition].with_lock( []( Partition& p ) {
return std::exchange( p.eventNumber, -1 ); } );
382 m_freeSlots.push( partition );
389 with_lock( [eventnumber](
const Partition& p ) {
return p.eventNumber == eventnumber; } ) );
394 StatusCode sc = service( m_loader, m_addrCreator,
true );
396 error() <<
"Failed to retrieve data loader " 397 <<
"\"" << m_loader <<
"\"" <<
endmsg;
401 sc = service( m_loader, dataLoader,
true );
403 error() <<
MSG::ERROR <<
"Failed to retrieve data loader " 404 <<
"\"" << m_loader <<
"\"" <<
endmsg;
407 sc = setDataLoader( dataLoader );
410 error() <<
MSG::ERROR <<
"Failed to set data loader " 411 <<
"\"" << m_loader <<
"\"" <<
endmsg;
418 if ( m_addrCreator ) m_addrCreator->
release();
419 if ( m_dataLoader ) m_dataLoader->
release();
420 m_addrCreator =
nullptr;
421 m_dataLoader =
nullptr;
433 error() <<
"Unable to initialize base class" <<
endmsg;
436 if ( m_slots < (
size_t)1 ) {
437 error() <<
"Invalid number of slots (" << m_slots <<
")" <<
endmsg;
441 if ( !setNumberOfStores( m_slots ).isSuccess() ) {
442 error() <<
"Cannot set number of slots" <<
endmsg;
447 for (
size_t i = 0; i < m_slots; i++ ) {
459 error() <<
"Failed to instantiate DataSvc as store partition" <<
endmsg;
462 m_partitions[i].with_lock( [&]( Partition& p ) {
463 p.dataProvider = svc;
466 m_freeSlots.push( i );
468 selectStore( 0 ).ignore();
469 return attachServices();
476 error() <<
"Unable to reinitialize base class" <<
endmsg;
480 sc = attachServices();
482 error() <<
"Failed to attach necessary services." <<
endmsg;
490 setDataLoader( 0 ).
ignore();
virtual StatusCode traverseTree(IDataStoreAgent *pAgent)=0
Analyse by traversing all data objects in the data store.
StatusCode updateObject(IRegistry *pDirectory) override
Update object identified by its directory entry.
StatusCode initialize() override
StatusCode unregisterObject(DataObject *pObj) override
Unregister object from the data store.
size_t allocateStore(int evtnumber) override
Allocate a store partition for a given event number.
virtual StatusCode objectLeaves(const DataObject *pObject, std::vector< IRegistry * > &refLeaves)=0
Explore the object store: retrieve all leaves attached to the object The object is identified by its ...
virtual StatusCode unlinkObject(IRegistry *from, boost::string_ref objPath)=0
Remove a link to another object.
StatusCode setDataLoader(IConversionSvc *pDataLoader, IDataProviderSvc *dpsvc __attribute__((unused))=nullptr) override
IDataManagerSvc: Pass a default data loader to the service.
StatusCode finalize() override
StatusCode linkObject(boost::string_ref fullPath, DataObject *to) override
Add a link to another object.
Implementation of property with value of concrete type.
StatusCode setProperty(const Gaudi::Details::PropertyBase &p) override
set the property form another property
StatusCode freeStore(size_t partition) override
Free a store partition.
StatusCode unlinkObject(IRegistry *from, boost::string_ref objPath) override
Remove a link to another object.
size_t getPartitionNumber(int eventnumber) const override
Get the partition number corresponding to a given event.
StatusCode clearStore(size_t partition) override
Remove all data objects in one 'slot' of the data store.
StatusCode registerAddress(boost::string_ref path, IOpaqueAddress *pAddr) override
IDataManagerSvc: Register object address with the data store.
virtual StatusCode setRoot(std::string root_name, DataObject *pObject)=0
Initialize data store for new event by giving new event path.
IAddressCreator interface definition.
StatusCode unlinkObject(boost::string_ref path) override
Remove a link to another object.
virtual StatusCode setDataProvider(IDataProviderSvc *pService)=0
Set Data provider service.
StatusCode findObject(IRegistry *parent, boost::string_ref path, DataObject *&pObj) override
Find object identified by its full path in the data store.
constexpr static const auto SUCCESS
virtual StatusCode preLoad()=0
Load all preload items of the list.
StatusCode unregisterAddress(boost::string_ref path) override
IDataManagerSvc: Unregister object address from the data store.
StatusCode resetPreLoad() override
Clear the preload list.
StatusCode finalize() override
Service initialisation.
StatusCode clearSubTree(DataObject *pObject) override
Remove all data objects below the sub tree identified.
size_t getNumberOfStores() const override
Get the number of event slots (copies of DataSvc objects).
StatusCode objectParent(const IRegistry *pObject, IRegistry *&refpParent) override
IDataManagerSvc: Explore the object store: retrieve the object's parent.
StatusCode addPreLoadItem(const DataStoreItem &item) override
Add an item to the preload list.
StatusCode updateObject(DataObject *pObj) override
Update object.
std::vector< Synced< Partition > > m_partitions
Datastore partitions.
Data provider interface definition.
StatusCode preLoad() override
load all preload items of the list
Description of the DataStoreItem class.
StatusCode unlinkObject(DataObject *from, boost::string_ref objPath) override
Remove a link to another object.
size_t freeSlots() override
Get free slots number.
virtual StatusCode objectParent(const DataObject *pObject, IRegistry *&refpParent)=0
IDataManagerSvc: Explore the object store: retrieve the object's parent.
virtual StatusCode traverseSubTree(boost::string_ref sub_tree_path, IDataStoreAgent *pAgent)=0
Analyse by traversing all data objects below the sub tree identified by its full path name...
StatusCode clearStore() override
IDataManagerSvc: Remove all data objects in the data store.
StatusCode selectStore(size_t partition) override
Activate a partition object. The identifies the partition uniquely.
Invalid root path object cannot be retrieved or stored.
virtual StatusCode linkObject(IRegistry *from, boost::string_ref objPath, DataObject *toObj)=0
Add a link to another object.
#define DECLARE_COMPONENT(type)
StatusCode detachServices()
TupleObj.h GaudiAlg/TupleObj.h namespace with few technical implementations.
StatusCode unregisterAddress(IRegistry *pParent, boost::string_ref path) override
IDataManagerSvc: Unregister object address from the data store.
StatusCode objectLeaves(const IRegistry *pObject, std::vector< IRegistry * > &leaves) override
Explore the object store: retrieve all leaves attached to the object.
This class is used for returning status codes from appropriate routines.
typename arg_helper< lambda >::type argument_t
virtual StatusCode updateObject(IRegistry *pDirectory)=0
Update object identified by its directory entry.
StatusCode linkObject(IRegistry *from, boost::string_ref objPath, DataObject *to) override
Add a link to another object.
StatusCode unregisterObject(boost::string_ref path) override
Unregister object from the data store.
StatusCode removePreLoadItem(const DataStoreItem &item) override
Remove an item from the preload list.
The IRegistry represents the entry door to the environment any data object residing in a transient da...
StatusCode reinitialize() override
StatusCode traverseSubTree(boost::string_ref path, IDataStoreAgent *pAgent) override
Analyze by traversing all data objects below the sub tree.
virtual StatusCode retrieveObject(IRegistry *pDirectory, boost::string_ref path, DataObject *&pObject)=0
Retrieve object identified by its directory entry.
unsigned int CLID
Class ID definition.
virtual StatusCode clearSubTree(boost::string_ref sub_path)=0
Remove all data objects below the sub tree identified by its full path name.
StatusCode clearSubTree(boost::string_ref path) override
Remove all data objects below the sub tree identified.
TTHREAD_TLS(Synced< Partition > *) s_current
StatusCode attachServices()
StatusCode traverseSubTree(DataObject *pObject, IDataStoreAgent *pAgent) override
IDataManagerSvc: Analyze by traversing all data objects below the sub tree.
virtual StatusCode unregisterAddress(boost::string_ref fullPath)=0
Unregister object address from the data store.
StatusCode registerObject(boost::string_ref fullPath, DataObject *pObject)
Register object with the data store.
virtual StatusCode unregisterObject(boost::string_ref fullPath)=0
Unregister object from the data store.
StatusCode objectParent(const DataObject *pObject, IRegistry *&refpParent) override
IDataManagerSvc: Explore the object store: retrieve the object's parent.
StatusCode setRoot(std::string path, IOpaqueAddress *pAddr) override
Initialize data store for new event by giving new event path and address of root object.
virtual unsigned long release()=0
Release Interface instance.
Generic data agent interface.
Base class used to extend a class implementing other interfaces.
StatusCode initialize() override
Service initialization.
StatusCode unregisterObject(DataObject *pObj, boost::string_ref path) override
Unregister object from the data store.
const StatusCode & ignore() const
Ignore/check StatusCode.
StatusCode setRoot(std::string path, DataObject *pObj) override
Initialize data store for new event by giving new event path and root object.
CLID rootCLID() const override
IDataManagerSvc: Accessor for root event CLID.
virtual StatusCode registerAddress(boost::string_ref fullPath, IOpaqueAddress *pAddress)=0
Register object address with the data store.
StatusCode registerAddress(IRegistry *parent, boost::string_ref path, IOpaqueAddress *pAdd) override
IDataManagerSvc: Register object address with the data store.
constexpr static const auto FAILURE
virtual unsigned long addRef()=0
Increment the reference count of Interface instance.
StatusCode objectLeaves(const DataObject *pObject, std::vector< IRegistry * > &leaves) override
Explore the object store: retrieve all leaves attached to the object.
StatusCode registerObject(DataObject *parent, boost::string_ref obj, DataObject *pObj) override
Register object with the data store.
StatusCode initialize() override
Service initialisation.
StatusCode traverseTree(IDataStoreAgent *pAgent) override
IDataManagerSvc: Analyze by traversing all data objects in the data store.
AttribStringParser::Iterator begin(const AttribStringParser &parser)
StatusCode findObject(boost::string_ref path, DataObject *&pObj) override
Find object identified by its full path in the data store.
Opaque address interface definition.
StatusCode registerObject(boost::string_ref parent, boost::string_ref obj, DataObject *pObj) override
Register object with the data store.
A DataObject is the base class of any identifiable object on any data store.
tbb::concurrent_queue< size_t > m_freeSlots
fifo queue of free slots
bool exists(const DataObjID &id) override
check if a data object exists in the current store
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
const std::string & rootName() const override
Name for root Event.
static GAUDI_API void setNumConcEvents(const std::size_t &nE)
StatusCode reinitialize() override
Service initialisation.
StatusCode retrieveObject(IRegistry *parent, boost::string_ref path, DataObject *&pObj) override
Retrieve object from data store.
StatusCode setNumberOfStores(size_t slots) override
Set the number of event slots (copies of DataSvc objects).
~HiveWhiteBoard() override
Standard Destructor.