diff --git a/Control/StoreGate/StoreGate/VarHandleKey.h b/Control/StoreGate/StoreGate/VarHandleKey.h index eaae6c24807a7f6b40f4c22a662d1e4732cbc541..bfa6e0320aeed2835c30080dfcbc477675ecdfd6 100644 --- a/Control/StoreGate/StoreGate/VarHandleKey.h +++ b/Control/StoreGate/StoreGate/VarHandleKey.h @@ -189,6 +189,13 @@ public: virtual StatusCode start(); + /** + * @brief Return the hashed StoreGate key. + * + * May be 0 if not yet initialized. + */ + SG::sgkey_t hashedKey() const; + private: /// Set the owning handle. Only callable from VarHandleBase. friend class VarHandleBase; @@ -228,6 +235,9 @@ private: /// StoreGate key, that doesn't include the storename std::string m_sgKey; + /// The hashed StoreGate key. May be 0 if not yet initialized. + SG::sgkey_t m_hashedKey = 0; + /// Cache test for whether we're referencing the event store. bool m_isEventStore = false; diff --git a/Control/StoreGate/StoreGate/VarHandleKey.icc b/Control/StoreGate/StoreGate/VarHandleKey.icc index 39415cc71ede3f83fcc9f8146b26114d967a61ca..c130972b2b3f5a4778fee14c6693ce918d4a4db3 100644 --- a/Control/StoreGate/StoreGate/VarHandleKey.icc +++ b/Control/StoreGate/StoreGate/VarHandleKey.icc @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration */ // $Id$ /** @@ -72,5 +72,16 @@ StatusCode VarHandleKey::start() return StatusCode::SUCCESS; } +/** + * @brief Return the hashed StoreGate key. + * + * May be 0 if not yet initialized. + */ +inline +SG::sgkey_t VarHandleKey::hashedKey() const +{ + return m_hashedKey; +} + } // namespace SG diff --git a/Control/StoreGate/share/VarHandleBase_test.txt b/Control/StoreGate/share/VarHandleBase_test.txt index ec103ddc669252cfc6e863edd30e1925f9bf4cf3..78e73d95195a425f6c729e2b07e5b4b66915bd62 100644 --- a/Control/StoreGate/share/VarHandleBase_test.txt +++ b/Control/StoreGate/share/VarHandleBase_test.txt @@ -1,2 +1,3 @@ +ApplicationMgr.ExtSvc={"StoreGateSvc/StoreGateSvc"}; ApplicationMgr.ExtSvc={"StoreGateSvc/OtherStore"}; OtherStore.ProxyProviderSvc=""; diff --git a/Control/StoreGate/src/VarHandleBase.cxx b/Control/StoreGate/src/VarHandleBase.cxx index a1d8acb6dff6d15d6cc56efd3e265c10095ea29c..51c38db1654606ce705889efc11abeb17214265c 100644 --- a/Control/StoreGate/src/VarHandleBase.cxx +++ b/Control/StoreGate/src/VarHandleBase.cxx @@ -504,7 +504,11 @@ namespace SG { if (store) m_store = store; } - StatusCode sc = this->setState(m_store->proxy(this->clid(), this->key())); + SG::DataProxy* proxy = m_store->proxy_exact (m_key->hashedKey()); + if (!proxy) { + proxy = m_store->proxy(this->clid(), this->key()); + } + StatusCode sc = this->setState(proxy); // Failure to find the proxy is ok in the case of a @c WriteHandle // that has not yet been written to. diff --git a/Control/StoreGate/src/VarHandleKey.cxx b/Control/StoreGate/src/VarHandleKey.cxx index 9eeae80388a5e30c66e6e13cc3e990107f0f5c54..0b798cd38893091a48296217b466171e2f21c7bd 100644 --- a/Control/StoreGate/src/VarHandleKey.cxx +++ b/Control/StoreGate/src/VarHandleKey.cxx @@ -112,6 +112,7 @@ StatusCode VarHandleKey::initialize (bool used /*= true*/) if (!used) { Gaudi::DataHandle::updateKey ( "" ); m_sgKey = ""; + m_hashedKey = 0; return StatusCode::SUCCESS; } @@ -130,6 +131,8 @@ StatusCode VarHandleKey::initialize (bool used /*= true*/) return StatusCode::FAILURE; } + m_hashedKey = m_storeHandle->stringToKey (m_sgKey, clid()); + return StatusCode::SUCCESS; } @@ -216,6 +219,8 @@ void VarHandleKey::updateKey(const std::string& /*key*/) const void VarHandleKey::parseKey (const std::string& key, const std::string& storeName) { + m_hashedKey = 0; + std::string sn; // test if storeName has classname std::string::size_type sp = storeName.find("/"); @@ -296,6 +301,7 @@ void VarHandleKey::updateHandle (const std::string& name) // Don't invalidate a stored pointer if the handle is already pointing // at the desired service. if (m_storeHandle.name() != name) { + m_hashedKey = 0; m_storeHandle = ServiceHandle<IProxyDict>(name, "VarHandleKey"); m_isEventStore = (name == StoreID::storeName(StoreID::EVENT_STORE) || name == StoreID::storeName(StoreID::PILEUP_STORE)); diff --git a/Control/StoreGate/test/ReadHandle_test.cxx b/Control/StoreGate/test/ReadHandle_test.cxx index a84d21e4b107ea3523a76a176c413319a5219534..2315d1ebdf35608dc966420940ce1c158216ad74 100644 --- a/Control/StoreGate/test/ReadHandle_test.cxx +++ b/Control/StoreGate/test/ReadHandle_test.cxx @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration */ // $Id$ @@ -14,6 +14,7 @@ #undef NDEBUG #include "AthenaKernel/ExtendedEventContext.h" #include "StoreGate/ReadHandle.h" +#include "StoreGate/StoreGateSvc.h" #include "StoreGate/exceptions.h" #include "SGTools/TestStore.h" #include "AthenaKernel/CLASS_DEF.h" @@ -21,6 +22,7 @@ #include "TestTools/expect_exception.h" #include "AthenaKernel/errorcheck.h" #include "CxxUtils/unused.h" +#include "boost/timer/timer.hpp" #include <cassert> #include <iostream> @@ -335,7 +337,40 @@ void test6() } -int main() +//************************************************************************ + + +unsigned int perftest (ISvcLocator* svcloc, unsigned int ntry) +{ + StoreGateSvc* sg = nullptr; + assert (svcloc->service ("StoreGateSvc", sg).isSuccess()); + assert (sg->record (std::make_unique<MyObj> (42), "MyObj", false).isSuccess()); + + SG::ReadHandleKey<MyObj> key ("MyObj"); + assert (key.initialize().isSuccess()); + + EventContext ctx; + ctx.setExtension( Atlas::ExtendedEventContext(sg->hiveProxyDict()) ); + unsigned int sum = 0; + boost::timer::cpu_timer timer; + for (unsigned int i=0; i < ntry; i++) { + SG::ReadHandle<MyObj> h (key, ctx); + sum += h->x; + } + timer.stop(); + boost::timer::cpu_times times = timer.elapsed(); + std::cout << ntry << " times: " << boost::timer::format(times); + std::cout << "Each: " << (float)times.user / ntry / 1000 << " us (user)\n"; + + return sum; +} + + + +//************************************************************************ + + +int main (int argc, char** argv) { errorcheck::ReportMessage::hideErrorLocus(); ISvcLocator* svcloc; @@ -344,6 +379,17 @@ int main() return 1; } + if (argc >= 2 && strncmp (argv[1], "--perf", 6) == 0) { + unsigned int ntry = 1000000; + const char* p = strchr (argv[1], '='); + if (p) { + ntry = atoi (p+1); + if (ntry < 1) ntry = 1; + } + perftest (svcloc, ntry); + return 0; + } + test1(); test2(); test3(); diff --git a/Control/StoreGate/test/VarHandleKey_test.cxx b/Control/StoreGate/test/VarHandleKey_test.cxx index ecdc129c79b52b3fc2849f5f281d6a68e9ab1135..835c7ac421b70c860147c5afd9fdd1139b89d81b 100644 --- a/Control/StoreGate/test/VarHandleKey_test.cxx +++ b/Control/StoreGate/test/VarHandleKey_test.cxx @@ -40,11 +40,13 @@ void test1() assert (k1.mode() == Gaudi::DataHandle::Reader); assert (k1.storeHandle().name() == "StoreGateSvc"); assert (!k1.storeHandle().isSet()); + assert (k1.hashedKey() == 0); assert (k1.initialize().isSuccess()); assert (k1.storeHandle().isSet()); assert (k1.start().isSuccess()); assert (!k1.isCondition()); assert (!k1.empty()); + assert (k1.hashedKey() == 752331202); k1 = "aab"; assert (k1.clid() == 1234);