Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 // -*- C++ -*-
0002 //
0003 // Package:     Framework
0004 // Class  :     ESProductResolverProvider
0005 //
0006 // Implementation:
0007 //     <Notes on implementation>
0008 //
0009 // Author:      Chris Jones
0010 // Created:     Mon Mar 28 15:07:54 EST 2005
0011 //
0012 
0013 // system include files
0014 #include <algorithm>
0015 #include <cassert>
0016 #include <cstring>
0017 #include <limits>
0018 
0019 // user include files
0020 #include "FWCore/Framework/interface/ESProductResolverProvider.h"
0021 #include "FWCore/Framework/interface/ESProductResolver.h"
0022 #include "FWCore/Framework/interface/RecordDependencyRegister.h"
0023 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0024 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0025 
0026 constexpr auto kInvalidIndex = std::numeric_limits<unsigned int>::max();
0027 
0028 namespace edm {
0029   namespace eventsetup {
0030 
0031     ESProductResolverProvider::ESProductResolverProvider() {}
0032 
0033     ESProductResolverProvider::~ESProductResolverProvider() noexcept(false) {}
0034 
0035     ESProductResolverProvider::KeyedResolvers::KeyedResolvers(ESProductResolverContainer* productResolverContainer,
0036                                                               unsigned int recordIndex)
0037         : productResolverContainer_(productResolverContainer),
0038           recordIndex_(recordIndex),
0039           productResolversIndex_(kInvalidIndex) {}
0040 
0041     bool ESProductResolverProvider::KeyedResolvers::unInitialized() const {
0042       return productResolversIndex_ == kInvalidIndex;
0043     }
0044 
0045     EventSetupRecordKey const& ESProductResolverProvider::KeyedResolvers::recordKey() const {
0046       return productResolverContainer_->perRecordInfos_[recordIndex_].recordKey_;
0047     }
0048 
0049     void ESProductResolverProvider::KeyedResolvers::insert(
0050         std::vector<std::pair<DataKey, std::shared_ptr<ESProductResolver>>>&& proxies,
0051         std::string const& appendToDataLabel) {
0052       PerRecordInfo& perRecordInfo = productResolverContainer_->perRecordInfos_[recordIndex_];
0053       if (perRecordInfo.indexToDataKeys_ == kInvalidIndex) {
0054         perRecordInfo.nDataKeys_ = proxies.size();
0055         perRecordInfo.indexToDataKeys_ = productResolverContainer_->dataKeys_.size();
0056         for (auto const& it : proxies) {
0057           productResolverContainer_->dataKeys_.push_back(it.first);
0058         }
0059       } else {
0060         assert(perRecordInfo.nDataKeys_ == proxies.size());
0061         unsigned index = 0;
0062         for (auto const& it : proxies) {
0063           if (appendToDataLabel.empty()) {
0064             assert(it.first == productResolverContainer_->dataKeys_[perRecordInfo.indexToDataKeys_ + index]);
0065           } else {
0066             assert(it.first.type() ==
0067                    productResolverContainer_->dataKeys_[perRecordInfo.indexToDataKeys_ + index].type());
0068             auto lengthDataLabel = std::strlen(it.first.name().value());
0069             assert(std::strncmp(
0070                        it.first.name().value(),
0071                        productResolverContainer_->dataKeys_[perRecordInfo.indexToDataKeys_ + index].name().value(),
0072                        lengthDataLabel) == 0);
0073           }
0074           ++index;
0075         }
0076       }
0077       assert(unInitialized());
0078       productResolversIndex_ = productResolverContainer_->productResolvers_.size();
0079       for (auto const& it : proxies) {
0080         productResolverContainer_->productResolvers_.emplace_back(it.second);
0081       }
0082     }
0083 
0084     bool ESProductResolverProvider::KeyedResolvers::contains(DataKey const& dataKey) const {
0085       PerRecordInfo const& perRecordInfo = productResolverContainer_->perRecordInfos_[recordIndex_];
0086       auto iter = productResolverContainer_->dataKeys_.begin() + perRecordInfo.indexToDataKeys_;
0087       auto iterEnd = iter + perRecordInfo.nDataKeys_;
0088       for (; iter != iterEnd; ++iter) {
0089         if (*iter == dataKey) {
0090           return true;
0091         }
0092       }
0093       return false;
0094     }
0095 
0096     unsigned int ESProductResolverProvider::KeyedResolvers::size() const {
0097       return productResolverContainer_->perRecordInfos_[recordIndex_].nDataKeys_;
0098     }
0099 
0100     ESProductResolverProvider::KeyedResolvers::Iterator&
0101     ESProductResolverProvider::KeyedResolvers::Iterator::operator++() {
0102       ++dataKeysIter_;
0103       ++productResolversIter_;
0104       return *this;
0105     }
0106 
0107     ESProductResolverProvider::KeyedResolvers::Iterator::Iterator(
0108         std::vector<DataKey>::iterator dataKeysIter,
0109         std::vector<edm::propagate_const<std::shared_ptr<ESProductResolver>>>::iterator productResolversIter)
0110         : dataKeysIter_(dataKeysIter), productResolversIter_(productResolversIter) {}
0111 
0112     ESProductResolverProvider::KeyedResolvers::Iterator ESProductResolverProvider::KeyedResolvers::begin() {
0113       return Iterator(productResolverContainer_->dataKeys_.begin() +
0114                           productResolverContainer_->perRecordInfos_[recordIndex_].indexToDataKeys_,
0115                       productResolverContainer_->productResolvers_.begin() + productResolversIndex_);
0116     }
0117 
0118     ESProductResolverProvider::KeyedResolvers::Iterator ESProductResolverProvider::KeyedResolvers::end() {
0119       unsigned int nDataKeys = productResolverContainer_->perRecordInfos_[recordIndex_].nDataKeys_;
0120       return Iterator(productResolverContainer_->dataKeys_.begin() +
0121                           productResolverContainer_->perRecordInfos_[recordIndex_].indexToDataKeys_ + nDataKeys,
0122                       productResolverContainer_->productResolvers_.begin() + productResolversIndex_ + nDataKeys);
0123     }
0124 
0125     ESProductResolverProvider::PerRecordInfo::PerRecordInfo(const EventSetupRecordKey& key)
0126         : recordKey_(key), indexToDataKeys_(kInvalidIndex) {}
0127 
0128     void ESProductResolverProvider::ESProductResolverContainer::usingRecordWithKey(const EventSetupRecordKey& iKey) {
0129       assert(keyedResolversCollection_.empty());
0130       perRecordInfos_.emplace_back(iKey);
0131     }
0132 
0133     bool ESProductResolverProvider::ESProductResolverContainer::isUsingRecord(const EventSetupRecordKey& iKey) const {
0134       auto lb = std::lower_bound(perRecordInfos_.begin(), perRecordInfos_.end(), PerRecordInfo(iKey));
0135       return (lb != perRecordInfos_.end() && iKey == lb->recordKey_);
0136     }
0137 
0138     std::set<EventSetupRecordKey> ESProductResolverProvider::ESProductResolverContainer::usingRecords() const {
0139       std::set<EventSetupRecordKey> returnValue;
0140       for (auto const& it : perRecordInfos_) {
0141         returnValue.insert(returnValue.end(), it.recordKey_);
0142       }
0143       return returnValue;
0144     }
0145 
0146     void ESProductResolverProvider::ESProductResolverContainer::fillRecordsNotAllowingConcurrentIOVs(
0147         std::set<EventSetupRecordKey>& recordsNotAllowingConcurrentIOVs) const {
0148       for (auto const& it : perRecordInfos_) {
0149         const EventSetupRecordKey& key = it.recordKey_;
0150         if (!allowConcurrentIOVs(key)) {
0151           recordsNotAllowingConcurrentIOVs.insert(recordsNotAllowingConcurrentIOVs.end(), key);
0152         }
0153       }
0154     }
0155 
0156     void ESProductResolverProvider::ESProductResolverContainer::sortEventSetupRecordKeys() {
0157       std::sort(perRecordInfos_.begin(), perRecordInfos_.end());
0158       perRecordInfos_.erase(std::unique(perRecordInfos_.begin(), perRecordInfos_.end()), perRecordInfos_.end());
0159     }
0160 
0161     void ESProductResolverProvider::ESProductResolverContainer::createKeyedResolvers(EventSetupRecordKey const& key,
0162                                                                                      unsigned int nConcurrentIOVs) {
0163       if (keyedResolversCollection_.empty()) {
0164         sortEventSetupRecordKeys();
0165       }
0166       assert(nConcurrentIOVs > 0U);
0167       auto lb = std::lower_bound(perRecordInfos_.begin(), perRecordInfos_.end(), PerRecordInfo(key));
0168       assert(lb != perRecordInfos_.end() && key == lb->recordKey_);
0169       if (lb->nIOVs_ == 0) {
0170         lb->nIOVs_ = nConcurrentIOVs;
0171         auto recordIndex = std::distance(perRecordInfos_.begin(), lb);
0172         lb->indexToKeyedResolvers_ = keyedResolversCollection_.size();
0173         for (unsigned int i = 0; i < nConcurrentIOVs; ++i) {
0174           keyedResolversCollection_.emplace_back(this, recordIndex);
0175         }
0176       }
0177     }
0178 
0179     ESProductResolverProvider::KeyedResolvers& ESProductResolverProvider::ESProductResolverContainer::keyedResolvers(
0180         const EventSetupRecordKey& iRecordKey, unsigned int iovIndex) {
0181       auto lb = std::lower_bound(perRecordInfos_.begin(), perRecordInfos_.end(), PerRecordInfo(iRecordKey));
0182       assert(lb != perRecordInfos_.end() && iRecordKey == lb->recordKey_);
0183       assert(iovIndex < lb->nIOVs_);
0184       return keyedResolversCollection_[lb->indexToKeyedResolvers_ + iovIndex];
0185     }
0186 
0187     void ESProductResolverProvider::updateLookup(eventsetup::ESRecordsToProductResolverIndices const&) {}
0188 
0189     void ESProductResolverProvider::setAppendToDataLabel(const edm::ParameterSet& iToAppend) {
0190       std::string oldValue(appendToDataLabel_);
0191       //this can only be changed once and the default value is the empty string
0192       assert(oldValue.empty());
0193 
0194       const std::string kParamName("appendToDataLabel");
0195       if (iToAppend.exists(kParamName)) {
0196         appendToDataLabel_ = iToAppend.getParameter<std::string>(kParamName);
0197       }
0198     }
0199 
0200     ESProductResolverProvider::KeyedResolvers& ESProductResolverProvider::keyedResolvers(
0201         const EventSetupRecordKey& iRecordKey, unsigned int iovIndex) {
0202       KeyedResolvers& keyedResolvers = productResolverContainer_.keyedResolvers(iRecordKey, iovIndex);
0203 
0204       if (keyedResolvers.unInitialized()) {
0205         //delayed registration
0206         std::vector<std::pair<DataKey, std::shared_ptr<ESProductResolver>>> keyedResolversVector =
0207             registerResolvers(iRecordKey, iovIndex);
0208         keyedResolvers.insert(std::move(keyedResolversVector), appendToDataLabel_);
0209 
0210         bool mustChangeLabels = (!appendToDataLabel_.empty());
0211         for (auto keyedResolver : keyedResolvers) {
0212           keyedResolver.productResolver_->setProviderDescription(&description());
0213           if (mustChangeLabels) {
0214             //Using swap is fine since
0215             // 1) the data structure is not a map and so we have not sorted on the keys
0216             // 2) this is the first time filling this so no outside agency has yet seen
0217             //   the label and therefore can not be dependent upon its value
0218             std::string temp(std::string(keyedResolver.dataKey_.name().value()) + appendToDataLabel_);
0219             DataKey newKey(keyedResolver.dataKey_.type(), temp.c_str());
0220             swap(keyedResolver.dataKey_, newKey);
0221           }
0222         }
0223       }
0224       return keyedResolvers;
0225     }
0226 
0227     static const std::string kAppendToDataLabel("appendToDataLabel");
0228 
0229     void ESProductResolverProvider::prevalidate(ConfigurationDescriptions& iDesc) {
0230       if (iDesc.defaultDescription()) {
0231         if (iDesc.defaultDescription()->isLabelUnused(kAppendToDataLabel)) {
0232           iDesc.defaultDescription()->add<std::string>(kAppendToDataLabel, std::string(""));
0233         }
0234       }
0235       for (auto& v : iDesc) {
0236         if (v.second.isLabelUnused(kAppendToDataLabel)) {
0237           v.second.add<std::string>(kAppendToDataLabel, std::string(""));
0238         }
0239       }
0240     }
0241 
0242   }  // namespace eventsetup
0243 }  // namespace edm