Skip to content

Commit

Permalink
Fix DataHandle::get() for non-collection types and remove dead code
Browse files Browse the repository at this point in the history
  • Loading branch information
jmcarcell committed Oct 28, 2024
1 parent 9efe708 commit 8ce662b
Showing 1 changed file with 21 additions and 38 deletions.
59 changes: 21 additions & 38 deletions k4FWCore/include/k4FWCore/DataHandle.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,8 @@
#include "k4FWCore/DataWrapper.h"
#include "k4FWCore/PodioDataSvc.h"

#include "Gaudi/Algorithm.h"
#include "GaudiKernel/DataObjectHandle.h"

#include "edm4hep/Constants.h"

#include <GaudiKernel/AnyDataWrapper.h>
#include <type_traits>

Expand Down Expand Up @@ -68,8 +65,6 @@ template <typename T> class DataHandle : public DataObjectHandle<DataWrapper<T>>

private:
ServiceHandle<IDataProviderSvc> m_eds;
bool m_isGoodType{false};
bool m_isCollection{false};
T* m_dataPtr;
};

Expand Down Expand Up @@ -108,40 +103,28 @@ DataHandle<T>::DataHandle(const std::string& descriptor, Gaudi::DataHandle::Mode
* static cast: we do not need the checks of the dynamic cast for every access!
*/
template <typename T> const T* DataHandle<T>::get() {
DataObject* dataObjectp = nullptr;
auto sc = m_eds->retrieveObject(DataObjectHandle<DataWrapper<T>>::fullKey().key(), dataObjectp);

if (sc.isSuccess()) {
if (!m_isGoodType && !m_isCollection) {
// only do this once (if both are false after this, we throw exception)
m_isGoodType = nullptr != dynamic_cast<DataWrapper<T>*>(dataObjectp);
if (!m_isGoodType) {
auto* tmp = dynamic_cast<DataWrapper<podio::CollectionBase>*>(dataObjectp);
if (tmp != nullptr) {
m_isCollection = nullptr != dynamic_cast<T*>(tmp->collectionBase());
}
}
}
if (m_isGoodType) {
return static_cast<DataWrapper<T>*>(dataObjectp)->getData();
} else if (m_isCollection) {
// The reader does not know the specific type of the collection. So we need a reinterpret_cast if the handle was
// created by the reader.
auto* tmp = static_cast<DataWrapper<podio::CollectionBase>*>(dataObjectp);
return reinterpret_cast<const T*>(tmp->collectionBase());
} else {
// When a functional has pushed a std::shared_ptr<podio::CollectionBase> into the store
auto ptr = static_cast<AnyDataWrapper<std::unique_ptr<podio::CollectionBase>>*>(dataObjectp);
if (ptr) {
return static_cast<const T*>(ptr->getData().get());
}
std::string errorMsg("The type provided for " + DataObjectHandle<DataWrapper<T>>::pythonRepr() +
" is different from the one of the object in the store.");
throw GaudiException(errorMsg, "wrong product type", StatusCode::FAILURE);
}
DataObject* dataObjectp;
auto sc = m_eds->retrieveObject(DataObjectHandle<DataWrapper<T>>::fullKey().key(), dataObjectp);

if (sc.isFailure()) {
std::string msg("Could not retrieve product " + DataObjectHandle<DataWrapper<T>>::pythonRepr());
throw GaudiException(msg, "wrong product name", StatusCode::FAILURE);
}
bool isGoodType = nullptr != dynamic_cast<DataWrapper<T>*>(dataObjectp);
if (isGoodType) {
return static_cast<DataWrapper<T>*>(dataObjectp)->getData();
}

// When a functional has pushed a std::unique_ptr<podio::CollectionBase> into the store
// We wrap it inside constexpr because if the handle has a type that is not a collection
// then the static_cast will fail at compile time
if constexpr (std::is_base_of_v<podio::CollectionBase, T>) {
auto ptr = static_cast<AnyDataWrapper<std::unique_ptr<podio::CollectionBase>>*>(dataObjectp);
return static_cast<const T*>(ptr->getData().get());
}
std::string msg("Could not retrieve product " + DataObjectHandle<DataWrapper<T>>::pythonRepr());
throw GaudiException(msg, "wrong product name", StatusCode::FAILURE);
std::string errorMsg("The type provided for " + DataObjectHandle<DataWrapper<T>>::pythonRepr() +
" is different from the one of the object in the store.");
throw GaudiException(errorMsg, "wrong product type", StatusCode::FAILURE);
}

//---------------------------------------------------------------------------
Expand Down

0 comments on commit 8ce662b

Please sign in to comment.