CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_1/src/FWCore/Framework/src/EventSetupProvider.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:     Framework
00004 // Module:      EventSetupProvider
00005 // 
00006 // Description: <one line class summary>
00007 //
00008 // Implementation:
00009 //     <Notes on implementation>
00010 //
00011 // Author:      Chris Jones
00012 // Created:     Thu Mar 24 16:27:14 EST 2005
00013 //
00014 
00015 // system include files
00016 #include "boost/bind.hpp"
00017 #include <algorithm>
00018 #include <cassert>
00019 
00020 // user include files
00021 #include "FWCore/Framework/interface/EventSetupProvider.h"
00022 #include "FWCore/Framework/interface/EventSetupRecordProvider.h"
00023 #include "FWCore/Framework/interface/EventSetupRecordProviderFactoryManager.h"
00024 #include "FWCore/Framework/interface/EventSetupRecord.h"
00025 #include "FWCore/Framework/interface/DataProxyProvider.h"
00026 #include "FWCore/Framework/interface/EventSetupRecordIntervalFinder.h"
00027 #include "FWCore/Framework/interface/ModuleFactory.h"
00028 #include "FWCore/Framework/interface/ParameterSetIDHolder.h"
00029 #include "FWCore/Framework/src/EventSetupsController.h"
00030 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00031 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00032 #include "FWCore/Utilities/interface/Algorithms.h"
00033 
00034 namespace edm {
00035    namespace eventsetup {
00036 
00037 //
00038 // constants, enums and typedefs
00039 //
00040 
00041 //
00042 // static data member definitions
00043 //
00044 
00045 //
00046 // constructors and destructor
00047 //
00048 EventSetupProvider::EventSetupProvider(unsigned subProcessIndex, const PreferredProviderInfo* iInfo) :
00049 eventSetup_(),
00050 providers_(),
00051 mustFinishConfiguration_(true),
00052 subProcessIndex_(subProcessIndex),
00053 preferredProviderInfo_((0!=iInfo) ? (new PreferredProviderInfo(*iInfo)): 0),
00054 finders_(new std::vector<boost::shared_ptr<EventSetupRecordIntervalFinder> >() ),
00055 dataProviders_(new std::vector<boost::shared_ptr<DataProxyProvider> >() ),
00056 referencedDataKeys_(new std::map<EventSetupRecordKey, std::map<DataKey, ComponentDescription const*> >),
00057 recordToFinders_(new std::map<EventSetupRecordKey, std::vector<boost::shared_ptr<EventSetupRecordIntervalFinder> > >),
00058 psetIDToRecordKey_(new std::map<ParameterSetIDHolder, std::set<EventSetupRecordKey> >),
00059 recordToPreferred_(new std::map<EventSetupRecordKey, std::map<DataKey, ComponentDescription> >),
00060 recordsWithALooperProxy_(new std::set<EventSetupRecordKey>)
00061 {
00062 }
00063 
00064 // EventSetupProvider::EventSetupProvider(const EventSetupProvider& rhs)
00065 // {
00066 //    // do actual copying here;
00067 // }
00068 
00069 EventSetupProvider::~EventSetupProvider()
00070 {
00071 }
00072 
00073 //
00074 // assignment operators
00075 //
00076 // const EventSetupProvider& EventSetupProvider::operator=(const EventSetupProvider& rhs)
00077 // {
00078 //   //An exception safe implementation is
00079 //   EventSetupProvider temp(rhs);
00080 //   swap(rhs);
00081 //
00082 //   return *this;
00083 // }
00084 
00085 //
00086 // member functions
00087 //
00088 void 
00089 EventSetupProvider::insert(const EventSetupRecordKey& iKey, std::auto_ptr<EventSetupRecordProvider> iProvider)
00090 {
00091    boost::shared_ptr<EventSetupRecordProvider> temp(iProvider.release());
00092    providers_[iKey] = temp;
00093    //temp->addRecordTo(*this);
00094 }
00095 
00096 void 
00097 EventSetupProvider::add(boost::shared_ptr<DataProxyProvider> iProvider)
00098 {
00099    assert(&(*iProvider) != 0);
00100    dataProviders_->push_back(iProvider);
00101 }
00102 
00103 void 
00104 EventSetupProvider::replaceExisting(boost::shared_ptr<DataProxyProvider> dataProxyProvider)
00105 {
00106    ParameterSetIDHolder psetID(dataProxyProvider->description().pid_);
00107    std::set<EventSetupRecordKey> const& keysForPSetID = (*psetIDToRecordKey_)[psetID];
00108    for (auto const& key : keysForPSetID) {
00109       boost::shared_ptr<EventSetupRecordProvider> const& recordProvider = providers_[key];
00110       recordProvider->resetProxyProvider(psetID, dataProxyProvider);
00111    }
00112 }
00113 
00114 void 
00115 EventSetupProvider::add(boost::shared_ptr<EventSetupRecordIntervalFinder> iFinder)
00116 {
00117    assert(&(*iFinder) != 0);
00118    finders_->push_back(iFinder);
00119 }
00120 
00121 typedef std::map<EventSetupRecordKey, boost::shared_ptr<EventSetupRecordProvider> > Providers;
00122 typedef std::map<EventSetupRecordKey, EventSetupRecordProvider::DataToPreferredProviderMap> RecordToPreferred;
00124 static
00125 void 
00126 preferEverything(const ComponentDescription& iComponent,
00127                  const Providers& iProviders,
00128                  RecordToPreferred& iReturnValue)
00129 {
00130    //need to get our hands on the actual DataProxyProvider
00131    bool foundProxyProvider = false;
00132    for(Providers::const_iterator itProvider = iProviders.begin(), itProviderEnd = iProviders.end();
00133        itProvider!= itProviderEnd;
00134        ++itProvider) {
00135       std::set<ComponentDescription> components = itProvider->second->proxyProviderDescriptions();
00136       if(components.find(iComponent)!= components.end()) {
00137          boost::shared_ptr<DataProxyProvider> proxyProv = 
00138          itProvider->second->proxyProvider(*(components.find(iComponent)));
00139          assert(proxyProv.get());
00140          
00141          std::set<EventSetupRecordKey> records = proxyProv->usingRecords();
00142          for(std::set<EventSetupRecordKey>::iterator itRecord = records.begin(),
00143              itRecordEnd = records.end();
00144              itRecord != itRecordEnd;
00145              ++itRecord){
00146             const DataProxyProvider::KeyedProxies& keyedProxies = proxyProv->keyedProxies(*itRecord);
00147             if(!keyedProxies.empty()){
00148                //add them to our output
00149                EventSetupRecordProvider::DataToPreferredProviderMap& dataToProviderMap =
00150                iReturnValue[*itRecord];
00151                
00152                for(DataProxyProvider::KeyedProxies::const_iterator itProxy = keyedProxies.begin(),
00153                    itProxyEnd = keyedProxies.end();
00154                    itProxy != itProxyEnd;
00155                    ++itProxy) {
00156                   EventSetupRecordProvider::DataToPreferredProviderMap::iterator itFind =
00157                   dataToProviderMap.find(itProxy->first);
00158                   if(itFind != dataToProviderMap.end()){
00159                      throw cms::Exception("ESPreferConflict") <<"Two providers have been set to be preferred for\n"
00160                      <<itProxy->first.type().name()<<" \""<<itProxy->first.name().value()<<"\""
00161                      <<"\n the providers are "
00162                      <<"\n 1) type="<<itFind->second.type_<<" label=\""<<itFind->second.label_<<"\""
00163                      <<"\n 2) type="<<iComponent.type_<<" label=\""<<iComponent.label_<<"\""
00164                      <<"\nPlease modify configuration so only one is preferred";
00165                   }
00166                   dataToProviderMap.insert(std::make_pair(itProxy->first,iComponent));
00167                }
00168             }
00169          }
00170          foundProxyProvider=true;
00171          break;
00172       }
00173    }
00174    if(!foundProxyProvider) {
00175       throw cms::Exception("ESPreferNoProvider")<<"Could not make type=\""<<iComponent.type_
00176       <<"\" label=\""<<iComponent.label_<<"\" a preferred Provider."<<
00177       "\n  Please check spelling of name, or that it was loaded into the job.";
00178    }
00179 }
00180 static
00181 RecordToPreferred determinePreferred(const EventSetupProvider::PreferredProviderInfo* iInfo, 
00182                                      const Providers& iProviders)
00183 {
00184    using namespace edm::eventsetup;
00185    RecordToPreferred returnValue;
00186    if(0 != iInfo){
00187       for(EventSetupProvider::PreferredProviderInfo::const_iterator itInfo = iInfo->begin(),
00188           itInfoEnd = iInfo->end();
00189           itInfo != itInfoEnd;
00190           ++itInfo) {
00191          if(itInfo->second.empty()) {
00192             //want everything
00193             preferEverything(itInfo->first, iProviders, returnValue);
00194          } else {
00195             for(EventSetupProvider::RecordToDataMap::const_iterator itRecData = itInfo->second.begin(),
00196                 itRecDataEnd = itInfo->second.end();
00197                 itRecData != itRecDataEnd;
00198                 ++itRecData) {
00199                std::string recordName= itRecData->first;
00200                EventSetupRecordKey recordKey(eventsetup::EventSetupRecordKey::TypeTag::findType(recordName));
00201                if(recordKey.type() == eventsetup::EventSetupRecordKey::TypeTag()) {
00202                   throw cms::Exception("ESPreferUnknownRecord") <<"Unknown record \""<<recordName
00203                   <<"\" used in es_prefer statement for type="
00204                   <<itInfo->first.type_<<" label=\""<<itInfo->first.label_
00205                   <<"\"\n Please check spelling.";
00206                   //record not found
00207                }
00208                //See if the ProxyProvider provides something for this Record
00209                Providers::const_iterator itRecordProvider = iProviders.find(recordKey);
00210                assert(itRecordProvider != iProviders.end());
00211                
00212                std::set<ComponentDescription> components = itRecordProvider->second->proxyProviderDescriptions();
00213                std::set<ComponentDescription>::iterator itProxyProv = components.find(itInfo->first);
00214                if(itProxyProv == components.end()){
00215                   throw cms::Exception("ESPreferWrongRecord")<<"The type="<<itInfo->first.type_<<" label=\""<<
00216                   itInfo->first.label_<<"\" does not provide data for the Record "<<recordName;
00217                }
00218                //Does it data type exist?
00219                eventsetup::TypeTag datumType = eventsetup::TypeTag::findType(itRecData->second.first);
00220                if(datumType == eventsetup::TypeTag()) {
00221                   //not found
00222                   throw cms::Exception("ESPreferWrongDataType")<<"The es_prefer statement for type="<<itInfo->first.type_<<" label=\""<<
00223                   itInfo->first.label_<<"\" has the unknown data type \""<<itRecData->second.first<<"\""
00224                   <<"\n Please check spelling";
00225                }
00226                eventsetup::DataKey datumKey(datumType, itRecData->second.second.c_str());
00227                
00228                //Does the proxyprovider make this?
00229                boost::shared_ptr<DataProxyProvider> proxyProv = 
00230                   itRecordProvider->second->proxyProvider(*itProxyProv);
00231                const DataProxyProvider::KeyedProxies& keyedProxies = proxyProv->keyedProxies(recordKey);
00232                if(std::find_if(keyedProxies.begin(), keyedProxies.end(), 
00233                                 boost::bind(std::equal_to<DataKey>(), datumKey, boost::bind(&DataProxyProvider::KeyedProxies::value_type::first,_1))) ==
00234                    keyedProxies.end()){
00235                   throw cms::Exception("ESPreferWrongData")<<"The es_prefer statement for type="<<itInfo->first.type_<<" label=\""<<
00236                   itInfo->first.label_<<"\" specifies the data item \n"
00237                   <<"  type=\""<<itRecData->second.first<<"\" label=\""<<itRecData->second.second<<"\""
00238                   <<"  which is not provided.  Please check spelling.";
00239                }
00240                
00241                EventSetupRecordProvider::DataToPreferredProviderMap& dataToProviderMap
00242                   =returnValue[recordKey];
00243                //has another provider already been specified?
00244                if(dataToProviderMap.end() != dataToProviderMap.find(datumKey)) {
00245                   EventSetupRecordProvider::DataToPreferredProviderMap::iterator itFind =
00246                   dataToProviderMap.find(datumKey);
00247                   throw cms::Exception("ESPreferConflict") <<"Two providers have been set to be preferred for\n"
00248                   <<datumKey.type().name()<<" \""<<datumKey.name().value()<<"\""
00249                   <<"\n the providers are "
00250                   <<"\n 1) type="<<itFind->second.type_<<" label=\""<<itFind->second.label_<<"\""
00251                   <<"\n 2) type="<<itProxyProv->type_<<" label=\""<<itProxyProv->label_<<"\""
00252                   <<"\nPlease modify configuration so only one is preferred";
00253                }
00254                dataToProviderMap.insert(std::make_pair(datumKey,*itProxyProv));
00255             }
00256          }
00257       }
00258    }
00259    return returnValue;
00260 }
00261 
00262 void
00263 EventSetupProvider::finishConfiguration()
00264 {   
00265    //we delayed adding finders to the system till here so that everything would be loaded first
00266    recordToFinders_->clear();
00267    for(std::vector<boost::shared_ptr<EventSetupRecordIntervalFinder> >::iterator itFinder=finders_->begin(),
00268        itEnd = finders_->end();
00269        itFinder != itEnd;
00270        ++itFinder) {
00271       typedef std::set<EventSetupRecordKey> Keys;
00272       const Keys recordsUsing = (*itFinder)->findingForRecords();
00273       
00274       for(Keys::const_iterator itKey = recordsUsing.begin(), itKeyEnd = recordsUsing.end();
00275           itKey != itKeyEnd;
00276           ++itKey) {
00277         (*recordToFinders_)[*itKey].push_back(*itFinder);
00278          Providers::iterator itFound = providers_.find(*itKey);
00279          if(providers_.end() == itFound) {
00280             //create a provider for this record
00281             insert(*itKey, EventSetupRecordProviderFactoryManager::instance().makeRecordProvider(*itKey));
00282             itFound = providers_.find(*itKey);
00283          }
00284          itFound->second->addFinder(*itFinder);
00285       }      
00286    }
00287    //we've transfered our ownership so this is no longer needed
00288    finders_.reset();
00289 
00290    //Now handle providers since sources can also be finders and the sources can delay registering
00291    // their Records and therefore could delay setting up their Proxies
00292    psetIDToRecordKey_->clear();
00293    typedef std::set<EventSetupRecordKey> Keys;
00294    for(std::vector<boost::shared_ptr<DataProxyProvider> >::iterator itProvider=dataProviders_->begin(),
00295        itEnd = dataProviders_->end();
00296        itProvider != itEnd;
00297        ++itProvider) {
00298       
00299       ParameterSetIDHolder psetID((*itProvider)->description().pid_);
00300 
00301       const Keys recordsUsing = (*itProvider)->usingRecords();
00302       
00303       for(Keys::const_iterator itKey = recordsUsing.begin(), itKeyEnd = recordsUsing.end();
00304           itKey != itKeyEnd;
00305           ++itKey) {
00306 
00307          if ((*itProvider)->description().isLooper_) {
00308             recordsWithALooperProxy_->insert(*itKey);
00309          }
00310 
00311          (*psetIDToRecordKey_)[psetID].insert(*itKey);
00312 
00313          Providers::iterator itFound = providers_.find(*itKey);
00314          if(providers_.end() == itFound) {
00315             //create a provider for this record
00316             insert(*itKey, EventSetupRecordProviderFactoryManager::instance().makeRecordProvider(*itKey));
00317             itFound = providers_.find(*itKey);
00318          }
00319          itFound->second->add(*itProvider);
00320       }
00321    }
00322    dataProviders_.reset();
00323    
00324    //used for the case where no preferred Providers have been specified for the Record
00325    static const EventSetupRecordProvider::DataToPreferredProviderMap kEmptyMap;
00326    
00327    *recordToPreferred_ = determinePreferred(preferredProviderInfo_.get(),providers_);
00328    //For each Provider, find all the Providers it depends on.  If a dependent Provider
00329    // can not be found pass in an empty list
00330    //CHANGE: now allow for missing Providers
00331    for(Providers::iterator itProvider = providers_.begin(), itProviderEnd = providers_.end();
00332         itProvider != itProviderEnd;
00333         ++itProvider) {
00334       const EventSetupRecordProvider::DataToPreferredProviderMap* preferredInfo = &kEmptyMap;
00335       RecordToPreferred::const_iterator itRecordFound = recordToPreferred_->find(itProvider->first);
00336       if(itRecordFound != recordToPreferred_->end()) {
00337          preferredInfo = &(itRecordFound->second);
00338       }
00339       //Give it our list of preferred 
00340       itProvider->second->usePreferred(*preferredInfo);
00341       
00342       std::set<EventSetupRecordKey> records = itProvider->second->dependentRecords();
00343       if(records.size() != 0) {
00344          std::string missingRecords;
00345          std::vector<boost::shared_ptr<EventSetupRecordProvider> > depProviders;
00346          depProviders.reserve(records.size());
00347          bool foundAllProviders = true;
00348          for(std::set<EventSetupRecordKey>::iterator itRecord = records.begin(),
00349               itRecordEnd = records.end();
00350               itRecord != itRecordEnd;
00351               ++itRecord) {
00352             Providers::iterator itFound = providers_.find(*itRecord);
00353             if(itFound == providers_.end()) {
00354                foundAllProviders = false;
00355                if(missingRecords.size() == 0) {
00356                  missingRecords = itRecord->name();
00357                } else {
00358                  missingRecords += ", ";
00359                  missingRecords += itRecord->name();
00360                }
00361                //break;
00362             } else {
00363                depProviders.push_back(itFound->second);
00364             }
00365          }
00366          
00367          if(!foundAllProviders) {
00368             edm::LogInfo("EventSetupDependency")<<"The EventSetup record "<<itProvider->second->key().name()
00369             <<" depends on at least one Record \n ("<<missingRecords<<") which is not present in the job."
00370            "\n This may lead to an exception begin thrown during event processing.\n If no exception occurs during the job than it is usually safe to ignore this message.";
00371 
00372             //depProviders.clear();
00373            //NOTE: should provide a warning
00374          }
00375           
00376          itProvider->second->setDependentProviders(depProviders);
00377       }
00378    }
00379    mustFinishConfiguration_ = false;
00380 }
00381 
00382 typedef std::map<EventSetupRecordKey, boost::shared_ptr<EventSetupRecordProvider> > Providers;
00383 typedef Providers::iterator Itr;
00384 static
00385 void
00386 findDependents(const EventSetupRecordKey& iKey,
00387                Itr itBegin,
00388                Itr itEnd,
00389                std::vector<boost::shared_ptr<EventSetupRecordProvider> >& oDependents)
00390 {
00391   
00392   for(Itr it = itBegin; it != itEnd; ++it) {
00393     //does it depend on the record in question?
00394     const std::set<EventSetupRecordKey>& deps = it->second->dependentRecords();
00395     if(deps.end() != deps.find(iKey)) {
00396       oDependents.push_back(it->second);
00397       //now see who is dependent on this record since they will be indirectly dependent on iKey
00398       findDependents(it->first, itBegin, itEnd, oDependents);
00399     }
00400   }
00401 }
00402                
00403 void 
00404 EventSetupProvider::resetRecordPlusDependentRecords(const EventSetupRecordKey& iKey)
00405 {
00406   Providers::iterator itFind = providers_.find(iKey);
00407   if(itFind == providers_.end()) {
00408     return;
00409   }
00410 
00411   
00412   std::vector<boost::shared_ptr<EventSetupRecordProvider> > dependents;
00413   findDependents(iKey, providers_.begin(), providers_.end(), dependents);
00414 
00415   dependents.erase(std::unique(dependents.begin(),dependents.end()), dependents.end());
00416   
00417   itFind->second->resetProxies();
00418   for_all(dependents,
00419                 boost::bind(&EventSetupRecordProvider::resetProxies,
00420                             _1));
00421 }
00422 
00423 void 
00424 EventSetupProvider::forceCacheClear()
00425 {
00426    for(Providers::iterator it=providers_.begin(), itEnd = providers_.end();
00427        it != itEnd;
00428        ++it) {
00429       it->second->resetProxies();
00430    }
00431 }
00432 
00433 void
00434 EventSetupProvider::checkESProducerSharing(EventSetupProvider& precedingESProvider,
00435                                            std::set<ParameterSetIDHolder>& sharingCheckDone,
00436                                            std::map<EventSetupRecordKey, std::vector<ComponentDescription const*> >& referencedESProducers,
00437                                            EventSetupsController& esController) {
00438 
00439    edm::LogVerbatim("EventSetupSharing") << "EventSetupProvider::checkESProducerSharing: Checking processes with SubProcess Indexes "
00440                                          << subProcessIndex() << " and " << precedingESProvider.subProcessIndex();
00441 
00442    if (referencedESProducers.empty()) {
00443       for (auto const& recordProvider : providers_) {
00444          recordProvider.second->getReferencedESProducers(referencedESProducers);
00445       }
00446    }
00447 
00448    // This records whether the configurations of all the DataProxyProviders
00449    // and finders matches for a particular pair of processes and
00450    // a particular record and also the records it depends on.
00451    std::map<EventSetupRecordKey, bool> allComponentsMatch;
00452 
00453    std::map<ParameterSetID, bool> candidateNotRejectedYet;
00454 
00455    // Loop over all the ESProducers which have a DataProxy
00456    // referenced by any EventSetupRecord in this EventSetupProvider
00457    for (auto const& iRecord : referencedESProducers) {
00458       for (auto const& iComponent : iRecord.second) {
00459 
00460          ParameterSetID const& psetID = iComponent->pid_;
00461          ParameterSetIDHolder psetIDHolder(psetID);
00462          if (sharingCheckDone.find(psetIDHolder) != sharingCheckDone.end()) continue;
00463 
00464          bool firstProcessWithThisPSet = false;
00465          bool precedingHasMatchingPSet = false;
00466 
00467          esController.lookForMatches(psetID,
00468                                      subProcessIndex_,
00469                                      precedingESProvider.subProcessIndex_,
00470                                      firstProcessWithThisPSet,
00471                                      precedingHasMatchingPSet);
00472 
00473          if (firstProcessWithThisPSet) {
00474             sharingCheckDone.insert(psetIDHolder);
00475             allComponentsMatch[iRecord.first] = false;
00476             continue;
00477          }
00478 
00479          if (!precedingHasMatchingPSet) {
00480             allComponentsMatch[iRecord.first] = false;
00481             continue;
00482          }
00483 
00484          // An ESProducer that survives to this point is a candidate.
00485          // It was shared with some other process in the first pass where
00486          // ESProducers were constructed and one of three possibilities exists:
00487          //    1) It should not have been shared and a new ESProducer needs
00488          //    to be created and the proper pointers set.
00489          //    2) It should have been shared with a different preceding process
00490          //    in which case some pointers need to be modified.
00491          //    3) It was originally shared which the correct prior process
00492          //    in which case nothing needs to be done, but we do need to
00493          //    do some work to verify that.
00494          // Make an entry in a map for each of these ESProducers. We
00495          // will set the value to false if and when we determine
00496          // the ESProducer cannot be shared between this pair of processes. 
00497          auto iCandidateNotRejectedYet = candidateNotRejectedYet.find(psetID);
00498          if (iCandidateNotRejectedYet == candidateNotRejectedYet.end()) {
00499             candidateNotRejectedYet[psetID] = true;
00500             iCandidateNotRejectedYet = candidateNotRejectedYet.find(psetID);
00501          }
00502 
00503          // At this point we know that the two processes both
00504          // have an ESProducer matching the type and label in
00505          // iComponent and also with exactly the same configuration.
00506          // And there was not an earlier preceding process
00507          // where the same instance of the ESProducer could
00508          // have been shared.  And this ESProducer was referenced
00509          // by the later process's EventSetupRecord (prefered or
00510          // or just the only thing that could have made the data).
00511          // To determine if sharing is allowed, now we need to
00512          // check if all the DataProxyProviders and all the
00513          // finders are the same for this record and also for
00514          // all records this record depends on. And even
00515          // if this is true, we have to wait until the loop
00516          // ends because some other DataProxy associated with
00517          // the ESProducer could write to a different record where
00518          // the same determination will need to be repeated. Only if
00519          // all of the the DataProxy's can be shared, can the ESProducer
00520          // instance be shared across processes.
00521 
00522          if (iCandidateNotRejectedYet->second == true) {
00523 
00524             auto iAllComponentsMatch = allComponentsMatch.find(iRecord.first);
00525             if (iAllComponentsMatch == allComponentsMatch.end()) {
00526 
00527                // We do not know the value in AllComponents yet and
00528                // we need it now so we have to do the difficult calculation
00529                // now.
00530                bool match = doRecordsMatch(precedingESProvider,
00531                                            iRecord.first,
00532                                            allComponentsMatch,
00533                                            esController);
00534                allComponentsMatch[iRecord.first] = match;
00535                iAllComponentsMatch = allComponentsMatch.find(iRecord.first);            
00536             }
00537             if (!iAllComponentsMatch->second) {
00538               iCandidateNotRejectedYet->second = false;
00539             }
00540          }
00541       }  // end loop over components used by record
00542    } // end loop over records
00543 
00544    // Loop over candidates
00545    for (auto const& candidate : candidateNotRejectedYet) {
00546       ParameterSetID const& psetID = candidate.first;
00547       bool canBeShared = candidate.second;
00548       if (canBeShared) {
00549          ParameterSet const& pset = *esController.getESProducerPSet(psetID, subProcessIndex_);
00550          logInfoWhenSharing(pset);
00551          ParameterSetIDHolder psetIDHolder(psetID);
00552          sharingCheckDone.insert(psetIDHolder);
00553          if (esController.isFirstMatch(psetID,
00554                                        subProcessIndex_,
00555                                        precedingESProvider.subProcessIndex_)) {
00556             continue;  // Proper sharing was already done. Nothing more to do.
00557          }
00558 
00559          // Need to reset the pointer from the EventSetupRecordProvider to the
00560          // the DataProxyProvider so these two processes share an ESProducer.
00561 
00562          boost::shared_ptr<DataProxyProvider> dataProxyProvider;
00563          std::set<EventSetupRecordKey> const& keysForPSetID1 = (*precedingESProvider.psetIDToRecordKey_)[psetIDHolder];
00564          for (auto const& key : keysForPSetID1) {
00565             boost::shared_ptr<EventSetupRecordProvider> const& recordProvider = precedingESProvider.providers_[key];
00566             dataProxyProvider = recordProvider->proxyProvider(psetIDHolder);
00567             assert(dataProxyProvider);
00568             break;
00569          }
00570 
00571          std::set<EventSetupRecordKey> const& keysForPSetID2 = (*psetIDToRecordKey_)[psetIDHolder];
00572          for (auto const& key : keysForPSetID2) {
00573             boost::shared_ptr<EventSetupRecordProvider> const& recordProvider = providers_[key];
00574             recordProvider->resetProxyProvider(psetIDHolder, dataProxyProvider);
00575          }
00576       } else {
00577          if (esController.isLastMatch(psetID,
00578                                       subProcessIndex_,
00579                                       precedingESProvider.subProcessIndex_)) {
00580             
00581 
00582             ParameterSet const& pset = *esController.getESProducerPSet(psetID, subProcessIndex_);
00583             ModuleFactory::get()->addTo(esController,
00584                                         *this,
00585                                         pset,
00586                                         true);
00587 
00588          }
00589       }
00590    }
00591 }
00592 
00593 bool
00594 EventSetupProvider::doRecordsMatch(EventSetupProvider & precedingESProvider,
00595                                    EventSetupRecordKey const& eventSetupRecordKey,
00596                                    std::map<EventSetupRecordKey, bool> & allComponentsMatch,
00597                                    EventSetupsController const& esController) {
00598    // first check if this record matches. If not just return false
00599 
00600    // then find the directly dependent records and iterate over them
00601    // recursively call this function on them. If they return false
00602    // set allComponentsMatch to false for them and return false.
00603    // if they all return true then set allComponents to true
00604    // and return true.
00605 
00606    if (precedingESProvider.recordsWithALooperProxy_->find(eventSetupRecordKey) != precedingESProvider.recordsWithALooperProxy_->end()) {
00607       return false;
00608    }
00609 
00610    if ((*recordToFinders_)[eventSetupRecordKey].size() != (*precedingESProvider.recordToFinders_)[eventSetupRecordKey].size()) {
00611       return false;
00612    }
00613 
00614    for (auto const& finder : (*recordToFinders_)[eventSetupRecordKey]) {
00615       ParameterSetID const& psetID = finder->descriptionForFinder().pid_;
00616       bool itMatches = esController.isMatchingESSource(psetID,
00617                                                        subProcessIndex_,
00618                                                        precedingESProvider.subProcessIndex_);
00619       if (!itMatches) {
00620          return false;
00621       }
00622    }
00623 
00624    fillReferencedDataKeys(eventSetupRecordKey);
00625    precedingESProvider.fillReferencedDataKeys(eventSetupRecordKey);
00626 
00627    std::map<DataKey, ComponentDescription const*> const& dataItems = (*referencedDataKeys_)[eventSetupRecordKey];
00628 
00629    std::map<DataKey, ComponentDescription const*> const& precedingDataItems = (*precedingESProvider.referencedDataKeys_)[eventSetupRecordKey];
00630 
00631    if (dataItems.size() != precedingDataItems.size()) {
00632       return false;
00633    }
00634 
00635    for (auto const& dataItem : dataItems) {
00636       auto precedingDataItem = precedingDataItems.find(dataItem.first);
00637       if (precedingDataItem == precedingDataItems.end()) {
00638          return false;
00639       }
00640       if (dataItem.second->pid_ != precedingDataItem->second->pid_) {
00641          return false;
00642       }
00643       // Check that the configurations match exactly for the ESProducers
00644       // (We already checked the ESSources above and there should not be
00645       // any loopers)
00646       if (!dataItem.second->isSource_ && !dataItem.second->isLooper_) {
00647          bool itMatches = esController.isMatchingESProducer(dataItem.second->pid_,
00648                                                             subProcessIndex_,
00649                                                             precedingESProvider.subProcessIndex_);
00650          if (!itMatches) {
00651             return false;
00652          }
00653       }
00654    }
00655    Providers::iterator itFound = providers_.find(eventSetupRecordKey);
00656    if (itFound != providers_.end()) {
00657       std::set<EventSetupRecordKey> dependentRecords = itFound->second->dependentRecords();
00658       for (auto const& dependentRecord : dependentRecords) {
00659          auto iter = allComponentsMatch.find(dependentRecord);
00660          if (iter != allComponentsMatch.end()) {
00661             if (iter->second) {
00662                continue;
00663             } else {
00664                return false;
00665             }
00666          }
00667          bool match = doRecordsMatch(precedingESProvider,
00668                                      dependentRecord,
00669                                      allComponentsMatch,
00670                                      esController);            
00671          allComponentsMatch[dependentRecord] = match;
00672          if (!match) return false;
00673       }
00674    }
00675    return true;
00676 }
00677 
00678 void
00679 EventSetupProvider::fillReferencedDataKeys(EventSetupRecordKey const& eventSetupRecordKey) {
00680 
00681    if (referencedDataKeys_->find(eventSetupRecordKey) != referencedDataKeys_->end()) return;
00682 
00683    auto recordProvider = providers_.find(eventSetupRecordKey);
00684    if (recordProvider == providers_.end()) {
00685       (*referencedDataKeys_)[eventSetupRecordKey];
00686       return;
00687    }
00688    if (recordProvider->second) {
00689       recordProvider->second->fillReferencedDataKeys((*referencedDataKeys_)[eventSetupRecordKey]);
00690    }
00691 }
00692 
00693 void
00694 EventSetupProvider::resetRecordToProxyPointers() {
00695    for (auto const& recordProvider : providers_) {
00696       static const EventSetupRecordProvider::DataToPreferredProviderMap kEmptyMap;
00697       const EventSetupRecordProvider::DataToPreferredProviderMap* preferredInfo = &kEmptyMap;
00698       RecordToPreferred::const_iterator itRecordFound = recordToPreferred_->find(recordProvider.first);
00699       if(itRecordFound != recordToPreferred_->end()) {
00700          preferredInfo = &(itRecordFound->second);
00701       }
00702       recordProvider.second->resetRecordToProxyPointers(*preferredInfo);
00703    }
00704 }
00705 
00706 void
00707 EventSetupProvider::clearInitializationData() {
00708    preferredProviderInfo_.reset();
00709    referencedDataKeys_.reset();
00710    recordToFinders_.reset();
00711    psetIDToRecordKey_.reset();
00712    recordToPreferred_.reset();
00713    recordsWithALooperProxy_.reset();
00714 }
00715 
00716 void
00717 EventSetupProvider::addRecordToEventSetup(EventSetupRecord& iRecord) {
00718    iRecord.setEventSetup(&eventSetup_);
00719    eventSetup_.add(iRecord);
00720 }
00721       
00722 //
00723 // const member functions
00724 //
00725 EventSetup const&
00726 EventSetupProvider::eventSetupForInstance(const IOVSyncValue& iValue)
00727 {
00728    eventSetup_.setIOVSyncValue(iValue);
00729 
00730    eventSetup_.clear();
00731 
00732    // In a cmsRun job this does nothing because the EventSetupsController
00733    // will have already called finishConfiguration, but some tests will
00734    // call finishConfiguration here.
00735    if(mustFinishConfiguration_) {
00736       finishConfiguration();
00737    }
00738 
00739    for(Providers::iterator itProvider = providers_.begin(), itProviderEnd = providers_.end();
00740         itProvider != itProviderEnd;
00741         ++itProvider) {
00742       itProvider->second->addRecordToIfValid(*this, iValue);
00743    }   
00744    return eventSetup_;
00745 }
00746 
00747 namespace {
00748    struct InsertAll : public std::unary_function< const std::set<ComponentDescription>&, void>{
00749       
00750       typedef std::set<ComponentDescription> Set;
00751       Set* container_;
00752       InsertAll(Set& iSet) : container_(&iSet) {}
00753       void operator()(const Set& iSet) {
00754          container_->insert(iSet.begin(), iSet.end());
00755       }
00756    };
00757 }
00758 std::set<ComponentDescription> 
00759 EventSetupProvider::proxyProviderDescriptions() const
00760 {
00761    using boost::bind;
00762    typedef std::set<ComponentDescription> Set;
00763    Set descriptions;
00764 
00765    for_all(providers_,
00766                  bind(InsertAll(descriptions),
00767                       bind(&EventSetupRecordProvider::proxyProviderDescriptions,
00768                            bind(&Providers::value_type::second,_1))));
00769    if(dataProviders_.get()) {
00770       for(std::vector<boost::shared_ptr<DataProxyProvider> >::const_iterator it = dataProviders_->begin(),
00771           itEnd = dataProviders_->end();
00772           it != itEnd;
00773           ++it) {
00774          descriptions.insert((*it)->description());
00775       }
00776          
00777    }
00778                        
00779    return descriptions;
00780 }
00781 
00782 //
00783 // static member functions
00784 //
00785 void EventSetupProvider::logInfoWhenSharing(ParameterSet const& iConfiguration) {
00786 
00787    std::string edmtype = iConfiguration.getParameter<std::string>("@module_edm_type");
00788    std::string modtype = iConfiguration.getParameter<std::string>("@module_type");
00789    std::string label = iConfiguration.getParameter<std::string>("@module_label");
00790    edm::LogVerbatim("EventSetupSharing") << "Sharing " << edmtype << ": class=" << modtype << " label='" << label << "'";
00791 }
00792    }
00793 }