CMS 3D CMS Logo

Classes | Public Member Functions | Private Attributes

edm::ProductHolderIndexHelper Class Reference

#include <ProductHolderIndexHelper.h>

List of all members.

Classes

class  IndexAndNames
class  Item
class  Matches
class  Range

Public Member Functions

unsigned int beginElements () const
ProductHolderIndex index (KindOfType kindOfType, TypeID const &typeID, char const *moduleLabel, char const *instance, char const *process=0) const
std::vector< IndexAndNames >
const & 
indexAndNames () const
unsigned int indexToIndexAndNames (KindOfType kindOfType, TypeID const &typeID, char const *moduleLabel, char const *instance, char const *process) const
unsigned int indexToType (KindOfType kindOfType, TypeID const &typeID) const
ProductHolderIndex insert (TypeWithDict const &typeWithDict, char const *moduleLabel, char const *instance, char const *process)
std::vector< std::string > const & lookupProcessNames () const
ProductHolderIndex nextIndexValue () const
void print (std::ostream &os) const
unsigned int processIndex (char const *process) const
std::vector< char > const & processNames () const
 ProductHolderIndexHelper ()
std::vector< Range > const & ranges () const
Matches relatedIndexes (KindOfType kindOfType, TypeID const &typeID) const
Matches relatedIndexes (KindOfType kindOfType, TypeID const &typeID, char const *moduleLabel, char const *instance) const
void sanityCheck () const
void setFrozen ()
std::vector< TypeID > const & sortedTypeIDs () const

Private Attributes

unsigned int beginElements_
std::vector< char > bigNamesContainer_
std::vector< IndexAndNamesindexAndNames_
std::unique_ptr< std::set< Item > > items_
std::vector< std::string > lookupProcessNames_
ProductHolderIndex nextIndexValue_
std::unique_ptr< std::set
< std::string > > 
processItems_
std::vector< char > processNames_
std::vector< Rangeranges_
std::vector< TypeIDsortedTypeIDs_

Detailed Description

This class assigns and gets the ProductHolderIndex associated with a type, module label, instance, and process. The ProductHolderIndex is used to tell the Principal where to store a ProductHolder and how to find it quickly.

One can also look up the same ProductHolderIndex's using the type or base type of an element in a container in the product (if the product is a container). In this case the KindOfType argument to the Principal::getByLabel function is ELEMENT_TYPE, whereas normally it is PRODUCT_TYPE.

There are also special ProductHolderIndex's generated where the process name is empty. These indexes refer to a special ProductHolders that search for a matching product from the most recent process that has a matching type, label and instance. There is ProductHolderIndex generated for each type/label/instance combination which has at least one entry in the tables in this class. Both PRODUCT_TYPEs and ELEMENT_TYPEs get these special ProductHolders.

The ProductHolderIndex for a particular product will not change during a process after the ProductRegistry has been frozen. Nor will any of the other member data of this class. Multiple threads can access it concurrently without problems. The ProductHolderIndexes can be safely cached in InputTags and possibly other places, because they never change within a process. The ProductHolderIndex for a particular product is not intended to be persistent and will be different in different processes.

The ProductHolderIndex is used to order the placement of the ProductHolders in the Principal that are either present in the input or produced in the current process. Be aware that there are other ProductHolders for products that come after ProductHolders placed by this class. For example, the placement of dropped products is not handled by this class, instead by the ProductRegistry. The reason for this distinction is that those other ProductHolders can change and be added as a process runs. The content of this class never changes after the ProductRegistry is frozen.

Author:
W. David Dagenhart, created 10 December, 2012

Definition at line 67 of file ProductHolderIndexHelper.h.


Constructor & Destructor Documentation

edm::ProductHolderIndexHelper::ProductHolderIndexHelper ( )

Definition at line 12 of file ProductHolderIndexHelper.cc.

                                                     :
    nextIndexValue_(0),
    beginElements_(0),
    items_(new std::set<ProductHolderIndexHelper::Item>),
    processItems_(new std::set<std::string>) {
  }

Member Function Documentation

unsigned int edm::ProductHolderIndexHelper::beginElements ( ) const [inline]

Definition at line 190 of file ProductHolderIndexHelper.h.

References beginElements_.

