The Gaudi Framework  v30r4 (9b837755)
DataHandleHolderBase< BASE > Class Template Reference

Common infrastructure for classes that manage data handles and other Scheduler-known data dependencies. More...

#include <GaudiKernel/DataHandleHolderBase.h>

Inheritance diagram for DataHandleHolderBase< BASE >:
Collaboration diagram for DataHandleHolderBase< BASE >:

Public Member Functions

template<typename... Args>
 DataHandleHolderBase (Args &&...args)
 NOTE: Cannot use "using Super::Super;" due to a GCC 6 bug. More...
 
void registerDataHandle (Gaudi::v2::DataHandle &handle) final override
 Register a data handle of this algorithm/tool. More...
 
void addDataDependency (const DataObjID &key, AccessMode access) final override
 Add a data dependency, even after initialization. More...
 
const DataObjIDColldataDependencies (AccessMode access) const final override
 Tell which whiteboard keys the algorithm will be reading or writing. More...
 
void declare (Gaudi::v1::DataHandle &handle) override
 Declare ownership of a legacy DataHandle. More...
 
void renounce (Gaudi::v1::DataHandle &handle) override
 Discard ownership of a legacy DataHandle. More...
 
const DataObjIDCollallDataDependencies () const final override
 
- Public Member Functions inherited from extends< BASE, IDataHandleHolder >
void * i_cast (const InterfaceID &tid) const override
 Implementation of IInterface::i_cast. More...
 
StatusCode queryInterface (const InterfaceID &ti, void **pp) override
 Implementation of IInterface::queryInterface. More...
 
std::vector< std::stringgetInterfaceNames () const override
 Implementation of IInterface::getInterfaceNames. More...
 

Protected Types

enum  CircularDepAction { CircularDepAction::Abort, CircularDepAction::Ignore }
 A circular dependency handling action. More...
 
using DataObjIDMapping = std::function< boost::optional< DataObjID >(const DataObjID &)>
 DataObjID mapping function, with optimized identity mapping case. More...
 
