CMS 3D CMS Logo

Public Types | Public Member Functions | Private Attributes

edm::TransientProductLookupMap Class Reference

#include <TransientProductLookupMap.h>

List of all members.

Public Types

typedef
ProductLookupIndexList::const_iterator 
const_iterator
typedef std::map< std::pair
< TypeInBranchType,
ConstBranchDescription const * >
, ProductTransientIndex,
CompareTypeInBranchTypeConstBranchDescription
FillFromMap
typedef std::vector
< ProductLookupIndex
ProductLookupIndexList
typedef std::vector< std::pair
< TypeInBranchType,
BranchDescriptionIndex > > 
TypeInBranchTypeLookup

Public Member Functions

const_iterator begin () const
const_iterator end () const
std::pair< const_iterator,
const_iterator
equal_range (TypeInBranchType const &, std::string const &, std::string const &) const
std::pair< const_iterator,
const_iterator
equal_range (TypeInBranchType const &) const
 returns a pair of iterators that define the range for items matching the TypeInBranchType
int fillCount () const
void fillFrom (FillFromMap const &)
void reorderIfNecessary (BranchType, ProcessHistory const &, std::string const &iNewProcessName)
 reorders the ProductLookupIndexes for the BranchType based on the processing ordering
void reset ()
 TransientProductLookupMap ()

Private Attributes

TypeInBranchTypeLookup branchLookup_
int fillCount_
std::vector< ProcessHistoryIDhistoryIDsForBranchType_
std::vector< std::vector
< std::string > > 
processNameOrderingForBranchType_
ProductLookupIndexList productLookupIndexList_

Detailed Description

Definition at line 49 of file TransientProductLookupMap.h.


Member Typedef Documentation

typedef ProductLookupIndexList::const_iterator edm::TransientProductLookupMap::const_iterator

Definition at line 55 of file TransientProductLookupMap.h.

Definition at line 59 of file TransientProductLookupMap.h.

Definition at line 53 of file TransientProductLookupMap.h.

Definition at line 52 of file TransientProductLookupMap.h.


Constructor & Destructor Documentation

TransientProductLookupMap::TransientProductLookupMap ( )

Definition at line 60 of file TransientProductLookupMap.cc.

                                                       :
      branchLookup_(),
      productLookupIndexList_(),
      historyIDsForBranchType_(static_cast<unsigned int>(NumBranchTypes), ProcessHistoryID()),
      processNameOrderingForBranchType_(static_cast<unsigned int>(NumBranchTypes), std::vector<std::string>()),
      fillCount_(0) {
  }

Member Function Documentation

const_iterator edm::TransientProductLookupMap::begin ( void  ) const [inline]

Definition at line 85 of file TransientProductLookupMap.h.

References productLookupIndexList_.

Referenced by edm::Principal::findGroupByLabel().

{return productLookupIndexList_.begin();}
const_iterator edm::TransientProductLookupMap::end ( void  ) const [inline]

Definition at line 87 of file TransientProductLookupMap.h.

References productLookupIndexList_.

Referenced by edm::Principal::findGroupByLabel().

{return productLookupIndexList_.end();}
std::pair< TransientProductLookupMap::const_iterator, TransientProductLookupMap::const_iterator > TransientProductLookupMap::equal_range ( TypeInBranchType const &  iKey) const

returns a pair of iterators that define the range for items matching the TypeInBranchType

Definition at line 383 of file TransientProductLookupMap.cc.

References branchLookup_, and productLookupIndexList_.