{ return beginElements_; }
ProductHolderIndex edm::ProductHolderIndexHelper::index ( KindOfType  kindOfType,
TypeID const &  typeID,
char const *  moduleLabel,
char const *  instance,
char const *  process = 0 
) const

Definition at line 20 of file ProductHolderIndexHelper.cc.

References indexAndNames_, indexToIndexAndNames(), max(), and edm::ProductHolderIndexInvalid.

Referenced by edm::Principal::findProductByLabel(), edm::PrincipalGetAdapter::getBranchDescription(), and edm::EDConsumerBase::updateLookup().

                                                             {

    unsigned int iToIndexAndNames = indexToIndexAndNames(kindOfType,
                                                         typeID,
                                                         moduleLabel,
                                                         instance,
                                                         process);

    if (iToIndexAndNames == std::numeric_limits<unsigned int>::max()) {
      return ProductHolderIndexInvalid;
    }
    return indexAndNames_[iToIndexAndNames].index();
  }
std::vector<IndexAndNames> const& edm::ProductHolderIndexHelper::indexAndNames ( ) const [inline]

Definition at line 193 of file ProductHolderIndexHelper.h.

References indexAndNames_.

{ return indexAndNames_; }
unsigned int edm::ProductHolderIndexHelper::indexToIndexAndNames ( KindOfType  kindOfType,
TypeID const &  typeID,
char const *  moduleLabel,
char const *  instance,
char const *  process 
) const

Definition at line 357 of file ProductHolderIndexHelper.cc.

References edm::ProductHolderIndexHelper::Range::begin(), begin, bigNamesContainer_, end, edm::ProductHolderIndexHelper::Range::end(), indexAndNames_, indexToType(), instance, diffTwoXMLs::label, max(), edm::max(), processIndex(), and ranges_.

Referenced by index(), and relatedIndexes().

                                                                            {

    // Look for the type and check to see if it found it
    unsigned iType = indexToType(kindOfType, typeID);
    if (iType != std::numeric_limits<unsigned int>::max()) {

      unsigned startProcess = 0;
      if (process) {
        startProcess = processIndex(process);
        if (startProcess == std::numeric_limits<unsigned int>::max()) {
          return std::numeric_limits<unsigned int>::max();
        }
      }

      ProductHolderIndexHelper::Range const& range = ranges_[iType];
      unsigned int begin = range.begin();
      unsigned int end = range.end();

      while (begin < end) {

        unsigned int midpoint = begin + ((end - begin) / 2);
        char const* namePtr = &bigNamesContainer_[indexAndNames_[midpoint].startInBigNamesContainer()];

        // Compare the module label
        char const* label = moduleLabel;
        while (*namePtr && (*namePtr == *label)) {
          ++namePtr; ++label;
        }
        if (*namePtr == *label) { // true only if both are at the '\0' at the end of the C string
          ++namePtr;              // move to the next C string

          // Compare the instance name
          char const* instanceName = instance;
          while (*namePtr && (*namePtr == *instanceName)) {
            ++namePtr; ++instanceName;
          }
          if (*namePtr == *instanceName) {

            // Compare the process name
            if (startProcess == indexAndNames_[midpoint].startInProcessNames()) {
              return midpoint;
            } else {
              if (indexAndNames_[midpoint].startInProcessNames() > startProcess) {
                while (true) {
                  --midpoint;
                  if (indexAndNames_[midpoint].startInProcessNames() == startProcess) {
                    return midpoint;
                  }
                  if (indexAndNames_[midpoint].startInProcessNames() == 0) break;
                }
              } else {
                while (true) {
                  ++midpoint;
                  if (midpoint == indexAndNames_.size()) break;
                  if (indexAndNames_[midpoint].startInProcessNames() == 0) break;
                  if (indexAndNames_[midpoint].startInProcessNames() == startProcess) {
                    return midpoint;
                  }
                }                
              }
              break;
            }
          } else if (*namePtr < *instanceName) {
            if (begin == midpoint) break;
            begin = midpoint;
          } else {
            end = midpoint;
          }
        } else if (*namePtr < *label) {
          if (begin == midpoint) break;
          begin = midpoint;
        } else {
          end = midpoint;
        }
      } // end while (begin < end)
    }
    return std::numeric_limits<unsigned int>::max();
  }
