diff --git a/Control/AthContainers/AthContainers/AuxTypeRegistry.h b/Control/AthContainers/AthContainers/AuxTypeRegistry.h index 79661353a42e241cc6004f917479bb6f7030e2e8..62a8b883078c14df07eb8a1077d700bb408ca617 100644 --- a/Control/AthContainers/AthContainers/AuxTypeRegistry.h +++ b/Control/AthContainers/AthContainers/AuxTypeRegistry.h @@ -1,10 +1,8 @@ // 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 + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ - -// $Id: AuxTypeRegistry.h 784452 2016-11-15 21:40:41Z ssnyder $ /** * @file AthContainers/AuxTypeRegistry.h * @author scott snyder <snyder@bnl.gov> @@ -23,6 +21,8 @@ #include "AthContainers/tools/AuxTypeVector.h" #include "AthContainers/tools/AuxTypeVectorFactory.h" #include "AthContainers/tools/threading.h" +#include "CxxUtils/ConcurrentStrMap.h" +#include "CxxUtils/SimpleUpdater.h" #include "CxxUtils/bitmask.h" #ifndef XAOD_STANDALONE #include "AthenaKernel/IInputRename.h" @@ -289,7 +289,7 @@ public: * @brief Return the vector factory for a given vector element type. * @param ti The type of the vector element. * - * Returns 0 if the type is not known. + * Returns nullptr if the type is not known. * (Use @c addFactory to add new mappings.) */ const IAuxTypeVectorFactory* getFactory (const std::type_info& ti) const; @@ -393,25 +393,12 @@ private: * @brief Return the vector factory for a given auxid. * @param auxid The desired aux data item. * - * Returns 0 if the type is not known. + * Returns nullptr if the type is not known. * (Use @c addFactory to add new mappings.) */ const IAuxTypeVectorFactory* getFactory (SG::auxid_t auxid) const; - /** - * @brief Return the vector factory for a given vector element type. - * (external locking) - * @param lock The registry lock. - * @param ti The type of the vector element. - * - * Returns 0 if the type is not known. - * (Use @c addFactory to add new mappings.) - */ - const IAuxTypeVectorFactory* getFactory (lock_t& lock, - const std::type_info& ti) const; - - /** * @brief Add a new type -> factory mapping. (external locking) * @param lock The registry lock. @@ -447,6 +434,15 @@ private: IAuxTypeVectorFactory* makeFactoryNull() const; + /** + * @brief Return the key used to look up an entry in m_auxids. + * @param name The name of the aux data item. + * @param clsname The name of its associated class. May be blank. + */ + static std::string makeKey (const std::string& name, + const std::string& clsname); + + /// Hold information about one aux data item. struct typeinfo_t { @@ -472,30 +468,12 @@ private: AthContainers_detail::concurrent_vector<typeinfo_t> m_types; - /// Key used for name -> auxid lookup. - /// First element is name, second is class name. - typedef std::pair<std::string, std::string> key_t; - - - /// Helper to hash the key type. - struct stringpair_hash - { - size_t operator() (const key_t& key) const - { - return shash (key.first) + shash (key.second); - } - std::hash<std::string> shash; - }; - - /// Map from name -> auxid. - typedef std::unordered_map<key_t, SG::auxid_t, stringpair_hash> - id_map_t; + using id_map_t = CxxUtils::ConcurrentStrMap<SG::auxid_t, CxxUtils::SimpleUpdater>; id_map_t m_auxids; /// Map from type_info name -> IAuxTypeVectorFactory. - typedef std::unordered_map<std::string, - const IAuxTypeVectorFactory*> ti_map_t; + using ti_map_t = CxxUtils::ConcurrentStrMap<const IAuxTypeVectorFactory*, CxxUtils::SimpleUpdater>; ti_map_t m_factories; /// Hold additional factory instances we need to delete. diff --git a/Control/AthContainers/AthContainers/AuxTypeRegistry.icc b/Control/AthContainers/AthContainers/AuxTypeRegistry.icc index f888377cebbacdf379784c5a802b5a7d5ad357c1..386ca1b5dd2f3ff8d1eec37bca14a479dea6581d 100644 --- a/Control/AthContainers/AthContainers/AuxTypeRegistry.icc +++ b/Control/AthContainers/AthContainers/AuxTypeRegistry.icc @@ -1,8 +1,6 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ - -// $Id: AuxTypeRegistry.icc 602003 2014-06-16 17:07:01Z ssnyder $ /** * @file AthContainers/AuxTypeRegistry.icc * @author scott snyder <snyder@bnl.gov> @@ -38,7 +36,7 @@ AuxTypeRegistry::getAuxID (const std::string& name, * @brief Return the vector factory for a given auxid. * @param auxid The desired aux data item. * - * Returns 0 if the type is not known. + * Returns nullptr if the type is not known. * (Use @c addFactory to add new mappings.) */ inline diff --git a/Control/AthContainers/Root/AuxTypeRegistry.cxx b/Control/AthContainers/Root/AuxTypeRegistry.cxx index 46da2502ef06d6064aee43b16df8b4ce1377f38c..0bf50e9e99bbac1d0f3eb24d7f060f3db11a328a 100644 --- a/Control/AthContainers/Root/AuxTypeRegistry.cxx +++ b/Control/AthContainers/Root/AuxTypeRegistry.cxx @@ -1,8 +1,6 @@ /* - Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ - -// $Id$ /** * @file AthContainers/AuxTypeRegistry.cxx * @author scott snyder <snyder@bnl.gov> @@ -68,9 +66,12 @@ SG::auxid_t AuxTypeRegistry::findAuxID( const std::string& name, const std::string& clsname ) const { - lock_t lock (m_mutex); - key_t key (name, clsname); - id_map_t::const_iterator i = m_auxids.find (key); + // No locking needed here. + // The extra test here is to avoid having to copy a string + // in the common case where clsname is blank. + id_map_t::const_iterator i = m_auxids.find (clsname.empty() ? + name : + makeKey (name, clsname)); if (i != m_auxids.end()) { return i->second; } @@ -121,6 +122,21 @@ AuxTypeRegistry::makeVectorFromData (SG::auxid_t auxid, } +/** + * @brief Return the key used to look up an entry in m_auxids. + * @param name The name of the aux data item. + * @param clsname The name of its associated class. May be blank. + */ +std::string AuxTypeRegistry::makeKey (const std::string& name, + const std::string& clsname) +{ + if (clsname.empty()) { + return name; + } + return clsname + "::" + name; +} + + /** * @brief Return the name of an aux data item. @@ -294,34 +310,16 @@ void AuxTypeRegistry::clear (SG::auxid_t auxid, void* dst, size_t dst_index) * @brief Return the vector factory for a given vector element type. * @param ti The type of the vector element. * - * Returns 0 if the type is not known. + * Returns nullptr if the type is not known. * (Use @c addFactory to add new mappings.) */ const IAuxTypeVectorFactory* AuxTypeRegistry::getFactory (const std::type_info& ti) const -{ - lock_t lock (m_mutex); - return getFactory (lock, ti); -} - - -/** - * @brief Return the vector factory for a given vector element type. - * (external locking) - * @param lock The registry lock. - * @param ti The type of the vector element. - * - * Returns 0 if the type is not known. - * (Use @c addFactory to add new mappings.) - */ -const IAuxTypeVectorFactory* -AuxTypeRegistry::getFactory (lock_t& /*lock*/, - const std::type_info& ti) const { ti_map_t::const_iterator it = m_factories.find (ti.name()); if (it != m_factories.end()) return it->second; - return 0; + return nullptr; } @@ -358,7 +356,7 @@ void AuxTypeRegistry::addFactory (lock_t& /*lock*/, const std::type_info& ti, IAuxTypeVectorFactory* factory) { - ti_map_t::iterator it = m_factories.find (ti.name()); + ti_map_t::const_iterator it = m_factories.find (ti.name()); if (it != m_factories.end()) { if (it->second->isDynamic() && !factory->isDynamic()) { // Replacing a dynamic factory with a non-dynamic one. @@ -366,13 +364,13 @@ void AuxTypeRegistry::addFactory (lock_t& /*lock*/, // Instead, push it on a vector to remember it so we can delete // it later. m_oldFactories.push_back (it->second); - it->second = factory; + m_factories.insert_or_assign (ti.name(), factory); } else delete factory; } else - m_factories[ti.name()] = factory; + m_factories.insert_or_assign (ti.name(), factory); } @@ -382,6 +380,8 @@ void AuxTypeRegistry::addFactory (lock_t& /*lock*/, * Populates the type -> factory mappings for standard C++ types. */ AuxTypeRegistry::AuxTypeRegistry() + : m_auxids (id_map_t::Updater_t()), + m_factories (ti_map_t::Updater_t()) { m_types.reserve (auxid_set_size_hint); @@ -419,7 +419,7 @@ AuxTypeRegistry::AuxTypeRegistry() */ AuxTypeRegistry::~AuxTypeRegistry() { - for (ti_map_t::value_type& p : m_factories) + for (auto& p : m_factories) delete p.second; for (const IAuxTypeVectorFactory* p : m_oldFactories) delete p; @@ -453,9 +453,9 @@ AuxTypeRegistry::findAuxID (const std::string& name, const std::type_info& ti, IAuxTypeVectorFactory* (AuxTypeRegistry::*makeFactory) () const) { - lock_t lock (m_mutex); - key_t key (name, clsname); - id_map_t::iterator i = m_auxids.find (key); + lock_t lock (m_mutex); // May be able to relax this lock. + std::string key = makeKey (name, clsname); + id_map_t::const_iterator i = m_auxids.find (key); if (i != m_auxids.end()) { typeinfo_t& m = m_types[i->second]; @@ -479,7 +479,7 @@ AuxTypeRegistry::findAuxID (const std::string& name, IAuxTypeVectorFactory* fac2 = (*this.*makeFactory)(); if (fac2) { addFactory (lock, ti, fac2); - m.m_factory = getFactory (lock, ti); + m.m_factory = getFactory (ti); } } return i->second; @@ -490,12 +490,12 @@ AuxTypeRegistry::findAuxID (const std::string& name, // fall through, get a new auxid and real type info // new auxid needed so a new data vector is created in the AuxStore } - const IAuxTypeVectorFactory* fac = getFactory (lock, ti); + const IAuxTypeVectorFactory* fac = getFactory (ti); if (!fac || fac->isDynamic()) { IAuxTypeVectorFactory* fac2 = (*this.*makeFactory)(); if (fac2) { addFactory (lock, ti, fac2); - fac = getFactory (lock, ti); + fac = getFactory (ti); } } if (!fac) return null_auxid; @@ -508,7 +508,7 @@ AuxTypeRegistry::findAuxID (const std::string& name, t.m_factory = fac; t.m_flags = flags; AthContainers_detail::fence_seq_cst(); - m_auxids[key] = auxid; + m_auxids.insert_or_assign (key, auxid); return auxid; }