Referenced by equal_range(), edm::Principal::findGroup(), edm::Principal::findGroupByLabel(), edm::Principal::findGroups(), edm::PrincipalGetAdapter::getBranchDescription(), and reorderIfNecessary().

                                                                           {
     TypeInBranchTypeLookup::const_iterator itFind = std::lower_bound(branchLookup_.begin(),
                                                                      branchLookup_.end(),
                                                                      std::make_pair(iKey, BranchDescriptionIndex(0)),
                                                                      CompareFirst());
     if(itFind == branchLookup_.end() || iKey < itFind->first) {
        return std::make_pair(productLookupIndexList_.end(), productLookupIndexList_.end());
     }
     const_iterator itStart = productLookupIndexList_.begin() + itFind->second;
     const_iterator itEnd = productLookupIndexList_.end();
     if(++itFind != branchLookup_.end()) {
        itEnd = productLookupIndexList_.begin() + itFind->second;
     }
     return std::make_pair(itStart, itEnd);
  }
std::pair< TransientProductLookupMap::const_iterator, TransientProductLookupMap::const_iterator > TransientProductLookupMap::equal_range ( TypeInBranchType const &  iKey,
std::string const &  moduleLabel,
std::string const &  productInstanceName 
) const

returns a pair of iterators that define the range for items matching the TypeInBranchType, the module label, and the product instance name

Definition at line 400 of file TransientProductLookupMap.cc.

References equal_range().

                                                     {
     std::pair<const_iterator, const_iterator> itPair = this->equal_range(iKey);

     if (itPair.first == itPair.second) {
        return itPair;
     }

     // Advance lower bound only
     itPair.first = std::lower_bound(itPair.first, itPair.second, std::make_pair(&moduleLabel, &productInstanceName), CompareModuleLabelAndProductInstanceName());
     // Protect against no match
     if (!(itPair.first < itPair.second) ||
         itPair.first->branchDescription()->moduleLabel() != moduleLabel ||
         itPair.first->branchDescription()->productInstanceName() != productInstanceName) {
       itPair.second = itPair.first;
     }
     return itPair;
  }
int edm::TransientProductLookupMap::fillCount ( ) const [inline]

Definition at line 89 of file TransientProductLookupMap.h.

References fillCount_.

Referenced by edm::Principal::findGroupByLabel().

{return fillCount_;}
void TransientProductLookupMap::fillFrom ( FillFromMap const &  iMap)

Definition at line 312 of file TransientProductLookupMap.cc.

References branchLookup_, fillCount_, edm::fillInProcessIndexes(), historyIDsForBranchType_, edm::NumBranchTypes, processNameOrderingForBranchType_, and productLookupIndexList_.

Referenced by edm::ProductRegistry::initializeLookupTables().

                                                             {

     assert(processNameOrderingForBranchType_.size() == historyIDsForBranchType_.size());

     //Increment the fill count so users can check if the map has been modified.
     ++fillCount_;

     productLookupIndexList_.clear();
     productLookupIndexList_.reserve(iMap.size());
     branchLookup_.clear();
     branchLookup_.reserve(iMap.size()); //this is an upperbound

     std::set<std::string, std::greater<std::string> > processNames;
     TypeInBranchType lastSeen(TypeID(), NumBranchTypes);

     //since the actual strings are stored elsewhere, there is no reason to make a copy
     static std::string const kEmpty;
     std::string const* lastSeenModule = &kEmpty;
     std::string const* lastSeenProductInstance = &kEmpty;
     for(FillFromMap::const_iterator it = iMap.begin(), itEnd = iMap.end();
         it != itEnd;
         ++it) {
        bool isFirst =  ((lastSeen < it->first.first) || (it->first.first < lastSeen));
        if(isFirst) {
           lastSeen = it->first.first;
           branchLookup_.push_back(std::make_pair(lastSeen, BranchDescriptionIndex(productLookupIndexList_.size())));
        } else {
           //see if this is the first of a group that only differ by ProcessName
           isFirst = (*lastSeenModule != it->first.second->moduleLabel() ||
                      *lastSeenProductInstance != it->first.second->productInstanceName());
        }
        productLookupIndexList_.push_back(ProductLookupIndex(it->first.second,
                                                it->second,
                                                0,
                                                isFirst)
                            );
        if(isFirst) {
           lastSeenModule = &(it->first.second->moduleLabel());
           lastSeenProductInstance = &(it->first.second->productInstanceName());
        }
        processNames.insert(it->first.second->processName());
     }

     std::vector<ProcessHistoryID>::iterator itPH = historyIDsForBranchType_.begin();
     std::vector<ProcessHistoryID>::iterator itPHEnd = historyIDsForBranchType_.end();

     std::vector<std::vector<std::string> >::iterator itPN = processNameOrderingForBranchType_.begin();
     //std::vector<std::vector<std::string> >::iterator itPNEnd = processNameOrderingForBranchType_.end();

     for(;itPH != itPHEnd; ++itPH, ++itPN) {
        *itPH = ProcessHistoryID();
        itPN->assign(processNames.begin(), processNames.end());
     }

     //Now that we know all the IDs time to set the values
     fillInProcessIndexes(productLookupIndexList_.begin(), productLookupIndexList_.end(), processNameOrderingForBranchType_.front());
  }