unsigned int edm::ProductHolderIndexHelper::indexToType ( KindOfType  kindOfType,
TypeID const &  typeID 
) const

Definition at line 441 of file ProductHolderIndexHelper.cc.

References beginElements_, edm::ELEMENT_TYPE, edm::max(), and sortedTypeIDs_.

Referenced by indexToIndexAndNames(), and relatedIndexes().

                                                                    {

    unsigned int beginType = 0;
    unsigned int endType = beginElements_;
    if (kindOfType == ELEMENT_TYPE) {
      beginType = beginElements_;
      endType = sortedTypeIDs_.size();
    }

    while (beginType < endType) {
      unsigned int midpointType = beginType + ((endType - beginType) / 2);
      if (sortedTypeIDs_[midpointType] == typeID) {
        return midpointType;  // Found it
      } else if (sortedTypeIDs_[midpointType] < typeID) {
        if (beginType == midpointType) break;
        beginType = midpointType;
      } else {
        endType = midpointType;
      }
    }
    return std::numeric_limits<unsigned int>::max(); // Failed to find it
  }
ProductHolderIndex edm::ProductHolderIndexHelper::insert ( TypeWithDict const &  typeWithDict,
char const *  moduleLabel,
char const *  instance,
char const *  process 
)

Definition at line 115 of file ProductHolderIndexHelper.cc.

References edm::ELEMENT_TYPE, Exception, edm::is_PtrVector(), edm::is_RefToBaseVector(), edm::is_RefVector(), items_, edm::errors::LogicError, nextIndexValue_, edm::PRODUCT_TYPE, edm::ProductHolderIndexAmbiguous, edm::public_base_classes(), edm::TypeWithDict::typeInfo(), and edm::value_type_of().

                                                        {
    if (!items_) {
      throw Exception(errors::LogicError)
        << "ProductHolderIndexHelper::insert - Attempt to insert more elements after frozen.\n";
    }

    if (process == 0 || *process == '\0') {
      throw Exception(errors::LogicError)
        << "ProductHolderIndexHelper::insert - Empty process.\n";
    }

    TypeID typeID(typeWithDict.typeInfo());

    // Throw if this has already been inserted
    Item item(PRODUCT_TYPE, typeID, moduleLabel, instance, process, 0);
    std::set<Item>::iterator iter = items_->find(item);
    if (iter != items_->end()) {
      throw Exception(errors::LogicError)
        << "ProductHolderIndexHelper::insert - Attempt to insert duplicate entry.\n";
    }

    // Put in an entry for the product
    item.setIndex(nextIndexValue_);
    unsigned int savedProductIndex = nextIndexValue_;
    ++nextIndexValue_;
    items_->insert(item);

    // Put in an entry for the product with an empty process name
    // if it is not already there
    item.clearProcess();
    iter = items_->find(item);
    if (iter == items_->end()) {
      item.setIndex(nextIndexValue_);
      ++nextIndexValue_;
      items_->insert(item);
    }

    // Now put in entries for a contained class if this is a
    // recognized container.
    TypeWithDict containedType;
    if((is_RefVector(typeWithDict, containedType) ||
        is_PtrVector(typeWithDict, containedType) ||
        is_RefToBaseVector(typeWithDict, containedType) ||
        value_type_of(typeWithDict, containedType))
        && bool(containedType)) {

      TypeID containedTypeID(containedType.typeInfo());
      Item containedItem(ELEMENT_TYPE, containedTypeID, moduleLabel, instance, process, savedProductIndex);
      iter = items_->find(containedItem);
      if (iter != items_->end()) {
        containedItem.setIndex(ProductHolderIndexAmbiguous);
        items_->erase(iter);
      }
      items_->insert(containedItem);

      containedItem.clearProcess();
      iter = items_->find(containedItem);
      if (iter == items_->end()) {
        containedItem.setIndex(nextIndexValue_);
        ++nextIndexValue_;
        items_->insert(containedItem);
      }

      // Repeat this for all public base classes of the contained type
      std::vector<TypeWithDict> baseTypes;
      public_base_classes(containedType, baseTypes);

      for(TypeWithDict const& baseType : baseTypes) {

        TypeID baseTypeID(baseType.typeInfo());
        Item baseItem(ELEMENT_TYPE, baseTypeID, moduleLabel, instance, process, savedProductIndex);
        iter = items_->find(baseItem);
        if (iter != items_->end()) {
          baseItem.setIndex(ProductHolderIndexAmbiguous);
          items_->erase(iter);
        }
        items_->insert(baseItem);

        baseItem.clearProcess();
        iter = items_->find(baseItem);
        if (iter == items_->end()) {
          baseItem.setIndex(nextIndexValue_);
          ++nextIndexValue_;
          items_->insert(baseItem);
        }
      }
    }
    return savedProductIndex;
  }
