CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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
19 
20 // system include files
21 #include <ostream>
22 
23 //
24 // constants, enums and typedefs
25 //
26 namespace edm {
27 //
28 // static data member definitions
29 //
30 
31 //
32 // constructor and destructor
33 //
35  }
36 
38  delete cachedItems_.load();
39  }
40 
42  core_(iOther.core_),
43  indicies_(iOther.indicies_),
44  cachedItems_(nullptr)
45  {
46  auto cache = iOther.cachedItems_.load();
47  if(cache) {
48  cachedItems_.store( new std::vector<void const*>(*cache));
49  }
50  }
51 
52 //
53 // assignment operators
54 //
55 
56 //
57 // member functions
58 //
59 
61  void
63  core_.swap(other.core_);
64  indicies_.swap(other.indicies_);
65  other.cachedItems_.store(cachedItems_.exchange(other.cachedItems_.load()));
66  }
67 
68  void
69  PtrVectorBase::push_back_base(RefCore const& core, key_type iKey, void const* iData) {
70  core_.pushBackItem(core, false);
71  //Did we already push a 'non-cached' Ptr into the container or is this a 'non-cached' Ptr?
72  if(not cachedItems_ and indicies_.empty()) {
73  cachedItems_.store( new std::vector<void const*>());
74  (*cachedItems_).reserve(indicies_.capacity());
75  }
76  auto tmpCachedItems = cachedItems_.load();
77  if(tmpCachedItems and (indicies_.size() == (*tmpCachedItems).size())) {
78  if(iData) {
79  tmpCachedItems->push_back(iData);
80  } else if(key_traits<key_type>::value == iKey) {
81  tmpCachedItems->push_back(nullptr);
82  } else {
83  delete tmpCachedItems;
84  cachedItems_.store(nullptr);
85  }
86  }
87  indicies_.push_back(iKey);
88  }
89 
90  bool
92  if(indicies_.empty()) {
93  return core_.isAvailable();
94  }
95  if(!hasCache()) {
96  if(!id().isValid() || productGetter() == nullptr) {
97  return false;
98  }
99  getProduct_();
100  }
101  auto tmpCachedItems = cachedItems_.load();
102  for(auto ptr : *tmpCachedItems) {
103  if(ptr == nullptr) {
104  return false;
105  }
106  }
107  return true;
108  }
109 
110 //
111 // const member functions
112 //
113  void
115  if(hasCache()) {
116  return;
117  }
118  if(indicies_.size() == 0) {
119  return;
120  }
121  //NOTE: Another thread could be getting the data
122  auto tmpProductGetter = productGetter();
123  if(nullptr == tmpProductGetter) {
124  throw Exception(errors::LogicError) << "Tried to get data for a PtrVector which has no EDProductGetter\n";
125  }
126  WrapperBase const* product = tmpProductGetter->getIt(id());
127 
128  auto tmpCachedItems = std::make_unique<std::vector<void const*>>();
129 
130  if(product != nullptr) {
131  product->fillPtrVector(typeInfo(), indicies_, *tmpCachedItems);
132 
133  std::vector<void const*>* expected = nullptr;
134  if(cachedItems_.compare_exchange_strong(expected, tmpCachedItems.get())) {
135  //we were the first thread to change the value
136  tmpCachedItems.release();
137  }
138 
139  return;
140  }
141 
142  tmpCachedItems->resize(indicies_.size(), nullptr);
143 
144  std::vector<unsigned int> thinnedKeys;
145  thinnedKeys.assign(indicies_.begin(), indicies_.end());
146  std::vector<WrapperBase const*> wrappers(indicies_.size(), nullptr);
147  tmpProductGetter->getThinnedProducts(id(), wrappers, thinnedKeys);
148  unsigned int nWrappers = wrappers.size();
149  assert(wrappers.size() == indicies_.size());
150  assert(wrappers.size() == tmpCachedItems->size());
151  for(unsigned k = 0; k < nWrappers; ++k) {
152  if (wrappers[k] != nullptr) {
153  wrappers[k]->setPtr(typeInfo(), thinnedKeys[k], (*tmpCachedItems)[k]);
154  }
155  }
156  {
157  std::vector<void const*>* expected = nullptr;
158  if(cachedItems_.compare_exchange_strong(expected, tmpCachedItems.get())) {
159  //we were the first thread to change the value
160  tmpCachedItems.release();
161  }
162  }
163  }
164 
165  bool
167  auto tmp = cachedItems_.load();
168  if(not tmp) { return false;}
169  for(auto item : *tmp) {
170  if(item == nullptr) {
171  throw Exception(errors::InvalidReference) << "Asked for data from a PtrVector which refers to a non-existent product with ProductID "
172  << id() << "\n";
173  }
174  }
175  return true;
176  }
177 
178  bool
180  if(core_ != iRHS.core_) {
181  return false;
182  }
183  if(indicies_.size() != iRHS.indicies_.size()){
184  return false;
185  }
186  return std::equal(indicies_.begin(),
187  indicies_.end(),
188  iRHS.indicies_.begin());
189  }
190 
191 //
192 // static member functions
193 //
194 
195  static const std::vector<void const*> s_emptyCache{};
196 
197  const std::vector<void const*>& PtrVectorBase::emptyCache() {
198  return s_emptyCache;
199  }
200 
201 }
void push_back_base(RefCore const &core, key_type iKey, void const *iData)
void pushBackItem(RefCore const &productToBeInserted, bool checkPointer)
Definition: RefCore.cc:193
void swap(RefCore &)
Definition: RefCore.h:157
bool checkCachedItems() const
assert(m_qm.get())
void swap(PtrVectorBase &other)
swap
static const std::vector< void const * > s_emptyCache
#define nullptr
virtual std::type_info const & typeInfo() const
bool equal(const T &first, const T &second)
Definition: Equal.h:34
static const std::vector< void const * > & emptyCache()
void getProduct_() const
ProductID id() const
Accessor for product ID.
Definition: PtrVectorBase.h:63
bool isAvailable() const
std::vector< key_type > indicies_
std::atomic< std::vector< void const * > * > cachedItems_
bool isAvailable() const
Definition: RefCore.cc:168
bool operator==(PtrVectorBase const &iRHS) const
void fillPtrVector(std::type_info const &iToType, std::vector< unsigned long > const &iIndicies, std::vector< void const * > &oPtr) const
Definition: WrapperBase.cc:34
virtual ~PtrVectorBase()
bool hasCache() const
Definition: PtrVectorBase.h:68
unsigned long key_type
Definition: PtrVectorBase.h:35
std::vector< std::vector< double > > tmp
Definition: MVATrainer.cc:100
EDProductGetter const * productGetter() const
Accessor for product getter.
Definition: PtrVectorBase.h:66
void const * product() const