void TransientProductLookupMap::reorderIfNecessary ( BranchType  iBranch,
ProcessHistory const &  iHistory,
std::string const &  iNewProcessName 
)

reorders the ProductLookupIndexes for the BranchType based on the processing ordering

Definition at line 180 of file TransientProductLookupMap.cc.

References edm::ProcessHistory::begin(), branchLookup_, edm::ProcessHistory::empty(), edm::ProcessHistory::end(), equal_range(), fillCount_, edm::fillInProcessIndexes(), spr::find(), historyIDsForBranchType_, edm::ProcessHistory::id(), processNameOrderingForBranchType_, productLookupIndexList_, edm::ProcessHistory::rbegin(), edm::ProcessHistory::rend(), python::multivaluedict::sort(), and groupFilesInBlocks::temp.

                                                                                                                                    {

     ProcessHistoryID& historyID = historyIDsForBranchType_[iBranch];
     if(iHistory.id() == historyID) {
        //std::cout <<"no reordering since history unchanged"<<std::endl;
        return;
     }

     if(iHistory.empty()) {
        //std::cout <<"no reordering since history empty"<<std::endl;
        historyID = iHistory.id();
        return;
     }
     std::vector<std::string>& processNameOrdering = processNameOrderingForBranchType_[iBranch];

     //iHistory may be missing entries in processNameOrdering if two files were merged together and one file
     // had fewer processing steps than the other one.
     //iHistory may have more entries than processNameOrdering if all data products for those extra entries
     // were dropped

     //if iHistory already in same order as processNameOrdering than we don't have to do anything
     std::vector<std::string>::iterator it = processNameOrdering.begin();
     std::vector<std::string>::iterator itEnd = processNameOrdering.end();
     ProcessHistory::const_iterator itH = iHistory.begin();
     ProcessHistory::const_iterator itHEnd = iHistory.end();

     {
        std::vector<std::string>::iterator itStart = it;
        bool mustReorder = false;
        while(it != itEnd && itH != itHEnd) {
           if(*it == itH->processName()) {
              ++it;
           } else {
              //see if we already passed it
              for(std::vector<std::string>::iterator itOld = itStart; itOld != it; ++itOld) {
                 if(*itOld == itH->processName()) {
                    mustReorder = true;
                    break;
                 }
              }
              if(mustReorder) {
                 break;
              }
           }
           ++itH;
        }
        if(!mustReorder && it != itEnd && *it == iNewProcessName) {
           ++it;
        }
        //can only reach the end if we found all the items in the correct order
        if(it == itEnd) {
           return;
        }
     }

     //must re-sort
     //Increment the fill count so users can check if the map has been modified.
     ++fillCount_;
     historyID = iHistory.id();
     std::vector<std::string> temp(processNameOrdering.size(), std::string());

     //we want to add the items at the back
     std::vector<std::string>::reverse_iterator itR = temp.rbegin();
     std::vector<std::string>::reverse_iterator itREnd = temp.rend();
     ProcessHistory::const_reverse_iterator itRH = iHistory.rbegin();
     ProcessHistory::const_reverse_iterator itRHEnd = iHistory.rend();

     if(processNameOrdering.end() != std::find(processNameOrdering.begin(), processNameOrdering.end(), iNewProcessName)) {
        *itR = iNewProcessName;
        ++itR;
        if (iNewProcessName == itRH->processName()) {
          ++itRH;
        }
     }
     for(; itRH != itRHEnd; ++itRH) {
        if(processNameOrdering.end() != std::find(processNameOrdering.begin(), processNameOrdering.end(), itRH->processName())) {

           *itR = itRH->processName();
           ++itR;
        }
     }

     //have to fill in the missing processes from processNameOrdering_
     // we do this at the beginning because we lookup data in the reverse order
     // so we want the ones we know are there to be searched first
     std::vector<std::string>::iterator itOld = processNameOrdering.begin();
     it = temp.begin();
     std::vector<std::string>::iterator itStart = temp.begin()+(itREnd - itR);
     while(it != itStart) {
        assert(itOld != processNameOrdering.end());
        if(temp.end() == std::find(itStart, temp.end(), *itOld)) {
           //didn't find it so need to add this to our list
           *it = *itOld;
           ++it;
        }
        ++itOld;
     }

     processNameOrdering.swap(temp);

     //now we need to go through our data structure and change the processing orders
     //first find the range for this BranchType
     std::pair<TypeInBranchTypeLookup::iterator, TypeInBranchTypeLookup::iterator> branchRange =
     std::equal_range(branchLookup_.begin(), branchLookup_.end(), std::make_pair(TypeInBranchType(TypeID(), iBranch), BranchDescriptionIndex(0)), BranchTypeOnlyCompare());

     if(branchRange.first == branchRange.second) {
        return;
     }
     //convert this into Index iterators since that is the structure we must reorder
     ProductLookupIndexList::iterator itIndex = productLookupIndexList_.begin() + branchRange.first->second;
     ProductLookupIndexList::iterator itIndexEnd = productLookupIndexList_.end();
     if(branchRange.second != branchLookup_.end()) {
        itIndexEnd = productLookupIndexList_.begin() + branchRange.second->second;
     }

     while(itIndex != itIndexEnd) {
        itIndex->setIsFirst(false);
        ProductLookupIndexList::iterator itNext = itIndex;
        while(itNext != itIndexEnd && !itNext->isFirst()) {
           ++itNext;
        }
        std::sort(itIndex, itNext, CompareProcessList(&processNameOrdering));
        itIndex->setIsFirst(true);
        itIndex = itNext;
     }

     //Now that we know all the IDs time to set the values
     fillInProcessIndexes(productLookupIndexList_.begin() + branchRange.first->second, itIndexEnd, processNameOrdering);

  }
void TransientProductLookupMap::reset ( void  )

Member Data Documentation

Definition at line 93 of file TransientProductLookupMap.h.

Referenced by equal_range(), fillFrom(), reorderIfNecessary(), and reset().

Definition at line 97 of file TransientProductLookupMap.h.

Referenced by fillCount(), fillFrom(), reorderIfNecessary(), and reset().

Definition at line 95 of file TransientProductLookupMap.h.

Referenced by fillFrom(), reorderIfNecessary(), and reset().

std::vector<std::vector<std::string> > edm::TransientProductLookupMap::processNameOrderingForBranchType_ [private]

Definition at line 96 of file TransientProductLookupMap.h.

Referenced by fillFrom(), reorderIfNecessary(), and reset().

Definition at line 94 of file TransientProductLookupMap.h.

Referenced by begin(), end(), equal_range(), fillFrom(), reorderIfNecessary(), and reset().