std::vector< std::string > const & edm::ProductHolderIndexHelper::lookupProcessNames ( ) const

Definition at line 348 of file ProductHolderIndexHelper.cc.

References Exception, items_, edm::errors::LogicError, and lookupProcessNames_.

                                                                                 {
    if (items_) {
      throw Exception(errors::LogicError)
        << "ProductHolderIndexHelper::lookupProcessNames - Attempt to access names before frozen.\n";
    }
    return lookupProcessNames_;
  }
ProductHolderIndex edm::ProductHolderIndexHelper::nextIndexValue ( ) const [inline]

Definition at line 218 of file ProductHolderIndexHelper.h.

References nextIndexValue_.

{ return nextIndexValue_; }
void edm::ProductHolderIndexHelper::print ( std::ostream &  os) const

Definition at line 568 of file ProductHolderIndexHelper.cc.

References beginElements_, bigNamesContainer_, gather_cfg::cout, i, indexAndNames_, items_, nextIndexValue_, processItems_, processNames_, ranges_, and sortedTypeIDs_.

                                                           {

    os << "\n******* Dump ProductHolderIndexHelper *************************\n";

    os << "\nnextIndexValue_ = " <<  nextIndexValue_ << "\n";
    os << "beginElements_ = " << beginElements_ << "\n";

    os << "\n******* sortedTypeIDs_ \n";
    for (auto const& i : sortedTypeIDs_) {
      os << i << "\n";
    }
    os << "******* ranges_ \n";
    for (auto const& i : ranges_) {
      os << i.begin() << " " << i.end() << "\n";
    }
    os << "******* indexAndNames_ \n";
    for (auto const& i : indexAndNames_) {
      os << i.index() << " " << i.startInBigNamesContainer() << " ";
      char const* ptr = &bigNamesContainer_[i.startInBigNamesContainer()];
      while (*ptr) {
        os << *ptr;
        ++ptr;
      }
      ++ptr;
      os << " ";
      while (*ptr) {
        os << *ptr;
        ++ptr;
      }
      os << " " << i.startInProcessNames() << " ";
      ptr = &processNames_[i.startInProcessNames()];
      while (*ptr) {
        os << *ptr;
        ++ptr;
      }
      os << "\n";
    }
    os << "******* bigNamesContainer_ \n";
    for (auto i : bigNamesContainer_) {
      if (i == '\0') os << '\\' << '0';
      else os << i;
    }
    if (!bigNamesContainer_.empty()) os << "\n";
    os << "******* processNames_ \n";
    for (auto i : processNames_) {
      if (i == '\0') os << '\\' << '0';
      else os << i;
    }
    if (!processNames_.empty()) os << "\n";
    if (items_) {
      os << "******* items_ \n";
      for (auto const& item : *items_) {
        std:: cout << item.kindOfType() << " " << item.moduleLabel() << " " << item.instance() << " " << item.process() << " " << item.index() << " " << item.typeID() << "\n";
      }
    }
    if (processItems_) {
      os << "******* processItems_ \n";
      for (auto const& item : *processItems_) {
        os << item << "\n";
      }
    }
    os << "sortedTypeIDs_.size() = " << sortedTypeIDs_.size() << "\n";
    os << "indexAndNames_.size() = " << indexAndNames_.size() << "\n";
    os << "bigNamesContainer_.size() = " << bigNamesContainer_.size() << "\n"; 
    os << "processNames_.size() = " << processNames_.size() << "\n"; 
    os << "\n";
  }
unsigned int edm::ProductHolderIndexHelper::processIndex ( char const *  process) const

Definition at line 465 of file ProductHolderIndexHelper.cc.

References begin, edm::max(), AlCaHLTBitMon_ParallelJobs::p, LaserDQM_cfg::process, and processNames_.

