/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
FWCore/Framework/interface/EventSetupRecord.h
248 строк
10 KB
Chris Jones
Return registered DataKeys by const ref
24 апр 2025, 22:00
24 апр 2025, 22:00
c63aa5b
Код
Авторство
О чём код?
// -*- C++ -*- #ifndef FWCore_Framework_EventSetupRecord_h #define FWCore_Framework_EventSetupRecord_h // // Package: Framework // Class : EventSetupRecord // /**\class edm::eventsetup::EventSetupRecord Description: Base class for all Records in an EventSetup. A record is associated with data with the same lifetime. Usage: This class contains the interface that clients of the EventSetup use to get data associated with a record. This class holds a pointer to an EventSetupRecordImpl class, which is the class used to get the ESProductResolvers associated with a given Record. It also has a pointer to the EventSetupImpl which is used to lookup dependent records in DependentRecordImplementation. It is important for the management of the Records that each Record know the ValidityInterval that represents the time over which its data is valid. The ValidityInterval is set by its EventSetupRecordProvider using the 'set' function. This quantity can be recovered through the 'validityInterval' method. Most of the time one uses a record obtained from an EventSetup object and in that case the pointers this contains will be properly initialized automatically. If you construct a record object directly (usually using a type derived from this), then only a very limited subset of functions can be called because most of the member functions will dereference one of the null pointers and seg fault. */ // // Author: Chris Jones // Created: Fri Mar 25 14:38:35 EST 2005 // // user include files #include "FWCore/Framework/interface/FunctorESHandleExceptionFactory.h" #include "FWCore/Framework/interface/DataKey.h" #include "FWCore/Framework/interface/HCTypeTag.h" #include "FWCore/Framework/interface/NoProductResolverException.h" #include "FWCore/Framework/interface/ValidityInterval.h" #include "FWCore/Framework/interface/EventSetupRecordImpl.h" #include "FWCore/Utilities/interface/ESGetToken.h" #include "FWCore/Utilities/interface/ESGetTokenGeneric.h" #include "FWCore/Utilities/interface/ESIndices.h" #include "FWCore/Utilities/interface/Likely.h" // system include files #include <exception> #include <memory> #include <utility> #include <vector> #include <cassert> #include <limits> // forward declarations namespace cms { class Exception; } class testEventsetup; class testEventsetupRecord; namespace edm { class ESHandleExceptionFactory; class ESParentContext; class EventSetupImpl; namespace eventsetup { struct ComponentDescription; class EventSetupRecordKey; class EventSetupRecord { public: EventSetupRecord(); EventSetupRecord(EventSetupRecord&&) = default; EventSetupRecord& operator=(EventSetupRecord&&) = default; EventSetupRecord(EventSetupRecord const&) = default; EventSetupRecord& operator=(EventSetupRecord const&) = default; virtual ~EventSetupRecord(); // ---------- const member functions --------------------- ValidityInterval validityInterval() const { return impl_->validityInterval(); } void setImpl(EventSetupRecordImpl const* iImpl, unsigned int transitionID, ESResolverIndex const* getTokenIndices, EventSetupImpl const* iEventSetupImpl, ESParentContext const* iContext) { impl_ = iImpl; transitionID_ = transitionID; getTokenIndices_ = getTokenIndices; eventSetupImpl_ = iEventSetupImpl; context_ = iContext; } ///returns false if no data available for key bool doGet(ESGetTokenGeneric const&, bool aGetTransiently = false) const; /**returns true only if someone has already requested data for this key and the data was retrieved */ bool wasGotten(DataKey const& aKey) const; /**returns the ComponentDescription for the module which creates the data or 0 if no module has been registered for the data. This does not cause the data to actually be constructed. */ ComponentDescription const* providerDescription(DataKey const& aKey) const; virtual EventSetupRecordKey key() const = 0; /**If you are caching data from the Record, you should also keep this number. If this number changes then you know that the data you have cached is invalid. This is NOT true if if the validityInterval() hasn't changed since it is possible that the job has gone to a new Record and then come back to the previous SyncValue and your algorithm didn't see the intervening Record. The value of '0' will never be returned so you can use that to denote that you have not yet checked the value. */ unsigned long long cacheIdentifier() const { return impl_->cacheIdentifier(); } /**When you are processing multiple validity intervals concurrently, each must have its own cache for data. These caches are numbered from 0 to one less than the maximum number of concurrent validity intervals allowed for that record. This number is returned by the following function. For one record type, all the different validity intervals being processed at the same time will have a different iovIndex. But the iovIndex's of record types that are different are independent of each other. */ unsigned int iovIndex() const { return impl_->iovIndex(); } ///clears the oToFill vector and then fills it with the keys for all registered data keys void fillRegisteredDataKeys(std::vector<DataKey>& oToFill) const { oToFill = impl_->registeredDataKeys(); } ///Classes that derive from EventSetupRecord can redefine this with a false value static constexpr bool allowConcurrentIOVs_ = true; friend class ::testEventsetup; friend class ::testEventsetupRecord; protected: template <template <typename> typename H, typename T, typename R> H<T> getHandleImpl(ESGetToken<T, R> const& iToken) const { if UNLIKELY (not iToken.isInitialized()) { std::rethrow_exception(makeUninitializedTokenException(this->key(), DataKey::makeTypeTag<T>())); } if UNLIKELY (iToken.transitionID() != transitionID()) { throwWrongTransitionID(); } assert(getTokenIndices_); //need to check token has valid index if UNLIKELY (not iToken.hasValidIndex()) { return invalidTokenHandle<H>(iToken); } auto resolverIndex = getTokenIndices_[iToken.index().value()]; if UNLIKELY (resolverIndex == ESResolverIndex::moduleLabelDoesNotMatch()) { return noResolverHandle<H>(iToken, true); } if UNLIKELY (resolverIndex == ESResolverIndex::noResolverConfigured()) { return noResolverHandle<H>(iToken, false); } T const* value = nullptr; ComponentDescription const* desc = nullptr; std::shared_ptr<ESHandleExceptionFactory> whyFailedFactory; impl_->getImplementation(value, resolverIndex, H<T>::transientAccessOnly, desc, whyFailedFactory); if UNLIKELY (not value) { return H<T>(std::move(whyFailedFactory)); } return H<T>(value, desc); } EventSetupImpl const& eventSetup() const noexcept { return *eventSetupImpl_; } ESResolverIndex const* getTokenIndices() const noexcept { return getTokenIndices_; } ESParentContext const* esParentContext() const noexcept { return context_; } void addTraceInfoToCmsException(cms::Exception& iException, char const* iName, ComponentDescription const*, DataKey const&) const; EventSetupRecordImpl const* impl() const { return impl_; } unsigned int transitionID() const { return transitionID_; } private: template <template <typename> typename H, typename T, typename R> H<T> invalidTokenHandle(ESGetToken<T, R> const& iToken) const { auto const key = this->key(); return H<T>{makeESHandleExceptionFactory([key, transitionID = iToken.transitionID()] { return makeInvalidTokenException(key, DataKey::makeTypeTag<T>(), transitionID); })}; } template <template <typename> typename H, typename T, typename R> H<T> noResolverHandle(ESGetToken<T, R> const& iToken, bool moduleLabelDoesNotMatch) const { auto const key = this->key(); auto productLabel = iToken.productLabel(); return H<T>{makeESHandleExceptionFactory([key, productLabel, moduleLabelDoesNotMatch] { NoProductResolverException ex(key, heterocontainer::className<T>(), productLabel, moduleLabelDoesNotMatch); return std::make_exception_ptr(ex); })}; } static std::exception_ptr makeUninitializedTokenException(EventSetupRecordKey const&, TypeTag const&); static std::exception_ptr makeInvalidTokenException(EventSetupRecordKey const&, TypeTag const&, unsigned int); void throwWrongTransitionID() const; // ---------- member data -------------------------------- EventSetupRecordImpl const* impl_ = nullptr; EventSetupImpl const* eventSetupImpl_ = nullptr; ESResolverIndex const* getTokenIndices_ = nullptr; ESParentContext const* context_ = nullptr; unsigned int transitionID_ = std::numeric_limits<unsigned int>::max(); }; class EventSetupRecordGeneric : public EventSetupRecord { public: EventSetupRecordGeneric(EventSetupRecordImpl const* iImpl, unsigned int iTransitionID, ESResolverIndex const* getTokenIndices, EventSetupImpl const* eventSetupImpl, ESParentContext const* context) { setImpl(iImpl, iTransitionID, getTokenIndices, eventSetupImpl, context); } EventSetupRecordKey key() const final { return impl()->key(); } }; } // namespace eventsetup } // namespace edm #endif