/* Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration */ #include "IOVSvc/CondSvc.h" #include "AthenaKernel/CondCont.h" #include "GaudiKernel/EventIDBase.h" #include "AthenaKernel/StoreID.h" #include "AthenaKernel/BaseInfo.h" //--------------------------------------------------------------------------- CondSvc::CondSvc( const std::string& name, ISvcLocator* svcLoc ): base_class(name,svcLoc), m_sgs("StoreGateSvc/ConditionStore", name) { } //--------------------------------------------------------------------------- CondSvc::~CondSvc() { } //--------------------------------------------------------------------------- StatusCode CondSvc::initialize() { // Initialise mother class in order to print DEBUG messages during initialize() StatusCode sc(AthService::initialize()); msg().setLevel( m_outputLevel.value() ); if (!sc.isSuccess()) { warning () << "Base class could not be initialized" << endmsg; return StatusCode::FAILURE; } if (!m_sgs.isValid()) { error() << "could not get ConditionStore" << endmsg; return StatusCode::FAILURE; } return StatusCode::SUCCESS; } //--------------------------------------------------------------------------- // void // CondSvc::dump() const { // std::ostringstream ost; // dump(ost); // info() << ost.str() << endmsg; // } //--------------------------------------------------------------------------- void CondSvc::dump(std::ostream& ost) const { std::lock_guard<mutex_t> lock(m_lock); ost << "CondSvc::dump()"; ost << "\ndumping id->alg map\n"; for (const auto& ent : m_idMap) { ost << std::endl << " + " << ent.first << " : "; for (const auto& a : ent.second) { ost << " " << a->name(); } } ost << "\n\ndumping alg->id map\n"; for (const auto& ent : m_algMap) { ost << std::endl << " + " << ent.first->name() << " : "; for (const auto& a : ent.second) { ost << " " << a; } } ost << "\n\ndumping ConditionStore:\n\n"; SG::ConstIterator<CondContBase> cib,cie; if (m_sgs->retrieve(cib,cie).isSuccess()) { while (cib != cie) { ost << " + "; cib->list(ost); ++cib; } } ost << "\n"; } //--------------------------------------------------------------------------- StatusCode CondSvc::finalize() { ATH_MSG_DEBUG( "CondSvc::finalize()" ); return StatusCode::SUCCESS; } StatusCode CondSvc::stop() { ATH_MSG_DEBUG( "CondSvc::stop()" ); if (msgLvl(MSG::DEBUG)) { std::ostringstream ost; dump(ost); ATH_MSG_DEBUG( ost.str() ); } return StatusCode::SUCCESS; } //--------------------------------------------------------------------------- StatusCode CondSvc::regHandle(IAlgorithm* alg, const Gaudi::DataHandle& dh) { std::lock_guard<mutex_t> lock(m_lock); return regHandle_i(alg, dh); } //--------------------------------------------------------------------------- // separate implementation to avoid the use of a recursive mutex StatusCode CondSvc::regHandle_i(IAlgorithm* alg, const Gaudi::DataHandle& dh) { ATH_MSG_DEBUG( "regHandle: alg: " << alg->name() << " id: " << dh.fullKey() ); if (dh.mode() != Gaudi::DataHandle::Writer) { info() << dh.fullKey() << " is a ReadHandle. no need to register" << endmsg; return StatusCode::SUCCESS; } id_map_t::iterator itd2 = m_idMap.find(dh.fullKey()); if (itd2 != m_idMap.end()) { IAlgorithm *ia = *(itd2->second.begin()); if (ia->name() != alg->name()) { error() << "WriteCondHandle " << dh.fullKey() << " is already registered against a different Algorithm " << ia->name() << ". This is not allowed." << endmsg; return StatusCode::FAILURE; } // FIXME : so why is it a set<IAlgorithm*> ?? } // m_keyMap[key] = dh.fullKey(); m_condAlgs.insert(alg); m_condIDs.emplace( dh.fullKey() ); // id_map_t::iterator itd2 = m_idMap.find(dh.fullKey()); if (itd2 != m_idMap.end()) { itd2->second.insert( alg ); } else { m_idMap[dh.fullKey()] = IAlgHashSet { alg }; } alg_map_t::iterator ita2 = m_algMap.find(alg); if (ita2 != m_algMap.end()) { ita2->second.insert( dh.fullKey() ); } else { m_algMap[alg] = DataObjIDColl { dh.fullKey() }; } StatusCode sc(StatusCode::SUCCESS); CLID clid = dh.fullKey().clid(); const SG::BaseInfoBase* bib = SG::BaseInfoBase::find( clid ); if ( bib ) { for (CLID clid2 : bib->get_bases()) { if (clid2 != clid) { SG::VarHandleKey vhk(clid2,dh.objKey(),Gaudi::DataHandle::Writer, StoreID::storeName(StoreID::CONDITION_STORE)); if (regHandle_i(alg, vhk).isFailure()) { sc = StatusCode::FAILURE; } } } } return sc; } //--------------------------------------------------------------------------- bool CondSvc::getInvalidIDs(const EventContext& ctx, DataObjIDColl& invalidIDs) { std::lock_guard<mutex_t> lock(m_lock); EventIDBase now(ctx.eventID()); std::ostringstream ost; ost << "getInvalidIDS " << ctx.eventID() << ": retrieving all ConstIterator<CondContBase>"; SG::ConstIterator<CondContBase> cib, cie; if (m_sgs->retrieve(cib,cie).isSuccess()) { while(cib != cie) { ost << std::endl << " + " << cib.key() << " " << cib->valid(now) << " id: " << cib->id(); if (! (cib->valid(now)) ) { invalidIDs.insert( cib->id() ); } ++cib; } } else { ATH_MSG_DEBUG(ost.str()); ATH_MSG_DEBUG("ConditionStore is empty"); return false; } ost << std::endl << " -> found " << invalidIDs.size() << " invalid IDs"; ATH_MSG_DEBUG( ost.str() ); return true; } //--------------------------------------------------------------------------- bool CondSvc::getIDValidity(const EventContext& ctx, DataObjIDColl& validIDs, DataObjIDColl& invalidIDs) { std::lock_guard<mutex_t> lock(m_lock); EventIDBase now(ctx.eventID()); std::ostringstream ost; ost << "getValidIDS " << ctx.eventID() << ": retrieving all ConstIterator<CondContBase>"; SG::ConstIterator<CondContBase> cib, cie; if (m_sgs->retrieve(cib,cie).isSuccess()) { while(cib != cie) { ost << std::endl << " + " << cib.key() << " v: " << cib->valid(now) << " id: " << cib->id(); if ( cib->valid(now) ) { validIDs.insert( cib->id() ); } else { invalidIDs.insert( cib->id() ); } ++cib; } } else { ATH_MSG_DEBUG( ost.str() ); ATH_MSG_DEBUG( "Condition store empty." ); return false; } ost << std::endl << " -> found " << validIDs.size() << " valid, " << invalidIDs.size() << " invalid IDs"; ATH_MSG_DEBUG( ost.str() ); return true; } //--------------------------------------------------------------------------- bool CondSvc::getValidIDs(const EventContext& ctx, DataObjIDColl& validIDs) { std::lock_guard<mutex_t> lock(m_lock); EventIDBase now(ctx.eventID()); std::ostringstream ost; ost << "getValidIDS " << ctx.eventID() << ": retrieving all ConstIterator<CondContBase>"; SG::ConstIterator<CondContBase> cib, cie; if (m_sgs->retrieve(cib,cie).isSuccess()) { while(cib != cie) { ost << std::endl << " + " << cib.key() << " v: " << cib->valid(now) << " id: " << cib->id(); if ( cib->valid(now) ) { validIDs.insert( cib->id() ); } ++cib; } } else { ATH_MSG_DEBUG( ost.str() ); ATH_MSG_DEBUG( "Condition store empty." ); return false; } ost << std::endl << " -> found " << validIDs.size() << " valid IDs"; ATH_MSG_DEBUG( ost.str() ); return true; } //--------------------------------------------------------------------------- bool CondSvc::isValidID(const EventContext& ctx, const DataObjID& id) const { std::lock_guard<mutex_t> lock(m_lock); EventIDBase now(ctx.eventID()); // FIXME: this is ugly, but we need to strip out the name of the store. std::string sk = id.key(); if (sk.find(StoreID::storeName(StoreID::CONDITION_STORE)) == 0) { sk.erase(0,15); } if (m_sgs->contains<CondContBase>( sk ) ) { CondContBase *cib; if (m_sgs->retrieve(cib, sk).isSuccess()) { ATH_MSG_VERBOSE("CondSvc::isValidID: now: " << ctx.eventID() << " id : " << id << (cib->valid(now) ? ": T" : ": F") ); return cib->valid(now); } } ATH_MSG_DEBUG("CondSvc::isValidID: now: " << ctx.eventID() << " id: " << id << " : F"); return false; } //--------------------------------------------------------------------------- bool CondSvc::isRegistered(const DataObjID& id) const { return (m_condIDs.find(id) != m_condIDs.end()); } //--------------------------------------------------------------------------- bool CondSvc::isRegistered(IAlgorithm* ialg) const { return (m_condAlgs.find(ialg) != m_condAlgs.end()); } //--------------------------------------------------------------------------- const DataObjIDColl& CondSvc::conditionIDs() const { return m_condIDs; }