Referenced by indexToIndexAndNames(), and setFrozen().

                                                                                {

    char const* ptr = &processNames_[0];
    char const* begin = ptr;
    while (true) {
      char const* p = process;
      char const* beginName = ptr;
      while (*ptr && (*ptr == *p)) {
        ++ptr; ++p;
      }
      if (*ptr == *p) {
        return beginName - begin;
      }
      while (*ptr) {
        ++ptr;
      }
      ++ptr;
      if (static_cast<unsigned>(ptr - begin) >=  processNames_.size()) {
        return std::numeric_limits<unsigned int>::max();
      }
    }
    return 0;
  }
std::vector<char> const& edm::ProductHolderIndexHelper::processNames ( ) const [inline]

Definition at line 194 of file ProductHolderIndexHelper.h.

References processNames_.

{ return processNames_; }
std::vector<Range> const& edm::ProductHolderIndexHelper::ranges ( ) const [inline]

Definition at line 192 of file ProductHolderIndexHelper.h.

References ranges_.

{ return ranges_; }
ProductHolderIndexHelper::Matches edm::ProductHolderIndexHelper::relatedIndexes ( KindOfType  kindOfType,
TypeID const &  typeID,
char const *  moduleLabel,
char const *  instance 
) const

Definition at line 69 of file ProductHolderIndexHelper.cc.

References indexAndNames_, indexToIndexAndNames(), j, and max().

Referenced by edm::Principal::findProductByLabel(), edm::Principal::getManyByType(), and edm::EDConsumerBase::updateLookup().

                                                                       {

    unsigned int startInIndexAndNames = indexToIndexAndNames(kindOfType,
                                                             typeID,
                                                             moduleLabel,
                                                             instance,
                                                             0);
    unsigned int numberOfMatches = 1;

    if (startInIndexAndNames == std::numeric_limits<unsigned int>::max()) {
      numberOfMatches = 0;
    } else {
      auto vSize = indexAndNames_.size();
      for (unsigned int j = startInIndexAndNames + 1U;
           j < vSize && (indexAndNames_[j].startInProcessNames() != 0U);
           ++j) {
        ++numberOfMatches;
      }
    }
    return Matches(this, startInIndexAndNames, numberOfMatches);
  }
ProductHolderIndexHelper::Matches edm::ProductHolderIndexHelper::relatedIndexes ( KindOfType  kindOfType,
TypeID const &  typeID 
) const

Definition at line 95 of file ProductHolderIndexHelper.cc.

References edm::ProductHolderIndexHelper::Range::begin(), edm::ProductHolderIndexHelper::Range::end(), indexToType(), max(), edm::max(), and ranges_.

                                                                       {

    unsigned int startInIndexAndNames = std::numeric_limits<unsigned int>::max();
    unsigned int numberOfMatches = 0;

    // Look for the type and check to see if it found it
    unsigned iType = indexToType(kindOfType, typeID);
    if (iType != std::numeric_limits<unsigned int>::max()) {

      // Get the range of entries with a matching TypeID
      Range const& range = ranges_[iType];

      startInIndexAndNames = range.begin();
      numberOfMatches = range.end() - range.begin();
    }
    return Matches(this, startInIndexAndNames, numberOfMatches);
  }
void edm::ProductHolderIndexHelper::sanityCheck ( ) const

Definition at line 489 of file ProductHolderIndexHelper.cc.

References bigNamesContainer_, Exception, indexAndNames_, j, edm::errors::LogicError, nextIndexValue_, processNames_, edm::ProductHolderIndexAmbiguous, ranges_, and sortedTypeIDs_.

Referenced by setFrozen().

                                                   {
    bool sanityChecksPass = true;
    if (sortedTypeIDs_.size() != ranges_.size()) sanityChecksPass = false;

    unsigned int previousEnd = 0;
    for ( auto const& range : ranges_) {
      if (range.begin() != previousEnd) sanityChecksPass = false;
      if (range.begin() >= range.end()) sanityChecksPass = false;
      previousEnd = range.end();
    }
    if (previousEnd != indexAndNames_.size()) sanityChecksPass = false;


    unsigned maxStart = 0;
    unsigned maxStartProcess = 0;
    for (auto const& indexAndName : indexAndNames_) {
      if (indexAndName.index() >= nextIndexValue_ && indexAndName.index() != ProductHolderIndexAmbiguous) sanityChecksPass = false;

      if (indexAndName.startInBigNamesContainer() >= bigNamesContainer_.size()) sanityChecksPass = false;
      if (indexAndName.startInProcessNames() >= processNames_.size()) sanityChecksPass = false;

      if (indexAndName.startInBigNamesContainer() > maxStart) maxStart = indexAndName.startInBigNamesContainer();
      if (indexAndName.startInProcessNames() > maxStartProcess) maxStartProcess = indexAndName.startInProcessNames();
    }

    if (!indexAndNames_.empty()) {
      if (bigNamesContainer_.back() != '\0')  sanityChecksPass = false;
      if (processNames_.back() != '\0')  sanityChecksPass = false;
      if (maxStart >= bigNamesContainer_.size()) sanityChecksPass = false;
      unsigned int countZeroes = 0;
      for (unsigned j = maxStart; j < bigNamesContainer_.size(); ++j) {
        if (bigNamesContainer_[j] == '\0') {
          ++countZeroes;
        }
      }
      if (countZeroes != 2) sanityChecksPass = false;
      if (maxStartProcess >= processNames_.size()) sanityChecksPass = false;
      countZeroes = 0;
      for (unsigned j = maxStartProcess; j < processNames_.size(); ++j) {
        if (processNames_[j] == '\0') {
          ++countZeroes;
        }        
      }
      if (countZeroes != 1) sanityChecksPass = false;
    }

    if (!sanityChecksPass) {
      throw Exception(errors::LogicError)
        << "ProductHolderIndexHelper::setFrozen - Detected illegal state.\n";
    }
  }
void edm::ProductHolderIndexHelper::setFrozen ( )

Definition at line 208 of file ProductHolderIndexHelper.cc.

References beginElements_, bigNamesContainer_, trackerHits::c, edm::ELEMENT_TYPE, Exception, indexAndNames_, items_, j, edm::errors::LogicError, lookupProcessNames_, max(), processIndex(), processItems_, processNames_, edm::PRODUCT_TYPE, ranges_, sanityCheck(), sortedTypeIDs_, and AlCaHLTBitMon_QueryRunRegistry::string.

                                           {

    if (!items_) return;

    // Make a first pass and count things so we
    // can reserve memory in the vectors. Also
    // fill processItems_ on the first pass.
    bool iFirstThisType = true;
    bool beginElementsWasSet = false;
    TypeID previousTypeID;
    KindOfType previousKindOfType = PRODUCT_TYPE;
    std::string previousModuleLabel;
    std::string previousInstance;
    unsigned int iCountTypes = 0;
    unsigned int iCountCharacters = 0;
    for (auto const& item : *items_) {

      if (iFirstThisType || item.typeID() != previousTypeID || item.kindOfType() != previousKindOfType) {
        ++iCountTypes;
        iFirstThisType = true;

        if (!beginElementsWasSet) {
          if (item.kindOfType() == ELEMENT_TYPE) {
            beginElementsWasSet = true;
          } else {
            beginElements_ = iCountTypes;
          }
        }
      }

      processItems_->insert(item.process());

      if (iFirstThisType ||
          item.moduleLabel() != previousModuleLabel ||
          item.instance() != previousInstance) {
        iCountCharacters += item.moduleLabel().size();
        iCountCharacters += item.instance().size();
        iCountCharacters += 2;
      }

      iFirstThisType = false;
      previousTypeID = item.typeID();
      previousKindOfType = item.kindOfType();
      previousModuleLabel = item.moduleLabel();
      previousInstance = item.instance();
    }

    // Size and fill the process name vector
    unsigned int processNamesSize = 0;
    for (auto const& processItem : *processItems_) {
      processNamesSize += processItem.size();
      ++processNamesSize;
    }
    processNames_.reserve(processNamesSize);
    for (auto const& processItem : *processItems_) {
      for (auto const& c : processItem) {
        processNames_.push_back(c);
      }
      processNames_.push_back('\0');
      lookupProcessNames_.push_back(processItem);
    }

    // Reserve memory in the vectors
    sortedTypeIDs_.reserve(iCountTypes);
    ranges_.reserve(iCountTypes);
    indexAndNames_.reserve(items_->size());
    bigNamesContainer_.reserve(iCountCharacters);

    // Second pass. Really fill the vectors this time.
    bool iFirstType = true;
    iFirstThisType = true;
    previousTypeID = TypeID();
    unsigned int iCount = 0;
    unsigned int iBeginning = 0;
    iCountCharacters = 0;
    unsigned int previousCharacterCount = 0;
    if (!items_->empty()) {
      for (auto const& item : *items_) {

        if (iFirstThisType || item.typeID() != previousTypeID || item.kindOfType() != previousKindOfType) {
          iFirstThisType = true;
          sortedTypeIDs_.push_back(item.typeID());
          if (iFirstType) {
            iFirstType = false;
          } else {
            ranges_.push_back(Range(iBeginning, iCount));
          }
          iBeginning = iCount;
        }
        ++iCount;

        if (iFirstThisType ||
            item.moduleLabel() != previousModuleLabel ||
            item.instance() != previousInstance) {

          unsigned int labelSize = item.moduleLabel().size();
          for (unsigned int j = 0; j < labelSize; ++j) {
            bigNamesContainer_.push_back(item.moduleLabel()[j]);
          }
          bigNamesContainer_.push_back('\0');

          unsigned int instanceSize = item.instance().size();
          for (unsigned int j = 0; j < instanceSize; ++j) {
            bigNamesContainer_.push_back(item.instance()[j]);
          }
          bigNamesContainer_.push_back('\0');

          previousCharacterCount = iCountCharacters;

          iCountCharacters += labelSize;
          iCountCharacters += instanceSize;
          iCountCharacters += 2;
        }

        unsigned int processStart = processIndex(item.process().c_str());
        if (processStart == std::numeric_limits<unsigned int>::max()) {
          throw Exception(errors::LogicError)
            << "ProductHolderIndexHelper::setFrozen - Process not found in processNames_.\n";
        }
        indexAndNames_.emplace_back(item.index(), previousCharacterCount, processStart);

        iFirstThisType = false;
        previousTypeID = item.typeID();
        previousKindOfType = item.kindOfType();
        previousModuleLabel = item.moduleLabel();
        previousInstance = item.instance();
      }
      ranges_.push_back(Range(iBeginning, iCount));
    }

    // Some sanity checks to protect against out of bounds vector accesses
    // These should only fail if there is a bug. If profiling ever shows
    // them to be expensive one might delete them.
    sanityCheck();

    // Cleanup, do not need the temporary containers anymore
    items_.reset();
    processItems_.reset();
  }
std::vector<TypeID> const& edm::ProductHolderIndexHelper::sortedTypeIDs ( ) const [inline]

Definition at line 191 of file ProductHolderIndexHelper.h.

References sortedTypeIDs_.

{ return sortedTypeIDs_; }

Member Data Documentation

Definition at line 232 of file ProductHolderIndexHelper.h.

Referenced by beginElements(), indexToType(), print(), and setFrozen().

Definition at line 270 of file ProductHolderIndexHelper.h.

Referenced by indexToIndexAndNames(), print(), sanityCheck(), and setFrozen().

std::unique_ptr<std::set<Item> > edm::ProductHolderIndexHelper::items_ [private]

Definition at line 309 of file ProductHolderIndexHelper.h.

Referenced by insert(), lookupProcessNames(), print(), and setFrozen().

std::vector<std::string> edm::ProductHolderIndexHelper::lookupProcessNames_ [private]

Definition at line 275 of file ProductHolderIndexHelper.h.

Referenced by lookupProcessNames(), and setFrozen().

Definition at line 227 of file ProductHolderIndexHelper.h.

Referenced by insert(), nextIndexValue(), print(), and sanityCheck().

std::unique_ptr<std::set<std::string> > edm::ProductHolderIndexHelper::processItems_ [private]

Definition at line 311 of file ProductHolderIndexHelper.h.

Referenced by print(), and setFrozen().

std::vector<char> edm::ProductHolderIndexHelper::processNames_ [private]

Definition at line 271 of file ProductHolderIndexHelper.h.

Referenced by print(), processIndex(), processNames(), sanityCheck(), and setFrozen().

Definition at line 239 of file ProductHolderIndexHelper.h.

Referenced by indexToType(), print(), sanityCheck(), setFrozen(), and sortedTypeIDs().