CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/FWCore/Framework/src/DependentRecordIntervalFinder.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:     Framework
00004 // Class  :     DependentRecordIntervalFinder
00005 // 
00006 // Implementation:
00007 //     <Notes on implementation>
00008 //
00009 // Author:      Chris Jones
00010 // Created:     Sat Apr 30 19:37:22 EDT 2005
00011 // $Id: DependentRecordIntervalFinder.cc,v 1.13 2010/12/17 19:33:53 chrjones Exp $
00012 //
00013 
00014 // system include files
00015 
00016 // user include files
00017 #include "FWCore/Framework/interface/DependentRecordIntervalFinder.h"
00018 #include "FWCore/Framework/interface/EventSetupRecordProvider.h"
00019 
00020 //
00021 // constants, enums and typedefs
00022 //
00023 namespace edm {
00024    namespace eventsetup {
00025 //
00026 // static data member definitions
00027 //
00028 
00029 //
00030 // constructors and destructor
00031 //
00032 DependentRecordIntervalFinder::DependentRecordIntervalFinder(const EventSetupRecordKey& iKey) :
00033   providers_()
00034 {
00035    findingRecordWithKey(iKey);
00036 }
00037 
00038 // DependentRecordIntervalFinder::DependentRecordIntervalFinder(const DependentRecordIntervalFinder& rhs)
00039 // {
00040 //    // do actual copying here;
00041 // }
00042 
00043 DependentRecordIntervalFinder::~DependentRecordIntervalFinder()
00044 {
00045 }
00046 
00047 //
00048 // assignment operators
00049 //
00050 // const DependentRecordIntervalFinder& DependentRecordIntervalFinder::operator=(const DependentRecordIntervalFinder& rhs)
00051 // {
00052 //   //An exception safe implementation is
00053 //   DependentRecordIntervalFinder temp(rhs);
00054 //   swap(rhs);
00055 //
00056 //   return *this;
00057 // }
00058 
00059 //
00060 // member functions
00061 //
00062 void 
00063 DependentRecordIntervalFinder::addProviderWeAreDependentOn(boost::shared_ptr<EventSetupRecordProvider> iProvider)
00064 {
00065    providers_.push_back(iProvider);
00066 }
00067 
00068 void 
00069 DependentRecordIntervalFinder::setAlternateFinder(boost::shared_ptr<EventSetupRecordIntervalFinder> iOther)
00070 {
00071   alternate_ = iOther;
00072 }
00073 
00074 void 
00075 DependentRecordIntervalFinder::setIntervalFor(const EventSetupRecordKey& iKey,
00076                                                const IOVSyncValue& iTime, 
00077                                                ValidityInterval& oInterval)
00078 {
00079    //NOTE: oInterval is the last value that was used so if nothing changed do not modify oInterval
00080    
00081    //I am assuming that an invalidTime is always less then the first valid time
00082    assert(IOVSyncValue::invalidIOVSyncValue() < IOVSyncValue::beginOfTime());
00083    if(providers_.size() == 0 && alternate_.get() == 0 ) {
00084       oInterval = ValidityInterval::invalidInterval();
00085       return;
00086    }
00087    bool haveAValidDependentRecord = false;
00088    bool allRecordsValid = true;
00089    ValidityInterval newInterval(IOVSyncValue::beginOfTime(), IOVSyncValue::endOfTime());
00090    
00091    if (alternate_.get() != 0) {
00092      ValidityInterval test = alternate_->findIntervalFor(iKey, iTime);
00093      if ( test != ValidityInterval::invalidInterval() ) {
00094        haveAValidDependentRecord =true;
00095        newInterval = test;
00096      }
00097    }
00098    bool intervalsWereComparible = true;
00099    for(Providers::iterator itProvider = providers_.begin(), itProviderEnd = providers_.end();
00100        itProvider != itProviderEnd;
00101        ++itProvider) {
00102       if((*itProvider)->setValidityIntervalFor(iTime)) {
00103          haveAValidDependentRecord=true;
00104          ValidityInterval providerInterval = (*itProvider)->validityInterval();
00105          if( (!newInterval.first().comparable(providerInterval.first())) ||
00106              (!newInterval.last().comparable(providerInterval.last()))) {
00107            intervalsWereComparible=false;
00108            break;
00109          }
00110          if(newInterval.first() < providerInterval.first()) {
00111             newInterval.setFirst(providerInterval.first());
00112          }
00113          if(newInterval.last() > providerInterval.last()) {
00114             newInterval.setLast(providerInterval.last());
00115          }
00116       } else {
00117         allRecordsValid = false;
00118       }
00119    }
00120    if(intervalsWereComparible) {
00121      if(!haveAValidDependentRecord) {
00122        //If no Finder has no valid time, then this record is also invalid for this time
00123        newInterval = ValidityInterval::invalidInterval();
00124      }
00125      if(!allRecordsValid) {
00126        //since some of the dependent providers do not have a valid IOV for this syncvalue
00127        // we do not know what the true end IOV is.  Therefore we must make it open ended
00128        // so that we can check each time to see if those providers become valid.
00129        newInterval.setLast(IOVSyncValue::invalidIOVSyncValue());
00130      }
00131      oInterval = newInterval;
00132      return;
00133    }
00134    //handle the case where some providers use time and others use run/lumi/event
00135    // in this case all we can do is find an IOV which changed since last time
00136    // and use its start time to do the synching and use an 'invalid' end time
00137    // so the system always checks back to see if something has changed
00138    if (previousIOVs_.empty()) {
00139       std::vector<ValidityInterval> tmp(providers_.size(),ValidityInterval());
00140       previousIOVs_.swap(tmp);
00141    }
00142 
00143    //I'm using an heuristic to pick a reasonable starting point for the IOV. The idea is to
00144    // assume that lumi sections are 23 seconds long and therefore if we take a difference between
00145    // iTime and the beginning of a changed IOV we can pick the changed IOV with the start time 
00146    // closest to iTime. This doesn't have to be perfect, we just want to reduce the dependency
00147    // on provider order to make the jobs more deterministic
00148    
00149    bool hadChangedIOV = false;
00150    //both start at the smallest value
00151    EventID closestID;
00152    Timestamp closestTimeStamp(0);
00153    std::vector<ValidityInterval>::iterator itIOVs = previousIOVs_.begin();
00154    for(Providers::iterator itProvider = providers_.begin(), itProviderEnd = providers_.end();
00155        itProvider != itProviderEnd;
00156        ++itProvider, ++itIOVs) {
00157       if((*itProvider)->setValidityIntervalFor(iTime)) {
00158          ValidityInterval providerInterval = (*itProvider)->validityInterval();
00159          if(*itIOVs != providerInterval) {
00160             hadChangedIOV = true;
00161             if(providerInterval.first().time().value() == 0) {
00162                //this is a run/lumi based one
00163                if( closestID < providerInterval.first().eventID()) {
00164                   closestID = providerInterval.first().eventID();
00165                }
00166             } else {
00167                if(closestTimeStamp < providerInterval.first().time()) {
00168                   closestTimeStamp = providerInterval.first().time();
00169                }
00170             }
00171             *itIOVs = providerInterval;
00172          }
00173       }
00174    }
00175    if(hadChangedIOV) {
00176       if(closestID.run() !=0) {
00177          if(closestTimeStamp.value() == 0) {
00178             //no time
00179             oInterval = ValidityInterval(IOVSyncValue(closestID), IOVSyncValue::invalidIOVSyncValue());
00180          } else {
00181             if(closestID.run() == iTime.eventID().run()) {
00182                //can compare time to lumi
00183                const unsigned long long kLumiTimeLength = 23;
00184                
00185                if( (iTime.eventID().luminosityBlock() - closestID.luminosityBlock())*kLumiTimeLength < 
00186                   iTime.time().unixTime() - closestTimeStamp.unixTime() ) {
00187                   //closestID was closer
00188                   oInterval = ValidityInterval(IOVSyncValue(closestID), IOVSyncValue::invalidIOVSyncValue());
00189                } else {
00190                   oInterval = ValidityInterval(IOVSyncValue(closestTimeStamp), IOVSyncValue::invalidIOVSyncValue());
00191                }
00192             } else {
00193                //since we don't know how to change run # into time we can't compare
00194                // so if we have a time just use it
00195                oInterval = ValidityInterval(IOVSyncValue(closestTimeStamp), IOVSyncValue::invalidIOVSyncValue());
00196             }
00197          }
00198       } else {
00199          oInterval = ValidityInterval( IOVSyncValue(closestTimeStamp), IOVSyncValue::invalidIOVSyncValue());
00200       }
00201    }
00202 }
00203 
00204 //
00205 // const member functions
00206 //
00207 
00208 //
00209 // static member functions
00210 //
00211    }
00212 }