1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
#include "DataFormats/Provenance/interface/processingOrderMerge.h"
#include "DataFormats/Provenance/interface/ProcessHistory.h"
#include "FWCore/Utilities/interface/Exception.h"
#include <algorithm>
namespace edm {
namespace {
[[noreturn]] void throwIncompatibleOrdering(std::string const& msg) {
throw cms::Exception("IncompatibleProcessHistoryOrdering")
<< "Incompatible process history ordering during merge: " << msg << "\n";
}
template <typename Iter>
Iter foundLaterIn(Iter itBegin, Iter it, Iter itEnd, std::string const& name) {
auto itFind = std::find(itBegin, itEnd, name);
if (itFind < it) {
throwIncompatibleOrdering("process " + name + " found earlier in other list");
}
return itFind;
}
} // namespace
void processingOrderMerge(ProcessHistory const& iHistory, std::vector<std::string>& processNames) {
if (processNames.empty()) {
for (auto it = iHistory.rbegin(); it != iHistory.rend(); ++it) {
processNames.push_back(it->processName());
}
} else {
std::vector<std::string> fromHistory;
fromHistory.reserve(iHistory.size());
for (auto it = iHistory.rbegin(); it != iHistory.rend(); ++it) {
fromHistory.push_back(it->processName());
}
processingOrderMerge(fromHistory, processNames);
}
}
void processingOrderMerge(std::vector<std::string> const& iHistory, std::vector<std::string>& processNames) {
if (processNames.empty()) {
processNames = iHistory;
} else {
std::vector<std::string> tempNames;
tempNames.reserve(processNames.size() > iHistory.size() ? processNames.size() : iHistory.size());
auto itNew = iHistory.begin();
auto itNewEnd = iHistory.end();
auto itOld = processNames.begin();
auto itOldEnd = processNames.end();
while (itNew != itNewEnd && itOld != itOldEnd) {
if (*itNew == *itOld) {
tempNames.push_back(*itOld);
++itNew;
++itOld;
} else {
//see if we can find it in the old list
auto itFindOld = foundLaterIn(processNames.begin(), itOld, itOldEnd, *itNew);
auto itFindNew = foundLaterIn(iHistory.begin(), itNew, itNewEnd, *itOld);
if (itFindOld != itOldEnd) {
if (itFindNew != itNewEnd) {
throwIncompatibleOrdering("process " + *itNew + " and " + *itOld + " are out of order");
}
//found it, copy over everything up to and including it
while (itOld != itFindOld) {
tempNames.push_back(*itOld);
++itOld;
}
tempNames.push_back(*itOld);
++itOld;
++itNew;
} else {
if (itFindNew == itNewEnd) {
throwIncompatibleOrdering("process " + *itOld + " and " + *itNew + " are independent");
}
while (itNew != itFindNew) {
tempNames.push_back(*itNew);
++itNew;
}
//not found, add the new one
tempNames.push_back(*itNew);
++itNew;
++itOld;
}
}
}
//copy over any remaining old names
while (itOld != itOldEnd) {
tempNames.push_back(*itOld);
++itOld;
}
while (itNew != itNewEnd) {
tempNames.push_back(*itNew);
++itNew;
}
processNames.swap(tempNames);
}
}
} // namespace edm
|