Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:27:52

0001 // -*- C++ -*-
0002 //
0003 // Package:     Framework
0004 // Class  :     DataProxyProvider
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/DataProxyProvider.h"
0021 #include "FWCore/Framework/interface/DataProxy.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     DataProxyProvider::DataProxyProvider() {}
0032 
0033     DataProxyProvider::~DataProxyProvider() noexcept(false) {}
0034 
0035     DataProxyProvider::KeyedProxies::KeyedProxies(DataProxyContainer* dataProxyContainer, unsigned int recordIndex)
0036         : dataProxyContainer_(dataProxyContainer), recordIndex_(recordIndex), dataProxiesIndex_(kInvalidIndex) {}
0037 
0038     bool DataProxyProvider::KeyedProxies::unInitialized() const { return dataProxiesIndex_ == kInvalidIndex; }
0039 
0040     EventSetupRecordKey const& DataProxyProvider::KeyedProxies::recordKey() const {
0041       return dataProxyContainer_->perRecordInfos_[recordIndex_].recordKey_;
0042     }
0043 
0044     void DataProxyProvider::KeyedProxies::insert(std::vector<std::pair<DataKey, std::shared_ptr<DataProxy>>>&& proxies,
0045                                                  std::string const& appendToDataLabel) {
0046       PerRecordInfo& perRecordInfo = dataProxyContainer_->perRecordInfos_[recordIndex_];
0047       if (perRecordInfo.indexToDataKeys_ == kInvalidIndex) {
0048         perRecordInfo.nDataKeys_ = proxies.size();
0049         perRecordInfo.indexToDataKeys_ = dataProxyContainer_->dataKeys_.size();
0050         for (auto const& it : proxies) {
0051           dataProxyContainer_->dataKeys_.push_back(it.first);
0052         }
0053       } else {
0054         assert(perRecordInfo.nDataKeys_ == proxies.size());
0055         unsigned index = 0;
0056         for (auto const& it : proxies) {
0057           if (appendToDataLabel.empty()) {
0058             assert(it.first == dataProxyContainer_->dataKeys_[perRecordInfo.indexToDataKeys_ + index]);
0059           } else {
0060             assert(it.first.type() == dataProxyContainer_->dataKeys_[perRecordInfo.indexToDataKeys_ + index].type());
0061             auto lengthDataLabel = std::strlen(it.first.name().value());
0062             assert(std::strncmp(it.first.name().value(),
0063                                 dataProxyContainer_->dataKeys_[perRecordInfo.indexToDataKeys_ + index].name().value(),
0064                                 lengthDataLabel) == 0);
0065           }
0066           ++index;
0067         }
0068       }
0069       assert(unInitialized());
0070       dataProxiesIndex_ = dataProxyContainer_->dataProxies_.size();
0071       for (auto const& it : proxies) {
0072         dataProxyContainer_->dataProxies_.emplace_back(it.second);
0073       }
0074     }
0075 
0076     bool DataProxyProvider::KeyedProxies::contains(DataKey const& dataKey) const {
0077       PerRecordInfo const& perRecordInfo = dataProxyContainer_->perRecordInfos_[recordIndex_];
0078       auto iter = dataProxyContainer_->dataKeys_.begin() + perRecordInfo.indexToDataKeys_;
0079       auto iterEnd = iter + perRecordInfo.nDataKeys_;
0080       for (; iter != iterEnd; ++iter) {
0081         if (*iter == dataKey) {
0082           return true;
0083         }
0084       }
0085       return false;
0086     }
0087 
0088     unsigned int DataProxyProvider::KeyedProxies::size() const {
0089       return dataProxyContainer_->perRecordInfos_[recordIndex_].nDataKeys_;
0090     }
0091 
0092     DataProxyProvider::KeyedProxies::Iterator& DataProxyProvider::KeyedProxies::Iterator::operator++() {
0093       ++dataKeysIter_;
0094       ++dataProxiesIter_;
0095       return *this;
0096     }
0097 
0098     DataProxyProvider::KeyedProxies::Iterator::Iterator(
0099         std::vector<DataKey>::iterator dataKeysIter,
0100         std::vector<edm::propagate_const<std::shared_ptr<DataProxy>>>::iterator dataProxiesIter)
0101         : dataKeysIter_(dataKeysIter), dataProxiesIter_(dataProxiesIter) {}
0102 
0103     DataProxyProvider::KeyedProxies::Iterator DataProxyProvider::KeyedProxies::begin() {
0104       return Iterator(
0105           dataProxyContainer_->dataKeys_.begin() + dataProxyContainer_->perRecordInfos_[recordIndex_].indexToDataKeys_,
0106           dataProxyContainer_->dataProxies_.begin() + dataProxiesIndex_);
0107     }
0108 
0109     DataProxyProvider::KeyedProxies::Iterator DataProxyProvider::KeyedProxies::end() {
0110       unsigned int nDataKeys = dataProxyContainer_->perRecordInfos_[recordIndex_].nDataKeys_;
0111       return Iterator(dataProxyContainer_->dataKeys_.begin() +
0112                           dataProxyContainer_->perRecordInfos_[recordIndex_].indexToDataKeys_ + nDataKeys,
0113                       dataProxyContainer_->dataProxies_.begin() + dataProxiesIndex_ + nDataKeys);
0114     }
0115 
0116     DataProxyProvider::PerRecordInfo::PerRecordInfo(const EventSetupRecordKey& key)
0117         : recordKey_(key), indexToDataKeys_(kInvalidIndex) {}
0118 
0119     void DataProxyProvider::DataProxyContainer::usingRecordWithKey(const EventSetupRecordKey& iKey) {
0120       assert(keyedProxiesCollection_.empty());
0121       perRecordInfos_.emplace_back(iKey);
0122     }
0123 
0124     bool DataProxyProvider::DataProxyContainer::isUsingRecord(const EventSetupRecordKey& iKey) const {
0125       auto lb = std::lower_bound(perRecordInfos_.begin(), perRecordInfos_.end(), PerRecordInfo(iKey));
0126       return (lb != perRecordInfos_.end() && iKey == lb->recordKey_);
0127     }
0128 
0129     std::set<EventSetupRecordKey> DataProxyProvider::DataProxyContainer::usingRecords() const {
0130       std::set<EventSetupRecordKey> returnValue;
0131       for (auto const& it : perRecordInfos_) {
0132         returnValue.insert(returnValue.end(), it.recordKey_);
0133       }
0134       return returnValue;
0135     }
0136 
0137     void DataProxyProvider::DataProxyContainer::fillRecordsNotAllowingConcurrentIOVs(
0138         std::set<EventSetupRecordKey>& recordsNotAllowingConcurrentIOVs) const {
0139       for (auto const& it : perRecordInfos_) {
0140         const EventSetupRecordKey& key = it.recordKey_;
0141         if (!allowConcurrentIOVs(key)) {
0142           recordsNotAllowingConcurrentIOVs.insert(recordsNotAllowingConcurrentIOVs.end(), key);
0143         }
0144       }
0145     }
0146 
0147     void DataProxyProvider::DataProxyContainer::sortEventSetupRecordKeys() {
0148       std::sort(perRecordInfos_.begin(), perRecordInfos_.end());
0149       perRecordInfos_.erase(std::unique(perRecordInfos_.begin(), perRecordInfos_.end()), perRecordInfos_.end());
0150     }
0151 
0152     void DataProxyProvider::DataProxyContainer::createKeyedProxies(EventSetupRecordKey const& key,
0153                                                                    unsigned int nConcurrentIOVs) {
0154       if (keyedProxiesCollection_.empty()) {
0155         sortEventSetupRecordKeys();
0156       }
0157       assert(nConcurrentIOVs > 0U);
0158       auto lb = std::lower_bound(perRecordInfos_.begin(), perRecordInfos_.end(), PerRecordInfo(key));
0159       assert(lb != perRecordInfos_.end() && key == lb->recordKey_);
0160       if (lb->nIOVs_ == 0) {
0161         lb->nIOVs_ = nConcurrentIOVs;
0162         auto recordIndex = std::distance(perRecordInfos_.begin(), lb);
0163         lb->indexToKeyedProxies_ = keyedProxiesCollection_.size();
0164         for (unsigned int i = 0; i < nConcurrentIOVs; ++i) {
0165           keyedProxiesCollection_.emplace_back(this, recordIndex);
0166         }
0167       }
0168     }
0169 
0170     DataProxyProvider::KeyedProxies& DataProxyProvider::DataProxyContainer::keyedProxies(
0171         const EventSetupRecordKey& iRecordKey, unsigned int iovIndex) {
0172       auto lb = std::lower_bound(perRecordInfos_.begin(), perRecordInfos_.end(), PerRecordInfo(iRecordKey));
0173       assert(lb != perRecordInfos_.end() && iRecordKey == lb->recordKey_);
0174       assert(iovIndex < lb->nIOVs_);
0175       return keyedProxiesCollection_[lb->indexToKeyedProxies_ + iovIndex];
0176     }
0177 
0178     void DataProxyProvider::updateLookup(eventsetup::ESRecordsToProxyIndices const&) {}
0179 
0180     void DataProxyProvider::setAppendToDataLabel(const edm::ParameterSet& iToAppend) {
0181       std::string oldValue(appendToDataLabel_);
0182       //this can only be changed once and the default value is the empty string
0183       assert(oldValue.empty());
0184 
0185       const std::string kParamName("appendToDataLabel");
0186       if (iToAppend.exists(kParamName)) {
0187         appendToDataLabel_ = iToAppend.getParameter<std::string>(kParamName);
0188       }
0189     }
0190 
0191     DataProxyProvider::KeyedProxies& DataProxyProvider::keyedProxies(const EventSetupRecordKey& iRecordKey,
0192                                                                      unsigned int iovIndex) {
0193       KeyedProxies& keyedProxies = dataProxyContainer_.keyedProxies(iRecordKey, iovIndex);
0194 
0195       if (keyedProxies.unInitialized()) {
0196         //delayed registration
0197         std::vector<std::pair<DataKey, std::shared_ptr<DataProxy>>> keyedProxiesVector =
0198             registerProxies(iRecordKey, iovIndex);
0199         keyedProxies.insert(std::move(keyedProxiesVector), appendToDataLabel_);
0200 
0201         bool mustChangeLabels = (!appendToDataLabel_.empty());
0202         for (auto keyedProxy : keyedProxies) {
0203           keyedProxy.dataProxy_->setProviderDescription(&description());
0204           if (mustChangeLabels) {
0205             //Using swap is fine since
0206             // 1) the data structure is not a map and so we have not sorted on the keys
0207             // 2) this is the first time filling this so no outside agency has yet seen
0208             //   the label and therefore can not be dependent upon its value
0209             std::string temp(std::string(keyedProxy.dataKey_.name().value()) + appendToDataLabel_);
0210             DataKey newKey(keyedProxy.dataKey_.type(), temp.c_str());
0211             swap(keyedProxy.dataKey_, newKey);
0212           }
0213         }
0214       }
0215       return keyedProxies;
0216     }
0217 
0218     static const std::string kAppendToDataLabel("appendToDataLabel");
0219 
0220     void DataProxyProvider::prevalidate(ConfigurationDescriptions& iDesc) {
0221       if (iDesc.defaultDescription()) {
0222         if (iDesc.defaultDescription()->isLabelUnused(kAppendToDataLabel)) {
0223           iDesc.defaultDescription()->add<std::string>(kAppendToDataLabel, std::string(""));
0224         }
0225       }
0226       for (auto& v : iDesc) {
0227         if (v.second.isLabelUnused(kAppendToDataLabel)) {
0228           v.second.add<std::string>(kAppendToDataLabel, std::string(""));
0229         }
0230       }
0231     }
0232 
0233   }  // namespace eventsetup
0234 }  // namespace edm