File indexing completed on 2024-11-25 02:29:29
0001 #include "DataFormats/Provenance/interface/ProductProvenanceLookup.h"
0002 #include "DataFormats/Provenance/interface/ProductRegistry.h"
0003 #include "FWCore/Utilities/interface/EDMException.h"
0004
0005 #include <algorithm>
0006
0007
0008
0009
0010
0011 namespace edm {
0012 ProductProvenanceLookup::ProductProvenanceLookup()
0013 : entryInfoSet_(), readEntryInfoSet_(), parentProcessRetriever_(nullptr) {}
0014
0015 ProductProvenanceLookup::ProductProvenanceLookup(edm::ProductRegistry const& iReg)
0016 : entryInfoSet_(), readEntryInfoSet_(), parentProcessRetriever_(nullptr) {
0017 setupEntryInfoSet(iReg);
0018 }
0019
0020 ProductProvenanceLookup::~ProductProvenanceLookup() { delete readEntryInfoSet_.load(); }
0021
0022 void ProductProvenanceLookup::setupEntryInfoSet(edm::ProductRegistry const& iReg) {
0023 std::set<BranchID> ids;
0024 for (auto const& p : iReg.productList()) {
0025 if (p.second.branchType() == edm::InEvent) {
0026 if (p.second.produced() or p.second.isProvenanceSetOnRead()) {
0027 ids.insert(p.second.branchID());
0028 }
0029 }
0030 }
0031 entryInfoSet_.reserve(ids.size());
0032 for (auto const& b : ids) {
0033 entryInfoSet_.emplace_back(b);
0034 }
0035 }
0036
0037 void ProductProvenanceLookup::update(edm::ProductRegistry const& iReg) {
0038 entryInfoSet_.clear();
0039 setupEntryInfoSet(iReg);
0040 }
0041
0042 void ProductProvenanceLookup::insertIntoSet(ProductProvenance const& entryInfo) const {
0043
0044
0045
0046
0047 auto itFound =
0048 std::lower_bound(entryInfoSet_.begin(),
0049 entryInfoSet_.end(),
0050 entryInfo.branchID(),
0051 [](auto const& iEntry, edm::BranchID const& iValue) { return iEntry.branchID() < iValue; });
0052 if UNLIKELY (itFound == entryInfoSet_.end() or itFound->branchID() != entryInfo.branchID()) {
0053 throw edm::Exception(edm::errors::LogicError) << "ProductProvenanceLookup::insertIntoSet passed a BranchID "
0054 << entryInfo.branchID().id() << " that has not been pre-registered";
0055 }
0056 itFound->threadsafe_set(entryInfo.parentageID());
0057 }
0058
0059 ProductProvenance const* ProductProvenanceLookup::branchIDToProvenance(BranchID const& bid) const {
0060 auto itFound = std::lower_bound(
0061 entryInfoSet_.begin(), entryInfoSet_.end(), bid, [](auto const& iEntry, edm::BranchID const& iValue) {
0062 return iEntry.branchID() < iValue;
0063 });
0064 if (itFound != entryInfoSet_.end() and itFound->branchID() == bid) {
0065 if (auto p = itFound->productProvenance()) {
0066 return p;
0067 }
0068 }
0069 if (parentProcessRetriever_) {
0070 return parentProcessRetriever_->branchIDToProvenance(bid);
0071 }
0072
0073 if (nullptr == readEntryInfoSet_.load()) {
0074 auto readProv = readProvenance();
0075 std::set<ProductProvenance> const* expected = nullptr;
0076 if (readEntryInfoSet_.compare_exchange_strong(expected, readProv.get())) {
0077 readProv.release();
0078 }
0079 }
0080 auto ptr = readEntryInfoSet_.load();
0081 if (ptr) {
0082 ProductProvenance ei(bid);
0083 auto itRead = ptr->find(ei);
0084 if (itRead != ptr->end()) {
0085 return &*itRead;
0086 }
0087 }
0088 auto nr = nextRetriever();
0089 if (nr) {
0090 return nr->branchIDToProvenance(bid);
0091 }
0092 return nullptr;
0093 }
0094
0095 ProductProvenance const* ProductProvenanceLookup::branchIDToProvenanceForProducedOnly(BranchID const& bid) const {
0096 auto itFound = std::lower_bound(
0097 entryInfoSet_.begin(), entryInfoSet_.end(), bid, [](auto const& iEntry, edm::BranchID const& iValue) {
0098 return iEntry.branchID() < iValue;
0099 });
0100 if (itFound != entryInfoSet_.end() and itFound->branchID() == bid) {
0101 if (auto p = itFound->productProvenance()) {
0102 return p;
0103 }
0104 }
0105 if (parentProcessRetriever_) {
0106 return parentProcessRetriever_->branchIDToProvenanceForProducedOnly(bid);
0107 }
0108 auto nr = nextRetriever();
0109 if (nr) {
0110 return nr->branchIDToProvenanceForProducedOnly(bid);
0111 }
0112 return nullptr;
0113 }
0114
0115 }