File indexing completed on 2025-05-19 07:19:54
0001 #ifndef DataFormats_Provenance_ProductProvenanceLookup_h
0002 #define DataFormats_Provenance_ProductProvenanceLookup_h
0003
0004
0005
0006
0007
0008
0009 #include "DataFormats/Provenance/interface/BranchID.h"
0010 #include "DataFormats/Provenance/interface/ProductProvenance.h"
0011 #include "FWCore/Utilities/interface/propagate_const.h"
0012 #include "FWCore/Utilities/interface/Likely.h"
0013 #include "FWCore/Utilities/interface/thread_safety_macros.h"
0014
0015 #include <vector>
0016 #include <memory>
0017 #include <set>
0018 #include <atomic>
0019
0020
0021
0022
0023
0024 namespace edm {
0025 class ProductRegistry;
0026
0027 class ProductProvenanceLookup {
0028 public:
0029 ProductProvenanceLookup();
0030 explicit ProductProvenanceLookup(edm::ProductRegistry const&);
0031 virtual ~ProductProvenanceLookup();
0032
0033 ProductProvenanceLookup& operator=(ProductProvenanceLookup const&) = delete;
0034
0035 ProductProvenance const* branchIDToProvenance(BranchID const& bid) const;
0036 void insertIntoSet(ProductProvenance const& provenanceProduct) const;
0037 ProductProvenance const* branchIDToProvenanceForProducedOnly(BranchID const& bid) const;
0038
0039 void update(edm::ProductRegistry const&);
0040
0041 class ProducedProvenanceInfo {
0042 public:
0043 ProducedProvenanceInfo(BranchID iBid) : provenance_{iBid}, isParentageSet_{false} {}
0044 ProducedProvenanceInfo(ProducedProvenanceInfo&& iOther)
0045 : provenance_{iOther.provenance_}, isParentageSet_{iOther.isParentageSet_.load(std::memory_order_acquire)} {}
0046 ProducedProvenanceInfo(ProducedProvenanceInfo const& iOther) : provenance_{iOther.provenance_.branchID()} {
0047 bool isSet = iOther.isParentageSet_.load(std::memory_order_acquire);
0048 if (isSet) {
0049 provenance_.set(iOther.provenance_.parentageID());
0050 }
0051 isParentageSet_.store(isSet, std::memory_order_release);
0052 }
0053
0054 ProducedProvenanceInfo& operator=(ProducedProvenanceInfo&& iOther) {
0055 provenance_ = iOther.provenance_;
0056 isParentageSet_.store(iOther.isParentageSet_.load(std::memory_order_acquire), std::memory_order_release);
0057 return *this;
0058 }
0059 ProducedProvenanceInfo& operator=(ProducedProvenanceInfo const& iOther) {
0060 bool isSet = iOther.isParentageSet_.load(std::memory_order_acquire);
0061 if (isSet) {
0062 provenance_ = iOther.provenance_;
0063 } else {
0064 provenance_ = ProductProvenance(iOther.provenance_.branchID());
0065 }
0066 isParentageSet_.store(isSet, std::memory_order_release);
0067 return *this;
0068 }
0069
0070 ProductProvenance const* productProvenance() const noexcept {
0071 if (LIKELY(isParentageSet())) {
0072 return &provenance_;
0073 }
0074 return nullptr;
0075 }
0076 BranchID branchID() const noexcept { return provenance_.branchID(); }
0077
0078 bool isParentageSet() const noexcept { return isParentageSet_.load(std::memory_order_acquire); }
0079
0080 void threadsafe_set(ParentageID const& id) const {
0081 provenance_.set(id);
0082 isParentageSet_.store(true, std::memory_order_release);
0083 }
0084
0085 void resetParentage() { isParentageSet_.store(false, std::memory_order_release); }
0086
0087 private:
0088 CMS_THREAD_GUARD(isParentageSet_) mutable ProductProvenance provenance_;
0089 mutable std::atomic<bool> isParentageSet_;
0090 };
0091
0092 protected:
0093 virtual std::unique_ptr<const std::set<ProductProvenance>> readProvenance() const = 0;
0094 virtual const ProductProvenanceLookup* nextRetriever() const = 0;
0095
0096 std::vector<ProducedProvenanceInfo> entryInfoSet_;
0097 mutable std::atomic<const std::set<ProductProvenance>*> readEntryInfoSet_;
0098 edm::propagate_const<ProductProvenanceLookup const*> parentProcessRetriever_;
0099
0100 private:
0101 void setupEntryInfoSet(edm::ProductRegistry const&);
0102 };
0103 }
0104 #endif