CMS 3D CMS Logo

PtrVectorBase.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: Common
4 // Class : PtrVectorBase
5 //
6 // Implementation:
7 // <Notes on implementation>
8 //
9 // Original Author: Chris Jones
10 // Created: Wed Oct 24 15:49:27 EDT 2007
11 //
12 
13 // user include files
20 
21 // system include files
22 #include <ostream>
23 
24 //
25 // constants, enums and typedefs
26 //
27 namespace edm {
28  //
29  // static data member definitions
30  //
31 
32  //
33  // constructor and destructor
34  //
35  PtrVectorBase::PtrVectorBase() : cachedItems_(nullptr) {}
36 
38 
40  : core_(iOther.core_), indicies_(iOther.indicies_), cachedItems_(nullptr) {
41  auto cache = iOther.cachedItems_.load();
42  if (cache) {
43  cachedItems_.store(new std::vector<void const*>(*cache));
44  }
45  }
46 
47  //
48  // assignment operators
49  //
50 
51  //
52  // member functions
53  //
54 
57  core_.swap(other.core_);
58  indicies_.swap(other.indicies_);
59  other.cachedItems_.store(cachedItems_.exchange(other.cachedItems_.load()));
60  }
61 
62  void PtrVectorBase::push_back_base(RefCore const& core, key_type iKey, void const* iData) {
63  core_.pushBackItem(core, false);
64  //Did we already push a 'non-cached' Ptr into the container or is this a 'non-cached' Ptr?
65  if (not cachedItems_ and indicies_.empty()) {
66  cachedItems_.store(new std::vector<void const*>());
67  (*cachedItems_).reserve(indicies_.capacity());
68  }
69  auto tmpCachedItems = cachedItems_.load();
70  if (tmpCachedItems and (indicies_.size() == (*tmpCachedItems).size())) {
71  if (iData) {
72  tmpCachedItems->push_back(iData);
73  } else if (key_traits<key_type>::value == iKey) {
74  tmpCachedItems->push_back(nullptr);
75  } else {
76  delete tmpCachedItems;
77  cachedItems_.store(nullptr);
78  }
79  }
80  indicies_.push_back(iKey);
81  }
82 
84  if (indicies_.empty()) {
85  return core_.isAvailable();
86  }
87  if (!hasCache()) {
88  if (!id().isValid() || productGetter() == nullptr) {
89  return false;
90  }
91  getProduct_();
92  }
93  auto tmpCachedItems = cachedItems_.load();
94  for (auto ptr : *tmpCachedItems) {
95  if (ptr == nullptr) {
96  return false;
97  }
98  }
99  return true;
100  }
101 
102  //
103  // const member functions
104  //
106  if (hasCache()) {
107  return;
108  }
109  if (indicies_.empty()) {
110  return;
111  }
112  //NOTE: Another thread could be getting the data
113  auto tmpProductGetter = productGetter();
114  if (nullptr == tmpProductGetter) {
115  throw Exception(errors::LogicError) << "Tried to get data for a PtrVector which has no EDProductGetter\n";
116  }
117  WrapperBase const* product = tmpProductGetter->getIt(id());
118 
119  auto tmpCachedItems = std::make_unique<std::vector<void const*>>();
120 
121  if (product != nullptr) {
122  product->fillPtrVector(typeInfo(), indicies_, *tmpCachedItems);
123 
124  std::vector<void const*>* expected = nullptr;
125  if (cachedItems_.compare_exchange_strong(expected, tmpCachedItems.get())) {
126  //we were the first thread to change the value
127  tmpCachedItems.release();
128  }
129 
130  return;
131  }
132 
133  tmpCachedItems->resize(indicies_.size(), nullptr);
134 
135  std::vector<unsigned int> thinnedKeys;
136  thinnedKeys.assign(indicies_.begin(), indicies_.end());
137  std::vector<WrapperBase const*> wrappers(indicies_.size(), nullptr);
138  tmpProductGetter->getThinnedProducts(id(), wrappers, thinnedKeys);
139  unsigned int nWrappers = wrappers.size();
140  assert(wrappers.size() == indicies_.size());
141  assert(wrappers.size() == tmpCachedItems->size());
142  for (unsigned k = 0; k < nWrappers; ++k) {
143  if (wrappers[k] != nullptr) {
144  wrappers[k]->setPtr(typeInfo(), thinnedKeys[k], (*tmpCachedItems)[k]);
145  }
146  }
147  {
148  std::vector<void const*>* expected = nullptr;
149  if (cachedItems_.compare_exchange_strong(expected, tmpCachedItems.get())) {
150  //we were the first thread to change the value
151  tmpCachedItems.release();
152  }
153  }
154  }
155 
157  auto tmp = cachedItems_.load();
158  if (not tmp) {
159  return false;
160  }
161  for (auto item : *tmp) {
162  if (item == nullptr) {
164  << "Asked for data from a PtrVector which refers to a non-existent product with ProductID " << id() << "\n";
165  }
166  }
167  return true;
168  }
169 
170  bool PtrVectorBase::operator==(PtrVectorBase const& iRHS) const {
171  if (core_ != iRHS.core_) {
172  return false;
173  }
174  if (indicies_.size() != iRHS.indicies_.size()) {
175  return false;
176  }
177  return std::equal(indicies_.begin(), indicies_.end(), iRHS.indicies_.begin());
178  }
179 
180  //
181  // static member functions
182  //
183 
184  static const std::vector<void const*> s_emptyCache{};
185 
186  const std::vector<void const*>& PtrVectorBase::emptyCache() { return s_emptyCache; }
187 
188 } // namespace edm
edm::RefCore
Definition: RefCore.h:21
edm::RefCore::swap
void swap(RefCore &) noexcept
Definition: RefCore.h:147
edm::PtrVectorBase::getProduct_
void getProduct_() const
Definition: PtrVectorBase.cc:105
edm::errors::InvalidReference
Definition: EDMException.h:39
edm::errors::LogicError
Definition: EDMException.h:37
edm::PtrVectorBase::push_back_base
void push_back_base(RefCore const &core, key_type iKey, void const *iData)
Definition: PtrVectorBase.cc:62
edm
HLT enums.
Definition: AlignableModifier.h:19
cms::cuda::assert
assert(be >=bs)
edm::PtrVectorBase::productGetter
EDProductGetter const * productGetter() const
Accessor for product getter.
Definition: PtrVectorBase.h:61
createJobs.tmp
tmp
align.sh
Definition: createJobs.py:716
edm::PtrVectorBase::product
void const * product() const
Definition: PtrVectorBase.h:104
edm::PtrVectorBase::checkCachedItems
bool checkCachedItems() const
Definition: PtrVectorBase.cc:156
EDMException.h
edm::PtrVectorBase::indicies_
std::vector< key_type > indicies_
Definition: PtrVectorBase.h:172
edm::s_emptyCache
static const std::vector< void const * > s_emptyCache
Definition: PtrVectorBase.cc:184
trackingPlots.other
other
Definition: trackingPlots.py:1465
dqmdumpme.k
k
Definition: dqmdumpme.py:60
edm::PtrVectorBase::~PtrVectorBase
virtual ~PtrVectorBase()
Definition: PtrVectorBase.cc:37
edm::key_traits
Definition: traits.h:32
utilities.cache
def cache(function)
Definition: utilities.py:3
WrapperBase.h
edm::PtrVectorBase::core_
RefCore core_
Definition: PtrVectorBase.h:171
core
Definition: __init__.py:1
edm::PtrVectorBase::operator==
bool operator==(PtrVectorBase const &iRHS) const
Definition: PtrVectorBase.cc:170
edm::RefCore::pushBackItem
void pushBackItem(RefCore const &productToBeInserted, bool checkPointer)
Definition: RefCore.cc:164
PtrVectorBase.h
edm::PtrVectorBase::cachedItems_
std::atomic< std::vector< void const * > * > cachedItems_
Definition: PtrVectorBase.h:173
edm::PtrVectorBase::emptyCache
static const std::vector< void const * > & emptyCache()
Definition: PtrVectorBase.cc:186
edm::WrapperBase
Definition: WrapperBase.h:23
edm::PtrVectorBase::isAvailable
bool isAvailable() const
Definition: PtrVectorBase.cc:83
B2GTnPMonitor_cfi.item
item
Definition: B2GTnPMonitor_cfi.py:147
edm::PtrVectorBase::id
ProductID id() const
Accessor for product ID.
Definition: PtrVectorBase.h:58
edm::PtrVectorBase::PtrVectorBase
PtrVectorBase()
Definition: PtrVectorBase.cc:35
edm::PtrVectorBase::key_type
unsigned long key_type
Definition: PtrVectorBase.h:34
edm::PtrVectorBase::typeInfo
virtual std::type_info const & typeInfo() const
Definition: PtrVectorBase.h:157
Exception
Definition: hltDiff.cc:246
Exception.h
EDProductGetter.h
edm::PtrVectorBase::hasCache
bool hasCache() const
Definition: PtrVectorBase.h:63
traits.h
edm::RefCore::isAvailable
bool isAvailable() const
Definition: RefCore.cc:145
edm::PtrVectorBase
Definition: PtrVectorBase.h:32
cond::serialization::equal
bool equal(const T &first, const T &second)
Definition: Equal.h:32
edm::PtrVectorBase::swap
void swap(PtrVectorBase &other)
swap
Definition: PtrVectorBase.cc:56