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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
#include "DataFormats/Provenance/interface/ProductProvenanceLookup.h"
#include "DataFormats/Provenance/interface/ProductRegistry.h"
#include "FWCore/Utilities/interface/EDMException.h"
#include <algorithm>
/*
ProductProvenanceLookup
*/
namespace edm {
ProductProvenanceLookup::ProductProvenanceLookup()
: entryInfoSet_(), readEntryInfoSet_(), parentProcessRetriever_(nullptr) {}
ProductProvenanceLookup::ProductProvenanceLookup(edm::ProductRegistry const& iReg)
: entryInfoSet_(), readEntryInfoSet_(), parentProcessRetriever_(nullptr) {
setupEntryInfoSet(iReg);
}
ProductProvenanceLookup::~ProductProvenanceLookup() { delete readEntryInfoSet_.load(); }
void ProductProvenanceLookup::setupEntryInfoSet(edm::ProductRegistry const& iReg) {
std::set<BranchID> ids;
for (auto const& p : iReg.productList()) {
if (p.second.branchType() == edm::InEvent) {
if (p.second.produced() or p.second.isProvenanceSetOnRead()) {
ids.insert(p.second.branchID());
}
}
}
entryInfoSet_.reserve(ids.size());
for (auto const& b : ids) {
entryInfoSet_.emplace_back(b);
}
}
void ProductProvenanceLookup::update(edm::ProductRegistry const& iReg) {
entryInfoSet_.clear();
setupEntryInfoSet(iReg);
}
void ProductProvenanceLookup::insertIntoSet(ProductProvenance const& entryInfo) const {
//NOTE:do not read provenance here because we only need the full
// provenance when someone tries to access it not when doing the insert
// doing the delay saves 20% of time when doing an analysis job
//readProvenance();
auto itFound =
std::lower_bound(entryInfoSet_.begin(),
entryInfoSet_.end(),
entryInfo.branchID(),
[](auto const& iEntry, edm::BranchID const& iValue) { return iEntry.branchID() < iValue; });
if UNLIKELY (itFound == entryInfoSet_.end() or itFound->branchID() != entryInfo.branchID()) {
throw edm::Exception(edm::errors::LogicError) << "ProductProvenanceLookup::insertIntoSet passed a BranchID "
<< entryInfo.branchID().id() << " that has not been pre-registered";
}
itFound->threadsafe_set(entryInfo.parentageID());
}
ProductProvenance const* ProductProvenanceLookup::branchIDToProvenance(BranchID const& bid) const {
auto itFound = std::lower_bound(
entryInfoSet_.begin(), entryInfoSet_.end(), bid, [](auto const& iEntry, edm::BranchID const& iValue) {
return iEntry.branchID() < iValue;
});
if (itFound != entryInfoSet_.end() and itFound->branchID() == bid) {
if (auto p = itFound->productProvenance()) {
return p;
}
}
if (parentProcessRetriever_) {
return parentProcessRetriever_->branchIDToProvenance(bid);
}
//check in source
if (nullptr == readEntryInfoSet_.load()) {
auto readProv = readProvenance();
std::set<ProductProvenance> const* expected = nullptr;
if (readEntryInfoSet_.compare_exchange_strong(expected, readProv.get())) {
readProv.release();
}
}
auto ptr = readEntryInfoSet_.load();
if (ptr) {
ProductProvenance ei(bid);
auto itRead = ptr->find(ei);
if (itRead != ptr->end()) {
return &*itRead;
}
}
auto nr = nextRetriever();
if (nr) {
return nr->branchIDToProvenance(bid);
}
return nullptr;
}
ProductProvenance const* ProductProvenanceLookup::branchIDToProvenanceForProducedOnly(BranchID const& bid) const {
auto itFound = std::lower_bound(
entryInfoSet_.begin(), entryInfoSet_.end(), bid, [](auto const& iEntry, edm::BranchID const& iValue) {
return iEntry.branchID() < iValue;
});
if (itFound != entryInfoSet_.end() and itFound->branchID() == bid) {
if (auto p = itFound->productProvenance()) {
return p;
}
}
if (parentProcessRetriever_) {
return parentProcessRetriever_->branchIDToProvenanceForProducedOnly(bid);
}
auto nr = nextRetriever();
if (nr) {
return nr->branchIDToProvenanceForProducedOnly(bid);
}
return nullptr;
}
} // namespace edm
|