CMS 3D CMS Logo

EventSetupProvider.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: Framework
4 // Module: EventSetupProvider
5 //
6 // Description: <one line class summary>
7 //
8 // Implementation:
9 // <Notes on implementation>
10 //
11 // Author: Chris Jones
12 // Created: Thu Mar 24 16:27:14 EST 2005
13 //
14 
15 // system include files
16 #include "boost/bind.hpp"
17 #include <algorithm>
18 #include <cassert>
19 
20 // user include files
33 
34 
35 namespace edm {
36  namespace eventsetup {
37 
38  namespace {
39  class KnownRecordsSupplierImpl : public EventSetupKnownRecordsSupplier {
40  public:
41  using Map = std::map<EventSetupRecordKey, std::shared_ptr<EventSetupRecordProvider> >;
42 
43  explicit KnownRecordsSupplierImpl( Map const& iMap) : map_(iMap) {}
44 
45  bool isKnown(EventSetupRecordKey const& iKey) const override {
46  return map_.find(iKey) != map_.end();
47  }
48 
49  private:
50  Map map_;
51  };
52  }
53 
54 //
55 // constants, enums and typedefs
56 //
57 
58 //
59 // static data member definitions
60 //
61 
62 //
63 // constructors and destructor
64 //
65 EventSetupProvider::EventSetupProvider(unsigned subProcessIndex, const PreferredProviderInfo* iInfo) :
66 eventSetup_(),
67 providers_(),
68 knownRecordsSupplier_( std::make_unique<KnownRecordsSupplierImpl>(providers_)),
69 mustFinishConfiguration_(true),
70 subProcessIndex_(subProcessIndex),
71 preferredProviderInfo_((0!=iInfo) ? (new PreferredProviderInfo(*iInfo)): 0),
72 finders_(new std::vector<std::shared_ptr<EventSetupRecordIntervalFinder> >() ),
73 dataProviders_(new std::vector<std::shared_ptr<DataProxyProvider> >() ),
74 referencedDataKeys_(new std::map<EventSetupRecordKey, std::map<DataKey, ComponentDescription const*> >),
75 recordToFinders_(new std::map<EventSetupRecordKey, std::vector<std::shared_ptr<EventSetupRecordIntervalFinder> > >),
76 psetIDToRecordKey_(new std::map<ParameterSetIDHolder, std::set<EventSetupRecordKey> >),
77 recordToPreferred_(new std::map<EventSetupRecordKey, std::map<DataKey, ComponentDescription> >),
78 recordsWithALooperProxy_(new std::set<EventSetupRecordKey>)
79 {
80  eventSetup_.setKnownRecordsSupplier(knownRecordsSupplier_.get());
81 }
82 
83 // EventSetupProvider::EventSetupProvider(const EventSetupProvider& rhs)
84 // {
85 // // do actual copying here;
86 // }
87 
88 EventSetupProvider::~EventSetupProvider()
89 {
90 }
91 
92 //
93 // assignment operators
94 //
95 // const EventSetupProvider& EventSetupProvider::operator=(const EventSetupProvider& rhs)
96 // {
97 // //An exception safe implementation is
98 // EventSetupProvider temp(rhs);
99 // swap(rhs);
100 //
101 // return *this;
102 // }
103 
104 //
105 // member functions
106 //
107 void
108 EventSetupProvider::insert(const EventSetupRecordKey& iKey, std::unique_ptr<EventSetupRecordProvider> iProvider)
109 {
110  std::shared_ptr<EventSetupRecordProvider> temp(iProvider.release());
111  providers_[iKey] = temp;
112  //temp->addRecordTo(*this);
113 }
114 
115 void
116 EventSetupProvider::add(std::shared_ptr<DataProxyProvider> iProvider)
117 {
118  assert(iProvider.get() != 0);
119  dataProviders_->push_back(iProvider);
120 }
121 
122 void
123 EventSetupProvider::replaceExisting(std::shared_ptr<DataProxyProvider> dataProxyProvider)
124 {
125  ParameterSetIDHolder psetID(dataProxyProvider->description().pid_);
126  std::set<EventSetupRecordKey> const& keysForPSetID = (*psetIDToRecordKey_)[psetID];
127  for (auto const& key : keysForPSetID) {
128  std::shared_ptr<EventSetupRecordProvider> const& recordProvider = providers_[key];
129  recordProvider->resetProxyProvider(psetID, dataProxyProvider);
130  }
131 }
132 
133 void
134 EventSetupProvider::add(std::shared_ptr<EventSetupRecordIntervalFinder> iFinder)
135 {
136  assert(iFinder.get() != 0);
137  finders_->push_back(iFinder);
138 }
139 
140 typedef std::map<EventSetupRecordKey, std::shared_ptr<EventSetupRecordProvider> > Providers;
141 typedef std::map<EventSetupRecordKey, EventSetupRecordProvider::DataToPreferredProviderMap> RecordToPreferred;
143 static
144 void
146  const Providers& iProviders,
147  RecordToPreferred& iReturnValue)
148 {
149  //need to get our hands on the actual DataProxyProvider
150  bool foundProxyProvider = false;
151  for(Providers::const_iterator itProvider = iProviders.begin(), itProviderEnd = iProviders.end();
152  itProvider!= itProviderEnd;
153  ++itProvider) {
154  std::set<ComponentDescription> components = itProvider->second->proxyProviderDescriptions();
155  if(components.find(iComponent)!= components.end()) {
156  std::shared_ptr<DataProxyProvider> proxyProv =
157  itProvider->second->proxyProvider(*(components.find(iComponent)));
158  assert(proxyProv.get());
159 
160  std::set<EventSetupRecordKey> records = proxyProv->usingRecords();
161  for(std::set<EventSetupRecordKey>::iterator itRecord = records.begin(),
162  itRecordEnd = records.end();
163  itRecord != itRecordEnd;
164  ++itRecord){
165  const DataProxyProvider::KeyedProxies& keyedProxies = proxyProv->keyedProxies(*itRecord);
166  if(!keyedProxies.empty()){
167  //add them to our output
169  iReturnValue[*itRecord];
170 
171  for(DataProxyProvider::KeyedProxies::const_iterator itProxy = keyedProxies.begin(),
172  itProxyEnd = keyedProxies.end();
173  itProxy != itProxyEnd;
174  ++itProxy) {
175  EventSetupRecordProvider::DataToPreferredProviderMap::iterator itFind =
176  dataToProviderMap.find(itProxy->first);
177  if(itFind != dataToProviderMap.end()){
178  throw cms::Exception("ESPreferConflict") <<"Two providers have been set to be preferred for\n"
179  <<itProxy->first.type().name()<<" \""<<itProxy->first.name().value()<<"\""
180  <<"\n the providers are "
181  <<"\n 1) type="<<itFind->second.type_<<" label=\""<<itFind->second.label_<<"\""
182  <<"\n 2) type="<<iComponent.type_<<" label=\""<<iComponent.label_<<"\""
183  <<"\nPlease modify configuration so only one is preferred";
184  }
185  dataToProviderMap.insert(std::make_pair(itProxy->first,iComponent));
186  }
187  }
188  }
189  foundProxyProvider=true;
190  break;
191  }
192  }
193  if(!foundProxyProvider) {
194  throw cms::Exception("ESPreferNoProvider")<<"Could not make type=\""<<iComponent.type_
195  <<"\" label=\""<<iComponent.label_<<"\" a preferred Provider."<<
196  "\n Please check spelling of name, or that it was loaded into the job.";
197  }
198 }
199 static
201  const Providers& iProviders)
202 {
203  using namespace edm::eventsetup;
204  RecordToPreferred returnValue;
205  if(0 != iInfo){
206  for(EventSetupProvider::PreferredProviderInfo::const_iterator itInfo = iInfo->begin(),
207  itInfoEnd = iInfo->end();
208  itInfo != itInfoEnd;
209  ++itInfo) {
210  if(itInfo->second.empty()) {
211  //want everything
212  preferEverything(itInfo->first, iProviders, returnValue);
213  } else {
214  for(EventSetupProvider::RecordToDataMap::const_iterator itRecData = itInfo->second.begin(),
215  itRecDataEnd = itInfo->second.end();
216  itRecData != itRecDataEnd;
217  ++itRecData) {
218  std::string recordName= itRecData->first;
220  if(recordKey.type() == eventsetup::EventSetupRecordKey::TypeTag()) {
221  throw cms::Exception("ESPreferUnknownRecord") <<"Unknown record \""<<recordName
222  <<"\" used in es_prefer statement for type="
223  <<itInfo->first.type_<<" label=\""<<itInfo->first.label_
224  <<"\"\n Please check spelling.";
225  //record not found
226  }
227  //See if the ProxyProvider provides something for this Record
228  Providers::const_iterator itRecordProvider = iProviders.find(recordKey);
229  assert(itRecordProvider != iProviders.end());
230 
231  std::set<ComponentDescription> components = itRecordProvider->second->proxyProviderDescriptions();
232  std::set<ComponentDescription>::iterator itProxyProv = components.find(itInfo->first);
233  if(itProxyProv == components.end()){
234  throw cms::Exception("ESPreferWrongRecord")<<"The type="<<itInfo->first.type_<<" label=\""<<
235  itInfo->first.label_<<"\" does not provide data for the Record "<<recordName;
236  }
237  //Does it data type exist?
238  eventsetup::TypeTag datumType = eventsetup::TypeTag::findType(itRecData->second.first);
239  if(datumType == eventsetup::TypeTag()) {
240  //not found
241  throw cms::Exception("ESPreferWrongDataType")<<"The es_prefer statement for type="<<itInfo->first.type_<<" label=\""<<
242  itInfo->first.label_<<"\" has the unknown data type \""<<itRecData->second.first<<"\""
243  <<"\n Please check spelling";
244  }
245  eventsetup::DataKey datumKey(datumType, itRecData->second.second.c_str());
246 
247  //Does the proxyprovider make this?
248  std::shared_ptr<DataProxyProvider> proxyProv =
249  itRecordProvider->second->proxyProvider(*itProxyProv);
250  const DataProxyProvider::KeyedProxies& keyedProxies = proxyProv->keyedProxies(recordKey);
251  if(std::find_if(keyedProxies.begin(), keyedProxies.end(),
252  boost::bind(std::equal_to<DataKey>(), datumKey, boost::bind(&DataProxyProvider::KeyedProxies::value_type::first,_1))) ==
253  keyedProxies.end()){
254  throw cms::Exception("ESPreferWrongData")<<"The es_prefer statement for type="<<itInfo->first.type_<<" label=\""<<
255  itInfo->first.label_<<"\" specifies the data item \n"
256  <<" type=\""<<itRecData->second.first<<"\" label=\""<<itRecData->second.second<<"\""
257  <<" which is not provided. Please check spelling.";
258  }
259 
261  =returnValue[recordKey];
262  //has another provider already been specified?
263  if(dataToProviderMap.end() != dataToProviderMap.find(datumKey)) {
264  EventSetupRecordProvider::DataToPreferredProviderMap::iterator itFind =
265  dataToProviderMap.find(datumKey);
266  throw cms::Exception("ESPreferConflict") <<"Two providers have been set to be preferred for\n"
267  <<datumKey.type().name()<<" \""<<datumKey.name().value()<<"\""
268  <<"\n the providers are "
269  <<"\n 1) type="<<itFind->second.type_<<" label=\""<<itFind->second.label_<<"\""
270  <<"\n 2) type="<<itProxyProv->type_<<" label=\""<<itProxyProv->label_<<"\""
271  <<"\nPlease modify configuration so only one is preferred";
272  }
273  dataToProviderMap.insert(std::make_pair(datumKey,*itProxyProv));
274  }
275  }
276  }
277  }
278  return returnValue;
279 }
280 
281 void
282 EventSetupProvider::finishConfiguration()
283 {
284  //we delayed adding finders to the system till here so that everything would be loaded first
285  recordToFinders_->clear();
286  for(std::vector<std::shared_ptr<EventSetupRecordIntervalFinder> >::iterator itFinder=finders_->begin(),
287  itEnd = finders_->end();
288  itFinder != itEnd;
289  ++itFinder) {
290  typedef std::set<EventSetupRecordKey> Keys;
291  const Keys recordsUsing = (*itFinder)->findingForRecords();
292 
293  for(Keys::const_iterator itKey = recordsUsing.begin(), itKeyEnd = recordsUsing.end();
294  itKey != itKeyEnd;
295  ++itKey) {
296  (*recordToFinders_)[*itKey].push_back(*itFinder);
297  Providers::iterator itFound = providers_.find(*itKey);
298  if(providers_.end() == itFound) {
299  //create a provider for this record
300  insert(*itKey, EventSetupRecordProviderFactoryManager::instance().makeRecordProvider(*itKey));
301  itFound = providers_.find(*itKey);
302  }
303  itFound->second->addFinder(*itFinder);
304  }
305  }
306  //we've transfered our ownership so this is no longer needed
307  finders_.reset();
308 
309  //Now handle providers since sources can also be finders and the sources can delay registering
310  // their Records and therefore could delay setting up their Proxies
311  psetIDToRecordKey_->clear();
312  typedef std::set<EventSetupRecordKey> Keys;
313  for(std::vector<std::shared_ptr<DataProxyProvider> >::iterator itProvider=dataProviders_->begin(),
314  itEnd = dataProviders_->end();
315  itProvider != itEnd;
316  ++itProvider) {
317 
318  ParameterSetIDHolder psetID((*itProvider)->description().pid_);
319 
320  const Keys recordsUsing = (*itProvider)->usingRecords();
321 
322  for(Keys::const_iterator itKey = recordsUsing.begin(), itKeyEnd = recordsUsing.end();
323  itKey != itKeyEnd;
324  ++itKey) {
325 
326  if ((*itProvider)->description().isLooper_) {
327  recordsWithALooperProxy_->insert(*itKey);
328  }
329 
330  (*psetIDToRecordKey_)[psetID].insert(*itKey);
331 
332  Providers::iterator itFound = providers_.find(*itKey);
333  if(providers_.end() == itFound) {
334  //create a provider for this record
335  insert(*itKey, EventSetupRecordProviderFactoryManager::instance().makeRecordProvider(*itKey));
336  itFound = providers_.find(*itKey);
337  }
338  itFound->second->add(*itProvider);
339  }
340  }
341  dataProviders_.reset();
342 
343  //used for the case where no preferred Providers have been specified for the Record
345 
346  *recordToPreferred_ = determinePreferred(preferredProviderInfo_.get(),providers_);
347  //For each Provider, find all the Providers it depends on. If a dependent Provider
348  // can not be found pass in an empty list
349  //CHANGE: now allow for missing Providers
350  for(Providers::iterator itProvider = providers_.begin(), itProviderEnd = providers_.end();
351  itProvider != itProviderEnd;
352  ++itProvider) {
353  const EventSetupRecordProvider::DataToPreferredProviderMap* preferredInfo = &kEmptyMap;
354  RecordToPreferred::const_iterator itRecordFound = recordToPreferred_->find(itProvider->first);
355  if(itRecordFound != recordToPreferred_->end()) {
356  preferredInfo = &(itRecordFound->second);
357  }
358  //Give it our list of preferred
359  itProvider->second->usePreferred(*preferredInfo);
360 
361  std::set<EventSetupRecordKey> records = itProvider->second->dependentRecords();
362  if(records.size() != 0) {
363  std::string missingRecords;
364  std::vector<std::shared_ptr<EventSetupRecordProvider> > depProviders;
365  depProviders.reserve(records.size());
366  bool foundAllProviders = true;
367  for(std::set<EventSetupRecordKey>::iterator itRecord = records.begin(),
368  itRecordEnd = records.end();
369  itRecord != itRecordEnd;
370  ++itRecord) {
371  Providers::iterator itFound = providers_.find(*itRecord);
372  if(itFound == providers_.end()) {
373  foundAllProviders = false;
374  if(missingRecords.size() == 0) {
375  missingRecords = itRecord->name();
376  } else {
377  missingRecords += ", ";
378  missingRecords += itRecord->name();
379  }
380  //break;
381  } else {
382  depProviders.push_back(itFound->second);
383  }
384  }
385 
386  if(!foundAllProviders) {
387  edm::LogInfo("EventSetupDependency")<<"The EventSetup record "<<itProvider->second->key().name()
388  <<" depends on at least one Record \n ("<<missingRecords<<") which is not present in the job."
389  "\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.";
390 
391  //depProviders.clear();
392  //NOTE: should provide a warning
393  }
394 
395  itProvider->second->setDependentProviders(depProviders);
396  }
397  }
398  mustFinishConfiguration_ = false;
399 }
400 
401 typedef std::map<EventSetupRecordKey, std::shared_ptr<EventSetupRecordProvider> > Providers;
402 typedef Providers::iterator Itr;
403 static
404 void
406  Itr itBegin,
407  Itr itEnd,
408  std::vector<std::shared_ptr<EventSetupRecordProvider> >& oDependents)
409 {
410 
411  for(Itr it = itBegin; it != itEnd; ++it) {
412  //does it depend on the record in question?
413  const std::set<EventSetupRecordKey>& deps = it->second->dependentRecords();
414  if(deps.end() != deps.find(iKey)) {
415  oDependents.push_back(it->second);
416  //now see who is dependent on this record since they will be indirectly dependent on iKey
417  findDependents(it->first, itBegin, itEnd, oDependents);
418  }
419  }
420 }
421 
422 void
423 EventSetupProvider::resetRecordPlusDependentRecords(const EventSetupRecordKey& iKey)
424 {
425  Providers::iterator itFind = providers_.find(iKey);
426  if(itFind == providers_.end()) {
427  return;
428  }
429 
430 
431  std::vector<std::shared_ptr<EventSetupRecordProvider> > dependents;
432  findDependents(iKey, providers_.begin(), providers_.end(), dependents);
433 
434  dependents.erase(std::unique(dependents.begin(),dependents.end()), dependents.end());
435 
436  itFind->second->resetProxies();
437  for_all(dependents,
438  boost::bind(&EventSetupRecordProvider::resetProxies,
439  _1));
440 }
441 
442 void
443 EventSetupProvider::forceCacheClear()
444 {
445  for(Providers::iterator it=providers_.begin(), itEnd = providers_.end();
446  it != itEnd;
447  ++it) {
448  it->second->resetProxies();
449  }
450 }
451 
452 void
453 EventSetupProvider::checkESProducerSharing(EventSetupProvider& precedingESProvider,
454  std::set<ParameterSetIDHolder>& sharingCheckDone,
455  std::map<EventSetupRecordKey, std::vector<ComponentDescription const*> >& referencedESProducers,
456  EventSetupsController& esController) {
457 
458  edm::LogVerbatim("EventSetupSharing") << "EventSetupProvider::checkESProducerSharing: Checking processes with SubProcess Indexes "
459  << subProcessIndex() << " and " << precedingESProvider.subProcessIndex();
460 
461  if (referencedESProducers.empty()) {
462  for (auto const& recordProvider : providers_) {
463  recordProvider.second->getReferencedESProducers(referencedESProducers);
464  }
465  }
466 
467  // This records whether the configurations of all the DataProxyProviders
468  // and finders matches for a particular pair of processes and
469  // a particular record and also the records it depends on.
470  std::map<EventSetupRecordKey, bool> allComponentsMatch;
471 
472  std::map<ParameterSetID, bool> candidateNotRejectedYet;
473 
474  // Loop over all the ESProducers which have a DataProxy
475  // referenced by any EventSetupRecord in this EventSetupProvider
476  for (auto const& iRecord : referencedESProducers) {
477  for (auto const& iComponent : iRecord.second) {
478 
479  ParameterSetID const& psetID = iComponent->pid_;
480  ParameterSetIDHolder psetIDHolder(psetID);
481  if (sharingCheckDone.find(psetIDHolder) != sharingCheckDone.end()) continue;
482 
483  bool firstProcessWithThisPSet = false;
484  bool precedingHasMatchingPSet = false;
485 
486  esController.lookForMatches(psetID,
487  subProcessIndex_,
488  precedingESProvider.subProcessIndex_,
489  firstProcessWithThisPSet,
490  precedingHasMatchingPSet);
491 
492  if (firstProcessWithThisPSet) {
493  sharingCheckDone.insert(psetIDHolder);
494  allComponentsMatch[iRecord.first] = false;
495  continue;
496  }
497 
498  if (!precedingHasMatchingPSet) {
499  allComponentsMatch[iRecord.first] = false;
500  continue;
501  }
502 
503  // An ESProducer that survives to this point is a candidate.
504  // It was shared with some other process in the first pass where
505  // ESProducers were constructed and one of three possibilities exists:
506  // 1) It should not have been shared and a new ESProducer needs
507  // to be created and the proper pointers set.
508  // 2) It should have been shared with a different preceding process
509  // in which case some pointers need to be modified.
510  // 3) It was originally shared which the correct prior process
511  // in which case nothing needs to be done, but we do need to
512  // do some work to verify that.
513  // Make an entry in a map for each of these ESProducers. We
514  // will set the value to false if and when we determine
515  // the ESProducer cannot be shared between this pair of processes.
516  auto iCandidateNotRejectedYet = candidateNotRejectedYet.find(psetID);
517  if (iCandidateNotRejectedYet == candidateNotRejectedYet.end()) {
518  candidateNotRejectedYet[psetID] = true;
519  iCandidateNotRejectedYet = candidateNotRejectedYet.find(psetID);
520  }
521 
522  // At this point we know that the two processes both
523  // have an ESProducer matching the type and label in
524  // iComponent and also with exactly the same configuration.
525  // And there was not an earlier preceding process
526  // where the same instance of the ESProducer could
527  // have been shared. And this ESProducer was referenced
528  // by the later process's EventSetupRecord (prefered or
529  // or just the only thing that could have made the data).
530  // To determine if sharing is allowed, now we need to
531  // check if all the DataProxyProviders and all the
532  // finders are the same for this record and also for
533  // all records this record depends on. And even
534  // if this is true, we have to wait until the loop
535  // ends because some other DataProxy associated with
536  // the ESProducer could write to a different record where
537  // the same determination will need to be repeated. Only if
538  // all of the the DataProxy's can be shared, can the ESProducer
539  // instance be shared across processes.
540 
541  if (iCandidateNotRejectedYet->second == true) {
542 
543  auto iAllComponentsMatch = allComponentsMatch.find(iRecord.first);
544  if (iAllComponentsMatch == allComponentsMatch.end()) {
545 
546  // We do not know the value in AllComponents yet and
547  // we need it now so we have to do the difficult calculation
548  // now.
549  bool match = doRecordsMatch(precedingESProvider,
550  iRecord.first,
551  allComponentsMatch,
552  esController);
553  allComponentsMatch[iRecord.first] = match;
554  iAllComponentsMatch = allComponentsMatch.find(iRecord.first);
555  }
556  if (!iAllComponentsMatch->second) {
557  iCandidateNotRejectedYet->second = false;
558  }
559  }
560  } // end loop over components used by record
561  } // end loop over records
562 
563  // Loop over candidates
564  for (auto const& candidate : candidateNotRejectedYet) {
565  ParameterSetID const& psetID = candidate.first;
566  bool canBeShared = candidate.second;
567  if (canBeShared) {
568  ParameterSet const& pset = *esController.getESProducerPSet(psetID, subProcessIndex_);
569  logInfoWhenSharing(pset);
570  ParameterSetIDHolder psetIDHolder(psetID);
571  sharingCheckDone.insert(psetIDHolder);
572  if (esController.isFirstMatch(psetID,
573  subProcessIndex_,
574  precedingESProvider.subProcessIndex_)) {
575  continue; // Proper sharing was already done. Nothing more to do.
576  }
577 
578  // Need to reset the pointer from the EventSetupRecordProvider to the
579  // the DataProxyProvider so these two processes share an ESProducer.
580 
581  std::shared_ptr<DataProxyProvider> dataProxyProvider;
582  std::set<EventSetupRecordKey> const& keysForPSetID1 = (*precedingESProvider.psetIDToRecordKey_)[psetIDHolder];
583  for (auto const& key : keysForPSetID1) {
584  std::shared_ptr<EventSetupRecordProvider> const& recordProvider = precedingESProvider.providers_[key];
585  dataProxyProvider = recordProvider->proxyProvider(psetIDHolder);
586  assert(dataProxyProvider);
587  break;
588  }
589 
590  std::set<EventSetupRecordKey> const& keysForPSetID2 = (*psetIDToRecordKey_)[psetIDHolder];
591  for (auto const& key : keysForPSetID2) {
592  std::shared_ptr<EventSetupRecordProvider> const& recordProvider = providers_[key];
593  recordProvider->resetProxyProvider(psetIDHolder, dataProxyProvider);
594  }
595  } else {
596  if (esController.isLastMatch(psetID,
597  subProcessIndex_,
598  precedingESProvider.subProcessIndex_)) {
599 
600 
601  ParameterSet const& pset = *esController.getESProducerPSet(psetID, subProcessIndex_);
602  ModuleFactory::get()->addTo(esController,
603  *this,
604  pset,
605  true);
606 
607  }
608  }
609  }
610 }
611 
612 bool
613 EventSetupProvider::doRecordsMatch(EventSetupProvider & precedingESProvider,
614  EventSetupRecordKey const& eventSetupRecordKey,
615  std::map<EventSetupRecordKey, bool> & allComponentsMatch,
616  EventSetupsController const& esController) {
617  // first check if this record matches. If not just return false
618 
619  // then find the directly dependent records and iterate over them
620  // recursively call this function on them. If they return false
621  // set allComponentsMatch to false for them and return false.
622  // if they all return true then set allComponents to true
623  // and return true.
624 
625  if (precedingESProvider.recordsWithALooperProxy_->find(eventSetupRecordKey) != precedingESProvider.recordsWithALooperProxy_->end()) {
626  return false;
627  }
628 
629  if ((*recordToFinders_)[eventSetupRecordKey].size() != (*precedingESProvider.recordToFinders_)[eventSetupRecordKey].size()) {
630  return false;
631  }
632 
633  for (auto const& finder : (*recordToFinders_)[eventSetupRecordKey]) {
634  ParameterSetID const& psetID = finder->descriptionForFinder().pid_;
635  bool itMatches = esController.isMatchingESSource(psetID,
636  subProcessIndex_,
637  precedingESProvider.subProcessIndex_);
638  if (!itMatches) {
639  return false;
640  }
641  }
642 
643  fillReferencedDataKeys(eventSetupRecordKey);
644  precedingESProvider.fillReferencedDataKeys(eventSetupRecordKey);
645 
646  std::map<DataKey, ComponentDescription const*> const& dataItems = (*referencedDataKeys_)[eventSetupRecordKey];
647 
648  std::map<DataKey, ComponentDescription const*> const& precedingDataItems = (*precedingESProvider.referencedDataKeys_)[eventSetupRecordKey];
649 
650  if (dataItems.size() != precedingDataItems.size()) {
651  return false;
652  }
653 
654  for (auto const& dataItem : dataItems) {
655  auto precedingDataItem = precedingDataItems.find(dataItem.first);
656  if (precedingDataItem == precedingDataItems.end()) {
657  return false;
658  }
659  if (dataItem.second->pid_ != precedingDataItem->second->pid_) {
660  return false;
661  }
662  // Check that the configurations match exactly for the ESProducers
663  // (We already checked the ESSources above and there should not be
664  // any loopers)
665  if (!dataItem.second->isSource_ && !dataItem.second->isLooper_) {
666  bool itMatches = esController.isMatchingESProducer(dataItem.second->pid_,
667  subProcessIndex_,
668  precedingESProvider.subProcessIndex_);
669  if (!itMatches) {
670  return false;
671  }
672  }
673  }
674  Providers::iterator itFound = providers_.find(eventSetupRecordKey);
675  if (itFound != providers_.end()) {
676  std::set<EventSetupRecordKey> dependentRecords = itFound->second->dependentRecords();
677  for (auto const& dependentRecord : dependentRecords) {
678  auto iter = allComponentsMatch.find(dependentRecord);
679  if (iter != allComponentsMatch.end()) {
680  if (iter->second) {
681  continue;
682  } else {
683  return false;
684  }
685  }
686  bool match = doRecordsMatch(precedingESProvider,
687  dependentRecord,
688  allComponentsMatch,
689  esController);
690  allComponentsMatch[dependentRecord] = match;
691  if (!match) return false;
692  }
693  }
694  return true;
695 }
696 
697 void
698 EventSetupProvider::fillReferencedDataKeys(EventSetupRecordKey const& eventSetupRecordKey) {
699 
700  if (referencedDataKeys_->find(eventSetupRecordKey) != referencedDataKeys_->end()) return;
701 
702  auto recordProvider = providers_.find(eventSetupRecordKey);
703  if (recordProvider == providers_.end()) {
704  (*referencedDataKeys_)[eventSetupRecordKey];
705  return;
706  }
707  if (recordProvider->second) {
708  recordProvider->second->fillReferencedDataKeys((*referencedDataKeys_)[eventSetupRecordKey]);
709  }
710 }
711 
712 void
713 EventSetupProvider::resetRecordToProxyPointers() {
714  for (auto const& recordProvider : providers_) {
716  const EventSetupRecordProvider::DataToPreferredProviderMap* preferredInfo = &kEmptyMap;
717  RecordToPreferred::const_iterator itRecordFound = recordToPreferred_->find(recordProvider.first);
718  if(itRecordFound != recordToPreferred_->end()) {
719  preferredInfo = &(itRecordFound->second);
720  }
721  recordProvider.second->resetRecordToProxyPointers(*preferredInfo);
722  }
723 }
724 
725 void
726 EventSetupProvider::clearInitializationData() {
727  preferredProviderInfo_.reset();
728  referencedDataKeys_.reset();
729  recordToFinders_.reset();
730  psetIDToRecordKey_.reset();
731  recordToPreferred_.reset();
732  recordsWithALooperProxy_.reset();
733 }
734 
735 void
736 EventSetupProvider::addRecordToEventSetup(EventSetupRecord& iRecord) {
737  iRecord.setEventSetup(&eventSetup_);
738  eventSetup_.add(iRecord);
739 }
740 
741 //
742 // const member functions
743 //
744 EventSetup const&
745 EventSetupProvider::eventSetupForInstance(const IOVSyncValue& iValue)
746 {
747  eventSetup_.setIOVSyncValue(iValue);
748 
749  eventSetup_.clear();
750 
751  // In a cmsRun job this does nothing because the EventSetupsController
752  // will have already called finishConfiguration, but some tests will
753  // call finishConfiguration here.
754  if(mustFinishConfiguration_) {
755  finishConfiguration();
756  }
757 
758  for(Providers::iterator itProvider = providers_.begin(), itProviderEnd = providers_.end();
759  itProvider != itProviderEnd;
760  ++itProvider) {
761  itProvider->second->addRecordToIfValid(*this, iValue);
762  }
763  return eventSetup_;
764 }
765 
766 namespace {
767  struct InsertAll : public std::unary_function< const std::set<ComponentDescription>&, void>{
768 
769  typedef std::set<ComponentDescription> Set;
771  InsertAll(Set& iSet) : container_(&iSet) {}
772  void operator()(const Set& iSet) {
773  container_->insert(iSet.begin(), iSet.end());
774  }
775  };
776 }
777 std::set<ComponentDescription>
778 EventSetupProvider::proxyProviderDescriptions() const
779 {
780  using boost::bind;
781  typedef std::set<ComponentDescription> Set;
782  Set descriptions;
783 
784  for_all(providers_,
785  bind(InsertAll(descriptions),
786  bind(&EventSetupRecordProvider::proxyProviderDescriptions,
787  bind(&Providers::value_type::second,_1))));
788  if(dataProviders_.get()) {
789  for(std::vector<std::shared_ptr<DataProxyProvider> >::const_iterator it = dataProviders_->begin(),
790  itEnd = dataProviders_->end();
791  it != itEnd;
792  ++it) {
793  descriptions.insert((*it)->description());
794  }
795 
796  }
797 
798  return descriptions;
799 }
800 
801 //
802 // static member functions
803 //
804 void EventSetupProvider::logInfoWhenSharing(ParameterSet const& iConfiguration) {
805 
806  std::string edmtype = iConfiguration.getParameter<std::string>("@module_edm_type");
807  std::string modtype = iConfiguration.getParameter<std::string>("@module_type");
808  std::string label = iConfiguration.getParameter<std::string>("@module_label");
809  edm::LogVerbatim("EventSetupSharing") << "Sharing " << edmtype << ": class=" << modtype << " label='" << label << "'";
810 }
811  }
812 }
size
Write out results.
std::map< DataKey, ComponentDescription > DataToPreferredProviderMap
void lookForMatches(ParameterSetID const &psetID, unsigned subProcessIndex, unsigned precedingProcessIndex, bool &firstProcessWithThisPSet, bool &precedingHasMatchingPSet) const
T getParameter(std::string const &) const
Map map_
std::pair< const char *, const std::type_info * > findType(const char *iClassName)
Definition: typelookup.cc:76
bool isFirstMatch(ParameterSetID const &psetID, unsigned subProcessIndex, unsigned precedingProcessIndex) const
bool isMatchingESProducer(ParameterSetID const &psetID, unsigned subProcessIndex, unsigned precedingProcessIndex) const
static PFTauRenderPlugin instance
std::unique_ptr< std::map< ParameterSetIDHolder, std::set< EventSetupRecordKey > > > psetIDToRecordKey_
void add(const std::vector< const T * > &source, std::vector< const T * > &dest)
bool isLastMatch(ParameterSetID const &psetID, unsigned subProcessIndex, unsigned precedingProcessIndex) const
std::unique_ptr< std::map< EventSetupRecordKey, std::map< DataKey, ComponentDescription const * > > > referencedDataKeys_
void fillReferencedDataKeys(EventSetupRecordKey const &eventSetupRecordKey)
std::map< EventSetupRecordKey, EventSetupRecordProvider::DataToPreferredProviderMap > RecordToPreferred
std::vector< std::pair< DataKey, edm::propagate_const< std::shared_ptr< DataProxy > > > > KeyedProxies
ParameterSet const * getESProducerPSet(ParameterSetID const &psetID, unsigned subProcessIndex) const
std::map< ComponentDescription, RecordToDataMap > PreferredProviderInfo
Func for_all(ForwardSequence &s, Func f)
wrapper for std::for_each
Definition: Algorithms.h:16
U second(std::pair< T, U > const &p)
static void findDependents(const EventSetupRecordKey &iKey, Itr itBegin, Itr itEnd, std::vector< std::shared_ptr< EventSetupRecordProvider > > &oDependents)
heterocontainer::HCTypeTag TypeTag
Definition: DataKeyTags.h:30
std::unique_ptr< std::set< EventSetupRecordKey > > recordsWithALooperProxy_
def unique(seq, keepstr=True)
Definition: tier0.py:24
std::map< EventSetupRecordKey, std::shared_ptr< EventSetupRecordProvider > > Providers
bool insert(Storage &iStorage, ItemType *iItem, const IdTag &iIdTag)
Definition: HCMethods.h:49
static RecordToPreferred determinePreferred(const EventSetupProvider::PreferredProviderInfo *iInfo, const Providers &iProviders)
std::unique_ptr< std::map< EventSetupRecordKey, std::vector< std::shared_ptr< EventSetupRecordIntervalFinder > > > > recordToFinders_
static void preferEverything(const ComponentDescription &iComponent, const Providers &iProviders, RecordToPreferred &iReturnValue)
find everything made by a DataProxyProvider and add it to the &#39;preferred&#39; list
std::vector< size_type > Keys
HLT enums.
bool isMatchingESSource(ParameterSetID const &psetID, unsigned subProcessIndex, unsigned precedingProcessIndex) const
void setIOVSyncValue(const IOVSyncValue &)
Definition: EventSetup.cc:63
void setEventSetup(EventSetup const *iEventSetup)
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
Definition: Utils.h:10
EventSetupProvider(unsigned subProcessIndex=0U, PreferredProviderInfo const *iInfo=0)
Set * container_
T get(const Candidate &c)
Definition: component.h:55
Providers::iterator Itr