diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/AthenaPoolCnvTPExtension.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/AthenaPoolCnvTPExtension.h old mode 100755 new mode 100644 diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/AthenaPoolConverter.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/AthenaPoolConverter.h old mode 100755 new mode 100644 index dc964f0f52e1a24af30aea4e7e6ab1df0916b556..07c813b577f7a5bc260713df568bc46e1e49a888 --- a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/AthenaPoolConverter.h +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/AthenaPoolConverter.h @@ -20,14 +20,12 @@ #include <string> #include <map> -namespace pool { - class Placement; -} class IOpaqueAddress; class DataObject; class StatusCode; class IAthenaPoolCnvSvc; class Guid; +class Placement; class Token; /// Abstract factory to create the converter @@ -80,7 +78,8 @@ protected: /// Read an object from POOL. /// @param pObj [OUT] pointer to the transient object. /// @param token [IN] POOL token of the persistent representation. - virtual StatusCode PoolToDataObject(DataObject*& pObj, const std::string& token) = 0; + //virtual StatusCode PoolToDataObject(DataObject*& pObj, const std::string& token) = 0; + virtual StatusCode PoolToDataObject(DataObject*& pObj, const Token* token) = 0; /// Set POOL placement hint for a given type. /// @param tname [IN] type name. @@ -90,32 +89,27 @@ protected: virtual void setPlacement(const std::string& key = "") = 0; /// @return data object from the converter. - virtual DataObject* getDataObject() const; - /// Set data object of the converter. - /// @param pObj [IN] data object pointer to be used by converter. - virtual void setDataObject(DataObject* pObj); + virtual const DataObject* getDataObject() const; bool compareClassGuid(const Guid &guid) const; protected: // data ServiceHandle<IAthenaPoolCnvSvc> m_athenaPoolCnvSvc; - pool::Placement* m_placement; - RootType m_classDesc; - bool m_dictionaryOkRead; - bool m_dictionaryOkWrite; + Placement* m_placement; + RootType m_classDesc; typedef std::map<std::string, std::string> StringMap; typedef StringMap::const_iterator StringMapIt; - StringMap m_placementHints; + StringMap m_placementHints; typedef std::map<std::string, RootType> ClassMap; typedef ClassMap::const_iterator ClassMapIt; - std::string m_className; - ClassMap m_classDescs; + std::string m_className; + ClassMap m_classDescs; - mutable std::string m_token; - DataObject* m_dataObject; - mutable const Token* m_poolToken; + DataObject* m_dataObject; + const Token* m_i_poolToken; + const Token* m_o_poolToken; }; #endif diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/AthenaPoolTopLevelTPCnvBase.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/AthenaPoolTopLevelTPCnvBase.h old mode 100755 new mode 100644 diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/AthenaPoolTopLevelTPConverter.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/AthenaPoolTopLevelTPConverter.h old mode 100755 new mode 100644 diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/IAthenaPoolCleanUp.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/IAthenaPoolCleanUp.h old mode 100755 new mode 100644 diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/IAthenaPoolCleanUpSvc.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/IAthenaPoolCleanUpSvc.h old mode 100755 new mode 100644 diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/IAthenaPoolCnvSvc.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/IAthenaPoolCnvSvc.h old mode 100755 new mode 100644 index 1cb0174297b41e883dee9198145f94d447563091..849819fc75eedf3e79395288284afc15c868c92a --- a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/IAthenaPoolCnvSvc.h +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/IAthenaPoolCnvSvc.h @@ -12,6 +12,7 @@ #include "AthenaPoolCnvSvc/IAthenaPoolCleanUpSvc.h" #include "GaudiKernel/IConversionSvc.h" +#include "AthenaKernel/IDataShare.h" #include "DataModelRoot/RootType.h" #include <string> @@ -19,11 +20,10 @@ // Forward declarations class IOpaqueAddress; class IPoolSvc; +class Placement; class Token; - namespace pool { - class Placement; class DbType; } @@ -33,7 +33,7 @@ static const InterfaceID IID_IAthenaPoolCnvSvc ("IAthenaPoolCnvSvc", 1 , 0); /** @class IAthenaPoolCnvSvc * @brief This class provides the interface between Athena and PoolSvc. **/ -class IAthenaPoolCnvSvc : virtual public IConversionSvc, public IAthenaPoolCleanUpSvc { +class IAthenaPoolCnvSvc : virtual public IConversionSvc, public IDataShare, public IAthenaPoolCleanUpSvc { public: /// Retrieve interface ID static const InterfaceID& interfaceID() { return(IID_IAthenaPoolCnvSvc); } @@ -60,7 +60,7 @@ public: /// @param placement [IN] pointer to the placement hint /// @param obj [IN] pointer to the Data Object to be written to Pool /// @param classDesc [IN] pointer to the Seal class description for the Data Object. - virtual const Token* registerForWrite(const pool::Placement* placement, + virtual const Token* registerForWrite(const Placement* placement, const void* obj, const RootType& classDesc) const = 0; @@ -68,10 +68,6 @@ public: /// @param token [IN] string token of the Data Object for which a Pool Ref is filled. virtual void setObjPtr(void*& obj, const Token* token) const = 0; - /// Utility to test whether the dictionary knows about a given class. - /// @param className [IN] string containing the name of the class to be checked. - virtual bool testDictionary(const std::string& className) const = 0; - /// @return a boolean for using detailed time and size statistics. virtual bool useDetailChronoStat() const = 0; @@ -102,6 +98,12 @@ public: /// @param refAddress [OUT] converted string form. virtual StatusCode convertAddress(const IOpaqueAddress* pAddress, std::string& refAddress) = 0; + /// Make this a server. + virtual StatusCode makeServer(int num) = 0; + + /// Make this a client. + virtual StatusCode makeClient(int num) = 0; + /// Implement registerCleanUp to register a IAthenaPoolCleanUp to be called during cleanUp. virtual StatusCode registerCleanUp(IAthenaPoolCleanUp* cnv) = 0; diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/ITPConverter.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/ITPConverter.h old mode 100755 new mode 100644 diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvElt.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvElt.h new file mode 100644 index 0000000000000000000000000000000000000000..7b82a2483cb30ae974a8eb8d8017c15a1e4427df --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvElt.h @@ -0,0 +1,167 @@ +// This file's extension implies that it's C, but it's really -*- C++ -*-. + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id$ +/** + * @file AthenaPoolCnvSvc/TPCnvElt.h + * @author scott snyder <snyder@bnl.gov> + * @date Jan, 2016 + * @brief Helper for calling a TP converter from an Athena converter. + */ + + +#ifndef ATHENAPOOLCNVSVC_TPCNVELT_H +#define ATHENAPOOLCNVSVC_TPCNVELT_H + + +#include "PersistentDataModel/Guid.h" +#include <typeinfo> +#include <memory> +class MsgStream; + + +/** + * @brief Placeholder for the case where no conversion is to be done. + */ +template <class TRANS> class T_TPCnvNull +{ +}; + + +namespace AthenaPoolCnvSvc { + + +/** + * @brief Given a @c type_info, get the corresponding pool guid. + * @param ti @c type_info to look for. + * + * Throws an exception on errors. + */ +Guid guidFromTypeinfo (const std::type_info& ti); + + +/** + * @brief Helper for calling a TP converter from an Athena converter. + * + * This is used to allow calling one out of a templated list of TP converters. + * The methods here test if the current guid matches the guid for this + * converter, and calls it if so. + * + * CNV is the top-level pool converter (that reads the persistent object). + * TPCNV is the TP converter class to be called. For the case where no + * conversion is to be done, use T_TPCnvNull<TRANS> for the TP converter + * class. + */ +template <class CNV, class TPCNV> +class TPCnvElt +{ +public: + /// Make available the persistent and transient types. + typedef typename TPCNV::Trans_t Trans_t; + typedef typename TPCNV::Pers_t Pers_t; + + + /** + * @brief Constructor. + */ + TPCnvElt(); + + + /** + * @brief Read the persistent object and convert it to transient. + * @param parent The top-level pool converter object. + * @param msg MsgStream for error reporting. + * + * Returns a newly-allocated object. + * If the type of the persistent object on the file does not match the + * type that this converter handles, return nullptr. + * Other errors are reported by raising exceptions. + */ + Trans_t* createTransient (CNV& parent, MsgStream& msg); + + + /** + * @brief Read the persistent object and convert it to transient. + * @param parent The top-level pool converter object. + * @param trans The transient object to modify. + * @param msg MsgStream for error reporting. + * + * Overwrites the provided transient object. + * If the type of the persistent object on the file does not match the + * type that this converter handles, returns false. + * Other errors are reported by raising exceptions. + */ + bool persToTrans (CNV& parent, Trans_t* trans, MsgStream& msg); + + +private: + /// GUID for the persistent class we read. + Guid m_guid; + + /// The underlying TP converter. + TPCNV m_cnv; +}; + + +/** + * @brief Helper for calling a TP converter from an Athena converter. + * Specialization for the case of no conversion. + */ +template <class CNV, class TRANS> +class TPCnvElt<CNV, T_TPCnvNull<TRANS> > +{ +public: + /// Make available the persistent and transient types. + typedef TRANS Trans_t; + typedef TRANS Pers_t; + + + /** + * @brief Constructor. + */ + TPCnvElt(); + + + /** + * @brief Read the persistent object and convert it to transient. + * @param parent The top-level pool converter object. + * @param msg MsgStream for error reporting. + * + * Returns a newly-allocated object. + * If the type of the persistent object on the file does not match the + * type that this converter handles, return nullptr. + * Other errors are reported by raising exceptions. + */ + Trans_t* createTransient (CNV& parent, MsgStream& msg); + + + /** + * @brief Read the persistent object and convert it to transient. + * @param parent The top-level pool converter object. + * @param trans The transient object to modify. + * @param msg MsgStream for error reporting. + * + * Overwrites the provided transient object. + * If the type of the persistent object on the file does not match the + * type that this converter handles, returns false. + * Other errors are reported by raising exceptions. + */ + bool persToTrans (CNV& parent, Trans_t* trans, MsgStream& msg); + + +private: + /// GUID for the persistent class we read. + Guid m_guid; +}; + + +} // namespace AthenaPoolCnvSvc + + +#include "AthenaPoolCnvSvc/TPCnvElt.icc" + + +#endif // not ATHENAPOOLCNVSVC_TPCNVELT_H diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvElt.icc b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvElt.icc new file mode 100644 index 0000000000000000000000000000000000000000..46ec8f189b2bb9d2d360e2abd40e68c5881b3318 --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvElt.icc @@ -0,0 +1,142 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id$ +/** + * @file AthenaPoolCnvSvc/TPCnvElt.icc + * @author scott snyder <snyder@bnl.gov> + * @date Jan, 2016 + * @brief Helper for calling a TP converter from an Athena converter. + */ + + +namespace AthenaPoolCnvSvc { + + +/** + * @brief Constructor. + */ +template <class CNV, class TPCNV> +TPCnvElt<CNV, TPCNV>::TPCnvElt() + // Remember the guid for our persistent type. + : m_guid (guidFromTypeinfo (typeid (Pers_t))) +{ +} + + +/** + * @brief Read the persistent object and convert it to transient. + * @param parent The top-level pool converter object. + * @param msg MsgStream for error reporting. + * + * Returns a newly-allocated object. + * If the type of the persistent object on the file does not match the + * type that this converter handles, return nullptr. + * Other errors are reported by raising exceptions. + */ +template <class CNV, class TPCNV> +typename TPCnvElt<CNV, TPCNV>::Trans_t* +TPCnvElt<CNV, TPCNV>::createTransient (CNV& parent, MsgStream& msg) +{ + if (!parent.compareClassGuid (m_guid)) + return nullptr; + + std::unique_ptr<Pers_t> old (parent.template poolReadObject<Pers_t>() ); + return m_cnv.createTransient(old.get(), msg); +} + + +/** + * @brief Read the persistent object and convert it to transient. + * @param parent The top-level pool converter object. + * @param trans The transient object to modify. + * @param msg MsgStream for error reporting. + * + * Overwrites the provided transient object. + * If the type of the persistent object on the file does not match the + * type that this converter handles, returns false. + * Other errors are reported by raising exceptions. + */ +template <class CNV, class TPCNV> +bool +TPCnvElt<CNV, TPCNV>::persToTrans (CNV& parent, Trans_t* trans, MsgStream& msg) +{ + if (!parent.compareClassGuid (m_guid)) + return false; + + std::unique_ptr<Pers_t> old ( parent.template poolReadObject<Pers_t>() ); + m_cnv.persToTrans (old.get(), trans, msg); + return true; +} + + +//************************************************************************* + + +/** + * @brief Constructor. + * + * Specialization for the case of no conversion. + */ +template <class CNV, class TRANS> +TPCnvElt<CNV, T_TPCnvNull<TRANS> >::TPCnvElt() + // Remember the guid for our persistent type. + : m_guid (guidFromTypeinfo (typeid (Pers_t))) +{ +} + + +/** + * @brief Read the persistent object and convert it to transient. + * @param parent The top-level pool converter object. + * @param msg MsgStream for error reporting. + * + * Specialization for the case of no conversion. + * + * Returns a newly-allocated object. + * If the type of the persistent object on the file does not match the + * type that this converter handles, return nullptr. + * Other errors are reported by raising exceptions. + */ +template <class CNV, class TRANS> +typename TPCnvElt<CNV, T_TPCnvNull<TRANS> >::Trans_t* +TPCnvElt<CNV, T_TPCnvNull<TRANS> >::createTransient (CNV& parent, + MsgStream& /*msg*/) +{ + if (!parent.compareClassGuid (m_guid)) + return nullptr; + + return parent.template poolReadObject<Pers_t>(); +} + + +/** + * @brief Read the persistent object and convert it to transient. + * @param parent The top-level pool converter object. + * @param trans The transient object to modify. + * @param msg MsgStream for error reporting. + * + * Specialization for the case of no conversion. + * + * Overwrites the provided transient object. + * If the type of the persistent object on the file does not match the + * type that this converter handles, returns false. + * Other errors are reported by raising exceptions. + */ +template <class CNV, class TRANS> +bool +TPCnvElt<CNV, T_TPCnvNull<TRANS> >::persToTrans (CNV& parent, + Trans_t* trans, + MsgStream& /*msg*/) +{ + if (!parent.compareClassGuid (m_guid)) + return false; + + std::unique_ptr<Pers_t> old ( parent.template poolReadObject<Pers_t>() ); + *trans = *old; + return true; +} + + +} // namespace AthenaPoolCnvSvc diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvList.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvList.h new file mode 100644 index 0000000000000000000000000000000000000000..92b0f0fa7b6e202beb7295cffc444c9453810e3a --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvList.h @@ -0,0 +1,127 @@ +// This file's extension implies that it's C, but it's really -*- C++ -*-. + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id$ +/** + * @file AthenaPoolCnvSvc/TPCnvList.h + * @author scott snyder <snyder@bnl.gov> + * @date Jan, 2016 + * @brief Helper for calling TP converters from an Athena converter. + */ + + +#ifndef ATHENAPOOLCNVSVC_TPCNVLIST_H +#define ATHENAPOOLCNVSVC_TPCNVLIST_H + + +#include "AthenaPoolCnvSvc/TPCnvElt.h" +#include "boost/mpl/vector.hpp" +#include "boost/mpl/transform.hpp" +#include <boost/fusion/mpl.hpp> +#include "boost/fusion/container/vector.hpp" +#include "boost/fusion/container/vector/convert.hpp" +#include "boost/fusion/algorithm/iteration/accumulate.hpp" + + +namespace AthenaPoolCnvSvc { + + +/** + * @brief Helper for calling TP converters from an Athena converter. + */ +template <class CNV, class TRANS, class ... TPCNVS> +class TPCnvList +{ + /// Metafunction to wrap a TP converter in @c TPCnvElt. + template <class TPCNV> + struct wrap_tpcnv + { + typedef TPCnvElt<CNV, TPCNV> type; + }; + + + /// Functional to iterate over TP converters and call @c createTransient + /// on each. Stop once one succeeds. + struct do_create_transient + { + do_create_transient (CNV& parent, MsgStream& msg); + + template <class ELT> + typename ELT::Trans_t* operator() (typename ELT::Trans_t* p, ELT& elt); + + CNV& m_parent; + MsgStream& m_msg; + }; + + + /// Functional to iterate over TP converters and call @c persToTrans + /// on each. Stop once one succeeds. + struct do_pers_to_trans + { + do_pers_to_trans (CNV& parent, TRANS* trans, MsgStream& msg); + + template <class ELT> + bool operator() (bool found, ELT& elt); + + CNV& m_parent; + TRANS* m_trans; + MsgStream& m_msg; + }; + + +public: + // Convert the list of TP converters <T1, T2, ...> to a boost fusion vector + // of converters wrapped by TPCnvElt: + // boost::fusion::vector<TPCnvElt<T1>, TPCnvElt<T2>, ...> + // We can create in instance of this vector to get an object that holds + // all the TP converter instances. + typedef boost::mpl::vector<TPCNVS...> vec_t; + typedef typename boost::mpl::transform<vec_t, wrap_tpcnv<boost::mpl::_1> >::type list_mpl_t; + typedef typename boost::fusion::result_of::as_vector<list_mpl_t>::type list_t; + + + /** + * @brief Read the persistent object and convert it to transient. + * @param parent The top-level pool converter object. + * @param msg MsgStream for error reporting. + * + * Returns a newly-allocated object. + * If the type of the persistent object on the file does not match the + * the type of any of our TP converters, return nullptr. + * Other errors are reported by raising exceptions. + */ + TRANS* createTransient (CNV& parent, MsgStream& msg); + + + /** + * @brief Read the persistent object and convert it to transient. + * @param parent The top-level pool converter object. + * @param trans The transient object to modify. + * @param msg MsgStream for error reporting. + * + * Overwrites the provided transient object. + * If the type of the persistent object on the file does not match the + * the type of any of our TP converters, return false. + * Other errors are reported by raising exceptions. + */ + bool persToTrans (CNV& parent, TRANS* trans, MsgStream& msg); + + +private: + /// List of TP converter instances, wrapped by @c TPCnvElt. + list_t m_list; +}; + + +} // namespace AthenaPoolCnvSvc + + +#include "AthenaPoolCnvSvc/TPCnvList.icc" + + +#endif // not ATHENAPOOLCNVSVC_TPCNVLIST_H + + diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvList.icc b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvList.icc new file mode 100644 index 0000000000000000000000000000000000000000..129f8d67a5206cf1f12adbd3464bf3efabd2c911 --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvList.icc @@ -0,0 +1,136 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id$ +/** + * @file AthenaPoolCnvSvc/TPCnvList.h + * @author scott snyder <snyder@bnl.gov> + * @date Jan, 2016 + * @brief Helper for calling TP converters from an Athena converter. + */ + + +namespace AthenaPoolCnvSvc { + + +/** + * @brief Constructor. + * @param parent The parent Athena pool converter. + * @param msg MsgStream for error reporting. + */ +template <class CNV, class TRANS, class ... TPCNVS> +inline +TPCnvList<CNV, TRANS, TPCNVS...>::do_create_transient::do_create_transient (CNV& parent, MsgStream& msg) + : m_parent (parent), + m_msg (msg) +{ +} + + +/** + * @brief Worker for loop over TP converters calling @c createTransient. + * @param p Result of the iteration (pointer to transient object). + * @param elt The TPCnvElt instance to call. + * + * This function gets called once for each TP converter instance. + * It gets as arguments the wrapped TP converter and the result @c p + * from the previous TP converter call. If a previous TP converter + * has succeeded, then @c p will be non-null, so we just return it + * without calling anything. Otherwise, we call the TP converter + * and return the result. + */ +template <class CNV, class TRANS, class ... TPCNVS> +template <class ELT> +inline +typename ELT::Trans_t* +TPCnvList<CNV, TRANS, TPCNVS...>::do_create_transient::operator() + (typename ELT::Trans_t* p, ELT& elt) +{ + if (p) return p; + return elt.createTransient (m_parent, m_msg); +} + + +/** + * @brief Constructor. + * @param parent The parent Athena pool converter. + * @param msg MsgStream for error reporting. + */ +template <class CNV, class TRANS, class ... TPCNVS> +inline +TPCnvList<CNV, TRANS, TPCNVS...>::do_pers_to_trans::do_pers_to_trans + (CNV& parent, TRANS* trans, MsgStream& msg) + : m_parent (parent), + m_trans (trans), + m_msg (msg) +{ +} + + +/** + * @brief Worker for loop over TP converters calling @c persToTrans. + * @param found Result of the iteration (has a converter succeeded?). + * @param elt The TPCnvElt instance to call. + * + * This function gets called once for each TP converter instance. + * It gets as arguments the wrapped TP converter and a flag @c found + * telling whether any TP converer has succeeded so far. If one has, + * then we just return the flag again without calling anything. + * Otherwise, we call the TP converter and return the result. + */ +template <class CNV, class TRANS, class ... TPCNVS> +template <class ELT> +inline +bool TPCnvList<CNV, TRANS, TPCNVS...>::do_pers_to_trans::operator() + (bool found, ELT& elt) +{ + if (found) return true; + return elt.persToTrans (m_parent, m_trans, m_msg); +} + + +/** + * @brief Read the persistent object and convert it to transient. + * @param parent The top-level pool converter object. + * @param msg MsgStream for error reporting. + * + * Returns a newly-allocated object. + * If the type of the persistent object on the file does not match the + * the type of any of our TP converters, return nullptr. + * Other errors are reported by raising exceptions. + */ +template <class CNV, class TRANS, class ... TPCNVS> +TRANS* TPCnvList<CNV, TRANS, TPCNVS...>::createTransient (CNV& parent, + MsgStream& msg) +{ + // Try createTransient on each TPCnv; stop when one succeeds. + TRANS* p = nullptr; + return boost::fusion::accumulate + (m_list, p, do_create_transient(parent, msg)); +} + + +/** + * @brief Read the persistent object and convert it to transient. + * @param parent The top-level pool converter object. + * @param trans The transient object to modify. + * @param msg MsgStream for error reporting. + * + * Overwrites the provided transient object. + * If the type of the persistent object on the file does not match the + * the type of any of our TP converters, return false. + * Other errors are reported by raising exceptions. + */ +template <class CNV, class TRANS, class ... TPCNVS> +bool TPCnvList<CNV, TRANS, TPCNVS...>::persToTrans (CNV& parent, + TRANS* trans, + MsgStream& msg) +{ + // Try persToTrans on each TPCnv; stop when one succeeds. + return boost::fusion::accumulate + (m_list, false, do_pers_to_trans(parent, trans, msg)); +} + + +} // namespace AthenaPoolCnvSvc diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolAuxContainerCnv.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolAuxContainerCnv.h new file mode 100644 index 0000000000000000000000000000000000000000..cb34231053cb1601c3249fd49e93d5334ba51cfa --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolAuxContainerCnv.h @@ -0,0 +1,88 @@ +// This file's extension implies that it's C, but it's really -*- C++ -*-. + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id$ +/** + * @file AthenaPoolCnvSvc/T_AthenaPoolAuxContainerCnv.h + * @author scott snyder <snyder@bnl.gov> + * @date Jan, 2016 + * @brief Athena pool converter for aux store classes. + */ + + +#ifndef ATHENAPOOLCNVSVC_T_ATHENAPOOLAUXCONTAINERCNV_H +#define ATHENAPOOLCNVSVC_T_ATHENAPOOLAUXCONTAINERCNV_H + + +#include "AthenaPoolCnvSvc/T_AthenaPoolCustomCnv.h" +#include "AthenaPoolCnvSvc/TPCnvList.h" +#include "AthenaPoolCnvSvc/exceptions.h" +#include "AthContainers/tools/copyThinned.h" +#include "AthenaKernel/IThinningSvc.h" + + +/** + * @brief Athena pool converter for aux store classes. + * + * AUXSTORE is the class being read/written. + * TPCNVS is a list of TP converters to handle older versions of the class. + * + * On writing, the container is copied (and thinned if required). + * For reading, we read the object either directly + * or using one of the TP converters, depending on the saved GUID. + */ +template <class AUXSTORE, class ... TPCNVS> +class T_AthenaPoolAuxContainerCnv + : public T_AthenaPoolCustomCnv<AUXSTORE, AUXSTORE> +{ + friend class CnvFactory< T_AthenaPoolAuxContainerCnv >; + + template <class CNV, class TPCNV> + friend class AthenaPoolCnvSvc::TPCnvElt; + +public: + typedef T_AthenaPoolCustomCnv<AUXSTORE, AUXSTORE> Base; + + + /** + * @brief Constructor. + * @param svcLoc Gaudi service locator. + */ + T_AthenaPoolAuxContainerCnv ( ISvcLocator* svcLoc ); + + + /** + * @brief Convert a transient object to persistent form. + * @param trans The transient object to convert. + * + * Returns a newly-allocated persistent object. + */ + virtual AUXSTORE* createPersistent( AUXSTORE* trans ) override; + + + /** + * @brief Read the persistent object and convert it to transient. + * + * Returns a newly-allocated transient object. + * Errors are reported by raising exceptions. + */ + virtual AUXSTORE* createTransient() override; + + +private: + /// GUID of the object being read. + Guid m_guid; + + /// List of TP converters. + AthenaPoolCnvSvc::TPCnvList<T_AthenaPoolAuxContainerCnv, AUXSTORE, TPCNVS...> m_tpcnvs; +}; + + +#include "AthenaPoolCnvSvc/T_AthenaPoolAuxContainerCnv.icc" + + +#endif // not ATHENAPOOLCNVSVC_T_ATHENAPOOLAUXCONTAINERCNV_H + diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolAuxContainerCnv.icc b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolAuxContainerCnv.icc new file mode 100644 index 0000000000000000000000000000000000000000..2c4993d79297a40d4a96f1d74ef9af97fed4e74d --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolAuxContainerCnv.icc @@ -0,0 +1,64 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id$ +/** + * @file AthenaPoolCnvSvc/T_AthenaPoolAuxContainerCnv.icc + * @author scott snyder <snyder@bnl.gov> + * @date Jan, 2016 + * @brief Athena pool converter for aux store classes. + */ + + +/** + * @brief Constructor. + * @param svcLoc Gaudi service locator. + */ +template <class AUXSTORE, class ... TPCNVS> +T_AthenaPoolAuxContainerCnv<AUXSTORE, TPCNVS...>::T_AthenaPoolAuxContainerCnv( ISvcLocator* svcLoc ) + : Base( svcLoc ) +{ + m_guid = AthenaPoolCnvSvc::guidFromTypeinfo (typeid (AUXSTORE)); +} + + +/** + * @brief Convert a transient object to persistent form. + * @param trans The transient object to convert. + * + * Returns a newly-allocated persistent object. + */ +template <class AUXSTORE, class ... TPCNVS> +AUXSTORE* T_AthenaPoolAuxContainerCnv<AUXSTORE, TPCNVS...>::createPersistent( AUXSTORE* trans ) +{ + return SG::copyThinned (*trans, IThinningSvc::instance()); +} + + +/** + * @brief Read the persistent object and convert it to transient. + * + * Returns a newly-allocated transient object. + * Errors are reported by raising exceptions. + */ +template <class AUXSTORE, class ... TPCNVS> +AUXSTORE* T_AthenaPoolAuxContainerCnv<AUXSTORE, TPCNVS...>::createTransient() +{ + if ( this->compareClassGuid( m_guid ) ) { + // It's the latest version, read it directly: + return this->template poolReadObject< AUXSTORE >(); + } + + // Try a converter. + AUXSTORE* c = m_tpcnvs.createTransient (*this, this->msg()); + if (c) + return c; + + // Didn't recognize the GUID. + AthenaPoolCnvSvc::throwExcUnsupportedVersion (typeid(AUXSTORE), + this->m_i_poolToken->classID()); + return 0; +} + + diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCnv.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCnv.h old mode 100755 new mode 100644 index 4d0b0abba1c0e9c0f69a5b78b4df0ebcea9b4ef7..ab49ff44310a72bfd7f72e90ff2d480f43e51744 --- a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCnv.h +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCnv.h @@ -10,12 +10,9 @@ * @author Peter van Gemmeren <gemmeren@anl.gov> **/ -#include "AthenaPoolCnvSvc/AthenaPoolConverter.h" - -#include <string> - -class DataObject; -class StatusCode; +#include "AthenaPoolCnvSvc/T_AthenaPoolCnvBase.h" +#include "AthenaPoolCnvSvc/T_AthenaPoolViewVectorCnv.h" +#include "AthContainers/ViewVector.h" /// Abstract factory to create the converter template <class TYPE> class CnvFactory; @@ -24,33 +21,22 @@ template <class TYPE> class CnvFactory; * @brief This templated class provides the converter to translate an object to/from its persistent POOL representation. **/ template <class T> -class T_AthenaPoolCnv : public AthenaPoolConverter { +class T_AthenaPoolCnv : public T_AthenaPoolCnvBase<T> { friend class CnvFactory<T_AthenaPoolCnv<T> >; protected: - /// Constructor - T_AthenaPoolCnv(ISvcLocator* svcloc); - - /// Gaudi Service Interface method implementations: - virtual StatusCode initialize(); - - /// Write an object into POOL. - /// @param pObj [IN] pointer to the transient object. - /// @param key [IN] StoreGate key (string) - placement hint to generate POOL container name - virtual StatusCode DataObjectToPool(DataObject* pObj, const std::string& key); + using T_AthenaPoolCnvBase<T>::T_AthenaPoolCnvBase; +}; - /// Read an object from POOL. - /// @param pObj [OUT] pointer to the transient object. - /// @param token [IN] POOL token of the persistent representation. - virtual StatusCode PoolToDataObject(DataObject*& pObj, const std::string& token); - /// Set POOL placement. - virtual void setPlacement(const std::string& key = ""); +template <class DV> +class T_AthenaPoolCnv<ViewVector<DV> > : public T_AthenaPoolViewVectorCnv<DV> +{ + friend class CnvFactory<T_AthenaPoolCnv<ViewVector<DV> > >; -public: - /// @return class ID. - static const CLID& classID(); +protected: + using T_AthenaPoolViewVectorCnv<DV>::T_AthenaPoolViewVectorCnv; }; -#include "AthenaPoolCnvSvc/T_AthenaPoolCnv.icc" + #endif diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCnvBase.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCnvBase.h new file mode 100644 index 0000000000000000000000000000000000000000..9db01715f530f59d59ad953407e40911bf86d3ff --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCnvBase.h @@ -0,0 +1,54 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef ATHENAPOOLCNVSVC_T_ATHENAPOOLCNVBASE_H +#define ATHENAPOOLCNVSVC_T_ATHENAPOOLCNVBASE_H + +/** @file T_AthenaPoolCnvBase.h + * @brief his file contains the class definition for the templated T_AthenaPoolCnvBase class. + * @author Peter van Gemmeren <gemmeren@anl.gov> + **/ + +#include "AthenaPoolCnvSvc/AthenaPoolConverter.h" + +#include <string> + +class DataObject; +class StatusCode; + +/** @class T_AthenaPoolCnvBase + * @brief This templated class provides the converter to translate an object to/from its persistent POOL representation. + **/ +template <class T> +class T_AthenaPoolCnvBase : public AthenaPoolConverter { + +protected: + /// Constructor + T_AthenaPoolCnvBase(ISvcLocator* svcloc); + + /// Gaudi Service Interface method implementations: + virtual StatusCode initialize(); + + /// Write an object into POOL. + /// @param pObj [IN] pointer to the transient object. + /// @param key [IN] StoreGate key (string) - placement hint to generate POOL container name + virtual StatusCode DataObjectToPool(DataObject* pObj, const std::string& key); + + /// Read an object from POOL. + /// @param pObj [OUT] pointer to the transient object. + /// @param token [IN] POOL token of the persistent representation. + virtual StatusCode PoolToDataObject(DataObject*& pObj, const Token* token); + + /// Set POOL placement. + virtual void setPlacement(const std::string& key = ""); + +public: + /// @return class ID. + static const CLID& classID(); +}; + + +#include "AthenaPoolCnvSvc/T_AthenaPoolCnvBase.icc" + +#endif diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCnv.icc b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCnvBase.icc old mode 100755 new mode 100644 similarity index 53% rename from Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCnv.icc rename to Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCnvBase.icc index c720e02b244edceaa11875bf20ab02aaf5c9f35a..4ab4fba104b7f308e09a3d60d460fbc916def97c --- a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCnv.icc +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCnvBase.icc @@ -2,8 +2,8 @@ Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration */ -/** @file T_AthenaPoolCnv.icc - * @brief This file contains the implementation for the templated T_AthenaPoolCnv class. +/** @file T_AthenaPoolCnvBase.icc + * @brief This file contains the implementation for the templated T_AthenaPoolCnvBase class. * @author Peter van Gemmeren <gemmeren@anl.gov> **/ @@ -18,17 +18,17 @@ #include "DataModelRoot/RootType.h" #include "CLIDSvc/CLASS_DEF.h" -#include "DataModel/ClassName.h" +#include "SGTools/ClassName.h" #include "SGTools/StorableConversions.h" //__________________________________________________________________________ template <class T> -T_AthenaPoolCnv<T>::T_AthenaPoolCnv(ISvcLocator* svcloc) : AthenaPoolConverter(classID(), svcloc) { +T_AthenaPoolCnvBase<T>::T_AthenaPoolCnvBase(ISvcLocator* svcloc) : AthenaPoolConverter(classID(), svcloc) { } //______________________________________________________________________________ template <class T> -StatusCode T_AthenaPoolCnv<T>::initialize() { - ATH_MSG_DEBUG("initialize() in T_AthenaPoolCnv " << classID()); +StatusCode T_AthenaPoolCnvBase<T>::initialize() { + ATH_MSG_DEBUG("initialize() in T_AthenaPoolCnvBase " << classID()); if (!AthenaPoolConverter::initialize().isSuccess()) { ATH_MSG_FATAL("Failed to initialize AthenaPoolConverter base class."); return(StatusCode::FAILURE); @@ -37,73 +37,53 @@ StatusCode T_AthenaPoolCnv<T>::initialize() { } //__________________________________________________________________________ template <class T> -const CLID& T_AthenaPoolCnv<T>::classID() { +const CLID& T_AthenaPoolCnvBase<T>::classID() { return(ClassID_traits<T>::ID()); } //__________________________________________________________________________ template <class T> -StatusCode T_AthenaPoolCnv<T>::DataObjectToPool(DataObject* /*pObj*/, const std::string& key) { +StatusCode T_AthenaPoolCnvBase<T>::DataObjectToPool(DataObject* pObj, const std::string& key) { const std::string className = ClassName<T>::name(); - if (!m_dictionaryOkWrite) { - m_dictionaryOkWrite = m_athenaPoolCnvSvc->testDictionary(className); - } - if (!m_dictionaryOkWrite) { - ATH_MSG_ERROR("There is no correct dictionary for class (type/key) " << className << "/" << getDataObject()->name()); - return(StatusCode::FAILURE); - } if (!m_classDesc) { - ATH_MSG_DEBUG("Retrieve class description for class (type/key) " << className << "/" << getDataObject()->name()); + ATH_MSG_DEBUG("Retrieve class description for class (type/key) " << className << "/" << pObj->name()); m_classDesc = RootType( typeid(T) ); } - if (this->getDataObject()->clID() == 1 && this->getDataObject()->registry()->address() != 0) { + if (pObj->clID() == 1 && pObj->registry()->address() != 0) { ATH_MSG_DEBUG("Failed to cast DataObject to transient type, doing pers to pers"); - if (this->m_poolToken == 0) this->m_poolToken = new Token; - const_cast<Token*>(m_poolToken)->fromString(this->getDataObject()->registry()->address()->par()[0]); //FIXME: get TokenAddress? - DataObject* pObj = 0; - if (!PoolToDataObject(pObj, "").isSuccess()) { - delete this->m_poolToken; this->m_poolToken = 0; + if (!PoolToDataObject(pObj, this->m_i_poolToken).isSuccess()) { ATH_MSG_ERROR("Failed to read persistent DataType"); return(StatusCode::FAILURE); } - delete this->m_poolToken; this->m_poolToken = 0; } T* obj = 0; - bool success = SG::fromStorable(getDataObject(), obj); + bool success = SG::fromStorable(pObj, obj); if (!success || obj == 0) { - ATH_MSG_ERROR("failed to cast to T for class (type/key) " << className << "/" << getDataObject()->name()); + ATH_MSG_ERROR("failed to cast to T for class (type/key) " << className << "/" << pObj->name()); return(StatusCode::FAILURE); } setPlacement(key); - this->m_poolToken = m_athenaPoolCnvSvc->registerForWrite(m_placement, obj, m_classDesc); + this->m_o_poolToken = m_athenaPoolCnvSvc->registerForWrite(m_placement, obj, m_classDesc); return(StatusCode::SUCCESS); } //__________________________________________________________________________ template <class T> -StatusCode T_AthenaPoolCnv<T>::PoolToDataObject(DataObject*& pObj, const std::string& /*token*/) { +StatusCode T_AthenaPoolCnvBase<T>::PoolToDataObject(DataObject*& pObj, const Token* token) { const std::string className = ClassName<T>::name(); - if (!m_dictionaryOkRead) { - m_dictionaryOkRead = m_athenaPoolCnvSvc->testDictionary(className); - } - if (!m_dictionaryOkRead) { - ATH_MSG_ERROR("There is no correct dictionary for class \"" << className << "\""); - return(StatusCode::FAILURE); - } - void* voidPtr; + void* voidPtr = 0; try { - m_athenaPoolCnvSvc->setObjPtr(voidPtr, this->m_poolToken); + m_athenaPoolCnvSvc->setObjPtr(voidPtr, token); } catch (std::exception &e) { std::string error = e.what(); ATH_MSG_ERROR("poolToObject: caught error: " << error); return(StatusCode::FAILURE); } T* obj = reinterpret_cast<T*>(voidPtr); - this->setDataObject(SG::asStorable(obj)); - pObj = this->getDataObject(); + pObj = SG::asStorable(obj); return(StatusCode::SUCCESS); } //__________________________________________________________________________ template <class T> -void T_AthenaPoolCnv<T>::setPlacement(const std::string& key) { +void T_AthenaPoolCnvBase<T>::setPlacement(const std::string& key) { const std::string typenm = ClassName<T>::name(); setPlacementWithType(typenm, key); } diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCoolMultChanCnv.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCoolMultChanCnv.h old mode 100755 new mode 100644 diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCoolMultChanCnv.icc b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCoolMultChanCnv.icc old mode 100755 new mode 100644 index 4f35581597d4c34d1398893694f1ab141b2283b6..382650ffb7bfdae185943837f88a01d1d8b9757c --- a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCoolMultChanCnv.icc +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCoolMultChanCnv.icc @@ -176,14 +176,6 @@ T_AthenaPoolCoolMultChanCnv<COLL_T, ELEM_T, ELEM_P>::objectToAttrListColl(COLL_T ATH_MSG_DEBUG("Chan " << *itChan1); } - // We must check the class def for CondMultChanCollImpl at least - // once. To do so, we need to reset the dict check flag once since - // it was already after checking ELEM_T - static bool first = true; - if (first) { - this->m_dictionaryOkWrite = false; - first = false; - } StatusCode sc = this->objectToPool(impl, implToken); if (sc != StatusCode::SUCCESS || !implToken) { ATH_MSG_ERROR("Unable to write out CondMultChanCollImpl"); @@ -310,7 +302,7 @@ T_AthenaPoolCoolMultChanCnv<COLL_T, ELEM_T, ELEM_P>::condMultChanCollImplToObjec // Read in the CondMultChanCollImpl CondMultChanCollImpl* impl = 0; this->setToken(collImplToken); - StatusCode sc = this->poolToObject(collImplToken, impl); + StatusCode sc = this->poolToObject(this->m_i_poolToken, impl); if (sc != StatusCode::SUCCESS) { ATH_MSG_ERROR("Unable to read in CondMultChanCollImpl"); return(StatusCode::FAILURE); @@ -376,7 +368,7 @@ template <class P> inline P* T_AthenaPoolCoolMultChanCnv<COLL_T, ELEM_T, ELEM_P>::poolReadObject() { P* persObj = 0; - if( this->poolToObject( this->m_poolToken != 0 ? this->m_poolToken->toString() : "", persObj ).isFailure() ) { + if( this->poolToObject( this->m_i_poolToken , persObj ).isFailure() ) { throw std::runtime_error("POOL read failed"); } return(persObj); @@ -389,7 +381,7 @@ template <class COLL_T, class ELEM_T, class ELEM_P> inline ELEM_T* T_AthenaPoolCoolMultChanCnv<COLL_T, ELEM_T, ELEM_P>::poolReadObject() { ELEM_T* persObj = 0; - if( this->poolToObject( this->m_poolToken != 0 ? this->m_poolToken->toString() : "", persObj ).isFailure() ) { + if( this->poolToObject( this->m_i_poolToken , persObj ).isFailure() ) { throw std::runtime_error("POOL read failed"); } return(persObj); diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustCnv.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustCnv.h old mode 100755 new mode 100644 index 3e05cffdb01eecc3c9330a47e0f34e8a44a19324..a9fe556da7b7fdf7dc11bc0040993012a9c54cc0 --- a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustCnv.h +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustCnv.h @@ -10,7 +10,7 @@ * @author Peter van Gemmeren <gemmeren@anl.gov> **/ -#include "AthenaPoolCnvSvc/T_AthenaPoolCnv.h" +#include "AthenaPoolCnvSvc/T_AthenaPoolCnvBase.h" #include "PersistentDataModel/Token.h" #include "PersistentDataModel/Guid.h" @@ -31,7 +31,7 @@ template <class TYPE> class CnvFactory; * @brief This templated class provides the converter to translate an object to/from its persistent POOL representation. **/ template <class TRANS, class PERS> -class T_AthenaPoolCustCnv : public T_AthenaPoolCnv<TRANS> { +class T_AthenaPoolCustCnv : public T_AthenaPoolCnvBase<TRANS> { friend class CnvFactory<T_AthenaPoolCustCnv<TRANS, PERS> >; protected: @@ -53,7 +53,7 @@ protected: /// Read an object from POOL. /// @param pObj [OUT] pointer to the transient object. /// @param token [IN] POOL token of the persistent representation. - virtual StatusCode PoolToDataObject(DataObject*& pObj, const std::string& token); + virtual StatusCode PoolToDataObject(DataObject*& pObj, const Token* token); /// Write an object into POOL returning its token. /// @param pObj [IN] pointer to the object to be written. @@ -66,7 +66,7 @@ protected: /// @param token [IN] POOL token of the persistent representation. /// @param pObj [OUT] pointer to the object read. template <class P> - StatusCode poolToObject(const std::string& token, P*& pObj); + StatusCode poolToObject(const Token*& token, P*& pObj); virtual StatusCode transToPers(TRANS* obj, PERS*& persObj) = 0; virtual StatusCode persToTrans(TRANS*& transObj, PERS* obj) = 0; @@ -83,8 +83,7 @@ protected: virtual void setToken(const std::string& token); // the POOL class ID (GUID) of the object being read. - // Set by PoolToDataObject() (together with m_token) - // available in createTransient() + // Set by PoolToDataObject() available in createTransient() Guid m_classID; public: diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustCnv.icc b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustCnv.icc old mode 100755 new mode 100644 index d77803888ff969eded31ae933f5eaaa25cb0ce1f..03ad20bc0f485548fb9a2b6c4365fc9544430f33 --- a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustCnv.icc +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustCnv.icc @@ -17,19 +17,19 @@ #include "StorageSvc/DbReflex.h" #include "CLIDSvc/CLASS_DEF.h" -#include "DataModel/ClassName.h" +#include "SGTools/ClassName.h" #include "PersistentDataModel/Token.h" #include "SGTools/StorableConversions.h" //__________________________________________________________________________ template <class TRANS, class PERS> -T_AthenaPoolCustCnv<TRANS, PERS>::T_AthenaPoolCustCnv(ISvcLocator* pSvcLocator) : T_AthenaPoolCnv<TRANS>(pSvcLocator) { +T_AthenaPoolCustCnv<TRANS, PERS>::T_AthenaPoolCustCnv(ISvcLocator* pSvcLocator) : T_AthenaPoolCnvBase<TRANS>(pSvcLocator) { } //______________________________________________________________________________ template <class TRANS, class PERS> StatusCode T_AthenaPoolCustCnv<TRANS, PERS>::initialize() { ATH_MSG_DEBUG("initialize() in T_AthenaPoolCustCnv " << classID()); - if (!T_AthenaPoolCnv<TRANS>::initialize().isSuccess()) { + if (!T_AthenaPoolCnvBase<TRANS>::initialize().isSuccess()) { ATH_MSG_FATAL("Failed to initialize AthenaPoolConverter base class."); return(StatusCode::FAILURE); } @@ -53,13 +53,6 @@ template <class P> StatusCode T_AthenaPoolCustCnv<TRANS, PERS>::objectToPool(P* pObj, const Token*& token, const std::string& key) { const std::string className = ClassName<P>::name(); // Check dictionary - if (!this->m_dictionaryOkWrite) { - this->m_dictionaryOkWrite = this->m_athenaPoolCnvSvc->testDictionary(className); - } - if (!this->m_dictionaryOkWrite) { - ATH_MSG_ERROR("There is no correct dictionary for class (type/key) " << className << "/" << key); - return(StatusCode::FAILURE); - } // Allow for multiple class names if (this->m_className != className) { this->m_className = className; @@ -67,7 +60,6 @@ StatusCode T_AthenaPoolCustCnv<TRANS, PERS>::objectToPool(P* pObj, const Token*& auto itClass = this->m_classDescs.find(className); if (itClass == this->m_classDescs.end()) { // For new class names, check dictionary - this->m_dictionaryOkWrite = false; this->m_classDesc = RootType( typeid(P) ); this->m_classDescs[className] = this->m_classDesc; } else { @@ -82,100 +74,51 @@ StatusCode T_AthenaPoolCustCnv<TRANS, PERS>::objectToPool(P* pObj, const Token*& //__________________________________________________________________________ template <class TRANS, class PERS> template <class P> -StatusCode T_AthenaPoolCustCnv<TRANS, PERS>::poolToObject(const std::string& /*token*/, P*& pObj) { +StatusCode T_AthenaPoolCustCnv<TRANS, PERS>::poolToObject(const Token*& token, P*& pObj) { pObj = 0; const std::string className = ClassName<P>::name(); - if (!this->m_dictionaryOkRead) { - this->m_dictionaryOkRead = this->m_athenaPoolCnvSvc->testDictionary(className); - } - if (!this->m_dictionaryOkRead) { - ATH_MSG_ERROR("There is no correct dictionary for class \"" << className << "\""); - return(StatusCode::FAILURE); - } void* voidPtr = 0; try { - this->m_athenaPoolCnvSvc->setObjPtr(voidPtr, this->m_poolToken); + this->m_athenaPoolCnvSvc->setObjPtr(voidPtr, token); } catch (std::exception &e) { ATH_MSG_ERROR("poolToObject: caught error: " << e.what()); return(StatusCode::FAILURE); } if (voidPtr == 0) { - ATH_MSG_ERROR("poolToObject: Could not get object for Token = " << (this->m_poolToken != 0 ? this->m_poolToken->toString() : "")); + ATH_MSG_ERROR("poolToObject: Could not get object for Token = " << (token != 0 ? token->toString() : "")); return(StatusCode::FAILURE); } pObj = reinterpret_cast<P*>(voidPtr); if (pObj == 0) { - ATH_MSG_ERROR("poolToObject: Failed to cast object for Token = " << (this->m_poolToken != 0 ? this->m_poolToken->toString() : "")); + ATH_MSG_ERROR("poolToObject: Failed to cast object for Token = " << (token != 0 ? token->toString() : "")); return(StatusCode::FAILURE); } return(StatusCode::SUCCESS); } //__________________________________________________________________________ template <class TRANS, class PERS> -StatusCode T_AthenaPoolCustCnv<TRANS, PERS>::DataObjectToPool(DataObject* /*pObj*/, const std::string& key) { +StatusCode T_AthenaPoolCustCnv<TRANS, PERS>::DataObjectToPool(DataObject* pObj, const std::string& key) { const std::string className = ClassName<TRANS>::name(); - bool skipDHE = false; TRANS* obj = 0; PERS* persObj = 0; - SG::fromStorable(this->getDataObject(), obj); + SG::fromStorable(pObj, obj); if (obj == 0) { - if (this->getDataObject()->clID() == 1) { - if (this->getDataObject()->registry() != 0 && this->getDataObject()->registry()->address() != 0) { - ATH_MSG_DEBUG("Failed to cast DataObject to transient type, doing pers to pers"); - const std::string className = ClassName<PERS>::name(); - if (this->m_className != className) { - this->m_className = className; - // Different class name - get description - auto itClass = this->m_classDescs.find(className); - if (itClass == this->m_classDescs.end()) { - this->m_classDesc = RootType( typeid(PERS) ); - this->m_classDescs[className] = this->m_classDesc; - } else { - // Set to correct class description - this->m_classDesc = (*itClass).second; - } - } - this->setToken(this->getDataObject()->registry()->address()->par()[0]); - ATH_MSG_DEBUG("Failed to cast DataObject to transient type, doing pers to pers"); - if (!this->compareClassGuid(pool::DbReflex::guid(this->m_classDesc))) { - ATH_MSG_ERROR("Can not evolve schema in pers to pers copy"); - return(StatusCode::FAILURE); - } - if (!poolToObject<PERS>("", persObj).isSuccess()) { - ATH_MSG_ERROR("Failed to read persistent DataType"); - return(StatusCode::FAILURE); - } - } else { - ATH_MSG_DEBUG("Failed to cast DataObject to transient type, using empty default"); - skipDHE = true; - persObj = new PERS(); - } - } else { - ATH_MSG_ERROR("failed to cast to T for class (type/key) " << className << "/" << this->getDataObject()->name()); - return(StatusCode::FAILURE); - } + ATH_MSG_ERROR("failed to cast to T for class (type/key) " << className << "/" << pObj->name()); + return(StatusCode::FAILURE); } else { if (!transToPers(obj, persObj).isSuccess()) { - ATH_MSG_ERROR("Failed to convert to persistent DataType for class (type/key) " << className << "/" << this->getDataObject()->name()); + ATH_MSG_ERROR("Failed to convert to persistent DataType for class (type/key) " << className << "/" << pObj->name()); return(StatusCode::FAILURE); } } - const Token* token = 0; - StatusCode status = objectToPool<PERS>(persObj, token, key); - if (skipDHE) { - delete token; token = 0; - this->setToken("\n"); - } else { - this->m_poolToken = token; token = 0; - } - return(status); + return(objectToPool<PERS>(persObj, this->m_o_poolToken, key)); } //__________________________________________________________________________ template <class TRANS, class PERS> -StatusCode T_AthenaPoolCustCnv<TRANS, PERS>::PoolToDataObject(DataObject*& pObj, const std::string& /*token*/) { +StatusCode T_AthenaPoolCustCnv<TRANS, PERS>::PoolToDataObject(DataObject*& pObj, const Token* token) { TRANS* transObj = 0; PERS* obj = 0; - if (!poolToObject<PERS>("", obj).isSuccess()) { + if (!poolToObject<PERS>(token, obj).isSuccess()) { ATH_MSG_ERROR("Failed to read persistent DataType"); return(StatusCode::FAILURE); } @@ -186,8 +129,7 @@ StatusCode T_AthenaPoolCustCnv<TRANS, PERS>::PoolToDataObject(DataObject*& pObj, return(StatusCode::FAILURE); } delete obj; obj = 0; - this->setDataObject(SG::asStorable(transObj)); - pObj = this->getDataObject(); + pObj = SG::asStorable(transObj); return(StatusCode::SUCCESS); } //__________________________________________________________________________ @@ -195,9 +137,9 @@ StatusCode T_AthenaPoolCustCnv<TRANS, PERS>::PoolToDataObject(DataObject*& pObj, // the object that will be read next. Required by compareClassGuid() template <class TRANS, class PERS> inline void T_AthenaPoolCustCnv<TRANS, PERS>::setToken(const std::string& token_str) { - if (this->m_poolToken == 0) this->m_poolToken = new Token; - const_cast<Token*>(this->m_poolToken)->fromString(token_str); - m_classID = this->m_poolToken != 0 ? this->m_poolToken->classID() : Guid::null(); + if (this->m_i_poolToken == 0) this->m_i_poolToken = new Token; + const_cast<Token*>(this->m_i_poolToken)->fromString(token_str); + m_classID = this->m_i_poolToken != 0 ? this->m_i_poolToken->classID() : Guid::null(); } //__________________________________________________________________________ // Compare POOL class GUID with the one from object being read diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustomCnv.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustomCnv.h old mode 100755 new mode 100644 index d7741852667d38799a75c154005e33731793d4e3..706a632f1b7a9b523cad8dbd96db2d150a8f7f32 --- a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustomCnv.h +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustomCnv.h @@ -91,7 +91,7 @@ protected: /// Read an object from POOL. /// @param pObj [OUT] pointer to the transient object. /// @param token [IN] POOL token of the persistent representation. - virtual StatusCode PoolToDataObject(DataObject*& pObj, const std::string& token); + virtual StatusCode PoolToDataObject(DataObject*& pObj, const Token* token); /// Callback from the CleanupSvc to delete persistent object in the local list virtual StatusCode cleanUp(); diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustomCnv.icc b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustomCnv.icc old mode 100755 new mode 100644 index 3459655dcdf9e2bd45452a983e9b16ce9fbffe70..f05c6cd770ae64e8e14bef56d17fc2c2f7f1cfd3 --- a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustomCnv.icc +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustomCnv.icc @@ -27,53 +27,14 @@ T_AthenaPoolCustomCnv<TRANS, PERS>::T_AthenaPoolCustomCnv(ISvcLocator* pSvcLocat } template <class TRANS, class PERS> -StatusCode T_AthenaPoolCustomCnv<TRANS, PERS>::DataObjectToPool(DataObject* /*pObj*/, const std::string& key) { - ATH_MSG_VERBOSE("In DataObjectToPool() for key = " << this->getDataObject()->name()); - bool skipDHE = false; +StatusCode T_AthenaPoolCustomCnv<TRANS, PERS>::DataObjectToPool(DataObject* pObj, const std::string& key) { + ATH_MSG_VERBOSE("In DataObjectToPool() for key = " << pObj->name()); TRANS* obj = 0; PERS* persObj = 0; - SG::fromStorable(this->getDataObject(), obj); + SG::fromStorable(pObj, obj); if (obj == 0) { - if (this->getDataObject()->clID() == 1) { - if (this->getDataObject()->registry() != 0 && this->getDataObject()->registry()->address() != 0) { - const std::string className = ClassName<PERS>::name(); - if (this->m_className != className) { - this->m_className = className; - auto itClass = this->m_classDescs.find(className); - if (itClass == this->m_classDescs.end()) { - this->m_classDesc = RootType( typeid(PERS) ); - this->m_classDescs[className] = this->m_classDesc; - } else { - // Set to correct class description - this->m_classDesc = (*itClass).second; - } - } - this->setToken(this->getDataObject()->registry()->address()->par()[0]); - ATH_MSG_DEBUG("Failed to cast DataObject to transient type, doing pers to pers"); - if (!this->compareClassGuid(pool::DbReflex::guid(this->m_classDesc))) { - ATH_MSG_ERROR("Can not evolve schema in pers to pers copy"); - return(StatusCode::FAILURE); - } - AthenaConverterTLPExtension *extCnv = dynamic_cast<AthenaConverterTLPExtension*>(this); - if (extCnv != 0) { - ATH_MSG_ERROR("Can not retrieve " << this->getDataObject()->name() << " in pers to pers copy"); - return(StatusCode::FAILURE); - } - try { - persObj = this->poolReadObject<PERS>(); - } catch (...) { - ATH_MSG_ERROR("Failed to read persistent DataType"); - return(StatusCode::FAILURE); - } - } else { - ATH_MSG_DEBUG("Failed to cast DataObject to transient type, using empty default"); - skipDHE = true; - persObj = new PERS(); - } - } else { - ATH_MSG_ERROR("Failed to cast DataObject to transient type"); - return(StatusCode::FAILURE); - } + ATH_MSG_ERROR("Failed to cast DataObject to transient type"); + return(StatusCode::FAILURE); } else { try { persObj = createPersistent(obj); @@ -93,21 +54,13 @@ StatusCode T_AthenaPoolCustomCnv<TRANS, PERS>::DataObjectToPool(DataObject* /*pO } } m_persObjList.push_back(persObj); - const Token* token = 0; - StatusCode status = this->objectToPool(persObj, token, key); - if (skipDHE) { - delete token; token = 0; - this->setToken("\n"); - } else { - this->m_poolToken = token; token = 0; - } - return(status); + return(this->objectToPool(persObj, this->m_o_poolToken, key)); } template <class TRANS, class PERS> -StatusCode T_AthenaPoolCustomCnv<TRANS, PERS>::PoolToDataObject(DataObject*& pObj, const std::string& /*token_str*/) { - if (this->m_poolToken != 0) { - this->m_classID = this->m_poolToken->classID(); +StatusCode T_AthenaPoolCustomCnv<TRANS, PERS>::PoolToDataObject(DataObject*& pObj, const Token* token) { + if (token != 0) { + this->m_classID = token->classID(); } TRANS* transObj = 0; AthenaConverterTLPExtension *extCnv = dynamic_cast<AthenaConverterTLPExtension*>(this); @@ -128,8 +81,7 @@ StatusCode T_AthenaPoolCustomCnv<TRANS, PERS>::PoolToDataObject(DataObject*& pOb if (extCnv != 0) { extCnv->deletePersistentObjects(); } - this->setDataObject(SG::asStorable(transObj)); - pObj = this->getDataObject(); + pObj = SG::asStorable(transObj); return(StatusCode::SUCCESS); } @@ -139,9 +91,9 @@ template <class TRANS, class PERS> template <class P> inline P* T_AthenaPoolCustomCnv<TRANS, PERS>::poolReadObject() { P* persObj = 0; - if (this->poolToObject("", persObj).isFailure()) { + if (this->poolToObject(this->m_i_poolToken, persObj).isFailure()) { std::string error("POOL read failed. Token = "); - throw std::runtime_error(error + (this->m_poolToken != 0 ? this->m_poolToken->toString() : "")); + throw std::runtime_error(error + (this->m_i_poolToken != 0 ? this->m_i_poolToken->toString() : "")); } AthenaConverterTLPExtension *extCnv = dynamic_cast<AthenaConverterTLPExtension*>(this); if (extCnv != 0) { diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolExtendingCnv.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolExtendingCnv.h old mode 100755 new mode 100644 diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolExtendingCnv.icc b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolExtendingCnv.icc old mode 100755 new mode 100644 index a971206011c3b0f55b732004e7ba7021e716a7bf..4f7695d349e0c87c777f4e4323a37eb57f9a59e8 --- a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolExtendingCnv.icc +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolExtendingCnv.icc @@ -38,7 +38,9 @@ wasClonedFrom( AthenaConverterTLPExtension *converter ) m_originalExtendingCnv = dynamic_cast< BaseType* >(converter); } else { // in case of cloning a clone, get the real original converter - m_originalExtendingCnv = dynamic_cast< T_AthenaPoolExtendingCnv< TRANS, PERS >* >(converter)->baseAthenaPoolCnv(); + auto* extcnv = dynamic_cast< T_AthenaPoolExtendingCnv< TRANS, PERS >* >(converter); + if (!extcnv) std::abort(); + m_originalExtendingCnv = extcnv->baseAthenaPoolCnv(); } // std::cout << " TPCNVINFO: Registering clone source " << (void*)m_originalExtendingCnv << std::endl; } diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolTPCnvCnv.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolTPCnvCnv.h new file mode 100644 index 0000000000000000000000000000000000000000..e6dbe97fef8381e5a5698d173bd054fdfa7f34af --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolTPCnvCnv.h @@ -0,0 +1,92 @@ +// This file's extension implies that it's C, but it's really -*- C++ -*-. + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id$ +/** + * @file AthenaPoolCnvSvc/T_AthenaPoolTPCnvCnv.h + * @author scott snyder <snyder@bnl.gov> + * @date Jan, 2016 + * @brief Athena pool converter for a class using TP separation. + */ + + +#ifndef ATHENAPOOLCNVSVC_T_ATHENAPOOLTPCNVCNV_H +#define ATHENAPOOLCNVSVC_T_ATHENAPOOLTPCNVCNV_H + + +#include "AthenaPoolCnvSvc/TPCnvList.h" +#include "AthenaPoolCnvSvc/T_AthenaPoolCustomCnv.h" +#include "AthenaPoolCnvSvc/exceptions.h" +#include "SGTools/ClassName.h" +#include <memory> + + +/** + * @brief Athena pool converter for aux store classes. + * + * AUXSTORE is the class being read/written. + * TPCNVS is a list of TP converters to handle older versions of the class. + * + * On writing, the container is copied (and thinned if required). + * For reading, we read the object either directly + * or using one of the TP converters, depending on the saved GUID. + */ +template <class TRANS, class TPCNV_CUR, class ... TPCNVS> +class T_AthenaPoolTPCnvCnv + : public T_AthenaPoolCustomCnv<TRANS, typename TPCNV_CUR::Pers_t> +{ + friend class CnvFactory< T_AthenaPoolTPCnvCnv >; + + template <class CNV, class TPCNV> + friend class AthenaPoolCnvSvc::TPCnvElt; + +public: + typedef T_AthenaPoolCustomCnv<TRANS, typename TPCNV_CUR::Pers_t> Base; + typedef typename TPCNV_CUR::Pers_t Pers_t; + + + /** + * @brief Constructor. + * @param svcLoc Gaudi service locator. + */ + T_AthenaPoolTPCnvCnv ( ISvcLocator* svcLoc ); + + + /** + * @brief Convert a transient object to persistent form. + * @param trans The transient object to convert. + * + * Returns a newly-allocated persistent object. + */ + virtual Pers_t* createPersistent( TRANS* trans ) override; + + + /** + * @brief Read the persistent object and convert it to transient. + * + * Returns a newly-allocated transient object. + * Errors are reported by raising exceptions. + */ + virtual TRANS* createTransient() override; + + +private: + /// GUID of the object being read. + Guid m_guid; + + /// TP converter for current persistent class version. + TPCNV_CUR m_tpcnv_cur; + + /// List of TP converters for older versions. + AthenaPoolCnvSvc::TPCnvList<T_AthenaPoolTPCnvCnv, TRANS, TPCNVS...> m_tpcnvs; +}; + + +#include "AthenaPoolCnvSvc/T_AthenaPoolTPCnvCnv.icc" + + +#endif // not ATHENAPOOLCNVSVC_T_ATHENAPOOLTPCNVCNV_H + diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolTPCnvCnv.icc b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolTPCnvCnv.icc new file mode 100644 index 0000000000000000000000000000000000000000..662e5776cc271f73b52765aaf3bdb6d99bf93a76 --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolTPCnvCnv.icc @@ -0,0 +1,65 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id$ +/** + * @file AthenaPoolCnvSvc/T_AthenaPoolTPCnvCnv.icc + * @author scott snyder <snyder@bnl.gov> + * @date Jan, 2016 + * @brief Athena pool converter for a class using TP separation. + */ + + +/** + * @brief Constructor. + * @param svcLoc Gaudi service locator. + */ +template <class TRANS, class TPCNV_CUR, class ... TPCNVS> +T_AthenaPoolTPCnvCnv<TRANS, TPCNV_CUR, TPCNVS...>::T_AthenaPoolTPCnvCnv( ISvcLocator* svcLoc ) + : Base( svcLoc ) +{ + m_guid = AthenaPoolCnvSvc::guidFromTypeinfo (typeid (Pers_t)); +} + + +/** + * @brief Convert a transient object to persistent form. + * @param trans The transient object to convert. + * + * Returns a newly-allocated persistent object. + */ +template <class TRANS, class TPCNV_CUR, class ... TPCNVS> +typename T_AthenaPoolTPCnvCnv<TRANS, TPCNV_CUR, TPCNVS...>::Pers_t* +T_AthenaPoolTPCnvCnv<TRANS, TPCNV_CUR, TPCNVS...>::createPersistent( TRANS* trans ) +{ + return m_tpcnv_cur.createPersistent (trans, this->msg()); +} + + +/** + * @brief Read the persistent object and convert it to transient. + * + * Returns a newly-allocated transient object. + * Errors are reported by raising exceptions. + */ +template <class TRANS, class TPCNV_CUR, class ... TPCNVS> +TRANS* +T_AthenaPoolTPCnvCnv<TRANS, TPCNV_CUR, TPCNVS...>::createTransient() +{ + if ( this->compareClassGuid( m_guid ) ) { + // It's the latest version. + std::unique_ptr<Pers_t> persObj( this->template poolReadObject<Pers_t>() ); + return m_tpcnv_cur.createTransient( persObj.get(), this->msg() ); + } + + // Try a converter. + TRANS* c = m_tpcnvs.createTransient (*this, this->msg()); + if (c) + return c; + + // Didn't recognize the GUID. + AthenaPoolCnvSvc::throwExcUnsupportedVersion (typeid(TRANS), + this->m_i_poolToken->classID()); + return 0; +} diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolTPConverter.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolTPConverter.h old mode 100755 new mode 100644 diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolViewVectorCnv.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolViewVectorCnv.h new file mode 100644 index 0000000000000000000000000000000000000000..5b533ccec24359bb85c6220fc7180635b42a4708 --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolViewVectorCnv.h @@ -0,0 +1,93 @@ +// This file's extension implies that it's C, but it's really -*- C++ -*-. + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id$ +/** + * @file AthenaPoolCnvSvc/T_AthenaPoolViewVectorCnv.h + * @author scott snyder <snyder@bnl.gov> + * @date Jan, 2016 + * @brief Athena pool converter for a ViewVector class. + */ + + +#ifndef ATHENAPOOLCNVSVC_T_ATHENAPOOLVIEWVECTORCNV_H +#define ATHENAPOOLCNVSVC_T_ATHENAPOOLVIEWVECTORCNV_H + + +#include "AthenaPoolCnvSvc/T_AthenaPoolCustomCnv.h" +#include "AthenaPoolCnvSvc/exceptions.h" +#include "StorageSvc/DbReflex.h" +#include "AthContainers/ViewVector.h" +#include "AthContainers/dataVectorAsELV.h" +#include "AthContainers/ConstDataVector.h" +#include "AthLinks/ElementLink.h" +#include "AthenaKernel/errorcheck.h" +#include "CxxUtils/make_unique.h" +#include "CxxUtils/StrFormat.h" +#include <vector> +#include <cstdlib> + + +/** + * @brief Athena pool converter for a ViewVector class. + * + * This pool converter converts between a transient ViewVector<DV> type + * and a persistent std::vector<ElementLink<DV> > type, where DV is + * a DataVector. + */ +template <class DV> +class T_AthenaPoolViewVectorCnv + : public T_AthenaPoolCustomCnv<ViewVector<DV>, + std::vector<ElementLink<DV> > > +{ +public: + /// The transient and persistent types. + typedef ViewVector<DV> trans_t; + typedef std::vector<ElementLink<DV> > pers_t; + + /// Base class. + typedef T_AthenaPoolCustomCnv<trans_t, pers_t> Base; + + + /** + * @brief Constructor. + * @param svcloc The Gaudi service locator. + */ + T_AthenaPoolViewVectorCnv (ISvcLocator* svcloc); + + + /** + * @brief Standard Gaudi initialize method. + */ + virtual StatusCode initialize() override; + + + /** + * @brief Convert a transient object to persistent form. + * @param trans The transient object to convert. + * + * Returns a newly-allocated persistent object. + */ + virtual pers_t* createPersistent( trans_t* trans ) override; + + + /** + * @brief Read the persistent object and convert it to transient. + * + * Returns a newly-allocated transient object. + * Errors are reported by raising exceptions. + */ + virtual trans_t* createTransient() override; + +private: + std::vector<pool::Guid> m_guids; +}; + + +#include "AthenaPoolCnvSvc/T_AthenaPoolViewVectorCnv.icc" + + +#endif // not ATHENAPOOLCNVSVC_T_ATHENAPOOLVIEWVECTORCNV_H diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolViewVectorCnv.icc b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolViewVectorCnv.icc new file mode 100644 index 0000000000000000000000000000000000000000..c774ea3eac3d66bc458e4be9e5af552adbde554e --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolViewVectorCnv.icc @@ -0,0 +1,118 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id$ +/** + * @file AthenaPoolCnvSvc/T_AthenaPoolViewVectorCnv.icc + * @author scott snyder <snyder@bnl.gov> + * @date Jan, 2016 + * @brief Athena pool converter for a ViewVector class. + */ + + +/** + * @brief Constructor. + * @param svcloc The Gaudi service locator. + */ +template <class DV> +T_AthenaPoolViewVectorCnv<DV>::T_AthenaPoolViewVectorCnv (ISvcLocator* svcloc) + : Base (svcloc) +{ +} + + +/** + * @brief Standard Gaudi initialize method. + */ +template <class DV> +StatusCode +T_AthenaPoolViewVectorCnv<DV>::initialize() +{ + CHECK( Base::initialize() ); + + // Make a list of all the guids that this converter can read. + // First, add the entry for pers_t. + pool::TypeH typ = pool::DbReflex::forTypeInfo (typeid(pers_t)); + if (!typ) + AthenaPoolCnvSvc::throwExcNoDictForClass (typeid(pers_t)); + m_guids.push_back (pool::DbReflex::guid (typ)); + + // Now look for entries for previous versions. + // Look for a version tag in the type name and try replacing it with + // previous versions. Eg, if the name for pers_t contains `_v3', + // then we also look for guids for the same name with `_v3' replaced + // by `_v2' and `_v1'. + + std::string name = typ.Name(); + std::string::size_type vpos = 0; + while ((vpos = name.find ("_v", vpos)) != std::string::npos) { + vpos += 2; + std::string::size_type vpos2 = vpos; + if (isdigit (name[vpos2])) { + ++vpos2; + while (vpos2 < name.size() && isdigit (name[vpos2])) + ++vpos2; + if (vpos2 < name.size() && name[vpos2] == '>') { + int vers = atoi (name.substr (vpos, vpos2-vpos).c_str()); + while (--vers > 0) { + std::string name2 = name.substr(0,vpos) + CxxUtils::strformat("%d", vers) + name.substr(vpos2,std::string::npos); + pool::TypeH typ2 = pool::DbReflex::forTypeName (name2); + if (typ2) + m_guids.push_back (pool::DbReflex::guid (typ2)); + } + } + } + } + return StatusCode::SUCCESS; +} + + +/** + * @brief Convert a transient object to persistent form. + * @param trans The transient object to convert. + * + * Returns a newly-allocated persistent object. + */ +template <class DV> +typename T_AthenaPoolViewVectorCnv<DV>::pers_t* +T_AthenaPoolViewVectorCnv<DV>::createPersistent( trans_t* trans ) +{ + // Convert to ElementLinks and apply thinning. + pers_t* pers = new pers_t (SG::dataVectorAsELV (static_cast<const DV&>(*trans))); + for (ElementLink<DV>& el : *pers) + el.thin(); + return pers; +} + + +/** + * @brief Read the persistent object and convert it to transient. + * + * Returns a newly-allocated transient object. + * Errors are reported by raising exceptions. + */ +template <class DV> +typename T_AthenaPoolViewVectorCnv<DV>::trans_t* +T_AthenaPoolViewVectorCnv<DV>::createTransient() +{ + // See if we're looking at one of the guids we can handle. + // FIXME: For old persistent versions, this works by essentially doing + // a reinterpret_cast from the version on the file to the current version. + // That works for current ElementLink classes, but it's not very nice. + for (const pool::Guid& guid : m_guids) { + if( this->compareClassGuid( guid ) ) { + std::unique_ptr<pers_t> v (this->template poolReadObject< pers_t >()); + auto c = CxxUtils::make_unique<ConstDataVector<trans_t> > (*v); + // FIXME: To get rid of this @c const_cast, the converter interfaces + // need to be changed to allow returning a const pointer + // all the way back to StoreGate. + return const_cast<trans_t*>(c.release()->asDataVector()); + } + } + + // Didn't recognize the ID. + AthenaPoolCnvSvc::throwExcUnsupportedVersion (typeid(pers_t), + this->m_i_poolToken->classID()); + return 0; +} diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolxAODCnv.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolxAODCnv.h new file mode 100644 index 0000000000000000000000000000000000000000..482b20cdd51fa694f0178196fce7c9fdeff2bad8 --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolxAODCnv.h @@ -0,0 +1,104 @@ +// This file's extension implies that it's C, but it's really -*- C++ -*-. + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id$ +/** + * @file AthenaPoolCnvSvc/T_AthenaPoolxAODCnv.h + * @author scott snyder <snyder@bnl.gov> + * @date Jan, 2016 + * @brief Athena pool converter for xAOD classes. + */ + + +#ifndef ATHENAPOOLCNVSVC_T_ATHENAPOOLXAODCNV_H +#define ATHENAPOOLCNVSVC_T_ATHENAPOOLXAODCNV_H + + +#include "AthenaPoolCnvSvc/T_AthenaPoolCustomCnv.h" +#include "AthenaPoolCnvSvc/TPCnvList.h" +#include "AthenaPoolCnvSvc/exceptions.h" +#include "AthContainers/AuxVectorBase.h" +#include "SGTools/ClassName.h" + + +/** + * @brief Athena pool converter for xAOD classes. + * + * XAOD is the class being read/written. + * TPCNVS is a list of TP converters to handle older versions of the class. + * + * On writing, the container is simply copied (thinning is handled by the + * thinning service). For reading, we read the object either directly + * or using one of the TP converters, depending on the saved GUID. + * The link to the aux store is then set based on the SG key. + */ +template <class XAOD, class ... TPCNVS> +class T_AthenaPoolxAODCnv + : public T_AthenaPoolCustomCnv<XAOD, XAOD> +{ + friend class CnvFactory< T_AthenaPoolxAODCnv >; + + template <class CNV, class TPCNV> + friend class AthenaPoolCnvSvc::TPCnvElt; + +public: + typedef T_AthenaPoolCustomCnv<XAOD, XAOD> Base; + + + /** + * @brief Constructor. + * @param svcLoc Gaudi service locator. + */ + T_AthenaPoolxAODCnv ( ISvcLocator* svcLoc ); + + + /** + * @brief Read an object from persistent storage. + * @param pAddr Address of the object to read. + * @param pObj[out] Pointer to the read object. + * + * This is overridden here in order to be able to pass the SG key + * from the address to @c createTransient. + */ + virtual StatusCode createObj( IOpaqueAddress* pAddr, + DataObject*& pObj ) override; + + + /** + * @brief Convert a transient object to persistent form. + * @param trans The transient object to convert. + * + * Returns a newly-allocated persistent object. + */ + virtual XAOD* createPersistent( XAOD* trans ) override; + + + /** + * @brief Read the persistent object and convert it to transient. + * + * Returns a newly-allocated transient object. + * Errors are reported by raising exceptions. + */ + virtual XAOD* createTransient() override; + + +private: + /// SG key for the object being read. + std::string m_key; + + /// GUID of the object being read. + Guid m_guid; + + /// List of TP converters. + AthenaPoolCnvSvc::TPCnvList<T_AthenaPoolxAODCnv, XAOD, TPCNVS...> m_tpcnvs; +}; + + +#include "AthenaPoolCnvSvc/T_AthenaPoolxAODCnv.icc" + + +#endif // not ATHENAPOOLCNVSVC_T_ATHENAPOOLXAODCNV_H + diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolxAODCnv.icc b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolxAODCnv.icc new file mode 100644 index 0000000000000000000000000000000000000000..d2953c029c817774e018adb79f1f04df387d0537 --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolxAODCnv.icc @@ -0,0 +1,90 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id$ +/** + * @file AthenaPoolCnvSvc/T_AthenaPoolxAODCnv.icc + * @author scott snyder <snyder@bnl.gov> + * @date Jan, 2016 + * @brief Athena pool converter for xAOD classes. + */ + + +/** + * @brief Constructor. + * @param svcLoc Gaudi service locator. + */ +template <class XAOD, class ... TPCNVS> +T_AthenaPoolxAODCnv<XAOD, TPCNVS...>::T_AthenaPoolxAODCnv( ISvcLocator* svcLoc ) + : Base( svcLoc ) +{ + m_guid = AthenaPoolCnvSvc::guidFromTypeinfo (typeid (XAOD)); +} + + +/** + * @brief Read an object from persistent storage. + * @param pAddr Address of the object to read. + * @param pObj[out] Pointer to the read object. + * + * This is overridden here in order to be able to pass the SG key + * from the address to @c createTransient. + */ +template <class XAOD, class ... TPCNVS> +StatusCode +T_AthenaPoolxAODCnv<XAOD, TPCNVS...>::createObj( IOpaqueAddress* pAddr, + DataObject*& pObj ) +{ + // Get the key of the container that we'll be creating: + m_key = pAddr->par()[1]; + ATH_MSG_VERBOSE( "Key of " << ClassName<XAOD>::name() << ": " << m_key ); + + // Let the base class do its thing now: + return AthenaPoolConverter::createObj( pAddr, pObj ); +} + + +/** + * @brief Convert a transient object to persistent form. + * @param trans The transient object to convert. + * + * Returns a newly-allocated persistent object. + */ +template <class XAOD, class ... TPCNVS> +XAOD* T_AthenaPoolxAODCnv<XAOD, TPCNVS...>::createPersistent( XAOD* trans ) +{ + return new XAOD (trans->begin(), trans->end(), SG::VIEW_ELEMENTS); +} + + +/** + * @brief Read the persistent object and convert it to transient. + * + * Returns a newly-allocated transient object. + * Errors are reported by raising exceptions. + */ +template <class XAOD, class ... TPCNVS> +XAOD* T_AthenaPoolxAODCnv<XAOD, TPCNVS...>::createTransient() +{ + XAOD* c = nullptr; + + if ( this->compareClassGuid( m_guid ) ) { + // It's the latest version, read it directly: + c = this->template poolReadObject< XAOD >(); + } + else { + // Try a converter. + c = m_tpcnvs.createTransient (*this, this->msg()); + } + + if (c) { + c->setStore( DataLink< SG::IConstAuxStore > (m_key + "Aux." ) ); + return c; + } + + // Didn't recognize the GUID. + AthenaPoolCnvSvc::throwExcUnsupportedVersion (typeid(XAOD), + this->m_i_poolToken->classID()); + return 0; +} diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/exceptions.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/exceptions.h new file mode 100644 index 0000000000000000000000000000000000000000..18a6db845d1446de972420b6c290d2b216d72109 --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/exceptions.h @@ -0,0 +1,84 @@ +// This file's extension implies that it's C, but it's really -*- C++ -*-. + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id$ +/** + * @file AthenaPoolCnvSvc/exceptions.h + * @author scott snyder <snyder@bnl.gov> + * @date Jan, 2016 + * @brief Exceptions that can be thrown from AthenaPoolCnvSvc. + */ + + +#ifndef ATHENAPOOLCNVSVC_EXCEPTIONS_H +#define ATHENAPOOLCNVSVC_EXCEPTIONS_H + + +#include "PersistentDataModel/Guid.h" +#include <stdexcept> +#include <typeinfo> +#include <string> + + +namespace AthenaPoolCnvSvc { + + +/** + * @brief Exception --- Can't find dictionary information for class. + * + * POOL was unable to find the dictionary information for a given class. + */ +class ExcNoDictForClass + : public std::runtime_error +{ +public: + /** + * @brief Constructor. + * @param ti The requested class. + */ + ExcNoDictForClass (const std::type_info& ti); +}; + + +/** + * @brief Throw a AthenaPoolCnvSvc::ExcNoDictForClass exception. + * @param ti The requested class. + */ +[[noreturn]] +void throwExcNoDictForClass (const std::type_info& ti); + + +/** + * @brief Exception --- Unsupported persistent version of CLASS found. + * + * The guid of the persistent class was not recognized. + */ +class ExcUnsupportedVersion + : public std::runtime_error +{ +public: + /** + * @brief Constructor. + * @param ti The class being read. + * @param guid The GUID of the persistent class. + */ + ExcUnsupportedVersion (const std::type_info& ti, const Guid& guid); +}; + + +/** + * @brief Throw a AthenaPoolCnvSvc::ExcUnsupportedVersion exception. + * @param ti The class being read. + * @param guid The GUID of the persistent class. +o */ +[[noreturn]] +void throwExcUnsupportedVersion (const std::type_info& ti, const Guid& guid); + + +} // namespace AthenaPoolCnvSvc + + +#endif // not EXCEPTIONS_H diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/selection_test.xml b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/selection_test.xml new file mode 100644 index 0000000000000000000000000000000000000000..abb50d92f452859da9279f34beeaebe846e93b93 --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/selection_test.xml @@ -0,0 +1,29 @@ +<lcgdict> + <class name="AthenaPoolCnvSvcTest::X" + id="CAE53A87-64AD-4576-A203-1A4142E1E10F" /> + <class name="AthenaPoolCnvSvcTest::X_p1" + id="6AD63B61-BE75-40FC-B0C6-DD3C7801D871" /> + <class name="AthenaPoolCnvSvcTest::X_p2" + id="0AAC9C99-726D-4CF4-B9F9-00B6674C57DD" /> + <class name="AthenaPoolCnvSvcTest::Y_v1"/> + <class name="AthenaPoolCnvSvcTest::Y_v2"/> + <class name="AthenaPoolCnvSvcTest::YCont_v1_pers" + id="7E1826B9-3666-42B3-A2E7-C916BD10A5B8" /> + <class name="AthenaPoolCnvSvcTest::YCont_v2_pers" + id="80C19103-FE9B-4227-8E48-8C0DB468F892" /> + <class name="DataVector<AthenaPoolCnvSvcTest::Y_v1>" + id="05309E49-5567-4790-BE56-2E541E0B4B24" /> + <class name="DataVector<AthenaPoolCnvSvcTest::Y_v2>" + id="0CC6B32E-6C95-4B0E-B97A-9B9040A8A9BE" /> + <class name="AthenaPoolCnvSvcTest::YAuxCont_v1" + id="BEE3C14E-149E-4366-9E24-8A32C419A3B4" /> + <class name="AthenaPoolCnvSvcTest::YAuxCont_v2" + id="170BFEE4-F6B2-4AF4-919B-7EB3986656FA" /> + + <class name="AthenaPoolCnvSvcTest::XCont" + id="6AEA6831-8777-4571-8595-95FFF40B171F" /> + <class name="AthenaPoolCnvSvcTest::XCont_p1" + id="421C967C-CB57-4234-A33F-EBE4928036C2" /> + <class name="AthenaPoolCnvSvcTest::XCont_p2" + id="F151C81D-869A-4585-8086-5F8835AB12E1" /> +</lcgdict> diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/CMakeLists.txt b/Database/AthenaPOOL/AthenaPoolCnvSvc/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..5a0eea9faa719c121273535bbe7d2afb52db0cfb --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/CMakeLists.txt @@ -0,0 +1,105 @@ +# $Id: CMakeLists.txt 733899 2016-04-05 07:43:22Z krasznaa $ +################################################################################ +# Package: AthenaPoolCnvSvc +################################################################################ + +# Declare the package name: +atlas_subdir( AthenaPoolCnvSvc ) + +# Declare the package's dependencies: +atlas_depends_on_subdirs( + PUBLIC + Control/AthContainers + Control/AthLinks + Control/AthenaBaseComps + Control/AthenaKernel + Control/CLIDSvc + Control/CxxUtils + Control/DataModelRoot + Control/SGTools + Database/APR/CollectionBase + Database/APR/CollectionUtilities + Database/APR/POOLCore + Database/APR/PersistencySvc + Database/APR/StorageSvc + Database/AthenaPOOL/AthenaPoolUtilities + Database/AthenaPOOL/PoolSvc + Database/PersistentDataModel + Database/TPTools + GaudiKernel + PRIVATE + AtlasTest/TestTools + Control/StoreGate ) + +# External dependencies: +find_package( Boost ) +find_package( ROOT COMPONENTS Core ) + +# Component(s) in the package: +atlas_add_library( AthenaPoolCnvSvcLib + AthenaPoolCnvSvc/*.h AthenaPoolCnvSvc/*.icc src/*.cxx + PUBLIC_HEADERS AthenaPoolCnvSvc + INCLUDE_DIRS ${Boost_INCLUDE_DIRS} + PRIVATE_INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} + LINK_LIBRARIES ${Boost_LIBRARIES} AthContainers AthLinks AthenaBaseComps + AthenaKernel CxxUtils DataModelRoot SGTools CollectionBase + CollectionUtilities POOLCore PersistencySvc StorageSvc AthenaPoolUtilities + PersistentDataModel TPTools GaudiKernel StoreGateLib + PRIVATE_LINK_LIBRARIES ${ROOT_LIBRARIES} ) + +atlas_add_component( AthenaPoolCnvSvc + src/components/*.cxx + LINK_LIBRARIES AthenaPoolCnvSvcLib ) + +atlas_add_dictionary( AthenaPoolCnvSvcTestDict + test/AthenaPoolCnvSvcTestDict.h + AthenaPoolCnvSvc/selection_test.xml + LINK_LIBRARIES AthenaPoolCnvSvcLib + NO_ROOTMAP_MERGE ) + +# Test(s) in the package: +atlas_add_test( exceptions_test + SOURCES test/exceptions_test.cxx + LINK_LIBRARIES AthenaPoolCnvSvcLib ) + +atlas_add_test( TPCnvElt_test + SOURCES test/TPCnvElt_test.cxx + INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} + LINK_LIBRARIES ${ROOT_LIBRARIES} GaudiKernel AthenaPoolCnvSvcLib ) + +atlas_add_test( TPCnvList_test + SOURCES test/TPCnvList_test.cxx + INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} + LINK_LIBRARIES ${ROOT_LIBRARIES} GaudiKernel AthenaPoolCnvSvcLib ) + +atlas_add_test( T_AthenaPoolViewVectorCnv_test + SOURCES test/T_AthenaPoolViewVectorCnv_test.cxx + INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} + LINK_LIBRARIES ${ROOT_LIBRARIES} AthContainers AthLinks SGTools GaudiKernel + TestTools AthenaPoolCnvSvcLib + ENVIRONMENT "JOBOPTSEARCHPATH=${CMAKE_CURRENT_SOURCE_DIR}/share" ) + +atlas_add_test( T_AthenaPoolxAODCnv_test + SOURCES test/T_AthenaPoolxAODCnv_test.cxx + INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} + LINK_LIBRARIES ${ROOT_LIBRARIES} PersistentDataModel SGTools TestTools + CxxUtils AthenaPoolCnvSvcLib + ENVIRONMENT "JOBOPTSEARCHPATH=${CMAKE_CURRENT_SOURCE_DIR}/share" ) + +atlas_add_test( T_AthenaPoolAuxContainerCnv_test + SOURCES test/T_AthenaPoolAuxContainerCnv_test.cxx + INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} + LINK_LIBRARIES ${ROOT_LIBRARIES} PersistentDataModel AthContainers SGTools + TestTools CxxUtils AthenaPoolCnvSvcLib + ENVIRONMENT "JOBOPTSEARCHPATH=${CMAKE_CURRENT_SOURCE_DIR}/share" ) + +atlas_add_test( T_AthenaPoolTPCnvCnv_test + SOURCES test/T_AthenaPoolTPCnvCnv_test.cxx + INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} + LINK_LIBRARIES ${ROOT_LIBRARIES} PersistentDataModel SGTools TestTools + CxxUtils AthenaPoolCnvSvcLib + ENVIRONMENT "JOBOPTSEARCHPATH=${CMAKE_CURRENT_SOURCE_DIR}/share" ) + +# Install files from the package: +atlas_install_python_modules( python/*.py ) +atlas_install_joboptions( share/*.py ) diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/cmt/requirements b/Database/AthenaPOOL/AthenaPoolCnvSvc/cmt/requirements old mode 100755 new mode 100644 index f3814f75f438b9ed44ee3f22f2b3eae0b8c20bbc..5305d6ce6f830a0ea3a78b7e381cba58a1fcd195 --- a/Database/AthenaPOOL/AthenaPoolCnvSvc/cmt/requirements +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/cmt/requirements @@ -4,12 +4,17 @@ author Peter Van Gemmeren <gemmeren@bnl.gov> use AtlasPolicy AtlasPolicy-* use AtlasPOOL AtlasPOOL-* External +use AtlasROOT AtlasROOT-* External use GaudiInterface GaudiInterface-* External +use AtlasBoost AtlasBoost-* External +use CxxUtils CxxUtils-* Control use AthenaBaseComps AthenaBaseComps-* Control +use AthenaKernel AthenaKernel-* Control use CLIDSvc CLIDSvc-* Control -use DataModel DataModel-* Control use DataModelRoot DataModelRoot-* Control use SGTools SGTools-* Control +use AthContainers AthContainers-* Control +use AthLinks AthLinks-* Control use PersistentDataModel PersistentDataModel-* Database use AthenaPoolUtilities AthenaPoolUtilities-* Database/AthenaPOOL use PoolSvc PoolSvc-* Database/AthenaPOOL @@ -27,9 +32,26 @@ apply_pattern declare_python_modules files="*.py" set POOL_AUTH_PATH "${AthenaPoolCnvSvc_root}/share" private -use AthenaKernel AthenaKernel-* Control use StoreGate StoreGate-* Control private apply_tag ROOTSTLDictLibs + +private + +# Dictionary entries used by the unit tests. +# Use no_rootmap so that they're not visible to other packages. +use AtlasReflex AtlasReflex-* External -no_auto_imports +apply_tag no_rootmap +apply_pattern lcgdict dict=AthenaPoolCnvSvcTest selectionfile=selection_test.xml\ + headerfiles="../test/AthenaPoolCnvSvcTestDict.h" + +use TestTools TestTools-* AtlasTest +apply_pattern UnitTest_run unit_test=exceptions +apply_pattern UnitTest_run unit_test=TPCnvElt +apply_pattern UnitTest_run unit_test=TPCnvList +apply_pattern UnitTest_run unit_test=T_AthenaPoolViewVectorCnv +apply_pattern UnitTest_run unit_test=T_AthenaPoolxAODCnv +apply_pattern UnitTest_run unit_test=T_AthenaPoolAuxContainerCnv +apply_pattern UnitTest_run unit_test=T_AthenaPoolTPCnvCnv diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/doc/MainPage.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/doc/MainPage.h old mode 100755 new mode 100644 diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/python/AthenaPool.py b/Database/AthenaPOOL/AthenaPoolCnvSvc/python/AthenaPool.py old mode 100755 new mode 100644 diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/python/ReadAthenaPool.py b/Database/AthenaPOOL/AthenaPoolCnvSvc/python/ReadAthenaPool.py old mode 100755 new mode 100644 index 20436037b4d3082e3f21491f362d50c56b3c3cc9..1f7f00c951fc5c9344d8b807cf03466702ac0c99 --- a/Database/AthenaPOOL/AthenaPoolCnvSvc/python/ReadAthenaPool.py +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/python/ReadAthenaPool.py @@ -59,6 +59,21 @@ def _configureReadAthenaPool(): theApp.EvtSel = _n del _n + # For Analysis release use DataHeader satellite and lower heartbeat + import os + if "AthAnalysisBase" in os.environ.get('CMTEXTRATAGS',""): + svcMgr.EventSelector.CollectionTree = "POOLContainer/basic" + # From Will Buttinger to suppress the event loop heartbeat as it is somewhat I/O hungry for + # no real gain in analysis scenarii + if not hasattr(svcMgr, theApp.EventLoop): + svcMgr += getattr(CfgMgr, theApp.EventLoop)() + evtloop = getattr(svcMgr, theApp.EventLoop) + try: + evtloop.EventPrintoutInterval = 10000 + except Exception, err: + msg.info('failed suppressing event loop heartbeat. performances might be sub-par... sorry.') + pass + # Add in AthenaPoolAddressProviderSvc if not hasattr (svcMgr, 'AthenaPoolAddressProviderSvc'): svcMgr += CfgMgr.AthenaPoolAddressProviderSvc ("AthenaPoolAddressProviderSvc") diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/python/WriteAthenaPool.py b/Database/AthenaPOOL/AthenaPoolCnvSvc/python/WriteAthenaPool.py old mode 100755 new mode 100644 diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/python/__init__.py b/Database/AthenaPOOL/AthenaPoolCnvSvc/python/__init__.py old mode 100755 new mode 100644 diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/share/AthenaPoolCnvSvc_jobOptions.py b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/AthenaPoolCnvSvc_jobOptions.py old mode 100755 new mode 100644 diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/share/AthenaPool_jobOptions.py b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/AthenaPool_jobOptions.py old mode 100755 new mode 100644 diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/share/ReadAthenaPool_jobOptions.py b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/ReadAthenaPool_jobOptions.py old mode 100755 new mode 100644 diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/share/TPCnvElt_test.ref b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/TPCnvElt_test.ref new file mode 100644 index 0000000000000000000000000000000000000000..bae42c55f9e0a4e297a4d197d8aadfe147ef269b --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/TPCnvElt_test.ref @@ -0,0 +1,2 @@ +test1 +test2 diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/share/TPCnvList_test.ref b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/TPCnvList_test.ref new file mode 100644 index 0000000000000000000000000000000000000000..a5bce3fd2565d8f458555a0c6f42d0504a848bd5 --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/TPCnvList_test.ref @@ -0,0 +1 @@ +test1 diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolAuxContainerCnv_test.ref b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolAuxContainerCnv_test.ref new file mode 100644 index 0000000000000000000000000000000000000000..3185ff4fc675710846a1a8a6d630df40762f1fa0 --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolAuxContainerCnv_test.ref @@ -0,0 +1,20 @@ + + +Initializing Gaudi ApplicationMgr using job opts ../share/test.txt +JobOptionsSvc INFO Job options successfully read in from ../share/test.txt +ApplicationMgr SUCCESS +==================================================================================================================================== + Welcome to ApplicationMgr (GaudiCoreSvc v999r999) + running on karma on Thu Jan 21 14:08:47 2016 +==================================================================================================================================== +ApplicationMgr INFO Application Manager Configured successfully +EventLoopMgr WARNING Unable to locate service "EventSelector" +EventLoopMgr WARNING No events will be processed from external input. +HistogramPersis...WARNING Histograms saving not required. +ApplicationMgr INFO Application Manager Initialized successfully +ApplicationMgr Ready +test1 +test2 +AthenaPoolConve... ERROR Failed to convert persistent object to transient: AthenaPoolCnvSvc::::ExcUnsupported version: Unsupported persistent version of AthenaPoolCnvSvcTest::YAuxCont_v2 found; guid: 8ACD1C53-D3C7-4FE5-9BC0-E388701DB8FA +AthenaPoolConve... ERROR createObj PoolToDataObject() failed, Token = [DB=00000000-0000-0000-0000-000000000000][CNT=][CLID=8ACD1C53-D3C7-4FE5-9BC0-E388701DB8FA][TECH=00000000][OID=FFFFFFFFFFFFFFFF-FFFFFFFFFFFFFFFF] +AthenaPoolConve... ERROR createObj failed to get DataObject, Token = [DB=00000000-0000-0000-0000-000000000000][CNT=][CLID=8ACD1C53-D3C7-4FE5-9BC0-E388701DB8FA][TECH=00000000][OID=FFFFFFFFFFFFFFFF-FFFFFFFFFFFFFFFF] diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolTPCnvCnv_test.ref b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolTPCnvCnv_test.ref new file mode 100644 index 0000000000000000000000000000000000000000..cabfcb0f73c7e1a5ea11db916dc3a57ec5d35c2a --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolTPCnvCnv_test.ref @@ -0,0 +1,20 @@ + + +Initializing Gaudi ApplicationMgr using job opts ../share/test.txt +JobOptionsSvc INFO Job options successfully read in from ../share/test.txt +ApplicationMgr SUCCESS +==================================================================================================================================== + Welcome to ApplicationMgr (GaudiCoreSvc v999r999) + running on karma on Fri Jan 22 14:26:54 2016 +==================================================================================================================================== +ApplicationMgr INFO Application Manager Configured successfully +EventLoopMgr WARNING Unable to locate service "EventSelector" +EventLoopMgr WARNING No events will be processed from external input. +HistogramPersis...WARNING Histograms saving not required. +ApplicationMgr INFO Application Manager Initialized successfully +ApplicationMgr Ready +test1 +test2 +AthenaPoolConve... ERROR Failed to convert persistent object to transient: AthenaPoolCnvSvc::::ExcUnsupported version: Unsupported persistent version of DataVector<AthenaPoolCnvSvcTest::X,DataModel_detail::NoBase> found; guid: 8ACD1C53-D3C7-4FE5-9BC0-E388701DB8FA +AthenaPoolConve... ERROR createObj PoolToDataObject() failed, Token = [DB=00000000-0000-0000-0000-000000000000][CNT=][CLID=8ACD1C53-D3C7-4FE5-9BC0-E388701DB8FA][TECH=00000000][OID=FFFFFFFFFFFFFFFF-FFFFFFFFFFFFFFFF] +AthenaPoolConve... ERROR createObj failed to get DataObject, Token = [DB=00000000-0000-0000-0000-000000000000][CNT=][CLID=8ACD1C53-D3C7-4FE5-9BC0-E388701DB8FA][TECH=00000000][OID=FFFFFFFFFFFFFFFF-FFFFFFFFFFFFFFFF] diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolViewVectorCnv_test.ref b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolViewVectorCnv_test.ref new file mode 100644 index 0000000000000000000000000000000000000000..f4f98f093a943c8060a266507d597302ce5711f0 --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolViewVectorCnv_test.ref @@ -0,0 +1,20 @@ + + +Initializing Gaudi ApplicationMgr using job opts ../share/test.txt +JobOptionsSvc INFO Job options successfully read in from ../share/test.txt +ApplicationMgr SUCCESS +==================================================================================================================================== + Welcome to ApplicationMgr (GaudiCoreSvc v999r999) + running on karma on Wed Jan 20 12:20:45 2016 +==================================================================================================================================== +ApplicationMgr INFO Application Manager Configured successfully +EventLoopMgr WARNING Unable to locate service "EventSelector" +EventLoopMgr WARNING No events will be processed from external input. +HistogramPersis...WARNING Histograms saving not required. +ApplicationMgr INFO Application Manager Initialized successfully +ApplicationMgr Ready +test1 +AthenaPoolConve... ERROR Failed to convert persistent object to transient: AthenaPoolCnvSvc::::ExcUnsupported version: Unsupported persistent version of std::vector<ElementLink<DataVector<AthenaPoolCnvSvcTest::Y_v2,DataModel_detail::NoBase> >,std::allocator<ElementLink<DataVector<AthenaPoolCnvSvcTest::Y_v2,DataModel_detail::NoBase> > > > found; guid: 79E2478D-C17F-45E9-848D-278240C2FED3 +AthenaPoolConve... ERROR createObj PoolToDataObject() failed, Token = [DB=00000000-0000-0000-0000-000000000000][CNT=][CLID=79E2478D-C17F-45E9-848D-278240C2FED3][TECH=00000000][OID=FFFFFFFFFFFFFFFF-FFFFFFFFFFFFFFFF] +AthenaPoolConve... ERROR createObj failed to get DataObject, Token = [DB=00000000-0000-0000-0000-000000000000][CNT=][CLID=79E2478D-C17F-45E9-848D-278240C2FED3][TECH=00000000][OID=FFFFFFFFFFFFFFFF-FFFFFFFFFFFFFFFF] +test2 diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolxAODCnv_test.ref b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolxAODCnv_test.ref new file mode 100644 index 0000000000000000000000000000000000000000..eb58bc43dba5ed9785f121434db5dbb622e240f9 --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolxAODCnv_test.ref @@ -0,0 +1,19 @@ + + +Initializing Gaudi ApplicationMgr using job opts ../share/test.txt +JobOptionsSvc INFO Job options successfully read in from ../share/test.txt +ApplicationMgr SUCCESS +==================================================================================================================================== + Welcome to ApplicationMgr (GaudiCoreSvc v999r999) + running on karma on Wed Jan 20 17:09:50 2016 +==================================================================================================================================== +ApplicationMgr INFO Application Manager Configured successfully +EventLoopMgr WARNING Unable to locate service "EventSelector" +EventLoopMgr WARNING No events will be processed from external input. +HistogramPersis...WARNING Histograms saving not required. +ApplicationMgr INFO Application Manager Initialized successfully +ApplicationMgr Ready +test1 +AthenaPoolConve... ERROR Failed to convert persistent object to transient: AthenaPoolCnvSvc::::ExcUnsupported version: Unsupported persistent version of DataVector<AthenaPoolCnvSvcTest::Y_v2,DataModel_detail::NoBase> found; guid: 8ACD1C53-D3C7-4FE5-9BC0-E388701DB8FA +AthenaPoolConve... ERROR createObj PoolToDataObject() failed, Token = [DB=00000000-0000-0000-0000-000000000000][CNT=][CLID=8ACD1C53-D3C7-4FE5-9BC0-E388701DB8FA][TECH=00000000][OID=FFFFFFFFFFFFFFFF-FFFFFFFFFFFFFFFF] +AthenaPoolConve... ERROR createObj failed to get DataObject, Token = [DB=00000000-0000-0000-0000-000000000000][CNT=][CLID=8ACD1C53-D3C7-4FE5-9BC0-E388701DB8FA][TECH=00000000][OID=FFFFFFFFFFFFFFFF-FFFFFFFFFFFFFFFF] diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/share/WriteAthenaPool_jobOptions.py b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/WriteAthenaPool_jobOptions.py old mode 100755 new mode 100644 diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/share/exceptions_test.ref b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/exceptions_test.ref new file mode 100644 index 0000000000000000000000000000000000000000..8809968d6245e8b2dcc9f58caf74ab4b8a5687bb --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/exceptions_test.ref @@ -0,0 +1,3 @@ +test1 +AthenaPoolCnvSvc::::ExcNoDictForClass: Can't find dictionary information for class: int +AthenaPoolCnvSvc::::ExcUnsupported version: Unsupported persistent version of int found; guid: 336F636C-D414-4261-8286-37429F353F0A diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/share/test.txt b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/test.txt new file mode 100644 index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/test.txt @@ -0,0 +1 @@ + diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaAttributeListCnv.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaAttributeListCnv.cxx old mode 100755 new mode 100644 diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaAttributeListCnv.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaAttributeListCnv.h old mode 100755 new mode 100644 diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolCnvSvc.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolCnvSvc.cxx old mode 100755 new mode 100644 index 7a832a36cb996db8ef8320312b76fbfc407ea62b..459580fa1c396fc3d77d0f1ffc11f1b7cb55c2dd --- a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolCnvSvc.cxx +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolCnvSvc.cxx @@ -14,11 +14,13 @@ #include "GaudiKernel/IOpaqueAddress.h" #include "GaudiKernel/IJobOptionsSvc.h" #include "GaudiKernel/IIncidentSvc.h" -#include "GaudiKernel/Tokenizer.h" +#include "GaudiKernel/AttribStringParser.h" #include "AthenaKernel/IAthenaIPCTool.h" +#include "AthenaKernel/IAthenaSerializeSvc.h" #include "AthenaKernel/IClassIDSvc.h" #include "AthenaKernel/IAthenaOutputStreamTool.h" +#include "PersistentDataModel/Placement.h" #include "PersistentDataModel/Token.h" #include "PersistentDataModel/TokenAddress.h" #include "PoolSvc/IPoolSvc.h" @@ -64,10 +66,26 @@ StatusCode AthenaPoolCnvSvc::initialize() { ATH_MSG_FATAL("Cannot get ClassIDSvc."); return(StatusCode::FAILURE); } - // Retrieve DataStreamingTool (if configured) - if (!m_dataStreamingTool.empty() && !m_dataStreamingTool.retrieve().isSuccess()) { - ATH_MSG_FATAL("Cannot get AthenaIPCTool"); - return(StatusCode::FAILURE); + // Retrieve InputStreamingTool (if configured) + if (!m_inputStreamingTool.empty()) { + if (!m_inputStreamingTool.retrieve().isSuccess()) { + ATH_MSG_FATAL("Cannot get Input AthenaIPCTool"); + return(StatusCode::FAILURE); + } + } + // Retrieve OutputStreamingTool (if configured) + if (!m_outputStreamingTool.empty()) { + if (!m_outputStreamingTool.retrieve().isSuccess()) { + ATH_MSG_FATAL("Cannot get Output AthenaIPCTool"); + return(StatusCode::FAILURE); + } + } + if (!m_inputStreamingTool.empty() || !m_outputStreamingTool.empty()) { + // Retrieve AthenaSerializeSvc + if (!m_serializeSvc.retrieve().isSuccess()) { + ATH_MSG_FATAL("Cannot get AthenaSerializeSvc."); + return(StatusCode::FAILURE); + } } // Extracting MaxFileSizes for global default and map by Database name. for (std::vector<std::string>::const_iterator iter = m_maxFileSizes.value().begin(), @@ -113,9 +131,23 @@ StatusCode AthenaPoolCnvSvc::initialize() { } //______________________________________________________________________________ StatusCode AthenaPoolCnvSvc::finalize() { - // Retrieve DataStreamingTool (if configured) - if (!m_dataStreamingTool.empty() && !m_dataStreamingTool.release().isSuccess()) { - ATH_MSG_WARNING("Cannot release AthenaIPCTool."); + // Release AthenaSerializeSvc + if (!m_serializeSvc.empty()) { + if (!m_serializeSvc.release().isSuccess()) { + ATH_MSG_WARNING("Cannot release AthenaSerializeSvc."); + } + } + // Release OutputStreamingTool (if configured) + if (!m_outputStreamingTool.empty()) { + if (!m_outputStreamingTool.release().isSuccess()) { + ATH_MSG_WARNING("Cannot release Output AthenaIPCTool."); + } + } + // Release InputStreamingTool (if configured) + if (!m_inputStreamingTool.empty()) { + if (!m_inputStreamingTool.release().isSuccess()) { + ATH_MSG_WARNING("Cannot release Input AthenaIPCTool."); + } } // Release ClassIDSvc if (!m_clidSvc.release().isSuccess()) { @@ -147,6 +179,10 @@ StatusCode AthenaPoolCnvSvc::queryInterface(const InterfaceID& riid, void** ppvI } //______________________________________________________________________________ StatusCode AthenaPoolCnvSvc::createObj(IOpaqueAddress* pAddress, DataObject*& refpObject) { +#ifdef ATHENAHIVE + std::lock_guard<CallMutex> lock(m_i_mut); +#endif + assert(pAddress); if (m_useDetailChronoStat.value() && m_doChronoStat) { std::string objName, keyName = "#" + *(pAddress->par() + 1); @@ -175,6 +211,9 @@ StatusCode AthenaPoolCnvSvc::createObj(IOpaqueAddress* pAddress, DataObject*& re } //______________________________________________________________________________ StatusCode AthenaPoolCnvSvc::createRep(DataObject* pObject, IOpaqueAddress*& refpAddress) { +#ifdef ATHENAHIVE + std::lock_guard<CallMutex> lock(m_o_mut); +#endif assert(pObject); if (m_useDetailChronoStat.value() && m_doChronoStat) { std::string objName, keyName = "#" + pObject->registry()->name(); @@ -291,17 +330,14 @@ StatusCode AthenaPoolCnvSvc::connectOutput(const std::string& outputConnectionSp } // Extract the technology - StatusCode status = decodeOutputSpec(m_outputConnectionSpec, m_dbType); - if (!status.isSuccess()) { + if (!decodeOutputSpec(m_outputConnectionSpec, m_dbType).isSuccess()) { ATH_MSG_ERROR("connectOutput FAILED extract file name and technology."); return(StatusCode::FAILURE); } - status = processPoolAttributes(m_domainAttr, m_outputConnectionSpec, IPoolSvc::kOutputStream); - if (!status.isSuccess()) { + if (!processPoolAttributes(m_domainAttr, m_outputConnectionSpec, IPoolSvc::kOutputStream).isSuccess()) { ATH_MSG_DEBUG("connectOutput failed process POOL domain attributes."); } - status = processPoolAttributes(m_databaseAttr, m_outputConnectionSpec, IPoolSvc::kOutputStream); - if (!status.isSuccess()) { + if (!processPoolAttributes(m_databaseAttr, m_outputConnectionSpec, IPoolSvc::kOutputStream).isSuccess()) { ATH_MSG_DEBUG("connectOutput failed process POOL database attributes."); } return(StatusCode::SUCCESS); @@ -312,16 +348,13 @@ StatusCode AthenaPoolCnvSvc::commitOutput(const std::string& /*outputConnectionS if (m_useDetailChronoStat.value()) { m_chronoStatSvc->chronoStart("commitOutput"); } - StatusCode status = processPoolAttributes(m_domainAttr, m_outputConnectionSpec, IPoolSvc::kOutputStream); - if (!status.isSuccess()) { + if (!processPoolAttributes(m_domainAttr, m_outputConnectionSpec, IPoolSvc::kOutputStream).isSuccess()) { ATH_MSG_DEBUG("commitOutput failed process POOL domain attributes."); } - status = processPoolAttributes(m_databaseAttr, m_outputConnectionSpec, IPoolSvc::kOutputStream); - if (!status.isSuccess()) { + if (!processPoolAttributes(m_databaseAttr, m_outputConnectionSpec, IPoolSvc::kOutputStream).isSuccess()) { ATH_MSG_DEBUG("commitOutput failed process POOL database attributes."); } - status = processPoolAttributes(m_containerAttr, m_outputConnectionSpec, IPoolSvc::kOutputStream); - if (!status.isSuccess()) { + if (!processPoolAttributes(m_containerAttr, m_outputConnectionSpec, IPoolSvc::kOutputStream).isSuccess()) { ATH_MSG_DEBUG("commitOutput failed process POOL container attributes."); } static int commitCounter = 1; @@ -429,7 +462,7 @@ IPoolSvc* AthenaPoolCnvSvc::getPoolSvc() { return(&*m_poolSvc); } //______________________________________________________________________________ -const Token* AthenaPoolCnvSvc::registerForWrite(const pool::Placement* placement, +const Token* AthenaPoolCnvSvc::registerForWrite(const Placement* placement, const void* obj, const RootType& classDesc) const { if (m_useDetailChronoStat.value() && m_doChronoStat) { @@ -446,21 +479,37 @@ void AthenaPoolCnvSvc::setObjPtr(void*& obj, const Token* token) const { if (m_useDetailChronoStat.value() && m_doChronoStat) { m_chronoStatSvc->chronoStart("cObjR_" + m_className.back()); } - m_poolSvc->setObjPtr(obj, token, m_contextIds.back()); + if (!m_inputStreamingTool.empty() && m_inputStreamingTool->isClient()) { + ATH_MSG_VERBOSE("Requesting object for: " << token->toString()); + if (!m_inputStreamingTool->lockObject(token->toString().c_str()).isSuccess()) { + ATH_MSG_WARNING("Failed to lock Data for " << token->toString()); + obj = 0; + } else { + void* buffer = 0; + size_t nbytes = 0; + StatusCode sc = m_inputStreamingTool->getObject(&buffer, nbytes); + while (sc.isRecoverable()) { + usleep(100); + sc = m_inputStreamingTool->getObject(&buffer, nbytes); + } + if (!sc.isSuccess()) { + ATH_MSG_WARNING("Failed to get Data for " << token->toString()); + obj = 0; + } else { + obj = m_serializeSvc->deserialize(buffer, nbytes, token->classID()); + } + } + } else if (!m_inputStreamingTool.empty() && m_inputStreamingTool->isServer()) { + // Reading in Server + m_poolSvc->setObjPtr(obj, token); + } else { + m_poolSvc->setObjPtr(obj, token, m_contextIds.back()); + } if (m_useDetailChronoStat.value() && m_doChronoStat) { m_chronoStatSvc->chronoStop("cObjR_" + m_className.back()); } } //______________________________________________________________________________ -bool AthenaPoolCnvSvc::testDictionary(const std::string& className) const { -#if ROOT_VERSION_CODE < ROOT_VERSION(5,99,0) - return(m_poolSvc->testDictionary(className)); -#else - ATH_MSG_DEBUG("Skipping Dictionary check for: " << className); - return(true); -#endif -} -//______________________________________________________________________________ bool AthenaPoolCnvSvc::useDetailChronoStat() const { return(m_useDetailChronoStat.value()); } @@ -474,7 +523,36 @@ StatusCode AthenaPoolCnvSvc::createAddress(long svcType, ATH_MSG_ERROR("createAddress: svcType != POOL_StorageType " << svcType << " " << POOL_StorageType); return(StatusCode::FAILURE); } - Token* token = m_poolSvc->getToken(par[0], par[1], ip[0]); + Token* token = 0; + if (!m_inputStreamingTool.empty() && m_inputStreamingTool->isClient()) { + Token addressToken; + addressToken.setDb(par[0].substr(4)); + addressToken.setCont(par[1]); + addressToken.setOid(Token::OID_t(ip[0], ip[1])); + if (!m_inputStreamingTool->lockObject(addressToken.toString().c_str()).isSuccess()) { + ATH_MSG_WARNING("Failed to lock Address Token: " << addressToken.toString()); + return(StatusCode::FAILURE); + } + void* buffer = 0; + size_t nbytes = 0; + StatusCode sc = m_inputStreamingTool->getObject(&buffer, nbytes); + while (sc.isRecoverable()) { + usleep(100); + sc = m_inputStreamingTool->getObject(&buffer, nbytes); + } + if (!sc.isSuccess()) { + ATH_MSG_WARNING("Failed to get Address Token: " << addressToken.toString()); + return(StatusCode::FAILURE); + } else { + token = new Token(); + token->fromString((char*)buffer); + if (token->classID() == Guid::null()) { + delete token; token = 0; + } + } + } else { + token = m_poolSvc->getToken(par[0], par[1], ip[0]); + } if (token == 0) { return(StatusCode::RECOVERABLE); } @@ -521,21 +599,106 @@ StatusCode AthenaPoolCnvSvc::cleanUp() { StatusCode AthenaPoolCnvSvc::setInputAttributes(const std::string& fileName) { // Set attributes for input file m_lastFileName = fileName; // Save file name for printing attributes per event - StatusCode status = processPoolAttributes(m_inputAttr, m_lastFileName, IPoolSvc::kInputStream, false, true, false); - if (!status.isSuccess()) { + if (!processPoolAttributes(m_inputAttr, m_lastFileName, IPoolSvc::kInputStream, false, true, false).isSuccess()) { ATH_MSG_DEBUG("setInputAttribute failed setting POOL database/container attributes."); } - status = processPoolAttributes(m_inputAttr, m_lastFileName, IPoolSvc::kInputStream, true, false); - if (!status.isSuccess()) { + if (!processPoolAttributes(m_inputAttr, m_lastFileName, IPoolSvc::kInputStream, true, false).isSuccess()) { ATH_MSG_DEBUG("setInputAttribute failed getting POOL database/container attributes."); } return(StatusCode::SUCCESS); } //______________________________________________________________________________ +StatusCode AthenaPoolCnvSvc::makeServer(int num) { + if (!m_outputStreamingTool.empty() && !m_outputStreamingTool->isServer()) { + ATH_MSG_DEBUG("makeServer: " << m_outputStreamingTool << " = " << num); + if (m_outputStreamingTool->makeServer(num).isFailure()) { + ATH_MSG_ERROR("makeServer: " << m_outputStreamingTool << " failed"); + return(StatusCode::FAILURE); + } + } + if (m_inputStreamingTool.empty()) { + return(StatusCode::RECOVERABLE); + } + m_doChronoStat = false; + ATH_MSG_DEBUG("makeServer: " << m_inputStreamingTool << " = " << num); + return(m_inputStreamingTool->makeServer(num)); +} +//________________________________________________________________________________ +StatusCode AthenaPoolCnvSvc::makeClient(int num) { + m_doChronoStat = false; + if (!m_outputStreamingTool.empty() && !m_outputStreamingTool->isClient() && num > 0) { + ATH_MSG_DEBUG("makeClient: " << m_outputStreamingTool << " = " << num); + if (m_outputStreamingTool->makeClient(num).isFailure()) { + ATH_MSG_ERROR("makeClient: " << m_outputStreamingTool << " failed"); + return(StatusCode::FAILURE); + } + } + if (m_inputStreamingTool.empty()) { + return(StatusCode::RECOVERABLE); + } + ATH_MSG_DEBUG("makeClient: " << m_inputStreamingTool << " = " << num); + return(m_inputStreamingTool->makeClient(num)); +} +//________________________________________________________________________________ +StatusCode AthenaPoolCnvSvc::readData() const { + if (m_inputStreamingTool.empty()) { + return(StatusCode::FAILURE); + } + char* tokenStr = 0; + int num = -1; + StatusCode sc = m_inputStreamingTool->clearObject(&tokenStr, num); + if (sc.isSuccess() && tokenStr != 0 && strlen(tokenStr) > 0 && num > 0) { + ATH_MSG_DEBUG("readData: " << tokenStr << ", for client: " << num); + } else { + delete tokenStr; tokenStr = 0; + return(sc); + } + // Read object instance via POOL/ROOT + void* instance = 0; + Token token; + token.fromString(tokenStr); + delete tokenStr; tokenStr = 0; + if (token.classID() != Guid::null()) { + this->setObjPtr(instance, &token); + // Serialize object via ROOT + void* buffer = 0; + size_t nbytes = 0; + buffer = m_serializeSvc->serialize(instance, token.classID(), nbytes); + // Share object + sc = m_inputStreamingTool->putObject(buffer, nbytes, num); + delete [] (char*)buffer; buffer = 0; + if (!sc.isSuccess()) { + ATH_MSG_ERROR("Could not share object for: " << token.toString()); + return(StatusCode::FAILURE); + } + } else if (token.dbID() != Guid::null()) { + std::string returnToken; + const Token* metadataToken = m_poolSvc->getToken("FID:" + token.dbID().toString(), token.contID(), token.oid().first); + if (metadataToken != 0) { + returnToken = metadataToken->toString(); + } else { + returnToken = token.toString(); + } + delete metadataToken; metadataToken = 0; + // Share token + sc = m_inputStreamingTool->putObject(returnToken.c_str(), returnToken.size() + 1, num); + while (sc.isRecoverable()) { + usleep(100); + sc = m_inputStreamingTool->putObject(returnToken.c_str(), returnToken.size() + 1, num); + } + if (!sc.isSuccess()) { + ATH_MSG_ERROR("Could not share token for: " << token.toString()); + return(StatusCode::FAILURE); + } + } else { + return(StatusCode::RECOVERABLE); + } + return(StatusCode::SUCCESS); +} +//______________________________________________________________________________ void AthenaPoolCnvSvc::handle(const Incident& incident) { if (incident.type() == "EndEvent") { - StatusCode status = processPoolAttributes(m_inputAttrPerEvent, m_lastFileName, IPoolSvc::kInputStream); - if (!status.isSuccess()) { + if (!processPoolAttributes(m_inputAttrPerEvent, m_lastFileName, IPoolSvc::kInputStream).isSuccess()) { ATH_MSG_DEBUG("handle EndEvent failed process POOL database attributes."); } } @@ -552,7 +715,9 @@ AthenaPoolCnvSvc::AthenaPoolCnvSvc(const std::string& name, ISvcLocator* pSvcLoc m_poolSvc("PoolSvc", name), m_chronoStatSvc("ChronoStatSvc", name), m_clidSvc("ClassIDSvc", name), - m_dataStreamingTool("", this), + m_serializeSvc("AthenaRootSerializeSvc", name), + m_inputStreamingTool("", this), + m_outputStreamingTool("", this), m_containerPrefix(), m_containerNameHint(), m_branchNameHint(), @@ -568,6 +733,8 @@ AthenaPoolCnvSvc::AthenaPoolCnvSvc(const std::string& name, ISvcLocator* pSvcLoc declareProperty("MaxFileSizes", m_maxFileSizes); declareProperty("CommitInterval", m_commitInterval = 0); declareProperty("SkipFirstChronoCommit", m_skipFirstChronoCommit = false); + declareProperty("InputStreamingTool", m_inputStreamingTool); + declareProperty("OutputStreamingTool", m_outputStreamingTool); } //______________________________________________________________________________ AthenaPoolCnvSvc::~AthenaPoolCnvSvc() { @@ -592,22 +759,19 @@ void AthenaPoolCnvSvc::extractPoolAttributes(const StringArrayProperty& property std::vector<std::vector<std::string> >* contAttr, std::vector<std::vector<std::string> >* dbAttr, std::vector<std::vector<std::string> >* domAttr) const { - Tokenizer tok; std::vector<std::string> opt; std::string attributeName, containerName, databaseName, valueString; for (std::vector<std::string>::const_iterator iter = property.value().begin(), last = property.value().end(); iter != last; iter++) { - tok.analyse(*iter, " ", "", "", "=", "'", "'"); opt.clear(); attributeName.clear(); containerName.clear(); databaseName.clear(); valueString.clear(); - for (Tokenizer::Items::iterator i = tok.items().begin(), iEnd = tok.items().end(); i != iEnd; i++) { - const size_t tagBegin = (*i).tag().find_first_not_of(" ;"); - const size_t tagEnd = (*i).tag().find_last_not_of(" ;"); - const std::string tag = (*i).tag().substr(tagBegin, tagEnd - tagBegin + 1); - const std::string val = (*i).value(); + using Gaudi::Utils::AttribStringParser; + for (const AttribStringParser::Attrib& attrib : AttribStringParser (*iter)) { + const std::string tag = attrib.tag; + const std::string val = attrib.value; if (tag == "DatabaseName") { databaseName = val; } else if (tag == "ContainerName") { @@ -654,6 +818,7 @@ StatusCode AthenaPoolCnvSvc::processPoolAttributes(std::vector<std::vector<std:: bool doSet, bool doClear) const { bool retError = false; + if (!m_inputStreamingTool.empty() && m_inputStreamingTool->isClient()) doGet = false; for (std::vector<std::vector<std::string> >::iterator iter = attr.begin(), last = attr.end(); iter != last; ++iter) { if (iter->size() == 2) { @@ -661,15 +826,13 @@ StatusCode AthenaPoolCnvSvc::processPoolAttributes(std::vector<std::vector<std:: std::string data = (*iter)[1]; if (data == "int" || data == "DbLonglong" || data == "double" || data == "string") { if (doGet) { - StatusCode status = m_poolSvc->getAttribute(opt, data, m_dbType.type(), contextId); - if (!status.isSuccess()) { + if (!m_poolSvc->getAttribute(opt, data, m_dbType.type(), contextId).isSuccess()) { ATH_MSG_DEBUG("getAttribute failed for domain attr " << opt); retError = true; } } } else if (doSet) { - StatusCode status = m_poolSvc->setAttribute(opt, data, m_dbType.type(), contextId); - if (status.isSuccess()) { + if (m_poolSvc->setAttribute(opt, data, m_dbType.type(), contextId).isSuccess()) { ATH_MSG_DEBUG("setAttribute " << opt << " to " << data); if (doClear) { iter->clear(); @@ -689,15 +852,13 @@ StatusCode AthenaPoolCnvSvc::processPoolAttributes(std::vector<std::vector<std:: && file.find("," + fileName + ",") == std::string::npos))) { if (data == "int" || data == "DbLonglong" || data == "double" || data == "string") { if (doGet) { - StatusCode status = m_poolSvc->getAttribute(opt, data, m_dbType.type(), fileName, cont, contextId); - if (!status.isSuccess()) { + if (!m_poolSvc->getAttribute(opt, data, m_dbType.type(), fileName, cont, contextId).isSuccess()) { ATH_MSG_DEBUG("getAttribute failed for database/container attr " << opt); retError = true; } } } else if (doSet) { - StatusCode status = m_poolSvc->setAttribute(opt, data, m_dbType.type(), fileName, cont, contextId); - if (status.isSuccess()) { + if (m_poolSvc->setAttribute(opt, data, m_dbType.type(), fileName, cont, contextId).isSuccess()) { ATH_MSG_DEBUG("setAttribute " << opt << " to " << data << " for db: " << fileName << " and cont: " << cont); if (doClear) { if (file.substr(0, 1) == "*") { diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolCnvSvc.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolCnvSvc.h old mode 100755 new mode 100644 index 5b18c00f40e7065b01b19407fa9df33ec5240ac6..97b0c566581dd12e011aa9affb2c619760fe9ba5 --- a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolCnvSvc.h +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolCnvSvc.h @@ -20,9 +20,11 @@ #include <vector> #include <map> +#include <mutex> // Forward declarations class IAthenaIPCTool; +class IAthenaSerializeSvc; class IChronoStatSvc; class IClassIDSvc; class IPoolSvc; @@ -95,7 +97,7 @@ public: /// @param placement [IN] pointer to the placement hint /// @param obj [IN] pointer to the Data Object to be written to Pool /// @param classDesc [IN] pointer to the Seal class description for the Data Object. - const Token* registerForWrite(const pool::Placement* placement, + const Token* registerForWrite(const Placement* placement, const void* obj, const RootType& classDesc) const; @@ -103,10 +105,6 @@ public: /// @param token [IN] string token of the Data Object for which a Pool Ref is filled. void setObjPtr(void*& obj, const Token* token) const; - /// Utility to test whether the dictionary knows about a given class. - /// @param className [IN] string containing the name of the class to be checked. - bool testDictionary(const std::string& className) const; - /// @return a boolean for using detailed time and size statistics. bool useDetailChronoStat() const; @@ -147,6 +145,15 @@ public: /// @param fileName [IN] name of the input file StatusCode setInputAttributes(const std::string& fileName); + /// Make this a server. + virtual StatusCode makeServer(int num); + + /// Make this a client. + virtual StatusCode makeClient(int num); + + /// Read the next data object + virtual StatusCode readData() const; + /// Implementation of IIncidentListener: Handle for EndEvent incidence void handle(const Incident& incident); @@ -185,7 +192,9 @@ private: // data ServiceHandle<IPoolSvc> m_poolSvc; ServiceHandle<IChronoStatSvc> m_chronoStatSvc; ServiceHandle<IClassIDSvc> m_clidSvc; - ToolHandle<IAthenaIPCTool> m_dataStreamingTool; + ServiceHandle<IAthenaSerializeSvc> m_serializeSvc; + ToolHandle<IAthenaIPCTool> m_inputStreamingTool; + ToolHandle<IAthenaIPCTool> m_outputStreamingTool; private: // properties /// UseDetailChronoStat, enable detailed output for time and size statistics for AthenaPOOL: @@ -231,6 +240,12 @@ private: // properties /// pool connection context std::vector<unsigned long> m_contextIds; + +#ifdef ATHENAHIVE + typedef std::recursive_mutex CallMutex; + mutable CallMutex m_i_mut; + mutable CallMutex m_o_mut; +#endif }; #endif diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolConverter.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolConverter.cxx old mode 100755 new mode 100644 index ea9850e417534a124a148f215b58bca731344366..68b75513f4607cdd9247a20b4c7242dffeee521b --- a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolConverter.cxx +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolConverter.cxx @@ -12,11 +12,11 @@ #include "SGTools/DataProxy.h" -#include "PersistencySvc/Placement.h" #include "PersistentDataModel/Guid.h" namespace pool { typedef ::Guid Guid; } +#include "PersistentDataModel/Placement.h" #include "PersistentDataModel/Token.h" #include "PersistentDataModel/TokenAddress.h" #include "StorageSvc/DbType.h" @@ -24,6 +24,8 @@ namespace pool { //__________________________________________________________________________ AthenaPoolConverter::~AthenaPoolConverter() { delete m_placement; m_placement = 0; + delete m_i_poolToken; m_i_poolToken = 0; + delete m_o_poolToken; m_o_poolToken = 0; } //__________________________________________________________________________ StatusCode AthenaPoolConverter::initialize() { @@ -54,44 +56,40 @@ long AthenaPoolConverter::repSvcType() const { StatusCode AthenaPoolConverter::createObj(IOpaqueAddress* pAddr, DataObject*& pObj) { TokenAddress* tokAddr = dynamic_cast<TokenAddress*>(pAddr); if (tokAddr == 0 || tokAddr->getToken() == 0) { - if (m_poolToken == 0) m_poolToken = new Token; - const_cast<Token*>(m_poolToken)->fromString(*(pAddr->par())); + if (m_i_poolToken == 0) m_i_poolToken = new Token; + const_cast<Token*>(m_i_poolToken)->fromString(*(pAddr->par())); } else { - m_poolToken = tokAddr->getToken(); - m_token.clear(); + m_i_poolToken = tokAddr->getToken(); } - m_dataObject = 0; try { - if (!PoolToDataObject(pObj, "").isSuccess()) { - ATH_MSG_ERROR("createObj PoolToDataObject() failed, Token = " << (m_poolToken ? m_poolToken->toString() : m_token)); - return(StatusCode::FAILURE); + if (!PoolToDataObject(pObj, m_i_poolToken).isSuccess()) { + ATH_MSG_ERROR("createObj PoolToDataObject() failed, Token = " << (m_i_poolToken ? m_i_poolToken->toString() : "NULL")); + pObj = 0; } } catch (std::exception& e) { ATH_MSG_ERROR("createObj - caught exception: " << e.what()); - return(StatusCode::FAILURE); + pObj = 0; } - m_dataObject = pObj; - if (m_dataObject == 0) { - ATH_MSG_ERROR("createObj failed to get DataObject, Token = " << (m_poolToken ? m_poolToken->toString() : m_token)); - return(StatusCode::FAILURE); + if (pObj == 0) { + ATH_MSG_ERROR("createObj failed to get DataObject, Token = " << (m_i_poolToken ? m_i_poolToken->toString() : "NULL")); } if (tokAddr == 0 || tokAddr->getToken() == 0) { - delete m_poolToken; m_poolToken = 0; + delete m_i_poolToken; m_i_poolToken = 0; } else { - m_poolToken = 0; + m_i_poolToken = 0; + } + if (pObj == 0) { + return(StatusCode::FAILURE); } - m_token.clear(); return(StatusCode::SUCCESS); } //__________________________________________________________________________ StatusCode AthenaPoolConverter::createRep(DataObject* pObj, IOpaqueAddress*& pAddr) { // Create a Pool object for DataObject - m_dataObject = pObj; - m_poolToken = 0; - m_token.clear(); + m_o_poolToken = 0; try { - if (!DataObjectToPool(pObj, m_dataObject->registry()->name()).isSuccess()) { - ATH_MSG_ERROR("CreateRep failed, key = " << m_dataObject->registry()->name()); + if (!DataObjectToPool(pObj, pObj->registry()->name()).isSuccess()) { + ATH_MSG_ERROR("CreateRep failed, key = " << pObj->registry()->name()); return(StatusCode::FAILURE); } } catch (std::exception& e) { @@ -99,22 +97,20 @@ StatusCode AthenaPoolConverter::createRep(DataObject* pObj, IOpaqueAddress*& pAd return(StatusCode::FAILURE); } // Null/empty token means ERROR - if ((m_poolToken == 0 || m_poolToken->classID() == Guid::null()) && m_token.empty()) { - ATH_MSG_ERROR("CreateRep failed to get Token, key = " << m_dataObject->registry()->name()); + if ((m_o_poolToken == 0 || m_o_poolToken->classID() == Guid::null())) { + ATH_MSG_ERROR("CreateRep failed to get Token, key = " << pObj->registry()->name()); return(StatusCode::FAILURE); } const SG::DataProxy* proxy = dynamic_cast<SG::DataProxy*>(pObj->registry()); if (proxy == 0) { ATH_MSG_ERROR("AthenaPoolConverter CreateRep failed to cast DataProxy, key = " - << m_dataObject->registry()->name()); + << pObj->registry()->name()); return(StatusCode::FAILURE); } const CLID clid = proxy->clID(); // Create a IOpaqueAddress for this object. - pAddr = new TokenAddress(POOL_StorageType, clid, "", "", 0, m_poolToken); - m_poolToken = 0; // Token will be inserted into DataHeader, which takes ownership - m_token.clear(); - m_dataObject = 0; + pAddr = new TokenAddress(POOL_StorageType, clid, "", "", 0, m_o_poolToken); + m_o_poolToken = 0; // Token will be inserted into DataHeader, which takes ownership return(StatusCode::SUCCESS); } //__________________________________________________________________________ @@ -127,20 +123,18 @@ AthenaPoolConverter::AthenaPoolConverter(const CLID& myCLID, ISvcLocator* pSvcLo ::AthMessaging((pSvcLocator != 0 ? msgSvc() : 0), "AthenaPoolConverter"), m_athenaPoolCnvSvc("AthenaPoolCnvSvc", "AthenaPoolConverter"), m_placement(0), - m_dictionaryOkRead(false), - m_dictionaryOkWrite(false), m_placementHints(), m_className(), m_classDescs(), - m_token(), m_dataObject(0), - m_poolToken(0) { + m_i_poolToken(0), + m_o_poolToken(0) { } //__________________________________________________________________________ void AthenaPoolConverter::setPlacementWithType(const std::string& tname, const std::string& key) { if (m_placement == 0) { // Create placement for this converter if needed - m_placement = new pool::Placement(); + m_placement = new Placement(); } // Use technology from AthenaPoolCnvSvc if (m_athenaPoolCnvSvc->technologyType().type() == 0) { @@ -150,7 +144,7 @@ void AthenaPoolConverter::setPlacementWithType(const std::string& tname, const s m_placement->setTechnology(m_athenaPoolCnvSvc->technologyType().type()); // Set DB and Container names const std::string fileName = m_athenaPoolCnvSvc->getOutputConnectionSpec(); - m_placement->setDatabase(fileName, pool::DatabaseSpecification::PFN); + m_placement->setFileName(fileName); if (key.empty()) { // No key will result in a separate tree by type for the data object m_placement->setContainerName(m_athenaPoolCnvSvc->getOutputContainer(tname)); } else if (m_placementHints.find(tname + key) != m_placementHints.end()) { // PlacementHint already generated? @@ -163,16 +157,12 @@ void AthenaPoolConverter::setPlacementWithType(const std::string& tname, const s } } //__________________________________________________________________________ -DataObject* AthenaPoolConverter::getDataObject() const { +const DataObject* AthenaPoolConverter::getDataObject() const { return(m_dataObject); } //__________________________________________________________________________ -void AthenaPoolConverter::setDataObject(DataObject* pObj) { - m_dataObject = pObj; -} -//__________________________________________________________________________ bool AthenaPoolConverter::compareClassGuid(const Guid &guid) const { - return(m_poolToken ? (guid == m_poolToken->classID()) : false); + return(m_i_poolToken ? (guid == m_i_poolToken->classID()) : false); } //__________________________________________________________________________ StatusCode AthenaPoolConverter::cleanUp() { diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolTopLevelTPCnvBase.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolTopLevelTPCnvBase.cxx old mode 100755 new mode 100644 diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaRootSerializeSvc.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaRootSerializeSvc.cxx new file mode 100644 index 0000000000000000000000000000000000000000..c63de7058896f05f9106c09378ff068a90e19a90 --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaRootSerializeSvc.cxx @@ -0,0 +1,79 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/* file contains the implementation for the AthenaRootSerializeSvc class. + * @author Peter van Gemmeren <gemmeren@anl.gov> + **/ + +#include "AthenaRootSerializeSvc.h" +#include "DataModelRoot/RootType.h" + +#include "StorageSvc/DbReflex.h" +#include "TBufferFile.h" + +//___________________________________________________________________________ +AthenaRootSerializeSvc::AthenaRootSerializeSvc(const std::string& name, + ISvcLocator* pSvcLocator) : AthService(name, pSvcLocator) { +} + +//___________________________________________________________________________ +AthenaRootSerializeSvc::~AthenaRootSerializeSvc() { +} + +//___________________________________________________________________________ +StatusCode AthenaRootSerializeSvc::initialize() { + ATH_MSG_INFO("Initializing " << name() << " - package version " << PACKAGE_VERSION); + if (!::AthService::initialize().isSuccess()) { + ATH_MSG_FATAL("Cannot initialize AthService base class."); + return(StatusCode::FAILURE); + } + return(StatusCode::SUCCESS); +} + +//___________________________________________________________________________ +StatusCode AthenaRootSerializeSvc::finalize() { + ATH_MSG_INFO("in finalize()"); + return(::AthService::finalize()); +} + +//___________________________________________________________________________ +StatusCode AthenaRootSerializeSvc::queryInterface(const InterfaceID& riid, void** ppvInterface) { + if ( IAthenaSerializeSvc::interfaceID().versionMatch(riid) ) { + *ppvInterface = (IAthenaSerializeSvc*)this; + } else { + // Interface is not directly available: try out a base class + return(AthService::queryInterface(riid, ppvInterface)); + } + addRef(); + return(StatusCode::SUCCESS); +} + +//___________________________________________________________________________ +void* AthenaRootSerializeSvc::serialize(const void* /*object*/, const std::string& /*name*/, size_t& /*nbytes*/) { + return(0); +} + +//___________________________________________________________________________ +void* AthenaRootSerializeSvc::serialize(const void* object, const Guid& id, size_t& nbytes) { + RootType cltype(pool::DbReflex::forGuid(id)); + TBufferFile writeBuffer(TBuffer::kWrite); + writeBuffer.WriteObjectAny(object, cltype); + void* buffer = writeBuffer.Buffer(); + nbytes = writeBuffer.Length(); + writeBuffer.ResetBit(TBuffer::kIsOwner); writeBuffer.SetBuffer(0); + return(buffer); +} + +//___________________________________________________________________________ +void* AthenaRootSerializeSvc::deserialize(void* /*buffer*/, size_t /*nbytes*/, const std::string& /*name*/) { + return(0); +} + +//___________________________________________________________________________ +void* AthenaRootSerializeSvc::deserialize(void* buffer, size_t nbytes, const Guid& id) { + RootType cltype(pool::DbReflex::forGuid(id)); + TBufferFile readBuffer(TBuffer::kRead, nbytes, buffer, kTRUE); + void* obj = readBuffer.ReadObjectAny(cltype); + return(obj); +} diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaRootSerializeSvc.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaRootSerializeSvc.h new file mode 100644 index 0000000000000000000000000000000000000000..9eddf084377b5247ca41bc9a5e9c36921403d018 --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaRootSerializeSvc.h @@ -0,0 +1,41 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef ATHENAROOTSERIALIZESVC_H +#define ATHENAROOTSERIALIZESVC_H + +/** @file AthenaRootSerializeSvc.h + * @brief This file contains the class definition for the AthenaRootSerializeSvc class. + * @author Peter van Gemmeren <gemmeren@anl.gov> + **/ + +#include "AthenaBaseComps/AthService.h" +#include "AthenaKernel/IAthenaSerializeSvc.h" + +/** @class AthenaRootSerializeSvc + * @brief This class provides the AthenaSerializeSvc using ROOT + **/ +class AthenaRootSerializeSvc : public ::AthService, virtual public IAthenaSerializeSvc { + // Allow the factory class access to the constructor + friend class SvcFactory<AthenaRootSerializeSvc>; + +public: + /// Standard Service Constructor + AthenaRootSerializeSvc(const std::string& name, ISvcLocator* pSvcLocator); + /// Destructor + virtual ~AthenaRootSerializeSvc(); + + /// Gaudi Service Interface method implementations: + StatusCode initialize(); + StatusCode finalize(); + StatusCode queryInterface(const InterfaceID& riid, void** ppvInterface); + + void* serialize(const void* object, const std::string& name, size_t& nbytes); + void* serialize(const void* object, const Guid& id, size_t& nbytes); + + void* deserialize(void* buffer, size_t nbytes, const std::string& name); + void* deserialize(void* buffer, size_t nbytes, const Guid& id); +}; + +#endif diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/CondAttrListCollCnv.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/CondAttrListCollCnv.cxx old mode 100755 new mode 100644 diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/CondAttrListCollCnv.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/CondAttrListCollCnv.h old mode 100755 new mode 100644 diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/CondAttrListVecCnv.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/CondAttrListVecCnv.cxx old mode 100755 new mode 100644 diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/CondAttrListVecCnv.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/CondAttrListVecCnv.h old mode 100755 new mode 100644 diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/TPCnvElt.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/TPCnvElt.cxx new file mode 100644 index 0000000000000000000000000000000000000000..5bdf2bf5062212699007183133cf065f4f25c187 --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/TPCnvElt.cxx @@ -0,0 +1,36 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id$ +/** + * @file AthenaPoolCnvSvc/src/TPCnvElt.cxx + * @author scott snyder <snyder@bnl.gov> + * @date Jan, 2016 + * @brief Helper for calling a TP converter from an Athena converter. + */ + + +#include "AthenaPoolCnvSvc/TPCnvElt.h" +#include "AthenaPoolCnvSvc/exceptions.h" +#include "StorageSvc/DbReflex.h" + + +namespace AthenaPoolCnvSvc { + + +/** + * @brief Given a @c type_info, get the corresponding pool guid. + * @param ti @c type_info to look for. + * + * Throws an exception on errors. + */ +Guid guidFromTypeinfo (const std::type_info& ti) +{ + pool::TypeH typ = pool::DbReflex::forTypeInfo (ti); + if (!typ) throwExcNoDictForClass (ti); + return pool::DbReflex::guid (typ); +} + + +} // namespace AthenaPoolCnvSvc diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/components/AthenaPoolCnvSvc_entries.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/components/AthenaPoolCnvSvc_entries.cxx old mode 100755 new mode 100644 index 5f984412ec2c784f5979b13f349c13a68fa9ccf9..f5f46df77847dce5f5bd20de9137c4265f6a2439 --- a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/components/AthenaPoolCnvSvc_entries.cxx +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/components/AthenaPoolCnvSvc_entries.cxx @@ -7,17 +7,20 @@ #include "GaudiKernel/DeclareFactoryEntries.h" #include "../AthenaPoolCnvSvc.h" +#include "../AthenaRootSerializeSvc.h" #include "../AthenaAttributeListCnv.h" #include "../CondAttrListCollCnv.h" #include "../CondAttrListVecCnv.h" DECLARE_SERVICE_FACTORY(AthenaPoolCnvSvc) +DECLARE_SERVICE_FACTORY(AthenaRootSerializeSvc) DECLARE_CONVERTER_FACTORY(AthenaAttributeListCnv) DECLARE_CONVERTER_FACTORY(CondAttrListCollCnv) DECLARE_CONVERTER_FACTORY(CondAttrListVecCnv) DECLARE_FACTORY_ENTRIES(AthenaPoolCnvSvc) { DECLARE_SERVICE(AthenaPoolCnvSvc); + DECLARE_SERVICE(AthenaRootSerializeSvc); DECLARE_CONVERTER(AthenaAttributeListCnv); DECLARE_CONVERTER(CondAttrListCollCnv); DECLARE_CONVERTER(CondAttrListVecCnv); diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/components/AthenaPoolCnvSvc_load.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/components/AthenaPoolCnvSvc_load.cxx old mode 100755 new mode 100644 diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/exceptions.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/exceptions.cxx new file mode 100644 index 0000000000000000000000000000000000000000..7a46d4896963d54ad5a89f11dc11e3f13598ff20 --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/exceptions.cxx @@ -0,0 +1,92 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id$ +/** + * @file AthenaPoolCnvSvc/src/exceptions.cxx + * @author scott snyder <snyder@bnl.gov> + * @date Jan, 2016 + * @brief Exceptions that can be thrown from AthenaPoolCnvSvc. + */ + + +#include "AthenaPoolCnvSvc/exceptions.h" +#include "GaudiKernel/System.h" +#include <sstream> + + +namespace AthenaPoolCnvSvc { + + +/// Helper: format exception error string. +std::string excNoDictForClass_format (const std::type_info& ti) +{ + std::ostringstream os; + os << "AthenaPoolCnvSvc::::ExcNoDictForClass: " + << "Can't find dictionary information for class: "; + os << System::typeinfoName(ti); + return os.str(); +} + + +/** + * @brief Constructor. + * @param ti The requested class. + */ +ExcNoDictForClass::ExcNoDictForClass (const std::type_info& ti) + : std::runtime_error (excNoDictForClass_format (ti)) +{ +} + + +/** + * @brief Throw a AthenaPoolCnvSvc::ExcNoDictForClass exception. + * @param ti The requested class. + */ +void throwExcNoDictForClass (const std::type_info& ti) +{ + throw ExcNoDictForClass (ti); +} + + +//************************************************************************* + + +/// Helper: format exception error string. +std::string excUnsupportedVersion_format (const std::type_info& ti, + const Guid& guid) +{ + std::ostringstream os; + os << "AthenaPoolCnvSvc::::ExcUnsupported version: " + << "Unsupported persistent version of " + << System::typeinfoName(ti) + << " found; guid: " << guid.toString(); + return os.str(); +} + + +/** + * @brief Constructor. + * @param ti The requested class. + * @param guid The GUID of the persistent class. + */ +ExcUnsupportedVersion::ExcUnsupportedVersion (const std::type_info& ti, + const Guid& guid) + : std::runtime_error (excUnsupportedVersion_format (ti, guid)) +{ +} + + +/** + * @brief Throw a AthenaPoolCnvSvc::ExcUnsupportedVersion exception. + * @param ti The class being read. + * @param guid The GUID of the persistent class. + */ +void throwExcUnsupportedVersion (const std::type_info& ti, const Guid& guid) +{ + throw ExcUnsupportedVersion (ti, guid); +} + + +} // namespace AthenaPoolCnvSvc diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/test/AthenaPoolCnvSvc.xml b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/AthenaPoolCnvSvc.xml new file mode 100644 index 0000000000000000000000000000000000000000..e685e3d92ead3f4464bb216f62aa62ca6da54640 --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/AthenaPoolCnvSvc.xml @@ -0,0 +1,15 @@ +<?xml version="1.0"?> +<atn> + <TEST name="AthenaPoolCnvSvcTest" type="makecheck" suite="Core"> + <package>Database/AthenaPOOL/AthenaPoolCnvSvc</package> + <timelimit>10</timelimit> + <mailto> snyder@bnl.gov</mailto> + <expectations> + <errorMessage>Athena exited abnormally</errorMessage> + <errorMessage>differ</errorMessage> + <warningMessage> # WARNING_MESSAGE : post.sh> ERROR</warningMessage> + <successMessage>check ok</successMessage> + <returnValue>0</returnValue> + </expectations> + </TEST> +</atn> diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/test/AthenaPoolCnvSvcTestDict.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/AthenaPoolCnvSvcTestDict.h new file mode 100644 index 0000000000000000000000000000000000000000..7cda5404718cb924ea6baa80c78d99aba669b596 --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/AthenaPoolCnvSvcTestDict.h @@ -0,0 +1,115 @@ +// This file's extension implies that it's C, but it's really -*- C++ -*-. + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id$ +/** + * @file AthenaPoolCnvSvcTestDict.h + * @author scott snyder <snyder@bnl.gov> + * @date Jan, 2016 + * @brief + */ + + +#ifndef ATHENAPOOLCNVSVC_ATHENAPOOLCNVSVCTESTDICT_H +#define ATHENAPOOLCNVSVC_ATHENAPOOLCNVSVCTESTDICT_H + + +#include "AthContainers/DataVector.h" +#include "AthContainers/ViewVector.h" +#include "AthContainers/AuxElement.h" +#include "AthContainers/AuxStoreInternal.h" +#include "AthLinks/ElementLink.h" +#include "SGTools/CLASS_DEF.h" +#include <vector> + + +namespace AthenaPoolCnvSvcTest { + + +class X +{ +public: + X(int a) : m_a(a) {} + int m_a; +}; +typedef DataVector<X> XCont; + +class X_p1 +{ +public: + X_p1(int a) : m_a(a) {} + int m_a; +}; +class XCont_p1 +{ +public: + std::vector<X_p1> m_v; +}; + + +class X_p2 +{ +public: + X_p2(int a) : m_a(a) {} + int m_a; +}; +class XCont_p2 +{ +public: + std::vector<X_p2> m_v; +}; + + +struct Y_v1 + : public SG::AuxElement +{ + Y_v1(int a) : m_a(a) {} + int m_a; +}; +struct Y_v2 + : public SG::AuxElement +{ + Y_v2(int a) : m_a(a) {} + int m_a; +}; + + +struct YAuxCont_v1 + : public SG::AuxStoreInternal +{ +}; + + +struct YAuxCont_v2 + : public SG::AuxStoreInternal +{ +}; + + +} // namespace AthenaPoolCnvSvcTest + + +CLASS_DEF(DataVector<AthenaPoolCnvSvcTest::Y_v1>, 524263040, 1) +CLASS_DEF(DataVector<AthenaPoolCnvSvcTest::Y_v2>, 524263041, 1) +CLASS_DEF(ViewVector<DataVector<AthenaPoolCnvSvcTest::Y_v1> >, 524263042, 1) +CLASS_DEF(ViewVector<DataVector<AthenaPoolCnvSvcTest::Y_v2> >, 524263043, 1) +CLASS_DEF(AthenaPoolCnvSvcTest::YAuxCont_v1, 524263044, 1) +CLASS_DEF(AthenaPoolCnvSvcTest::YAuxCont_v2, 524263045, 1) +CLASS_DEF(AthenaPoolCnvSvcTest::XCont, 524263046, 1) + + +namespace AthenaPoolCnvSvcTest { + + +typedef std::vector<ElementLink<DataVector<Y_v1> > > YCont_v1_pers; +typedef std::vector<ElementLink<DataVector<Y_v2> > > YCont_v2_pers; + + + +} // namespace AthenaPoolCnvSvcTest + + +#endif // not ATHENAPOOLCNVSVC_ATHENAPOOLCNVSVCTESTDICT_H diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/test/TPCnvElt_test.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/TPCnvElt_test.cxx new file mode 100644 index 0000000000000000000000000000000000000000..173f5a0a13cfc3b70010d630b208f8a2f9895f96 --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/TPCnvElt_test.cxx @@ -0,0 +1,113 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id$ +/** + * @file AthenaPoolCnvSvc/test/TPCnvElt_test.cxx + * @author scott snyder <snyder@bnl.gov> + * @date Jan, 2016 + * @brief Tests for TPCnvElt. + */ + + +#undef NDEBUG +#include "AthenaPoolCnvSvc/TPCnvElt.h" +#include "AthenaPoolCnvSvcTestDict.h" +#include "GaudiKernel/MsgStream.h" +#include "TSystem.h" +#include <iostream> +#include <typeinfo> +#include <cassert> + + +using namespace AthenaPoolCnvSvcTest; + + +class XCnv_p1 +{ +public: + typedef X Trans_t; + typedef X_p1 Pers_t; + + X* createTransient (const X_p1* pers, MsgStream&) + { return new X(pers->m_a*2); } + + void persToTrans (const X_p1* pers, X* trans, MsgStream&) + { + trans->m_a = pers->m_a*2; + } +}; + + +std::string X_guid = "CAE53A87-64AD-4576-A203-1A4142E1E10F"; +std::string X_p1_guid = "6AD63B61-BE75-40FC-B0C6-DD3C7801D871"; + + +class TestConverter +{ +public: + TestConverter (const std::string& guid) : m_guid (guid) {} + + bool compareClassGuid (const Guid& guid) + { return guid == m_guid; } + + template <class T> + T* poolReadObject() { return new T (10); } + + +private: + Guid m_guid; +}; + + +void test1() +{ + std::cout << "test1\n"; + + assert (AthenaPoolCnvSvc::guidFromTypeinfo (typeid (X_p1)) == Guid (X_p1_guid)); +} + + +void test2() +{ + std::cout << "test2\n"; + MsgStream msg (nullptr, ""); + + AthenaPoolCnvSvc::TPCnvElt<TestConverter, XCnv_p1> tpcnv; + + TestConverter cnv1 (X_p1_guid); + X* x = tpcnv.createTransient (cnv1, msg); + assert (x->m_a == 20); + delete x; + + X x2 (0); + assert (tpcnv.persToTrans (cnv1, &x2, msg)); + assert (x2.m_a == 20); + + TestConverter cnv2 ("8ADE9DD7-ED1F-447E-A096-0F8F786291CD"); + assert (tpcnv.createTransient (cnv2, msg) == nullptr); + assert (!tpcnv.persToTrans (cnv2, &x2, msg)); + + AthenaPoolCnvSvc::TPCnvElt<TestConverter, T_TPCnvNull<X> > tpcnv_null; + TestConverter cnv3 (X_guid); + x = tpcnv_null.createTransient (cnv3, msg); + assert (x->m_a == 10); + delete x; + assert (tpcnv_null.createTransient (cnv1, msg) == nullptr); + + assert (tpcnv_null.persToTrans (cnv3, &x2, msg)); + assert (x2.m_a == 10); + assert (!tpcnv_null.persToTrans (cnv1, &x2, msg)); +} + + +int main() +{ + gSystem->Load("libAthenaPoolCnvSvcTestDict"); + test1(); + test2(); + return 0; +} + + diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/test/TPCnvList_test.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/TPCnvList_test.cxx new file mode 100644 index 0000000000000000000000000000000000000000..b1cc8a859733f99b70cf8413a003580091010751 --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/TPCnvList_test.cxx @@ -0,0 +1,129 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id$ +/** + * @file AthenaPoolCnvSvc/test/TPCnvList_test.cxx + * @author scott snyder <snyder@bnl.gov> + * @date Jan, 2016 + * @brief Tests for TPCnvList. + */ + + +#undef NDEBUG +#include "AthenaPoolCnvSvc/TPCnvList.h" +#include "AthenaPoolCnvSvcTestDict.h" +#include "GaudiKernel/MsgStream.h" +#include "TSystem.h" +#include <iostream> +#include <typeinfo> +#include <cassert> + + +using namespace AthenaPoolCnvSvcTest; + + +class XCnv_p1 +{ +public: + typedef X Trans_t; + typedef X_p1 Pers_t; + + X* createTransient (const X_p1* pers, MsgStream&) + { return new X(pers->m_a*2); } + + void persToTrans (const X_p1* pers, X* trans, MsgStream&) + { + trans->m_a = pers->m_a*2; + } +}; + + +class XCnv_p2 +{ +public: + typedef X Trans_t; + typedef X_p2 Pers_t; + + X* createTransient (const X_p2* pers, MsgStream&) + { return new X(pers->m_a*3); } + + void persToTrans (const X_p2* pers, X* trans, MsgStream&) + { + trans->m_a = pers->m_a*3; + } +}; + + +std::string X_guid = "CAE53A87-64AD-4576-A203-1A4142E1E10F"; +std::string X_p1_guid = "6AD63B61-BE75-40FC-B0C6-DD3C7801D871"; +std::string X_p2_guid = "0AAC9C99-726D-4CF4-B9F9-00B6674C57DD"; + + +class TestConverter +{ +public: + TestConverter (const std::string& guid) : m_guid (guid) {} + + bool compareClassGuid (const Guid& guid) + { return guid == m_guid; } + + template <class T> + T* poolReadObject() { return new T (10); } + + +private: + Guid m_guid; +}; + + +void test1() +{ + std::cout << "test1\n"; + MsgStream msg (nullptr, ""); + + AthenaPoolCnvSvc::TPCnvList<TestConverter, X, + XCnv_p2, + XCnv_p1, + T_TPCnvNull<X> > tpcnv; + + X* x = nullptr; + X x2(0); + + TestConverter cnv1 (X_p1_guid); + x = tpcnv.createTransient (cnv1, msg); + assert (x->m_a == 20); + delete x; + + assert (tpcnv.persToTrans (cnv1, &x2, msg)); + assert (x2.m_a == 20); + + TestConverter cnv2 (X_p2_guid); + x = tpcnv.createTransient (cnv2, msg); + assert (x->m_a == 30); + delete x; + + assert (tpcnv.persToTrans (cnv2, &x2, msg)); + assert (x2.m_a == 30); + + TestConverter cnv0 (X_guid); + x = tpcnv.createTransient (cnv0, msg); + assert (x->m_a == 10); + delete x; + + assert (tpcnv.persToTrans (cnv0, &x2, msg)); + assert (x2.m_a == 10); + + TestConverter cnvx ("B3FCEE90-66FC-4AE1-A81B-5257A0306EF8"); + assert (tpcnv.createTransient (cnvx, msg) == nullptr); + assert (!tpcnv.persToTrans (cnvx, &x2, msg)); +} + + +int main() +{ + gSystem->Load("libAthenaPoolCnvSvcTestDict"); + test1(); + return 0; +} diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/test/T_AthenaPoolAuxContainerCnv_test.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/T_AthenaPoolAuxContainerCnv_test.cxx new file mode 100644 index 0000000000000000000000000000000000000000..24605568a7d2761b7c5a998f029e36a38169221c --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/T_AthenaPoolAuxContainerCnv_test.cxx @@ -0,0 +1,269 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id$ +/** + * @file AthenaPoolCnvSvc/test/T_AthenaPoolAuxContainerCnv_test.cxx + * @author scott snyder <snyder@bnl.gov> + * @date Jan, 2016 + * @brief Tests for T_AthenaPoolAuxContainerCnv_test. + */ + + +#undef NDEBUG +#include "AthenaPoolCnvSvc/T_AthenaPoolAuxContainerCnv.h" +#include "PersistentDataModel/TokenAddress.h" +#include "AthContainers/AuxTypeRegistry.h" +#include "SGTools/TestStore.h" +#include "TestTools/initGaudi.h" +#include "CxxUtils/make_unique.h" +#include "TSystem.h" +#include "AthenaPoolCnvSvcTestDict.h" +#include "TestThinningSvc.icc" +#include "TestCnvSvcBase.icc" +#include <iostream> +#include <cassert> +#include <vector> + + +using namespace AthenaPoolCnvSvcTest; + + +std::string YAuxCont_v1_guid = "BEE3C14E-149E-4366-9E24-8A32C419A3B4"; +std::string YAuxCont_v2_guid = "170BFEE4-F6B2-4AF4-919B-7EB3986656FA"; + + +class TestCnvSvc + : public TestCnvSvcBase +{ +public: + TestCnvSvc (const std::string& name, ISvcLocator* svcloc) + : TestCnvSvcBase (name, svcloc), + m_pers1 (nullptr), + m_pers2 (nullptr) + {} + + virtual void setObjPtr(void*& obj, const Token* /*token*/) const override + { + if (m_pers2) { + obj = new YAuxCont_v2 (*m_pers2); + } + else if (m_pers1) { + obj = new YAuxCont_v1 (*m_pers1); + } + else + std::abort(); + } + + std::string m_name; + YAuxCont_v1* m_pers1; + YAuxCont_v2* m_pers2; +}; + + +class YAuxContCnv_v1 +{ +public: + typedef YAuxCont_v2 Trans_t; + typedef YAuxCont_v1 Pers_t; + + Trans_t* createTransient (const Pers_t* pers, MsgStream& msg) + { + auto trans = CxxUtils::make_unique<Trans_t>(); + persToTrans (pers, trans.get(), msg); + return trans.release(); + } + + void persToTrans (const Pers_t* pers, Trans_t* trans, MsgStream&) + { + typedef ElementLink<DataVector<Y_v2> > Link_t; + SG::AuxTypeRegistry& reg = SG::AuxTypeRegistry::instance(); + SG::auxid_t x_auxid = reg.getAuxID<int> ("x"); + SG::auxid_t l_auxid = reg.getAuxID<Link_t> ("l"); + + size_t sz = pers->size(); + + int* xt = reinterpret_cast<int*> (trans->getData (x_auxid, sz, sz)); + Link_t* lt = reinterpret_cast<Link_t*> (trans->getData (l_auxid, sz, sz)); + + const int* xp = reinterpret_cast<const int*> (pers->getData (x_auxid)); + const Link_t* lp = reinterpret_cast<const Link_t*> (pers->getData (l_auxid)); + + for (size_t i = 0; i < sz; i++) { + lt[i] = lp[i]; + xt[i] = xp[i]*3; + } + } +}; + + +// Writing +void test1 (ISvcLocator* svcloc, TestCnvSvc& /*testsvc*/) +{ + std::cout << "test1\n"; + const size_t N = 10; + + DataVector<Y_v2>* vec = new DataVector<Y_v2>; + for (size_t i = 0; i < N; i++) + vec->push_back (new Y_v2(i)); + SGTest::store.record (vec, "vec"); + + T_AthenaPoolAuxContainerCnv<YAuxCont_v2, YAuxContCnv_v1> cnv (svcloc); + assert (static_cast<AthenaPoolConverter&>(cnv).initialize().isSuccess()); + + typedef ElementLink<DataVector<Y_v2> > Link_t; + SG::AuxTypeRegistry& reg = SG::AuxTypeRegistry::instance(); + SG::auxid_t x_auxid = reg.getAuxID<int> ("x"); + SG::auxid_t l_auxid = reg.getAuxID<Link_t> ("l"); + YAuxCont_v2* trans2 = new YAuxCont_v2; + int* x2 = reinterpret_cast<int*> (trans2->getData (x_auxid, N, N)); + Link_t* l2 = reinterpret_cast<Link_t*> (trans2->getData (l_auxid, N, N)); + for (size_t i = 0; i < N; i++) { + x2[i] = i*2; + l2[i] = Link_t ("vec", i); + } + SGTest::store.record (trans2, "store"); + + YAuxCont_v2* pers2a = cnv.createPersistent (trans2); + assert (pers2a->size() == trans2->size()); + const int* x2a = reinterpret_cast<const int*> (pers2a->getData (x_auxid)); + const Link_t* l2a = reinterpret_cast<const Link_t*> (pers2a->getData (l_auxid)); + for (size_t i = 0; i < N; i++) { + assert (x2a[i] == static_cast<int>(i)*2); + assert (l2a[i].dataID() == "vec"); + assert (l2a[i].index() == i); + } + + TestThinningSvc thinsvc; + TestThinningSvc::instance (&thinsvc, true); + thinsvc.remap (vec, 5, IThinningSvc::RemovedIdx); + for (size_t i = 6; i < N; i++) + thinsvc.remap (vec, i, i-1); + thinsvc.remap (trans2, 7, IThinningSvc::RemovedIdx); + + YAuxCont_v2* pers2b = cnv.createPersistent (trans2); + assert (pers2b->size() == trans2->size()-1); + const int* x2b = reinterpret_cast<const int*> (pers2b->getData (x_auxid)); + const Link_t* l2b = reinterpret_cast<const Link_t*> (pers2b->getData (l_auxid)); + for (size_t i = 0; i < N-1; i++) { + size_t ii = i; + if (i >= 7) ii = i+1; + assert (x2b[i] == static_cast<int>(ii)*2); + if (ii == 5) { + assert (l2b[i].key() == 0); + assert (l2b[i].index() == 0); + } + else { + assert (l2b[i].dataID() == "vec"); + if (i < 5) + assert (l2b[i].index() == ii); + else + assert (l2b[i].index() == ii-1); + } + } + + TestThinningSvc::instance (nullptr, true); + delete trans2; + delete pers2a; + delete pers2b; +} + + +// Reading +void test2 (ISvcLocator* svcloc, TestCnvSvc& testsvc) +{ + std::cout << "test2\n"; + const size_t N = 10; + + T_AthenaPoolAuxContainerCnv<YAuxCont_v2, YAuxContCnv_v1> cnv (svcloc); + assert (static_cast<AthenaPoolConverter&>(cnv).initialize().isSuccess()); + + typedef ElementLink<DataVector<Y_v2> > Link_t; + SG::AuxTypeRegistry& reg = SG::AuxTypeRegistry::instance(); + SG::auxid_t x_auxid = reg.getAuxID<int> ("x"); + SG::auxid_t l_auxid = reg.getAuxID<Link_t> ("l"); + YAuxCont_v2 pers2; + int* x2 = reinterpret_cast<int*> (pers2.getData (x_auxid, N, N)); + Link_t* l2 = reinterpret_cast<Link_t*> (pers2.getData (l_auxid, N, N)); + for (size_t i = 0; i < N; i++) { + x2[i] = i*2; + l2[i] = Link_t ("vec", i); + } + + testsvc.m_pers2 = &pers2; + Token* token = new Token; + token->setClassID (Guid (YAuxCont_v2_guid)); + TokenAddress taddr (0, 0, "", "", 0, token); + + { + DataObject* pObj = nullptr; + assert (cnv.createObj (&taddr, pObj).isSuccess()); + auto* trans = SG::Storable_cast<YAuxCont_v2> (pObj); + assert (trans->size() == pers2.size()); + const int* xt = reinterpret_cast<const int*> (trans->getData (x_auxid)); + const Link_t* lt = reinterpret_cast<const Link_t*> (trans->getData (l_auxid)); + for (size_t i = 0; i < N; i++) { + assert (xt[i] == static_cast<int>(i)*2); + assert (lt[i].dataID() == "vec"); + assert (lt[i].index() == i); + } + + delete pObj; + } + testsvc.m_pers2 = nullptr; + + YAuxCont_v1 pers1; + int* x1 = reinterpret_cast<int*> (pers1.getData (x_auxid, N, N)); + Link_t* l1 = reinterpret_cast<Link_t*> (pers1.getData (l_auxid, N, N)); + for (size_t i = 0; i < N; i++) { + x1[i] = i*4; + l1[i] = Link_t ("vec", i); + } + + testsvc.m_pers1 = &pers1; + token->setClassID (Guid (YAuxCont_v1_guid)); + { + DataObject* pObj = nullptr; + assert (cnv.createObj (&taddr, pObj).isSuccess()); + auto* trans = SG::Storable_cast<YAuxCont_v2> (pObj); + assert (trans->size() == pers2.size()); + const int* xt = reinterpret_cast<const int*> (trans->getData (x_auxid)); + const Link_t* lt = reinterpret_cast<const Link_t*> (trans->getData (l_auxid)); + for (size_t i = 0; i < N; i++) { + assert (xt[i] == static_cast<int>(i)*3*4); + assert (lt[i].dataID() == "vec"); + assert (lt[i].index() == i); + } + + delete pObj; + } + + token->setClassID (Guid ("8ACD1C53-D3C7-4FE5-9BC0-E388701DB8FA")); + DataObject* pObj = nullptr; + assert (cnv.createObj (&taddr, pObj).isFailure()); + + testsvc.m_pers1 = nullptr; +} + + +int main() +{ + SGTest::initTestStore(); + ISvcLocator* pSvcLoc = nullptr; + if (!Athena_test::initGaudi("test.txt", pSvcLoc)) { + std::cerr << "This test can not be run" << std::endl; + return 0; + } + + TestCnvSvc* svc = new TestCnvSvc ("AthenaPoolCnvSvc", pSvcLoc); + ISvcManager* mgr = dynamic_cast<ISvcManager*> (pSvcLoc); + if (mgr->addService (svc).isFailure()) + std::abort(); + + gSystem->Load("libAthenaPoolCnvSvcTestDict"); + + test1 (pSvcLoc, *svc); + test2 (pSvcLoc, *svc); + return 0; +} diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/test/T_AthenaPoolTPCnvCnv_test.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/T_AthenaPoolTPCnvCnv_test.cxx new file mode 100644 index 0000000000000000000000000000000000000000..c31154526fa82b06b070d2204b08702002a04152 --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/T_AthenaPoolTPCnvCnv_test.cxx @@ -0,0 +1,227 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id$ +/** + * @file AthenaPoolCnvSvc/test/T_AthenaPoolTPCnvCnv_test.cxx + * @author scott snyder <snyder@bnl.gov> + * @date Jan, 2016 + * @brief Tests for T_AthenaPoolTPCnvCnv_test. + */ + + +#undef NDEBUG +#include "AthenaPoolCnvSvc/T_AthenaPoolTPCnvCnv.h" +#include "AthenaPoolCnvSvc/T_AthenaPoolTPConverter.h" +#include "PersistentDataModel/TokenAddress.h" +#include "SGTools/TestStore.h" +#include "TestTools/initGaudi.h" +#include "CxxUtils/make_unique.h" +#include "TSystem.h" +#include "AthenaPoolCnvSvcTestDict.h" +#include "TestCnvSvcBase.icc" +#include <iostream> +#include <cassert> +#include <vector> + + +using namespace AthenaPoolCnvSvcTest; + + +std::string XCont_guid = "6AEA6831-8777-4571-8595-95FFF40B171F"; +std::string XCont_p1_guid = "421C967C-CB57-4234-A33F-EBE4928036C2"; +std::string XCont_p2_guid = "F151C81D-869A-4585-8086-5F8835AB12E1"; + + +class TestCnvSvc + : public TestCnvSvcBase +{ +public: + TestCnvSvc (const std::string& name, ISvcLocator* svcloc) + : TestCnvSvcBase (name, svcloc), + m_pers0 (nullptr), + m_pers1 (nullptr), + m_pers2 (nullptr) + {} + + virtual void setObjPtr(void*& obj, const Token* /*token*/) const override + { + if (m_pers2) { + obj = new XCont_p2 (*m_pers2); + } + else if (m_pers1) { + obj = new XCont_p1 (*m_pers1); + } + else if (m_pers0) { + obj = new XCont (*m_pers0); + } + else + std::abort(); + } + + std::string m_name; + XCont* m_pers0; + XCont_p1* m_pers1; + XCont_p2* m_pers2; +}; + + +class XContCnv_p1 + : public T_AthenaPoolTPCnvBase<XCont, XCont_p1> +{ +public: + virtual + void persToTrans (const Pers_t* pers, Trans_t* trans, MsgStream&) override + { + trans->clear(); + for (const X_p1& x : pers->m_v) + trans->push_back (new X (x.m_a / 20)); + } + + virtual + void transToPers (const Trans_t* trans, Pers_t* pers, MsgStream&) override + { + pers->m_v.clear(); + for (const X* x : *trans) + pers->m_v.emplace_back (x->m_a * 20); + } +}; + + +class XContCnv_p2 + : public T_AthenaPoolTPCnvBase<XCont, XCont_p2> +{ +public: + virtual + void persToTrans (const Pers_t* pers, Trans_t* trans, MsgStream&) override + { + trans->clear(); + for (const X_p2& x : pers->m_v) + trans->push_back (new X (x.m_a / 10)); + } + + virtual + void transToPers (const Trans_t* trans, Pers_t* pers, MsgStream&) override + { + pers->m_v.clear(); + for (const X* x : *trans) + pers->m_v.emplace_back (x->m_a * 10); + } +}; + + +// Writing +void test1 (ISvcLocator* svcloc, TestCnvSvc& /*testsvc*/) +{ + std::cout << "test1\n"; + const size_t N = 10; + + T_AthenaPoolTPCnvCnv<XCont, XContCnv_p2, XContCnv_p1, T_TPCnvNull<XCont> > + cnv (svcloc); + assert (static_cast<AthenaPoolConverter&>(cnv).initialize().isSuccess()); + + XCont trans; + for (size_t i = 0; i < N; i++) + trans.push_back (new X(i)); + + { + XCont_p2* pers2 = cnv.createPersistent (&trans); + assert (pers2->m_v.size() == N); + for (size_t i = 0; i < N; i++) + assert (pers2->m_v[i].m_a == static_cast<int>(i*10)); + delete pers2; + } +} + + +// Reading +void test2 (ISvcLocator* svcloc, TestCnvSvc& testsvc) +{ + std::cout << "test2\n"; + const size_t N = 10; + T_AthenaPoolTPCnvCnv<XCont, XContCnv_p2, XContCnv_p1, T_TPCnvNull<XCont> > + cnv (svcloc); + assert (static_cast<AthenaPoolConverter&>(cnv).initialize().isSuccess()); + + XCont_p2 pers2; + for (size_t i = 0; i < N; i++) + pers2.m_v.push_back (X_p2 (i*50)); + + testsvc.m_pers2 = &pers2; + Token* token = new Token; + token->setClassID (Guid (XCont_p2_guid)); + TokenAddress taddr (0, 0, "", "", 0, token); + + { + DataObject* pObj = nullptr; + assert (cnv.createObj (&taddr, pObj).isSuccess()); + auto* trans = SG::Storable_cast<XCont> (pObj); + assert (trans->size() == N); + for (size_t i = 0; i < N; i++) + assert ((*trans)[i]->m_a == static_cast<int>(i*5)); + delete pObj; + } + testsvc.m_pers2 = nullptr; + + XCont_p1 pers1; + for (size_t i = 0; i < N; i++) + pers1.m_v.push_back (X_p1 (i*80)); + + testsvc.m_pers1 = &pers1; + token->setClassID (Guid (XCont_p1_guid)); + { + DataObject* pObj = nullptr; + assert (cnv.createObj (&taddr, pObj).isSuccess()); + auto* trans = SG::Storable_cast<XCont> (pObj); + assert (trans->size() == N); + for (size_t i = 0; i < N; i++) + assert ((*trans)[i]->m_a == static_cast<int>(i*4)); + delete pObj; + } + testsvc.m_pers1 = nullptr; + + XCont pers0; + for (size_t i = 0; i < N; i++) + pers0.push_back (new X (i*11)); + + testsvc.m_pers0 = &pers0; + token->setClassID (Guid (XCont_guid)); + { + DataObject* pObj = nullptr; + assert (cnv.createObj (&taddr, pObj).isSuccess()); + auto* trans = SG::Storable_cast<XCont> (pObj); + assert (trans->size() == N); + for (size_t i = 0; i < N; i++) + assert ((*trans)[i]->m_a == static_cast<int>(i*11)); + delete pObj; + } + + token->setClassID (Guid ("8ACD1C53-D3C7-4FE5-9BC0-E388701DB8FA")); + DataObject* pObj = nullptr; + assert (cnv.createObj (&taddr, pObj).isFailure()); + + testsvc.m_pers1 = nullptr; +} + + +int main() +{ + SGTest::initTestStore(); + ISvcLocator* pSvcLoc = nullptr; + if (!Athena_test::initGaudi("test.txt", pSvcLoc)) { + std::cerr << "This test can not be run" << std::endl; + return 0; + } + + TestCnvSvc* svc = new TestCnvSvc ("AthenaPoolCnvSvc", pSvcLoc); + ISvcManager* mgr = dynamic_cast<ISvcManager*> (pSvcLoc); + if (mgr->addService (svc).isFailure()) + std::abort(); + + gSystem->Load("libAthenaPoolCnvSvcTestDict"); + + test1 (pSvcLoc, *svc); + test2 (pSvcLoc, *svc); + return 0; +} diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/test/T_AthenaPoolViewVectorCnv_test.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/T_AthenaPoolViewVectorCnv_test.cxx new file mode 100644 index 0000000000000000000000000000000000000000..bb4eb0acf7815bee145a896e20061460af1f12a5 --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/T_AthenaPoolViewVectorCnv_test.cxx @@ -0,0 +1,186 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id$ +/** + * @file AthenaPoolCnvSvc/test/T_AthenaPoolViewVectorCnv_test.cxx + * @author scott snyder <snyder@bnl.gov> + * @date Jan, 2016 + * @brief Tests for T_AthenaPoolViewVectorCnv_test. + */ + + +#undef NDEBUG +#include "AthenaPoolCnvSvc/T_AthenaPoolViewVectorCnv.h" +#include "AthenaPoolCnvSvc/T_AthenaPoolCnv.h" +#include "PersistentDataModel/TokenAddress.h" +#include "AthContainers/DataVector.h" +#include "AthLinks/ElementLink.h" +#include "SGTools/TestStore.h" +#include "SGTools/StorableConversions.h" +#include "TestTools/initGaudi.h" +#include "GaudiKernel/MsgStream.h" +#include "TSystem.h" +#include "AthenaPoolCnvSvcTestDict.h" +#include "TestThinningSvc.icc" +#include "TestCnvSvcBase.icc" +#include <iostream> +#include <cassert> +#include <vector> + + +using namespace AthenaPoolCnvSvcTest; + + +std::string YCont_v1_guid = "7E1826B9-3666-42B3-A2E7-C916BD10A5B8"; +std::string YCont_v2_guid = "80C19103-FE9B-4227-8E48-8C0DB468F892"; + + +class TestCnvSvc + : public TestCnvSvcBase +{ +public: + TestCnvSvc (const std::string& name, ISvcLocator* svcloc) + : TestCnvSvcBase (name, svcloc), + m_pers (nullptr) + {} + + virtual void setObjPtr(void*& obj, const Token* /*token*/) const override + { + obj = new YCont_v2_pers (*m_pers); + } + + std::string m_name; + YCont_v2_pers* m_pers; +}; + + +void test1 (ISvcLocator* svcloc, TestCnvSvc& testsvc, DataVector<Y_v2>& vec) +{ + std::cout << "test1\n"; + + T_AthenaPoolCnv<ViewVector<DataVector<Y_v2> > > cnv (svcloc); + assert (cnv.initialize().isSuccess()); + + ViewVector<DataVector<Y_v2> > view (SG::VIEW_ELEMENTS); + size_t sz = vec.size(); + for (size_t i = 0; i < sz; i++) + view.push_back (vec[sz-i-1]); + + YCont_v2_pers* pers = cnv.createPersistent (&view); + assert (pers->size() == sz); + for (size_t i = 0; i < sz; i++) { + assert ((*pers)[i].dataID() == "vec"); + assert ((*pers)[i].index() == sz-i-1); + } + + testsvc.m_pers = pers; + Token* token = new Token; + token->setClassID (Guid (YCont_v2_guid)); + TokenAddress taddr (0, 0, "", "", 0, token); + + DataObject* pObj; + assert (cnv.createObj (&taddr, pObj).isSuccess()); + auto* trans1 = SG::Storable_cast<ViewVector<DataVector<Y_v2> > > (pObj); + assert (trans1->size() == 10); + for (size_t i = 0; i < sz; i++) + assert ((*trans1)[i] == view[i]); + delete pObj; + pObj = nullptr; + delete pers; + testsvc.m_pers = nullptr; + + YCont_v2_pers pers1; + size_t ii = 0; + for (size_t i = 0; i < sz; i++, ii+=2) { + if (ii >= sz) ii = 1; + pers1.emplace_back ("vec", ii); + } + testsvc.m_pers = &pers1; + token->setClassID (Guid (YCont_v1_guid)); + assert (cnv.createObj (&taddr, pObj).isSuccess()); + auto* trans2 = SG::Storable_cast<ViewVector<DataVector<Y_v2> > > (pObj); + assert (trans2->size() == 10); + ii = 0; + for (size_t i = 0; i < sz; i++, ii+=2) { + if (ii >= sz) ii = 1; + assert ((*trans2)[i] == vec[ii]); + } + delete trans2; + + token->setClassID (Guid ("79E2478D-C17F-45E9-848D-278240C2FED3")); + assert (cnv.createObj (&taddr, pObj).isFailure()); +} + + +// Test with thinning. +void test2 (ISvcLocator* svcloc, TestCnvSvc& /*testsvc*/, DataVector<Y_v2>& vec) +{ + std::cout << "test2\n"; + size_t sz = vec.size(); + + TestThinningSvc thinsvc; + TestThinningSvc::instance (&thinsvc, true); + thinsvc.remap (&vec, 5, IThinningSvc::RemovedIdx); + for (size_t i = 6; i < sz; i++) + thinsvc.remap (&vec, i, i-1); + + T_AthenaPoolCnv<ViewVector<DataVector<Y_v2> > > cnv (svcloc); + assert (cnv.initialize().isSuccess()); + + ViewVector<DataVector<Y_v2> > view (SG::VIEW_ELEMENTS); + for (size_t i = 0; i < sz; i++) + view.push_back (vec[i]); + + YCont_v2_pers* pers = cnv.createPersistent (&view); + assert (pers->size() == sz); + for (size_t i = 0; i < sz; i++) { + const ElementLink<DataVector<Y_v2> >& l = (*pers)[i]; + if (i == 5) { + assert (l.key() == 0); + assert (l.index() == 0); + } + else { + assert (l.dataID() == "vec"); + if (i < 5) + assert (l.index() == i); + else + assert (l.index() == i-1); + } + } + delete pers; +} + + +DataVector<Y_v2>& makeVecs() +{ + auto vec = CxxUtils::make_unique<DataVector<Y_v2> >(); + for (size_t i = 0; i < 10; i++) + vec->push_back (new Y_v2(i)); + DataVector<Y_v2>& ret = *vec.get(); + SGTest::store.record (vec.release(), "vec"); + return ret; +} + + +int main() +{ + SGTest::initTestStore(); + ISvcLocator* pSvcLoc = nullptr; + if (!Athena_test::initGaudi("test.txt", pSvcLoc)) { + std::cerr << "This test can not be run" << std::endl; + return 0; + } + + TestCnvSvc* svc = new TestCnvSvc ("AthenaPoolCnvSvc", pSvcLoc); + ISvcManager* mgr = dynamic_cast<ISvcManager*> (pSvcLoc); + if (mgr->addService (svc).isFailure()) + std::abort(); + + gSystem->Load("libAthenaPoolCnvSvcTestDict"); + DataVector<Y_v2>& vec = makeVecs(); + test1 (pSvcLoc, *svc, vec); + test2 (pSvcLoc, *svc, vec); +} + diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/test/T_AthenaPoolxAODCnv_test.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/T_AthenaPoolxAODCnv_test.cxx new file mode 100644 index 0000000000000000000000000000000000000000..fd5216ce376899619839a63d6f4c48d3f9ebdb80 --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/T_AthenaPoolxAODCnv_test.cxx @@ -0,0 +1,161 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id$ +/** + * @file AthenaPoolCnvSvc/test/T_AthenaPoolxAODCnv_test.cxx + * @author scott snyder <snyder@bnl.gov> + * @date Jan, 2016 + * @brief Tests for T_AthenaPoolxAODCnv_test. + */ + + +#undef NDEBUG +#include "AthenaPoolCnvSvc/T_AthenaPoolxAODCnv.h" +#include "PersistentDataModel/TokenAddress.h" +#include "SGTools/TestStore.h" +#include "TestTools/initGaudi.h" +#include "CxxUtils/make_unique.h" +#include "TSystem.h" +#include "AthenaPoolCnvSvcTestDict.h" +#include "TestCnvSvcBase.icc" +#include <iostream> +#include <cassert> +#include <vector> + + +using namespace AthenaPoolCnvSvcTest; + + +std::string YCont_v1_guid = "05309E49-5567-4790-BE56-2E541E0B4B24"; +std::string YCont_v2_guid = "0CC6B32E-6C95-4B0E-B97A-9B9040A8A9BE"; + + +class TestCnvSvc + : public TestCnvSvcBase +{ +public: + TestCnvSvc (const std::string& name, ISvcLocator* svcloc) + : TestCnvSvcBase (name, svcloc), + m_pers1 (nullptr), + m_pers2 (nullptr) + {} + + virtual void setObjPtr(void*& obj, const Token* /*token*/) const override + { + if (m_pers2) { + DataVector<Y_v2>* v = new DataVector<Y_v2>; + for (const Y_v2* y : *m_pers2) + v->push_back (new Y_v2(*y)); + obj = v; + } + else if (m_pers1) { + DataVector<Y_v1>* v = new DataVector<Y_v1>; + for (const Y_v1* y : *m_pers1) + v->push_back (new Y_v1(*y)); + obj = v; + } + else + std::abort(); + } + + std::string m_name; + DataVector<Y_v1>* m_pers1; + DataVector<Y_v2>* m_pers2; +}; + + +class YCnv_v1 +{ +public: + typedef DataVector<Y_v2> Trans_t; + typedef DataVector<Y_v1> Pers_t; + + DataVector<Y_v2>* createTransient (const DataVector<Y_v1>* pers, MsgStream& msg) + { + auto trans = CxxUtils::make_unique<DataVector<Y_v2> >(); + persToTrans (pers, trans.get(), msg); + return trans.release(); + } + + void persToTrans (const DataVector<Y_v1>* pers, DataVector<Y_v2>* trans, MsgStream&) + { + for (const Y_v1* y : *pers) + trans->push_back (new Y_v2 (y->m_a * 3)); + } +}; + + +void test1 (ISvcLocator* svcloc, TestCnvSvc& testsvc) +{ + std::cout << "test1\n"; + const size_t N = 10; + + T_AthenaPoolxAODCnv<DataVector<Y_v2>, YCnv_v1> cnv (svcloc); + assert (static_cast<AthenaPoolConverter&>(cnv).initialize().isSuccess()); + + DataVector<Y_v2> trans1; + for (size_t i=0; i < N; i++) + trans1.push_back (new Y_v2(i)); + + DataVector<Y_v2>* pers1 = cnv.createPersistent (&trans1); + assert (pers1->size() == trans1.size()); + for (size_t i = 0; i < N; i++) + assert ((*pers1)[i] == trans1[i]); + + testsvc.m_pers2 = pers1; + Token* token = new Token; + token->setClassID (Guid (YCont_v2_guid)); + TokenAddress taddr (0, 0, "xyz", "key", 0, token); + + DataObject* pObj = nullptr; + assert (cnv.createObj (&taddr, pObj).isSuccess()); + auto* trans2 = SG::Storable_cast<DataVector<Y_v2> > (pObj); + assert (trans2->size() == 10); + for (size_t i = 0; i < 10; i++) + assert ((*trans2)[i]->m_a == (int)i); + assert (trans2->getConstStoreLink().dataID() == "keyAux."); + delete pObj; + delete pers1; + testsvc.m_pers2 = nullptr; + + DataVector<Y_v1> pers_old; + for (size_t i=0; i < N; i++) + pers_old.push_back (new Y_v1(i)); + testsvc.m_pers1 = &pers_old; + token->setClassID (Guid (YCont_v1_guid)); + pObj = nullptr; + assert (cnv.createObj (&taddr, pObj).isSuccess()); + auto* trans3 = SG::Storable_cast<DataVector<Y_v2> > (pObj); + assert (trans3->size() == 10); + for (size_t i = 0; i < 10; i++) + assert ((*trans3)[i]->m_a == (int)i*3); + assert (trans3->getConstStoreLink().dataID() == "keyAux."); + delete pObj; + + token->setClassID (Guid ("8ACD1C53-D3C7-4FE5-9BC0-E388701DB8FA")); + pObj = nullptr; + assert (cnv.createObj (&taddr, pObj).isFailure()); +} + + +int main() +{ + SGTest::initTestStore(); + ISvcLocator* pSvcLoc = nullptr; + if (!Athena_test::initGaudi("test.txt", pSvcLoc)) { + std::cerr << "This test can not be run" << std::endl; + return 0; + } + + TestCnvSvc* svc = new TestCnvSvc ("AthenaPoolCnvSvc", pSvcLoc); + ISvcManager* mgr = dynamic_cast<ISvcManager*> (pSvcLoc); + if (mgr->addService (svc).isFailure()) + std::abort(); + + gSystem->Load("libAthenaPoolCnvSvcTestDict"); + + test1 (pSvcLoc, *svc); + return 0; +} diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/test/TestCnvSvcBase.icc b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/TestCnvSvcBase.icc new file mode 100644 index 0000000000000000000000000000000000000000..a245f02b89af2ba0675e2adb82a968ae8904044b --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/TestCnvSvcBase.icc @@ -0,0 +1,145 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id$ +/** + * @file AthenaPoolCnvSvc/test/TestCnvSvcBase.icc + * @author scott snyder <snyder@bnl.gov> + * @date Jan, 2016 + * @brief Helper for AthenaPoolCnvSvc unit tests. + */ + + +#include "AthenaPoolCnvSvc/IAthenaPoolCnvSvc.h" +#include "AthenaBaseComps/AthService.h" +#include "StorageSvc/DbType.h" + + +class TestCnvSvcBase + : public IAthenaPoolCnvSvc, public AthService +{ +public: + TestCnvSvcBase (const std::string& name, ISvcLocator* svcloc) + : AthService (name, svcloc), + m_name (name) + {} + + virtual StatusCode disconnectOutput() override + { std::abort(); } + virtual const std::string& getOutputConnectionSpec() const override + { std::abort(); } + virtual std::string getOutputContainer(const std::string& /*typeName*/, + const std::string& /*key*/ = "") const override + { std::abort(); } + virtual pool::DbType technologyType() const override + { std::abort(); } + virtual IPoolSvc* getPoolSvc() override + { std::abort(); } + virtual const Token* registerForWrite(const Placement* /*placement*/, + const void* /*obj*/, + const RootType& /*classDesc*/) const override + { std::abort(); } + virtual bool useDetailChronoStat() const override + { std::abort(); } + virtual StatusCode createAddress(long /*svcType*/, + const CLID& /*clid*/, + const std::string* /*par*/, + const unsigned long* /*ip*/, + IOpaqueAddress*& /*refpAddress*/) override + { std::abort(); } + virtual StatusCode createAddress(long /*svcType*/, + const CLID& /*clid*/, + const std::string& /*refAddress*/, + IOpaqueAddress*& /*refpAddress*/) override + { std::abort(); } + virtual StatusCode convertAddress(const IOpaqueAddress* /*pAddress*/, + std::string& /*refAddress*/) override + + { std::abort(); } + virtual StatusCode makeServer(int /*num*/) override + { std::abort(); } + virtual StatusCode makeClient(int /*num*/) override + { std::abort(); } + virtual StatusCode cleanUp() override + { std::abort(); } + virtual StatusCode setInputAttributes(const std::string& /*fileName*/) override + { std::abort(); } + + virtual StatusCode initialize() override + { std::abort(); } + virtual StatusCode finalize() override + { std::abort(); } + virtual const CLID& objType() const override + { std::abort(); } + virtual long repSvcType() const override + { std::abort(); } + virtual StatusCode setDataProvider(IDataProviderSvc* /*pService*/) override + { std::abort(); } + virtual SmartIF<IDataProviderSvc>& dataProvider() const override + { std::abort(); } + virtual StatusCode setConversionSvc(IConversionSvc* /*pService*/) override + { std::abort(); } + virtual SmartIF<IConversionSvc>& conversionSvc() const override + { std::abort(); } + virtual StatusCode setAddressCreator(IAddressCreator* /*creator*/) override + { std::abort(); } + virtual SmartIF<IAddressCreator>& addressCreator() const override + { std::abort(); } + virtual StatusCode createObj(IOpaqueAddress* /*pAddress*/, DataObject*& /*refpObject*/) override + { std::abort(); } + virtual StatusCode fillObjRefs(IOpaqueAddress* /*pAddress*/, DataObject* /*pObject*/) override + { std::abort(); } + virtual StatusCode updateObj(IOpaqueAddress* /*pAddress*/, DataObject* /*refpObject*/) override + { std::abort(); } + virtual StatusCode updateObjRefs(IOpaqueAddress* /*pAddress*/, DataObject* /*pObject*/) override + { std::abort(); } + virtual StatusCode createRep(DataObject* /*pObject*/, IOpaqueAddress*& /*refpAddress*/) override + { std::abort(); } + virtual StatusCode fillRepRefs(IOpaqueAddress* /*pAddress*/, DataObject* /*pObject*/) override + { std::abort(); } + virtual StatusCode updateRep(IOpaqueAddress* /*pAddress*/, DataObject* /*pObject*/) override + { std::abort(); } + virtual StatusCode updateRepRefs(IOpaqueAddress* /*pAddress*/, DataObject* /*pObject*/) override + { std::abort(); } + virtual StatusCode addConverter(const CLID& /*clid*/) override + { std::abort(); } + virtual StatusCode removeConverter(const CLID& /*clid*/) override + { std::abort(); } + virtual IConverter* converter(const CLID& /*clid*/) override + { std::abort(); } + virtual StatusCode connectOutput(const std::string& /*outputFile*/) override + { std::abort(); } + virtual StatusCode readData() const override + { std::abort(); } + virtual const std::string& name() const override + { return m_name; } + virtual StatusCode addConverter(IConverter* /*pConverter*/) override + { std::abort(); } + virtual StatusCode connectOutput(const std::string& /*outputFile*/, + const std::string& /*openMode*/) override + { std::abort(); } + virtual StatusCode commitOutput(const std::string& /*outputFile*/, + bool /*do_commit*/) override + { std::abort(); } + + + + virtual StatusCode queryInterface(const InterfaceID &ti, void** pp) override + { + if (ti == IID_IAthenaPoolCnvSvc) { + *pp = this; + return StatusCode::SUCCESS; + } + return Service::queryInterface (ti, pp); + } + + virtual StatusCode registerCleanUp(IAthenaPoolCleanUp* /*cnv*/) override + { + return StatusCode::SUCCESS; + } + + std::string m_name; +}; + + diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/test/TestThinningSvc.icc b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/TestThinningSvc.icc new file mode 100644 index 0000000000000000000000000000000000000000..1cc613c983da70846d94d0ac7281746f34f1ddf8 --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/TestThinningSvc.icc @@ -0,0 +1,138 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id$ +/** + * @file TestThinningSvc.icc + * @author scott snyder <snyder@bnl.gov> + * @date Jul, 2014 + * @brief Dummy thinning service, for regression tests. + */ + + +#include "SGTools/DataProxy.h" +#include "SGTools/TestStore.h" +#include "AthenaKernel/IThinningSvc.h" +#include <map> + + +class TestThinningSvc + : virtual public IThinningSvc, public SGTest::TestStore +{ +public: + StatusCode sysInitialize() override + { std::cout << "sysInitialize\n"; std::abort(); } + StatusCode sysStart() override + { std::cout << "sysStart\n"; std::abort(); } + StatusCode sysStop() override + { std::cout << "sysStop\n"; std::abort(); } + StatusCode sysFinalize() override + { std::cout << "sysFinalize\n"; std::abort(); } + StatusCode sysReinitialize() override + { std::cout << "sysReinitialize\n"; std::abort(); } + StatusCode sysRestart() override + { std::cout << "sysRestart\n"; std::abort(); } + StatusCode configure() override + { std::cout << "configure\n"; std::abort(); } + StatusCode initialize() override + { std::cout << "initialize\n"; std::abort(); } + StatusCode start() override + { std::cout << "start\n"; std::abort(); } + StatusCode stop() override + { std::cout << "stop\n"; std::abort(); } + StatusCode finalize() override + { std::cout << "finalize\n"; std::abort(); } + StatusCode terminate() override + { std::cout << "terminate\n"; std::abort(); } + StatusCode reinitialize() override + { std::cout << "reinitialize\n"; std::abort(); } + StatusCode restart() override + { std::cout << "restart\n"; std::abort(); } + Gaudi::StateMachine::State FSMState() const override + { std::cout << "FSMState\n"; std::abort(); } + Gaudi::StateMachine::State targetFSMState() const override + { std::cout << "targetFSMState\n"; std::abort(); } + void setServiceManager (ISvcManager*) override + { std::cout << "setServiceManager\n"; std::abort(); } + StatusCode register_slimmer (Athena::ISlimmingHdlr */*handler*/) override + { std::cout << "register_slimmer\n"; std::abort(); } + virtual Athena::IThinningHdlr* handler( SG::DataProxy* /*proxy*/ ) override + { std::cout << "handler\n"; std::abort(); } + virtual StatusCode + filter_impl( Athena::IThinningHdlr* /*handler*/, + SG::DataProxy* /*proxy*/, + const Filter_t& /*filter*/, + const IThinningSvc::Operator::Type /*op*/ = Operator::And ) override + { std::cout << "filter_impl\n"; std::abort(); } + StatusCode commit() override + { std::cout << "commit\n"; std::abort(); } + StatusCode rollback() override + { std::cout << "rollback\n"; std::abort(); } + virtual + sgkey_t stringToKey (const std::string& /*str*/, CLID /*clid*/) override + { std::abort(); } + virtual + const std::string* keyToString (sgkey_t /*key*/) const override + { std::abort(); } + virtual + const std::string* keyToString (sgkey_t /*key*/, + CLID& /*clid*/) const override + { std::abort(); } + virtual + void registerKey (sgkey_t /*key*/, + const std::string& /*str*/, + CLID /*clid*/) override + { std::abort(); } + + virtual + bool thinningOccurred() const override + { + return m_map.size() > 0; + } + + virtual + bool is_thinned_impl(const SG::DataProxy* p) const override + { + proxymap_t::const_iterator i = m_map.find (p); + if (i != m_map.end()) + return true; + return false; + } + + using SGTest::TestStore::proxy; + virtual + SG::DataProxy* proxy(const void* const pTransient) const override + { + return SG::CurrentEventStore::store()->proxy (pTransient); + } + + virtual + std::size_t index_impl( const SG::DataProxy* objProxy, + std::size_t idx ) const override + { + proxymap_t::const_iterator i = m_map.find (objProxy); + if (i != m_map.end()) { + map_t::const_iterator ii = i->second.find (idx); + if (ii != i->second.end()) + return ii->second; + } + return idx; + } + + void remap (const void* obj, size_t from, size_t to) + { + SG::DataProxy* proxy = SG::CurrentEventStore::store()->proxy (obj); + + if (!proxy) { + std::abort(); + } + + m_map[proxy][from] = to; + } + + typedef std::map<size_t, size_t> map_t; + + typedef std::map<const SG::DataProxy*, map_t> proxymap_t; + proxymap_t m_map; +}; diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/test/exceptions_test.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/exceptions_test.cxx new file mode 100644 index 0000000000000000000000000000000000000000..c72d18fa9ce71295725109a334c3354f9e60144b --- /dev/null +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/exceptions_test.cxx @@ -0,0 +1,35 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id$ +/** + * @file AthenaPoolCnvSvc/test/exceptions_test.cxx + * @author scott snyder <snyder@bnl.gov> + * @date Jan, 2016 + * @brief Tests for exceptions. + */ + + +#undef NDEBUG +#include "AthenaPoolCnvSvc/exceptions.h" +#include <iostream> +#include <typeinfo> + + +void test1() +{ + std::cout << "test1\n"; + + std::cout << AthenaPoolCnvSvc::ExcNoDictForClass (typeid(int)).what() << "\n"; + std::cout << AthenaPoolCnvSvc::ExcUnsupportedVersion + ( typeid(int), + Guid("336F636C-D414-4261-8286-37429F353F0A") ).what() << "\n"; +} + + +int main() +{ + test1(); + return 0; +}