using CircularDepHandler = std::function< CircularDepAction(const DataObjID &)>
 A circular dependency handler, which can take any user-specified step (e.g. More...
 

Protected Member Functions

void updateDataDependencies (const DataObjIDMapping &keyMap)
 Update the key of each registered data dependency, using a user-defined mapping from the old to the new key. More...
 
void collectExplicitDataDependencies ()
 Collect all explicit data dependencies in a single place. More...
 
StatusCode handleCircularDataDependencies (CircularDepHandler &&circularDepHandler)
 Look for circular dependencies and let a user-specified handler deal with each of them. More...
 
void collectImplicitDataDependencies (const IDataHandleHolder *child)
 Add the dependencies of another DataHandleHolder to our dependency list. More...
 
const DataObjIDCollignoredDataDependencies (AccessMode access) const
 Tell which data dependencies have been ignored due to an empty key. More...
 
void initializeDataHandleHolder ()
 Initialize the DataHandles. More...
 

Private Types

using Super = extends< BASE, IDataHandleHolder >
 
using AccessMode = Gaudi::v2::DataHandle::AccessMode
 
using DataHandleList = std::vector< Gaudi::v2::DataHandle * >
 

Private Member Functions

bool isNewDataDependency (const Gaudi::v2::DataHandle &handle) const
 Check if a data dependency has not been declared before (new DataHandle version) More...
 
bool isNewDataDependency (const Gaudi::v1::DataHandle &handle) const
 Check if a data dependency has not been declared before (new DataHandle version) More...
 
template<typename KeyHolderColl >
void collectDependencies (const KeyHolderColl keyHolderArray[])
 
void collectDependencies (const std::unordered_set< Gaudi::v1::DataHandle * > legacyHandles)
 Specialization of extractDependencies for legacy DataHandles. More...
 

Static Private Member Functions

static size_t accessToIndex (AccessMode access)
 Convert a data dependency access mode to its index in our internal storage. More...
 
static const DataObjIDaccessKey (const Gaudi::v2::DataHandle *handlePtr)
 Access the key of a DataHandle. More...
 
static const DataObjIDaccessKey (const DataObjID &key)
 Access the key of a DataObjID (identity function) More...
 
static const DataObjIDaccessKey (const Gaudi::v1::DataHandle *handlePtr)
 Access the key of a legacy (non-reentrant) DataHandle. More...
 
template<typename KeyHolder >
static void extractKey (DataObjIDColl &validOutput, DataObjIDColl &ignoredOutput, const KeyHolder &holder)
 Extract the key of a key holder, putting empty keys on an ignore list. More...
 
template<typename KeyHolderColl >
static void extractKeys (DataObjIDColl &validOutput, DataObjIDColl &ignoredOutput, const KeyHolderColl &keyHolders)
 Extract non-empty DataObjID keys from a collection of key holders. More...
 
static void updateKey (Gaudi::v2::DataHandle *target, DataObjID &&key)
 Update the key of a DataHandle. More...
 
static void updateKey (DataObjID &target, DataObjID &&key)
 Update the key of a DataObjID. More...
 
static void updateKey (Gaudi::v1::DataHandle *target, DataObjID &&key)
 Update the key of a legacy (non-reentrant) DataHandle. More...
 
template<typename KeyHolderColl >
static void updateDependencies (KeyHolderColl &keyHolders, const DataObjIDMapping &keyMap)
 Update the DataObjID keys of a collection of key holders. More...
 
static void updateDependencies (DataObjIDColl &keys, const DataObjIDMapping &keyMap)
 Specialization of the above algorithm for DataObjIDColls, where updating the keys in place is not possible. More...
 
static void updateDependencies (Gaudi::Property< DataObjIDColl > &keys, const DataObjIDMapping &keyMap)
 Specialization for properties which accesses the inner collection. More...
 
template<typename KeyHolderColl >
static void updateDependencies (KeyHolderColl keyHoldersArray[], const DataObjIDMapping &keyMap)
 Specialization of the above algorithm for arrays of KeyHolderColls. More...
 

Private Attributes

DataHandleList m_dataHandles [NUM_ACCESS_MODES]
 
std::unordered_set< Gaudi::v1::DataHandle * > m_legacyHandles
 
Gaudi::Property< DataObjIDCollm_extraDeps [NUM_ACCESS_MODES]
 
DataObjIDColl m_dataDepKeys [NUM_ACCESS_MODES]
 
bool m_explicitDepsCollected = false
 Truth that all explicit data dependencies have already been collected in a single list. More...
 
DataObjIDColl m_ignoredDataDeps [NUM_ACCESS_MODES]
 

Static Private Attributes

static constexpr size_t NUM_ACCESS_MODES = static_cast<size_t>( AccessMode::NUM_ACCESS_MODES )
 

Additional Inherited Members

- Public Types inherited from extends< BASE, IDataHandleHolder >
using base_class = extends
 Typedef to this class. More...
 
using extend_interfaces_base = extend_interfaces< Interfaces... >
 Typedef to the base of this class. More...
 
- Public Types inherited from extend_interfaces< Interfaces... >
using ext_iids = typename Gaudi::interface_list_cat< typename Interfaces::ext_iids... >::type
 take union of the ext_iids of all Interfaces... More...
 

Detailed Description

template<typename BASE>
class DataHandleHolderBase< BASE >

Common infrastructure for classes that manage data handles and other Scheduler-known data dependencies.

This template is intended to be used as a common base class of Algorithms and AlgTools. It factors out the bookkeeping associated with DataHandles and other explicitly declared data dependencies.

Definition at line 27 of file DataHandleHolderBase.h.

Member Typedef Documentation

template<typename BASE>
using DataHandleHolderBase< BASE >::AccessMode = Gaudi::v2::DataHandle::AccessMode
private

Definition at line 30 of file DataHandleHolderBase.h.

template<typename BASE>
using DataHandleHolderBase< BASE >::CircularDepHandler = std::function<CircularDepAction( const DataObjID& )>
protected

A circular dependency handler, which can take any user-specified step (e.g.

logging), then produces a dependency handling action.

See CircularDepAction documentation for more information.

Definition at line 224 of file DataHandleHolderBase.h.

template<typename BASE>
using DataHandleHolderBase< BASE >::DataHandleList = std::vector<Gaudi::v2::DataHandle*>
private

Definition at line 319 of file DataHandleHolderBase.h.

template<typename BASE>
using DataHandleHolderBase< BASE >::DataObjIDMapping = std::function<boost::optional<DataObjID>( const DataObjID& )>
protected

DataObjID mapping function, with optimized identity mapping case.

This construct is used when updating the DataObjIDs associated with data dependencies, which is needed for some legacy workarounds.

The mapping function shall return boost::none when no change is required, and the modified DataObjID otherwise. This design optimizes the "no change" case, which is expected to be the norm.

Definition at line 141 of file DataHandleHolderBase.h.

template<typename BASE>
using DataHandleHolderBase< BASE >::Super = extends<BASE, IDataHandleHolder>
private

Definition at line 29 of file DataHandleHolderBase.h.

Member Enumeration Documentation

template<typename BASE>
enum DataHandleHolderBase::CircularDepAction
strongprotected

A circular dependency handling action.

A Gaudi Algorithm with circular dependencies is not schedulable: the Scheduler will not run it until all of its data dependencies are present, but it must be run for at least one of its dependencies to be created. As a result of this deadlock, the Scheduler will stall.

Most circular dependencies are the result of a bug, in which case aborting framework initialization is the right course of action. But some circular dependencies accidentally emerge as a result of Algs having inner structure (e.g. calling multiple AlgTools/SubAlgs which generate each other's inputs). In this latter case, silently breaking up the circularity by deleting the conflicting input dependency may be the right course of action.

The user-specified circular dependency handler will notify the DataHandleHolder of its decision with this enum.

Enumerator
Abort 

The framework cannot recover from this circular dependency and will shut down, iteration should be terminated.

Ignore 

The circular dependency is assumed to be a false alarm (e.g.

data dependencies from inner AlgTools) and the corresponding input dependency can be deleted to avoid scheduler stalls.

Definition at line 208 of file DataHandleHolderBase.h.

208  {
211  Abort,
212 
216  Ignore
217  };

Constructor & Destructor Documentation

template<typename BASE>
template<typename... Args>
DataHandleHolderBase< BASE >::DataHandleHolderBase ( Args &&...  args)
inline

NOTE: Cannot use "using Super::Super;" due to a GCC 6 bug.

Definition at line 35 of file DataHandleHolderBase.h.

35  : Super( std::forward<Args>( args )... )
36  {
37  }
extends< BASE, IDataHandleHolder > Super

Member Function Documentation

template<typename BASE>
static const DataObjID& DataHandleHolderBase< BASE >::accessKey ( const Gaudi::v2::DataHandle handlePtr)
inlinestaticprivate

Access the key of a DataHandle.

Definition at line 371 of file DataHandleHolderBase.h.

371 { return handlePtr->targetKey(); }
const DataObjID & targetKey() const
(Configurable) ID of the data being accessed via this handle
Definition: DataHandle.h:133
template<typename BASE>
static const DataObjID& DataHandleHolderBase< BASE >::accessKey ( const DataObjID key)
inlinestaticprivate

Access the key of a DataObjID (identity function)

Definition at line 374 of file DataHandleHolderBase.h.

374 { return key; }
template<typename BASE>
static const DataObjID& DataHandleHolderBase< BASE >::accessKey ( const Gaudi::v1::DataHandle handlePtr)
inlinestaticprivate

Access the key of a legacy (non-reentrant) DataHandle.

Definition at line 377 of file DataHandleHolderBase.h.

377 { return handlePtr->fullKey(); }
virtual const DataObjID & fullKey() const
Definition: DataHandle.h:56
template<typename BASE>
static size_t DataHandleHolderBase< BASE >::accessToIndex ( AccessMode  access)
inlinestaticprivate

Convert a data dependency access mode to its index in our internal storage.

Definition at line 346 of file DataHandleHolderBase.h.

346 { return static_cast<size_t>( access ); }
template<typename BASE>
void DataHandleHolderBase< BASE >::addDataDependency ( const DataObjID key,
AccessMode  access 
)
inlinefinaloverride

Add a data dependency, even after initialization.

DataHandles are the preferred way to declare statically known data dependencies. However, there are cases in which an Algorithm's data dependencies are only known at execution time, typically when data is loaded on demand from a file or database. In this case, this method should be used to declare those dynamic data dependencies.

Definition at line 62 of file DataHandleHolderBase.h.

63  {
64  auto index = accessToIndex( access );
65  m_dataDepKeys[index].insert( key );
66  }
static size_t accessToIndex(AccessMode access)
Convert a data dependency access mode to its index in our internal storage.
DataObjIDColl m_dataDepKeys[NUM_ACCESS_MODES]
T insert(T...args)
template<typename BASE>
const DataObjIDColl* DataHandleHolderBase< BASE >::allDataDependencies ( ) const
inlinefinaloverride

Definition at line 122 of file DataHandleHolderBase.h.

123  {
124  if ( !m_explicitDepsCollected ) {
125  throw GaudiException( "Cannot read data dependencies before they are collected", this->name(),
127  }
128  return m_dataDepKeys;
129  }
constexpr static const auto FAILURE
Definition: StatusCode.h:88
Define general base for Gaudi exception.
bool m_explicitDepsCollected
Truth that all explicit data dependencies have already been collected in a single list...
DataObjIDColl m_dataDepKeys[NUM_ACCESS_MODES]
template<typename BASE>
template<typename KeyHolderColl >
void DataHandleHolderBase< BASE >::collectDependencies ( const KeyHolderColl  keyHolderArray[])
inlineprivate

Definition at line 408 of file DataHandleHolderBase.h.

409  {
410  for ( size_t i = 0; i < NUM_ACCESS_MODES; ++i ) {
411  extractKeys( m_dataDepKeys[i], m_ignoredDataDeps[i], keyHolderArray[i] );
412  }
413  }
static constexpr size_t NUM_ACCESS_MODES
DataObjIDColl m_dataDepKeys[NUM_ACCESS_MODES]
DataObjIDColl m_ignoredDataDeps[NUM_ACCESS_MODES]
static void extractKeys(DataObjIDColl &validOutput, DataObjIDColl &ignoredOutput, const KeyHolderColl &keyHolders)
Extract non-empty DataObjID keys from a collection of key holders.
template<typename BASE>
void DataHandleHolderBase< BASE >::collectDependencies ( const std::unordered_set< Gaudi::v1::DataHandle * >  legacyHandles)
inlineprivate

Specialization of extractDependencies for legacy DataHandles.

These need special treatment, among other things because they can be both reading from and writing to a given whiteboard location.

Definition at line 420 of file DataHandleHolderBase.h.

421  {
422  DataObjIDColl& validInputs = m_dataDepKeys[accessToIndex( AccessMode::Read )];
423  DataObjIDColl& validOutputs = m_dataDepKeys[accessToIndex( AccessMode::Write )];
424  DataObjIDColl& ignoredInputs = m_ignoredDataDeps[accessToIndex( AccessMode::Read )];
425  DataObjIDColl& ignoredOutputs = m_ignoredDataDeps[accessToIndex( AccessMode::Write )];
426 
427  for ( auto handle : legacyHandles ) {
428  if ( handle->mode() & Gaudi::v1::DataHandle::Reader ) {
429  extractKey( validInputs, ignoredInputs, handle );
430  }
431  if ( handle->mode() & Gaudi::v1::DataHandle::Writer ) {
432  extractKey( validOutputs, ignoredOutputs, handle );
433  }
434  }
435  }
static size_t accessToIndex(AccessMode access)
Convert a data dependency access mode to its index in our internal storage.
DataObjIDColl m_dataDepKeys[NUM_ACCESS_MODES]
DataObjIDColl m_ignoredDataDeps[NUM_ACCESS_MODES]
static void extractKey(DataObjIDColl &validOutput, DataObjIDColl &ignoredOutput, const KeyHolder &holder)
Extract the key of a key holder, putting empty keys on an ignore list.
template<typename BASE>
void DataHandleHolderBase< BASE >::collectExplicitDataDependencies ( )
inlineprotected

Collect all explicit data dependencies in a single place.

Like updateDataDependencies(), this method must be called at a framework initialization stage where the DataObjIDs associated with data dependencies are set in stone and will not change anymore.

For optimal performance, it should also be called after any call to updateKeys (see that method's documentation for more info).

Definition at line 173 of file DataHandleHolderBase.h.

174  {
175  // Considering this function's interface contract, calling it multiple
176  // times is very likely to be the result of a usage error.
177  if ( m_explicitDepsCollected ) {
178  throw GaudiException( "Explicit dependencies may only be collected once", this->name(), StatusCode::FAILURE );
179  }
180 
181  // Collect the centralized lists of inputs and outputs
185 
186  // Take note that the explicit dependencies have been collected
188  }
constexpr static const auto FAILURE
Definition: StatusCode.h:88
Define general base for Gaudi exception.
void collectDependencies(const KeyHolderColl keyHolderArray[])
std::unordered_set< Gaudi::v1::DataHandle * > m_legacyHandles
Gaudi::Property< DataObjIDColl > m_extraDeps[NUM_ACCESS_MODES]
bool m_explicitDepsCollected
Truth that all explicit data dependencies have already been collected in a single list...
DataHandleList m_dataHandles[NUM_ACCESS_MODES]
template<typename BASE>
void DataHandleHolderBase< BASE >::collectImplicitDataDependencies ( const IDataHandleHolder child)
inlineprotected

Add the dependencies of another DataHandleHolder to our dependency list.

This method is used to collect the implicit data dependencies that appear when an Algorithm holds inner Tools and SubAlgs, which have data dependencies themselves. We need this so that the Scheduler can see those "inner" dependencies.

This method must be called after the dependencies of the child Tool/Algorithm have been collected. This includes implicit dependencies, if applicable.

Definition at line 279 of file DataHandleHolderBase.h.

280  {
281  if ( !child ) return; // Framework randomly sends nulls to this function...
283  }
void collectDependencies(const KeyHolderColl keyHolderArray[])
virtual const DataObjIDColl * allDataDependencies() const =0
Access the internal array of data dependencies.
template<typename BASE>
const DataObjIDColl& DataHandleHolderBase< BASE >::dataDependencies ( AccessMode  access) const
inlinefinaloverride

Tell which whiteboard keys the algorithm will be reading or writing.

This function will only provide the full dependency list after it has been collected, which happens during initialization.

Definition at line 73 of file DataHandleHolderBase.h.

74  {
75  auto index = accessToIndex( access );
76  return allDataDependencies()[index];
77  }
static size_t accessToIndex(AccessMode access)
Convert a data dependency access mode to its index in our internal storage.
const DataObjIDColl * allDataDependencies() const final override
template<typename BASE>
void DataHandleHolderBase< BASE >::declare ( Gaudi::v1::DataHandle handle)
inlineoverride

Declare ownership of a legacy DataHandle.

Definition at line 80 of file DataHandleHolderBase.h.

81  {
82  if ( m_explicitDepsCollected && isNewDataDependency( handle ) ) {
83  throw GaudiException( "Cannot register a new data handle after data dependency collection", this->name(),
85  }
86 
87  if ( !handle.owner() ) {
88  handle.setOwner( this );
89  } else if ( handle.owner() != this ) {
90  throw GaudiException( "Attempt to declare foreign handle with algorithm!", this->name(), StatusCode::FAILURE );
91  }
92 
93  m_legacyHandles.insert( &handle );
94  }
bool isNewDataDependency(const Gaudi::v2::DataHandle &handle) const
Check if a data dependency has not been declared before (new DataHandle version)
constexpr static const auto FAILURE
Definition: StatusCode.h:88
Define general base for Gaudi exception.
virtual IDataHandleHolder * owner() const
Definition: DataHandle.h:48
std::unordered_set< Gaudi::v1::DataHandle * > m_legacyHandles
bool m_explicitDepsCollected
Truth that all explicit data dependencies have already been collected in a single list...
virtual void setOwner(IDataHandleHolder *o)
Definition: DataHandle.h:47
T insert(T...args)
template<typename BASE>
template<typename KeyHolder >
static void DataHandleHolderBase< BASE >::extractKey ( DataObjIDColl validOutput,
DataObjIDColl ignoredOutput,
const KeyHolder &  holder 
)
inlinestaticprivate

Extract the key of a key holder, putting empty keys on an ignore list.

Definition at line 381 of file DataHandleHolderBase.h.

382  {
383  const DataObjID& key = accessKey( holder );
384  if ( !key.empty() ) {
385  validOutput.insert( key );
386  } else {
387  ignoredOutput.insert( key );
388  }
389  }
T insert(T...args)
bool empty() const
Tell if this DataObjID is has an empty key.
Definition: DataObjID.h:53
static const DataObjID & accessKey(const Gaudi::v2::DataHandle *handlePtr)
Access the key of a DataHandle.
template<typename BASE>
template<typename KeyHolderColl >
static void DataHandleHolderBase< BASE >::extractKeys ( DataObjIDColl validOutput,
DataObjIDColl ignoredOutput,
const KeyHolderColl &  keyHolders 
)
inlinestaticprivate

Extract non-empty DataObjID keys from a collection of key holders.

Given an output key collection and a collection of objects that have an associated DataObjID key which can be accessed via an overload of accessKey(), extract the keys, filter out empty ones, and store the rest in the output collection.

Definition at line 399 of file DataHandleHolderBase.h.

400  {
401  validOutput.reserve( keyHolders.size() );
402  for ( const auto& holder : keyHolders ) {
403  extractKey( validOutput, ignoredOutput, holder );
404  }
405  }
static void extractKey(DataObjIDColl &validOutput, DataObjIDColl &ignoredOutput, const KeyHolder &holder)
Extract the key of a key holder, putting empty keys on an ignore list.
T reserve(T...args)
template<typename BASE>
StatusCode DataHandleHolderBase< BASE >::handleCircularDataDependencies ( CircularDepHandler &&  circularDepHandler)
inlineprotected

Look for circular dependencies and let a user-specified handler deal with each of them.

This method must be called after explicit dependencies have been collected, as otherwise it may miss some circular dependencies.

Definition at line 232 of file DataHandleHolderBase.h.

233  {
234  // Make sure that explicit dependencies have been collected beforehand
235  if ( !m_explicitDepsCollected ) {
236  throw GaudiException( "Explicit dependencies must be collected first", this->name(), StatusCode::FAILURE );
237  }
238 
239  // Go through the output dependencies, looking for circular input
240  // dependencies
241  //
242  // We must use this inefficient O(N²) iteration pattern because circular
243  // dependency handling may mutate the input dependency list,
244  // invalidating any iterator to that list.
245  //
246  const DataObjIDColl& outputKeys = m_dataDepKeys[accessToIndex( AccessMode::Write )];
247  DataObjIDColl& inputKeys = m_dataDepKeys[accessToIndex( AccessMode::Read )];
248  for ( const auto& outputKey : outputKeys ) {
249  auto inputPos = inputKeys.find( outputKey );
250  if ( inputPos != inputKeys.end() ) {
251  // Call the user circular dependency handler on each dependency
252  switch ( circularDepHandler( *inputPos ) ) {
253  // Abort iteration if asked to do so
255  return StatusCode::FAILURE;
256 
257  // Break the circular dependency otherwise
259  inputKeys.erase( inputPos );
260  }
261  }
262  }
263 
264  // If control reached this point, we are fine
265  return StatusCode::SUCCESS;
266  }
static size_t accessToIndex(AccessMode access)
Convert a data dependency access mode to its index in our internal storage.
constexpr static const auto FAILURE
Definition: StatusCode.h:88
Define general base for Gaudi exception.
bool m_explicitDepsCollected
Truth that all explicit data dependencies have already been collected in a single list...
The circular dependency is assumed to be a false alarm (e.g.
T erase(T...args)
DataObjIDColl m_dataDepKeys[NUM_ACCESS_MODES]
The framework cannot recover from this circular dependency and will shut down, iteration should be te...
constexpr static const auto SUCCESS
Definition: StatusCode.h:87
T find(T...args)
template<typename BASE>
const DataObjIDColl& DataHandleHolderBase< BASE >::ignoredDataDependencies ( AccessMode  access) const
inlineprotected

Tell which data dependencies have been ignored due to an empty key.

The interface caveats described in inputKeys() also apply here.

Definition at line 289 of file DataHandleHolderBase.h.

290  {
291  if ( !m_explicitDepsCollected ) {
292  throw GaudiException( "Cannot read ignored data dependencies before they are collected", this->name(),
294  }
295  return m_ignoredDataDeps[accessToIndex( access )];
296  }
static size_t accessToIndex(AccessMode access)
Convert a data dependency access mode to its index in our internal storage.
constexpr static const auto FAILURE
Definition: StatusCode.h:88
Define general base for Gaudi exception.
bool m_explicitDepsCollected
Truth that all explicit data dependencies have already been collected in a single list...
DataObjIDColl m_ignoredDataDeps[NUM_ACCESS_MODES]
template<typename BASE>
void DataHandleHolderBase< BASE >::initializeDataHandleHolder ( )
inlineprotected

Initialize the DataHandles.

This operation accesses framework services and must therefore be run after the host Algorithm or AlgTool has been sysInitialized.

Definition at line 303 of file DataHandleHolderBase.h.

304  {
305  for ( auto handle : m_legacyHandles ) handle->init();
306 
307  for ( auto handleArray : m_dataHandles ) {
308  for ( auto handle : handleArray ) {
309  handle->initialize( *this );
310  }
311  }
312  }
std::unordered_set< Gaudi::v1::DataHandle * > m_legacyHandles
DataHandleList m_dataHandles[NUM_ACCESS_MODES]
template<typename BASE>
bool DataHandleHolderBase< BASE >::isNewDataDependency ( const Gaudi::v2::DataHandle handle) const
inlineprivate

Check if a data dependency has not been declared before (new DataHandle version)

Definition at line 349 of file DataHandleHolderBase.h.

350  {
351  auto index = accessToIndex( handle.access() );
352  return m_dataDepKeys[index].find( handle.targetKey() ) == m_dataDepKeys[index].end();
353  }
static size_t accessToIndex(AccessMode access)
Convert a data dependency access mode to its index in our internal storage.
const DataObjID & targetKey() const
(Configurable) ID of the data being accessed via this handle
Definition: DataHandle.h:133
DataObjIDColl m_dataDepKeys[NUM_ACCESS_MODES]
T find(T...args)
AccessMode access() const
Definition: DataHandle.h:116
template<typename BASE>
bool DataHandleHolderBase< BASE >::isNewDataDependency ( const Gaudi::v1::DataHandle handle) const
inlineprivate

Check if a data dependency has not been declared before (new DataHandle version)

Definition at line 356 of file DataHandleHolderBase.h.

357  {
358  bool result = false;
359  if ( handle.mode() & Gaudi::v1::DataHandle::Reader ) {
360  auto index = accessToIndex( AccessMode::Read );
361  result &= ( m_dataDepKeys[index].find( handle.fullKey() ) == m_dataDepKeys[index].end() );
362  }
363  if ( handle.mode() & Gaudi::v1::DataHandle::Writer ) {
364  auto index = accessToIndex( AccessMode::Write );
365  result &= ( m_dataDepKeys[index].find( handle.fullKey() ) == m_dataDepKeys[index].end() );
366  }
367  return result;
368  }
static size_t accessToIndex(AccessMode access)
Convert a data dependency access mode to its index in our internal storage.
virtual const DataObjID & fullKey() const
Definition: DataHandle.h:56
virtual Mode mode() const
Definition: DataHandle.h:50
DataObjIDColl m_dataDepKeys[NUM_ACCESS_MODES]
T find(T...args)
template<typename BASE>
void DataHandleHolderBase< BASE >::registerDataHandle ( Gaudi::v2::DataHandle handle)
inlinefinaloverride

Register a data handle of this algorithm/tool.

You should not need to call this method manually, as it is automatically called by the DataHandle constructor.

Definition at line 44 of file DataHandleHolderBase.h.

45  {
46  if ( m_explicitDepsCollected && isNewDataDependency( handle ) ) {
47  throw GaudiException( "Cannot register a new data handle after data dependency collection", this->name(),
49  }
50  auto index = accessToIndex( handle.access() );
51  m_dataHandles[index].push_back( &handle );
52  }
static size_t accessToIndex(AccessMode access)
Convert a data dependency access mode to its index in our internal storage.
bool isNewDataDependency(const Gaudi::v2::DataHandle &handle) const
Check if a data dependency has not been declared before (new DataHandle version)
constexpr static const auto FAILURE
Definition: StatusCode.h:88
Define general base for Gaudi exception.
bool m_explicitDepsCollected
Truth that all explicit data dependencies have already been collected in a single list...
T push_back(T...args)
DataHandleList m_dataHandles[NUM_ACCESS_MODES]
AccessMode access() const
Definition: DataHandle.h:116
template<typename BASE>
void DataHandleHolderBase< BASE >::renounce ( Gaudi::v1::DataHandle handle)
inlineoverride

Discard ownership of a legacy DataHandle.

Definition at line 97 of file DataHandleHolderBase.h.

98  {
99  // In general, deleting a DataHandle after the data dependencies have been
100  // collected is bogus, because this change will not propagate to the data
101  // dependency list, and to our clients that have queried and potentially
102  // made copies of this list, such as the Scheduler.
103  //
104  // Nevertheless, this operation is safe and should be allowed during
105  // and after Algorithm finalization.
106  //
108  dynamic_cast<IStateful*>( this )->targetFSMState() >= Gaudi::StateMachine::INITIALIZED ) {
109  throw GaudiException( "Cannot discard legacy handle after data dependency collection", this->name(),
111  }
112 
113  if ( handle.owner() != this ) {
114  throw GaudiException( "Attempt to renounce foreign handle with algorithm!", this->name(), StatusCode::FAILURE );
115  }
116 
117  m_legacyHandles.erase( &handle );
118  }
constexpr static const auto FAILURE
Definition: StatusCode.h:88
Define general base for Gaudi exception.
virtual IDataHandleHolder * owner() const
Definition: DataHandle.h:48
std::unordered_set< Gaudi::v1::DataHandle * > m_legacyHandles
bool m_explicitDepsCollected
Truth that all explicit data dependencies have already been collected in a single list...
T erase(T...args)
template<typename BASE>
void DataHandleHolderBase< BASE >::updateDataDependencies ( const DataObjIDMapping keyMap)
inlineprotected

Update the key of each registered data dependency, using a user-defined mapping from the old to the new key.

This method must be called at a framework initialization stage where the DataObjIDs associated with data dependencies are guaranteed not to change anymore. Otherwise the DataObjIDs changes brought by this update will be overwritten.

It should also be called before the explicit dependencies are collected by collectExplicitDependencies(), as otherwise the DataObjIDs modifications will be carried out in two different places, resulting in worse performance.

Definition at line 156 of file DataHandleHolderBase.h.

157  {
161  updateDependencies( m_extraDeps, keyMap );
162  }
std::unordered_set< Gaudi::v1::DataHandle * > m_legacyHandles
Gaudi::Property< DataObjIDColl > m_extraDeps[NUM_ACCESS_MODES]
static void updateDependencies(KeyHolderColl &keyHolders, const DataObjIDMapping &keyMap)
Update the DataObjID keys of a collection of key holders.
DataObjIDColl m_dataDepKeys[NUM_ACCESS_MODES]
DataHandleList m_dataHandles[NUM_ACCESS_MODES]
template<typename BASE>
template<typename KeyHolderColl >
static void DataHandleHolderBase< BASE >::updateDependencies ( KeyHolderColl &  keyHolders,
const DataObjIDMapping keyMap 
)
inlinestaticprivate

Update the DataObjID keys of a collection of key holders.

Access the key from each key holder using accessKey, pass it through a user-defined transform, and if the result is different from the original key update the key using updateKey.

Definition at line 453 of file DataHandleHolderBase.h.

454  {
455  for ( auto& holder : keyHolders ) {
456  const DataObjID& oldKey = accessKey( holder );
457  auto mappedKey = keyMap( oldKey );
458  if ( mappedKey ) {
459  updateKey( holder, *std::move( mappedKey ) );
460  }
461  }
462  }
static void updateKey(Gaudi::v2::DataHandle *target, DataObjID &&key)
Update the key of a DataHandle.
T move(T...args)
static const DataObjID & accessKey(const Gaudi::v2::DataHandle *handlePtr)
Access the key of a DataHandle.
template<typename BASE>
static void DataHandleHolderBase< BASE >::updateDependencies ( DataObjIDColl keys,
const DataObjIDMapping keyMap 
)
inlinestaticprivate

Specialization of the above algorithm for DataObjIDColls, where updating the keys in place is not possible.

Definition at line 466 of file DataHandleHolderBase.h.

467  {
468  DataObjIDColl result;
469  result.reserve( keys.size() );
470  for ( const auto& key : keys ) {
471  result.emplace( keyMap( key ).value_or( key ) );
472  }
473  keys = std::move( result );
474  }
T move(T...args)
T size(T...args)
T emplace(T...args)
T reserve(T...args)
template<typename BASE>
static void DataHandleHolderBase< BASE >::updateDependencies ( Gaudi::Property< DataObjIDColl > &  keys,
const DataObjIDMapping keyMap 
)
inlinestaticprivate

Specialization for properties which accesses the inner collection.

Definition at line 477 of file DataHandleHolderBase.h.

478  {
479  updateDependencies( keys.value(), keyMap );
480  }
static void updateDependencies(KeyHolderColl &keyHolders, const DataObjIDMapping &keyMap)
Update the DataObjID keys of a collection of key holders.
const ValueType & value() const
Backward compatibility (.
Definition: Property.h:587
template<typename BASE>
template<typename KeyHolderColl >
static void DataHandleHolderBase< BASE >::updateDependencies ( KeyHolderColl  keyHoldersArray[],
const DataObjIDMapping keyMap 
)
inlinestaticprivate

Specialization of the above algorithm for arrays of KeyHolderColls.

Definition at line 484 of file DataHandleHolderBase.h.

485  {
486  for ( size_t i = 0; i < NUM_ACCESS_MODES; ++i ) {
487  updateDependencies( keyHoldersArray[i], keyMap );
488  }
489  }
static constexpr size_t NUM_ACCESS_MODES
static void updateDependencies(KeyHolderColl &keyHolders, const DataObjIDMapping &keyMap)
Update the DataObjID keys of a collection of key holders.
template<typename BASE>
static void DataHandleHolderBase< BASE >::updateKey ( Gaudi::v2::DataHandle target,
DataObjID &&  key 
)
inlinestaticprivate

Update the key of a DataHandle.

Definition at line 438 of file DataHandleHolderBase.h.

438 { target->setTargetKey( std::move( key ) ); }
void setTargetKey(const DataObjID &id)
Change the ID of the target data.
Definition: DataHandle.h:136
T move(T...args)
template<typename BASE>
static void DataHandleHolderBase< BASE >::updateKey ( DataObjID target,
DataObjID &&  key 
)
inlinestaticprivate

Update the key of a DataObjID.

Definition at line 441 of file DataHandleHolderBase.h.

441 { target = std::move( key ); }
T move(T...args)
template<typename BASE>
static void DataHandleHolderBase< BASE >::updateKey ( Gaudi::v1::DataHandle target,
DataObjID &&  key 
)
inlinestaticprivate

Update the key of a legacy (non-reentrant) DataHandle.

Definition at line 444 of file DataHandleHolderBase.h.

444 { target->setKey( std::move( key ) ); }
virtual void setKey(const DataObjID &key) const
Definition: DataHandle.h:52
T move(T...args)

Member Data Documentation

template<typename BASE>
DataObjIDColl DataHandleHolderBase< BASE >::m_dataDepKeys[NUM_ACCESS_MODES]
private

Definition at line 335 of file DataHandleHolderBase.h.

template<typename BASE>
DataHandleList DataHandleHolderBase< BASE >::m_dataHandles[NUM_ACCESS_MODES]
private

Definition at line 320 of file DataHandleHolderBase.h.

template<typename BASE>
bool DataHandleHolderBase< BASE >::m_explicitDepsCollected = false
private

Truth that all explicit data dependencies have already been collected in a single list.

Definition at line 339 of file DataHandleHolderBase.h.

template<typename BASE>
Gaudi::Property<DataObjIDColl> DataHandleHolderBase< BASE >::m_extraDeps[NUM_ACCESS_MODES]
private
Initial value:
{{this, "ExtraInputs", DataObjIDColl{}},
{this, "ExtraOutputs", DataObjIDColl{}}}

Definition at line 331 of file DataHandleHolderBase.h.

template<typename BASE>
DataObjIDColl DataHandleHolderBase< BASE >::m_ignoredDataDeps[NUM_ACCESS_MODES]
private

Definition at line 343 of file DataHandleHolderBase.h.

template<typename BASE>
std::unordered_set<Gaudi::v1::DataHandle*> DataHandleHolderBase< BASE >::m_legacyHandles
private

Definition at line 323 of file DataHandleHolderBase.h.

template<typename BASE>
constexpr size_t DataHandleHolderBase< BASE >::NUM_ACCESS_MODES = static_cast<size_t>( AccessMode::NUM_ACCESS_MODES )
staticprivate

Definition at line 316 of file DataHandleHolderBase.h.


The documentation for this class was generated from the following file: