Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-09-12 09:52:30

0001 #include "DataFormats/Provenance/interface/processingOrderMerge.h"
0002 #include "DataFormats/Provenance/interface/ProcessHistory.h"
0003 #include "FWCore/Utilities/interface/Exception.h"
0004 #include <algorithm>
0005 
0006 namespace edm {
0007   namespace {
0008     [[noreturn]] void throwIncompatibleOrdering(std::string const& msg) {
0009       throw cms::Exception("IncompatibleProcessHistoryOrdering")
0010           << "Incompatible process history ordering during merge: " << msg << "\n";
0011     }
0012 
0013     template <typename Iter>
0014     Iter foundLaterIn(Iter itBegin, Iter it, Iter itEnd, std::string const& name) {
0015       auto itFind = std::find(itBegin, itEnd, name);
0016       // Sanity check, it should be impossible for this to happen
0017       if (itFind < it) {
0018         throwIncompatibleOrdering("process " + name + " found earlier in other list");
0019       }
0020       return itFind;
0021     }
0022   }  // namespace
0023 
0024   void processingOrderMerge(ProcessHistory const& iHistory, std::vector<std::string>& processNames) {
0025     if (processNames.empty()) {
0026       for (auto it = iHistory.rbegin(); it != iHistory.rend(); ++it) {
0027         processNames.push_back(it->processName());
0028       }
0029     } else {
0030       std::vector<std::string> fromHistory;
0031       fromHistory.reserve(iHistory.size());
0032       for (auto it = iHistory.rbegin(); it != iHistory.rend(); ++it) {
0033         fromHistory.push_back(it->processName());
0034       }
0035       processingOrderMerge(fromHistory, processNames);
0036     }
0037   }
0038 
0039   void processingOrderMerge(std::vector<std::string> const& iHistory, std::vector<std::string>& processNames) {
0040     if (processNames.empty()) {
0041       processNames = iHistory;
0042     } else {
0043       std::vector<std::string> tempNames;
0044       tempNames.reserve(processNames.size() > iHistory.size() ? processNames.size() : iHistory.size());
0045       auto itNew = iHistory.begin();
0046       auto itNewEnd = iHistory.end();
0047       auto itOld = processNames.begin();
0048       auto itOldEnd = processNames.end();
0049       while (itNew != itNewEnd && itOld != itOldEnd) {
0050         if (*itNew == *itOld) {
0051           tempNames.push_back(*itOld);
0052           ++itNew;
0053           ++itOld;
0054         } else {
0055           //see if we can find it in the old list
0056           auto itFindOld = foundLaterIn(processNames.begin(), itOld, itOldEnd, *itNew);
0057           auto itFindNew = foundLaterIn(iHistory.begin(), itNew, itNewEnd, *itOld);
0058           if (itFindOld != itOldEnd) {
0059             if (itFindNew != itNewEnd) {
0060               throwIncompatibleOrdering("order of processes " + *itNew + " and " + *itOld +
0061                                         " is not the same in all ProcessHistories");
0062             }
0063             tempNames.push_back(*itOld);
0064             ++itOld;
0065           } else {
0066             if (itFindNew == itNewEnd) {
0067               throwIncompatibleOrdering("order of processes " + *itOld + " and " + *itNew + " is ambiguous");
0068             }
0069             tempNames.push_back(*itNew);
0070             ++itNew;
0071           }
0072         }
0073       }
0074       //copy over any remaining old names
0075       while (itOld != itOldEnd) {
0076         tempNames.push_back(*itOld);
0077         ++itOld;
0078       }
0079       while (itNew != itNewEnd) {
0080         tempNames.push_back(*itNew);
0081         ++itNew;
0082       }
0083       processNames.swap(tempNames);
0084     }
0085   }
0086 }  // namespace edm