File indexing completed on 2021-02-14 13:27:44
0001 #ifndef FWCore_Framework_ESProducer_h
0002 #define FWCore_Framework_ESProducer_h
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072 #include <memory>
0073 #include <string>
0074 #include <optional>
0075
0076
0077 #include "FWCore/Framework/interface/ESConsumesCollector.h"
0078 #include "FWCore/Framework/interface/es_impl/MayConsumeChooserBase.h"
0079 #include "FWCore/Framework/interface/ESProxyFactoryProducer.h"
0080 #include "FWCore/Framework/interface/ProxyArgumentFactoryTemplate.h"
0081
0082 #include "FWCore/Framework/interface/CallbackProxy.h"
0083 #include "FWCore/Framework/interface/Callback.h"
0084 #include "FWCore/Framework/interface/produce_helpers.h"
0085 #include "FWCore/Framework/interface/eventsetup_dependsOn.h"
0086 #include "FWCore/Framework/interface/es_Label.h"
0087
0088 #include "FWCore/Framework/interface/SharedResourcesAcquirer.h"
0089
0090
0091 namespace edm {
0092 namespace eventsetup {
0093
0094 class ESRecordsToProxyIndices;
0095
0096
0097
0098 template <typename T, typename TRecord, typename TDecorator>
0099 inline const TDecorator& createDecoratorFrom(T*, const TRecord*, const TDecorator& iDec) {
0100 return iDec;
0101 }
0102 }
0103
0104 class ESProducer : public ESProxyFactoryProducer {
0105 public:
0106 ESProducer();
0107 ~ESProducer() noexcept(false) override;
0108 ESProducer(const ESProducer&) = delete;
0109 ESProducer const& operator=(const ESProducer&) = delete;
0110
0111 void updateLookup(eventsetup::ESRecordsToProxyIndices const&) final;
0112 ESProxyIndex const* getTokenIndices(unsigned int iIndex) const {
0113 if (itemsToGetFromRecords_.empty()) {
0114 return nullptr;
0115 }
0116 return (itemsToGetFromRecords_[iIndex].empty()) ? static_cast<ESProxyIndex const*>(nullptr)
0117 : &(itemsToGetFromRecords_[iIndex].front());
0118 }
0119 ESRecordIndex const* getTokenRecordIndices(unsigned int iIndex) const {
0120 if (recordsUsedDuringGet_.empty()) {
0121 return nullptr;
0122 }
0123 return (recordsUsedDuringGet_[iIndex].empty()) ? static_cast<ESRecordIndex const*>(nullptr)
0124 : &(recordsUsedDuringGet_[iIndex].front());
0125 }
0126 size_t numberOfTokenIndices(unsigned int iIndex) const {
0127 if (itemsToGetFromRecords_.empty()) {
0128 return 0;
0129 }
0130 return itemsToGetFromRecords_[iIndex].size();
0131 }
0132
0133 bool hasMayConsumes() const noexcept { return hasMayConsumes_; }
0134
0135 template <typename Record>
0136 std::optional<std::vector<ESProxyIndex>> updateFromMayConsumes(unsigned int iIndex, const Record& iRecord) const {
0137 if (not hasMayConsumes()) {
0138 return {};
0139 }
0140 std::vector<ESProxyIndex> ret = itemsToGetFromRecords_[iIndex];
0141 auto const info = consumesInfos_[iIndex].get();
0142 for (size_t i = 0; i < info->size(); ++i) {
0143 auto chooserBase = (*info)[i].chooser_.get();
0144 if (chooserBase) {
0145 auto chooser = static_cast<eventsetup::impl::MayConsumeChooserBase<Record>*>(chooserBase);
0146 ret[i] = chooser->makeChoice(iRecord);
0147 }
0148 }
0149 return ret;
0150 }
0151
0152 SerialTaskQueueChain& queue() { return acquirer_.serialQueueChain(); }
0153
0154 protected:
0155
0156 void usesResources(std::vector<std::string> const&);
0157
0158
0159
0160
0161
0162 template <typename T>
0163 auto setWhatProduced(T* iThis, const es::Label& iLabel = {}) {
0164 return setWhatProduced(iThis, &T::produce, iLabel);
0165 }
0166
0167 template <typename T>
0168 auto setWhatProduced(T* iThis, const char* iLabel) {
0169 return setWhatProduced(iThis, es::Label(iLabel));
0170 }
0171 template <typename T>
0172 auto setWhatProduced(T* iThis, const std::string& iLabel) {
0173 return setWhatProduced(iThis, es::Label(iLabel));
0174 }
0175
0176 template <typename T, typename TDecorator>
0177 auto setWhatProduced(T* iThis, const TDecorator& iDec, const es::Label& iLabel = {}) {
0178 return setWhatProduced(iThis, &T::produce, iDec, iLabel);
0179 }
0180
0181
0182
0183
0184
0185 template <typename T, typename TReturn, typename TRecord>
0186 auto setWhatProduced(T* iThis, TReturn (T ::*iMethod)(const TRecord&), const es::Label& iLabel = {}) {
0187 return setWhatProduced(iThis, iMethod, eventsetup::CallbackSimpleDecorator<TRecord>(), iLabel);
0188 }
0189
0190
0191
0192
0193
0194
0195 template <typename T, typename TReturn, typename TRecord, typename TArg>
0196 ESConsumesCollectorT<TRecord> setWhatProduced(T* iThis,
0197 TReturn (T ::*iMethod)(const TRecord&),
0198 const TArg& iDec,
0199 const es::Label& iLabel = {}) {
0200 const auto id = consumesInfos_.size();
0201 using DecoratorType = typename eventsetup::DecoratorFromArg<T, TRecord, TArg>::Decorator_t;
0202 using CallbackType = eventsetup::Callback<T, TReturn, TRecord, DecoratorType>;
0203 unsigned int iovIndex = 0;
0204 auto temp = std::make_shared<CallbackType>(
0205 iThis, iMethod, id, createDecoratorFrom(iThis, static_cast<const TRecord*>(nullptr), iDec));
0206 auto callback =
0207 std::make_shared<std::pair<unsigned int, std::shared_ptr<CallbackType>>>(iovIndex, std::move(temp));
0208 registerProducts(std::move(callback),
0209 static_cast<const typename eventsetup::produce::product_traits<TReturn>::type*>(nullptr),
0210 static_cast<const TRecord*>(nullptr),
0211 iLabel);
0212 consumesInfos_.push_back(std::make_unique<ESConsumesInfo>());
0213 return ESConsumesCollectorT<TRecord>(consumesInfos_.back().get(), id);
0214 }
0215
0216 private:
0217 template <typename CallbackT, typename TList, typename TRecord>
0218 void registerProducts(std::shared_ptr<std::pair<unsigned int, std::shared_ptr<CallbackT>>> iCallback,
0219 const TList*,
0220 const TRecord* iRecord,
0221 const es::Label& iLabel) {
0222 registerProduct(iCallback, static_cast<const typename TList::tail_type*>(nullptr), iRecord, iLabel);
0223 registerProducts(std::move(iCallback), static_cast<const typename TList::head_type*>(nullptr), iRecord, iLabel);
0224 }
0225
0226 template <typename CallbackT, typename TRecord>
0227 void registerProducts(std::shared_ptr<std::pair<unsigned int, std::shared_ptr<CallbackT>>>,
0228 const eventsetup::produce::Null*,
0229 const TRecord*,
0230 const es::Label&) {
0231
0232 }
0233
0234 template <typename CallbackT, typename TProduct, typename TRecord>
0235 void registerProduct(std::shared_ptr<std::pair<unsigned int, std::shared_ptr<CallbackT>>> iCallback,
0236 const TProduct*,
0237 const TRecord*,
0238 const es::Label& iLabel) {
0239 using ProxyType = eventsetup::CallbackProxy<CallbackT, TRecord, TProduct>;
0240 using FactoryType = eventsetup::ProxyArgumentFactoryTemplate<ProxyType, CallbackT>;
0241 registerFactory(std::make_unique<FactoryType>(std::move(iCallback)), iLabel.default_);
0242 }
0243
0244 template <typename CallbackT, typename TProduct, typename TRecord, int IIndex>
0245 void registerProduct(std::shared_ptr<std::pair<unsigned int, std::shared_ptr<CallbackT>>> iCallback,
0246 const es::L<TProduct, IIndex>*,
0247 const TRecord*,
0248 const es::Label& iLabel) {
0249 if (iLabel.labels_.size() <= IIndex || iLabel.labels_[IIndex] == es::Label::def()) {
0250 Exception::throwThis(errors::Configuration,
0251 "Unnamed Label\nthe index ",
0252 IIndex,
0253 " was never assigned a name in the 'setWhatProduced' method");
0254 }
0255 using ProxyType = eventsetup::CallbackProxy<CallbackT, TRecord, es::L<TProduct, IIndex>>;
0256 using FactoryType = eventsetup::ProxyArgumentFactoryTemplate<ProxyType, CallbackT>;
0257 registerFactory(std::make_unique<FactoryType>(std::move(iCallback)), iLabel.labels_[IIndex]);
0258 }
0259
0260 std::vector<std::unique_ptr<ESConsumesInfo>> consumesInfos_;
0261 std::vector<std::vector<ESProxyIndex>> itemsToGetFromRecords_;
0262
0263
0264 std::vector<std::vector<ESRecordIndex>> recordsUsedDuringGet_;
0265
0266 SharedResourcesAcquirer acquirer_;
0267 std::unique_ptr<std::vector<std::string>> sharedResourceNames_;
0268 bool hasMayConsumes_ = false;
0269 };
0270 }
0271 #endif