CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
AssociationVector.h
Go to the documentation of this file.
1 #ifndef DataFormats_Common_AssociationVector_h
2 #define DataFormats_Common_AssociationVector_h
3 /* class edm::AssociationVector<CKey, CVal>
4  *
5  * adds to a std::vector<CVal> a edm::RefProd<CKey>, in such a way
6  * that, assuming that the CVal and CKey collections have the same
7  * size and are properly ordered, the two collections can be
8  * in one-to-one correspondance
9  *
10  * \author Luca Lista, INFN
11  *
12  */
13 
24 
25 #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
26 #include <atomic>
27 #endif
28 #include <memory>
29 #include "boost/static_assert.hpp"
30 
31 namespace edm {
32  namespace helper {
33 
35  template<typename T>
36  static T const& get(T const& t, ProductID) { return t; }
37  };
38 
39  template<typename T>
42  };
43 
44  template<typename REFPROD>
45  struct RefFromRefProdTrait { };
46 
47  template<typename C>
50  };
51 
52  template<typename T>
55  };
56  }
57 
58  template<typename KeyRefProd, typename CVal,
59  typename KeyRef = typename helper::RefFromRefProdTrait<KeyRefProd>::ref_type,
60  typename SizeType = unsigned int,//the type used here can not change when go from 32bit to 64bit or across platforms
61  typename KeyReferenceHelper = typename helper::AssociationKeyReferenceTrait<KeyRef>::type>
65 
66  public:
67  typedef KeyRefProd refprod_type;
68  typedef typename KeyRefProd::product_type CKey;
69  typedef SizeType size_type;
70  typedef typename KeyRef::value_type key_type;
71  typedef typename std::pair<KeyRef, typename CVal::value_type> value_type;
72  typedef std::vector<value_type> transient_vector_type;
73  typedef value_type const& const_reference;
75  AssociationVector(KeyRefProd const& ref, CKey const* = 0);
78 
79  size_type size() const;
80  bool empty() const;
82  typename CVal::const_reference operator[](KeyRef const& k) const;
83  typename CVal::reference operator[](KeyRef const& k);
84 
85  self& operator=(self const&);
86 
87  void clear();
88  void swap(self& other);
89  KeyRefProd const& keyProduct() const { return ref_; }
90  KeyRef key(size_type i) const { return KeyRef(ref_, i); }
91  typename CVal::value_type const value(size_type i) const { return data_[ i ]; }
92  void setValue(size_type i, typename CVal::value_type const& val);
93  void fillView(ProductID const& id,
94  std::vector<void const*>& pointers,
95  helper_vector& helpers) const;
96 
97  typedef typename transient_vector_type::const_iterator const_iterator;
98 
99  const_iterator begin() const { return transientVector().begin(); }
100  const_iterator end() const { return transientVector().end(); }
101 
102  //Used by ROOT storage
104 
105  private:
107  CVal data_;
108  KeyRefProd ref_;
109 #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
110  mutable std::atomic<transient_vector_type*> transientVector_;
111 #else
113 #endif
114 
115  transient_vector_type const& transientVector() const;
116  void fixup() const;
117  };
118 
119 #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
120  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
123  fixup();
124  return *(transientVector_.load(std::memory_order_acquire)); }
125 #endif
126 
127  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
129  data_(), ref_(), transientVector_(nullptr) { }
130 
131  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
133  CKey const* coll) :
134  data_(coll == 0 ? ref->size() : coll->size()), ref_(ref),
135  transientVector_( new transient_vector_type(coll == 0 ? ref->size() : coll->size())) { }
136 
137 #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
138  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
141  data_(o.data_), ref_(o.ref_), transientVector_() {
142  auto t = o.transientVector_.load(std::memory_order_acquire);
143  if(t) {
144  transientVector_.store( new transient_vector_type(*t), std::memory_order_release);
145  }
146  }
147 #endif
148 
149 #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
150  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
152  delete transientVector_.load(std::memory_order_acquire);
153  }
154 #endif
155 
156  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
159  return transientVector()[ n ];
160  }
161 
162  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
163  inline typename CVal::const_reference
165  KeyRef keyRef = KeyReferenceHelper::get(k, ref_.id());
166  checkForWrongProduct(keyRef.id(), ref_.id());
167  return data_[ keyRef.key() ];
168  }
169 
170 
171 #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
172  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
173  inline typename CVal::reference
175  KeyRef keyRef = KeyReferenceHelper::get(k, ref_.id());
176  auto t = transientVector_.exchange(nullptr,std::memory_order_acq_rel);
177  delete t;
178  checkForWrongProduct(keyRef.id(), ref_.id());
179  return data_[ keyRef.key() ];
180  }
181 #endif
182 
183 #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
184  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
187  if(this == &o) {
188  return *this;
189  }
190  data_ = o.data_;
191  ref_ = o.ref_;
192  auto t =transientVector_.exchange(nullptr, std::memory_order_acq_rel);
193  delete t;
194  return *this;
195  }
196 
197  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
199  data_[ i ] = val;
200  KeyRef ref(ref_, i);
201  auto t = transientVector_.load(std::memory_order_acquire);
202  (*t)[ i ].first = ref;
203  (*t)[ i ].second = data_[ i ];
204  }
205 #endif
206 
207  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
210  return data_.size();
211  }
212 
213  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
215  return data_.empty();
216  }
217 
218 #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
219  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
221  data_.clear();
222  auto t = transientVector_.load(std::memory_order_acquire);
223  if(t) t->clear();
224  ref_ = KeyRefProd();
225  }
226 
227  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
229  data_.swap(other.data_);
230  other.transientVector_.store(transientVector_.exchange(other.transientVector_.load(std::memory_order_acquire),std::memory_order_acq_rel),std::memory_order_release);
231  ref_.swap(other.ref_);
232  }
233 
234  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
236  if (nullptr == transientVector_.load(std::memory_order_acquire)) {
237  std::unique_ptr<transient_vector_type> newT {new transient_vector_type(size()) };
238  for(size_type i = 0; i != size(); ++i) {
239  (*newT)[ i ] = std::make_pair(KeyRef(ref_, i), data_[ i ]);
240  }
241  transient_vector_type* expected = nullptr;
242  if(transientVector_.compare_exchange_strong(expected, newT.get()) ) {
243  newT.release();
244  }
245  }
246  }
247 #endif
248 
249  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
251  std::vector<void const*>& pointers,
252  helper_vector& helpers) const
253  {
254  detail::reallyFillView(*this, id, pointers, helpers);
255 // pointers.reserve(this->size());
256 // for(typename CVal::const_iterator i=data_.begin(), e=data_.end(); i!=e; ++i)
257 // pointers.push_back(&(*i));
258 // // helpers is not yet filled in.
259 // //Exception::throwThis(errors::UnimplementedFeature, "AssociationVector<T>::fillView(...)");
260  }
261 
262  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
265  a.swap(b);
266  }
267 
268  //----------------------------------------------------------------------
269  //
270  // Free function template to support creation of Views.
271 
272  template <typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
273  inline
274  void
276  ProductID const& id,
277  std::vector<void const*>& pointers,
278  helper_vector& helpers) {
279  obj.fillView(id, pointers, helpers);
280  }
281 
282  template <typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
283  struct has_fillView<AssociationVector<KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper> > {
284  static bool const value = true;
285  };
286 
287 }
288 
289 #endif
void checkForWrongProduct(ProductID const &keyID, ProductID const &refID)
int i
Definition: DBlmapReader.cc:9
void fillView(AssociationVector< KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper > const &obj, ProductID const &id, std::vector< void const * > &pointers, helper_vector &helpers)
transient_vector_type::const_iterator const_iterator
Ref< typename RefProd< C >::product_type > ref_type
void reallyFillView(COLLECTION const &coll, ProductID const &id, std::vector< void const * > &ptrs, helper_vector &helpers)
Definition: FillView.h:49
void fillView(ProductID const &id, std::vector< void const * > &pointers, helper_vector &helpers) const
self & operator=(self const &)
const_iterator end() const
std::vector< value_type > transient_vector_type
#define nullptr
#define CMS_CLASS_VERSION(_version_)
Definition: classes.h:31
void swap(Association< C > &lhs, Association< C > &rhs)
Definition: Association.h:116
AssociationIdenticalKeyReference type
value_type const & const_reference
const_reference operator[](size_type n) const
std::pair< KeyRef, typename CVal::value_type > value_type
BOOST_STATIC_ASSERT((boost::is_convertible< SizeType, typename CVal::size_type >::value))
void swap(self &other)
CVal::value_type const value(size_type i) const
KeyRefProd::product_type CKey
Container::transient_vector_type transient_vector_type
Container::value_type value_type
KeyRef key(size_type i) const
JetCorrectorParametersCollection coll
Definition: classes.h:10
double b
Definition: hdecay.h:120
KeyRef::value_type key_type
#define private
Definition: FWFileEntry.h:17
double a
Definition: hdecay.h:121
std::atomic< transient_vector_type * > transientVector_
KeyRefProd const & keyProduct() const
transient_vector_type const & transientVector() const
long double T
void setValue(size_type i, typename CVal::value_type const &val)
const_iterator begin() const
tuple size
Write out results.
T get(const Candidate &c)
Definition: component.h:55
static bool const value
Definition: traits.h:124
size_type size() const