File indexing completed on 2024-04-06 12:03:55
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include "DataFormats/Common/interface/WrapperBase.h"
0015 #include "DataFormats/Common/interface/PtrVectorBase.h"
0016 #include "DataFormats/Common/interface/traits.h"
0017 #include "DataFormats/Common/interface/EDProductGetter.h"
0018 #include "FWCore/Utilities/interface/EDMException.h"
0019 #include "FWCore/Utilities/interface/Exception.h"
0020
0021
0022 #include <ostream>
0023
0024
0025
0026
0027 namespace edm {
0028
0029
0030
0031
0032
0033
0034
0035 PtrVectorBase::PtrVectorBase() : cachedItems_(nullptr) {}
0036
0037 PtrVectorBase::~PtrVectorBase() { delete cachedItems_.load(); }
0038
0039 PtrVectorBase::PtrVectorBase(const PtrVectorBase& iOther)
0040 : core_(iOther.core_), indicies_(iOther.indicies_), cachedItems_(nullptr) {
0041 auto cache = iOther.cachedItems_.load();
0042 if (cache) {
0043 cachedItems_.store(new std::vector<void const*>(*cache));
0044 }
0045 }
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056 void PtrVectorBase::swap(PtrVectorBase& other) {
0057 core_.swap(other.core_);
0058 indicies_.swap(other.indicies_);
0059 other.cachedItems_.store(cachedItems_.exchange(other.cachedItems_.load()));
0060 }
0061
0062 void PtrVectorBase::push_back_base(RefCore const& core, key_type iKey, void const* iData) {
0063 core_.pushBackItem(core, false);
0064
0065 if (not cachedItems_ and indicies_.empty()) {
0066 cachedItems_.store(new std::vector<void const*>());
0067 (*cachedItems_).reserve(indicies_.capacity());
0068 }
0069 auto tmpCachedItems = cachedItems_.load();
0070 if (tmpCachedItems and (indicies_.size() == (*tmpCachedItems).size())) {
0071 if (iData) {
0072 tmpCachedItems->push_back(iData);
0073 } else if (key_traits<key_type>::value == iKey) {
0074 tmpCachedItems->push_back(nullptr);
0075 } else {
0076 delete tmpCachedItems;
0077 cachedItems_.store(nullptr);
0078 }
0079 }
0080 indicies_.push_back(iKey);
0081 }
0082
0083 bool PtrVectorBase::isAvailable() const {
0084 if (indicies_.empty()) {
0085 return core_.isAvailable();
0086 }
0087 if (!hasCache()) {
0088 if (!id().isValid() || productGetter() == nullptr) {
0089 return false;
0090 }
0091 getProduct_();
0092 }
0093 auto tmpCachedItems = cachedItems_.load();
0094 for (auto ptr : *tmpCachedItems) {
0095 if (ptr == nullptr) {
0096 return false;
0097 }
0098 }
0099 return true;
0100 }
0101
0102
0103
0104
0105 void PtrVectorBase::getProduct_() const {
0106 if (hasCache()) {
0107 return;
0108 }
0109 if (indicies_.empty()) {
0110 return;
0111 }
0112
0113 auto tmpProductGetter = productGetter();
0114 if (nullptr == tmpProductGetter) {
0115 throw Exception(errors::LogicError) << "Tried to get data for a PtrVector which has no EDProductGetter\n";
0116 }
0117 WrapperBase const* product = tmpProductGetter->getIt(id());
0118
0119 auto tmpCachedItems = std::make_unique<std::vector<void const*>>();
0120
0121 if (product != nullptr) {
0122 product->fillPtrVector(typeInfo(), indicies_, *tmpCachedItems);
0123
0124 std::vector<void const*>* expected = nullptr;
0125 if (cachedItems_.compare_exchange_strong(expected, tmpCachedItems.get())) {
0126
0127 tmpCachedItems.release();
0128 }
0129
0130 return;
0131 }
0132
0133 tmpCachedItems->resize(indicies_.size(), nullptr);
0134
0135 std::vector<unsigned int> thinnedKeys;
0136 thinnedKeys.assign(indicies_.begin(), indicies_.end());
0137 std::vector<WrapperBase const*> wrappers(indicies_.size(), nullptr);
0138 tmpProductGetter->getThinnedProducts(id(), wrappers, thinnedKeys);
0139 unsigned int nWrappers = wrappers.size();
0140 assert(wrappers.size() == indicies_.size());
0141 assert(wrappers.size() == tmpCachedItems->size());
0142 for (unsigned k = 0; k < nWrappers; ++k) {
0143 if (wrappers[k] != nullptr) {
0144 wrappers[k]->setPtr(typeInfo(), thinnedKeys[k], (*tmpCachedItems)[k]);
0145 }
0146 }
0147 {
0148 std::vector<void const*>* expected = nullptr;
0149 if (cachedItems_.compare_exchange_strong(expected, tmpCachedItems.get())) {
0150
0151 tmpCachedItems.release();
0152 }
0153 }
0154 }
0155
0156 bool PtrVectorBase::checkCachedItems() const {
0157 auto tmp = cachedItems_.load();
0158 if (not tmp) {
0159 return false;
0160 }
0161 for (auto item : *tmp) {
0162 if (item == nullptr) {
0163 throw Exception(errors::InvalidReference)
0164 << "Asked for data from a PtrVector which refers to a non-existent product with ProductID " << id() << "\n";
0165 }
0166 }
0167 return true;
0168 }
0169
0170 bool PtrVectorBase::operator==(PtrVectorBase const& iRHS) const {
0171 if (core_ != iRHS.core_) {
0172 return false;
0173 }
0174 if (indicies_.size() != iRHS.indicies_.size()) {
0175 return false;
0176 }
0177 return std::equal(indicies_.begin(), indicies_.end(), iRHS.indicies_.begin());
0178 }
0179
0180
0181
0182
0183
0184 static const std::vector<void const*> s_emptyCache{};
0185
0186 const std::vector<void const*>& PtrVectorBase::emptyCache() { return s_emptyCache; }
0187
0188 }