Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:12:03

0001 #ifndef FWCore_Framework_EventSetupRecord_h
0002 #define FWCore_Framework_EventSetupRecord_h
0003 // -*- C++ -*-
0004 //
0005 // Package:     Framework
0006 // Class  :     EventSetupRecord
0007 //
0008 /**\class edm::eventsetup::EventSetupRecord
0009 
0010  Description: Base class for all Records in an EventSetup.  A record is associated
0011  with data with the same lifetime.
0012 
0013  Usage:
0014 
0015  This class contains the interface that clients of the EventSetup
0016  use to get data associated with a record.
0017 
0018  This class holds a pointer to an EventSetupRecordImpl class, which
0019  is the class used to get the DataProxies associated with a given Record.
0020  It also has a pointer to the EventSetupImpl which is used to lookup
0021  dependent records in DependentRecordImplementation.
0022 
0023  It is important for the management of the Records that each Record
0024  know the ValidityInterval that represents the time over which its
0025  data is valid. The ValidityInterval is set by its EventSetupRecordProvider
0026  using the 'set' function.  This quantity can be recovered
0027  through the 'validityInterval' method.
0028 
0029  Most of the time one uses a record obtained from an EventSetup object
0030  and in that case the pointers this contains will be properly initialized
0031  automatically. If you construct a record object directly (usually using
0032  a type derived from this), then only a very limited subset of functions
0033  can be called because most of the member functions will dereference one
0034  of the null pointers and seg fault.
0035 */
0036 //
0037 // Author:      Chris Jones
0038 // Created:     Fri Mar 25 14:38:35 EST 2005
0039 //
0040 
0041 // user include files
0042 #include "FWCore/Framework/interface/FunctorESHandleExceptionFactory.h"
0043 #include "FWCore/Framework/interface/DataKey.h"
0044 #include "FWCore/Framework/interface/NoProductResolverException.h"
0045 #include "FWCore/Framework/interface/ValidityInterval.h"
0046 #include "FWCore/Framework/interface/EventSetupRecordImpl.h"
0047 #include "FWCore/Utilities/interface/ESGetToken.h"
0048 #include "FWCore/Utilities/interface/ESGetTokenGeneric.h"
0049 #include "FWCore/Utilities/interface/ESIndices.h"
0050 #include "FWCore/Utilities/interface/Likely.h"
0051 
0052 // system include files
0053 #include <exception>
0054 #include <memory>
0055 #include <utility>
0056 #include <vector>
0057 #include <cassert>
0058 #include <limits>
0059 
0060 // forward declarations
0061 namespace cms {
0062   class Exception;
0063 }
0064 
0065 class testEventsetup;
0066 class testEventsetupRecord;
0067 
0068 namespace edm {
0069   class ESHandleExceptionFactory;
0070   class ESParentContext;
0071   class EventSetupImpl;
0072 
0073   namespace eventsetup {
0074     struct ComponentDescription;
0075     class EventSetupRecordKey;
0076 
0077     class EventSetupRecord {
0078     public:
0079       EventSetupRecord();
0080       EventSetupRecord(EventSetupRecord&&) = default;
0081       EventSetupRecord& operator=(EventSetupRecord&&) = default;
0082 
0083       EventSetupRecord(EventSetupRecord const&) = default;
0084       EventSetupRecord& operator=(EventSetupRecord const&) = default;
0085       virtual ~EventSetupRecord();
0086 
0087       // ---------- const member functions ---------------------
0088       ValidityInterval validityInterval() const { return impl_->validityInterval(); }
0089 
0090       void setImpl(EventSetupRecordImpl const* iImpl,
0091                    unsigned int transitionID,
0092                    ESResolverIndex const* getTokenIndices,
0093                    EventSetupImpl const* iEventSetupImpl,
0094                    ESParentContext const* iContext) {
0095         impl_ = iImpl;
0096         transitionID_ = transitionID;
0097         getTokenIndices_ = getTokenIndices;
0098         eventSetupImpl_ = iEventSetupImpl;
0099         context_ = iContext;
0100       }
0101 
0102       ///returns false if no data available for key
0103       bool doGet(ESGetTokenGeneric const&, bool aGetTransiently = false) const;
0104 
0105       /**returns true only if someone has already requested data for this key
0106           and the data was retrieved
0107           */
0108       bool wasGotten(DataKey const& aKey) const;
0109 
0110       /**returns the ComponentDescription for the module which creates the data or 0
0111           if no module has been registered for the data. This does not cause the data to
0112           actually be constructed.
0113           */
0114       ComponentDescription const* providerDescription(DataKey const& aKey) const;
0115 
0116       virtual EventSetupRecordKey key() const = 0;
0117 
0118       /**If you are caching data from the Record, you should also keep
0119           this number.  If this number changes then you know that
0120           the data you have cached is invalid. This is NOT true if
0121           if the validityInterval() hasn't changed since it is possible that
0122           the job has gone to a new Record and then come back to the
0123           previous SyncValue and your algorithm didn't see the intervening
0124           Record.
0125           The value of '0' will never be returned so you can use that to
0126           denote that you have not yet checked the value.
0127           */
0128       unsigned long long cacheIdentifier() const { return impl_->cacheIdentifier(); }
0129 
0130       /**When you are processing multiple validity intervals concurrently,
0131           each must have its own cache for data. These caches are numbered
0132           from 0 to one less than the maximum number of concurrent validity
0133           intervals allowed for that record. This number is returned by
0134           the following function. For one record type, all the different validity
0135           intervals being processed at the same time will have a different
0136           iovIndex. But the iovIndex's of record types that are different
0137           are independent of each other.
0138           */
0139       unsigned int iovIndex() const { return impl_->iovIndex(); }
0140 
0141       ///clears the oToFill vector and then fills it with the keys for all registered data keys
0142       void fillRegisteredDataKeys(std::vector<DataKey>& oToFill) const { impl_->fillRegisteredDataKeys(oToFill); }
0143 
0144       ///Classes that derive from EventSetupRecord can redefine this with a false value
0145       static constexpr bool allowConcurrentIOVs_ = true;
0146 
0147       friend class ::testEventsetup;
0148       friend class ::testEventsetupRecord;
0149 
0150     protected:
0151       template <template <typename> typename H, typename T, typename R>
0152       H<T> getHandleImpl(ESGetToken<T, R> const& iToken) const {
0153         if UNLIKELY (not iToken.isInitialized()) {
0154           std::rethrow_exception(makeUninitializedTokenException(this->key(), DataKey::makeTypeTag<T>()));
0155         }
0156         if UNLIKELY (iToken.transitionID() != transitionID()) {
0157           throwWrongTransitionID();
0158         }
0159         assert(getTokenIndices_);
0160         //need to check token has valid index
0161         if UNLIKELY (not iToken.hasValidIndex()) {
0162           return invalidTokenHandle<H>(iToken);
0163         }
0164 
0165         auto resolverIndex = getTokenIndices_[iToken.index().value()];
0166         if UNLIKELY (resolverIndex.value() == std::numeric_limits<int>::max()) {
0167           return noResolverHandle<H>(iToken);
0168         }
0169 
0170         T const* value = nullptr;
0171         ComponentDescription const* desc = nullptr;
0172         std::shared_ptr<ESHandleExceptionFactory> whyFailedFactory;
0173 
0174         impl_->getImplementation(value, resolverIndex, H<T>::transientAccessOnly, desc, whyFailedFactory);
0175 
0176         if UNLIKELY (not value) {
0177           return H<T>(std::move(whyFailedFactory));
0178         }
0179         return H<T>(value, desc);
0180       }
0181 
0182       EventSetupImpl const& eventSetup() const noexcept { return *eventSetupImpl_; }
0183 
0184       ESResolverIndex const* getTokenIndices() const noexcept { return getTokenIndices_; }
0185 
0186       ESParentContext const* esParentContext() const noexcept { return context_; }
0187 
0188       void addTraceInfoToCmsException(cms::Exception& iException,
0189                                       char const* iName,
0190                                       ComponentDescription const*,
0191                                       DataKey const&) const;
0192 
0193       EventSetupRecordImpl const* impl() const { return impl_; }
0194 
0195       unsigned int transitionID() const { return transitionID_; }
0196 
0197     private:
0198       template <template <typename> typename H, typename T, typename R>
0199       H<T> invalidTokenHandle(ESGetToken<T, R> const& iToken) const {
0200         auto const key = this->key();
0201         return H<T>{makeESHandleExceptionFactory([key, transitionID = iToken.transitionID()] {
0202           return makeInvalidTokenException(key, DataKey::makeTypeTag<T>(), transitionID);
0203         })};
0204       }
0205 
0206       template <template <typename> typename H, typename T, typename R>
0207       H<T> noResolverHandle(ESGetToken<T, R> const& iToken) const {
0208         auto const key = this->key();
0209         auto name = iToken.name();
0210         return H<T>{makeESHandleExceptionFactory([key, name] {
0211           NoProductResolverException<T> ex(key, DataKey{DataKey::makeTypeTag<T>(), name});
0212           return std::make_exception_ptr(ex);
0213         })};
0214       }
0215 
0216       static std::exception_ptr makeUninitializedTokenException(EventSetupRecordKey const&, TypeTag const&);
0217       static std::exception_ptr makeInvalidTokenException(EventSetupRecordKey const&, TypeTag const&, unsigned int);
0218       void throwWrongTransitionID() const;
0219 
0220       // ---------- member data --------------------------------
0221       EventSetupRecordImpl const* impl_ = nullptr;
0222       EventSetupImpl const* eventSetupImpl_ = nullptr;
0223       ESResolverIndex const* getTokenIndices_ = nullptr;
0224       ESParentContext const* context_ = nullptr;
0225       unsigned int transitionID_ = std::numeric_limits<unsigned int>::max();
0226     };
0227 
0228     class EventSetupRecordGeneric : public EventSetupRecord {
0229     public:
0230       EventSetupRecordGeneric(EventSetupRecordImpl const* iImpl,
0231                               unsigned int iTransitionID,
0232                               ESResolverIndex const* getTokenIndices,
0233                               EventSetupImpl const* eventSetupImpl,
0234                               ESParentContext const* context) {
0235         setImpl(iImpl, iTransitionID, getTokenIndices, eventSetupImpl, context);
0236       }
0237 
0238       EventSetupRecordKey key() const final { return impl()->key(); }
0239     };
0240   }  // namespace eventsetup
0241 }  // namespace edm
0242 #endif