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 #include <type_traits>
28 #endif
29 #include <memory>
30 #include "boost/static_assert.hpp"
31 
32 namespace edm {
33  template<class T> class Ptr;
34 
35  namespace helper {
36 
38  template<typename T>
39  static T const& get(T const& t, ProductID) { return t; }
40  };
41 
42  template<typename T>
45  };
46 
47  template<typename REFPROD>
48  struct RefFromRefProdTrait { };
49 
50  template<typename C>
53  };
54 
55  template<typename T>
58  };
59  }
60 
61  template<typename KeyRefProd, typename CVal,
62  typename KeyRef = typename helper::RefFromRefProdTrait<KeyRefProd>::ref_type,
63  typename SizeType = unsigned int,//the type used here can not change when go from 32bit to 64bit or across platforms
64  typename KeyReferenceHelper = typename helper::AssociationKeyReferenceTrait<KeyRef>::type>
68 
69  public:
70  typedef KeyRefProd refprod_type;
71  typedef typename KeyRefProd::product_type CKey;
72  typedef SizeType size_type;
73  typedef typename KeyRef::value_type key_type;
74  typedef typename std::pair<KeyRef, typename CVal::value_type> value_type;
75  typedef std::vector<value_type> transient_vector_type;
76  typedef value_type const& const_reference;
78  AssociationVector(KeyRefProd const& ref, CKey const* = 0);
81 
82  size_type size() const;
83  bool empty() const;
85  typename CVal::const_reference operator[](KeyRef const& k) const;
86  typename CVal::reference operator[](KeyRef const& k);
87 
88  template< typename K>
89  typename CVal::const_reference operator[](edm::Ptr<K> const& k) const;
90  template< typename K>
91  typename CVal::const_reference operator[](edm::RefToBase<K> const& k) const;
92 
93  self& operator=(self const&);
94 
95  void clear();
96  void swap(self& other);
97  KeyRefProd const& keyProduct() const { return ref_; }
98  KeyRef key(size_type i) const { return KeyRef(ref_, i); }
99  typename CVal::value_type const value(size_type i) const { return data_[ i ]; }
100  void setValue(size_type i, typename CVal::value_type const& val);
101  void fillView(ProductID const& id,
102  std::vector<void const*>& pointers,
103  FillViewHelperVector& helpers) const;
104 
105  typedef typename transient_vector_type::const_iterator const_iterator;
106 
107  const_iterator begin() const { return transientVector().begin(); }
108  const_iterator end() const { return transientVector().end(); }
109 
110  //Used by ROOT storage
112 
113  private:
115  CVal data_;
116  KeyRefProd ref_;
117 #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
118  mutable std::atomic<transient_vector_type*> transientVector_;
119 #else
121 #endif
122 
123  transient_vector_type const& transientVector() const;
124  void fixup() const;
125  };
126 
127 #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
128  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
131  fixup();
132  return *(transientVector_.load(std::memory_order_acquire)); }
133 #endif
134 
135  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
137  data_(), ref_(), transientVector_(nullptr) { }
138 
139  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
141  CKey const* coll) :
142  data_(coll == 0 ? ref->size() : coll->size()), ref_(ref),
143  transientVector_( new transient_vector_type(coll == 0 ? ref->size() : coll->size())) { }
144 
145 #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
146  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
149  data_(o.data_), ref_(o.ref_), transientVector_() {
150  auto t = o.transientVector_.load(std::memory_order_acquire);
151  if(t) {
152  transientVector_.store( new transient_vector_type(*t), std::memory_order_release);
153  }
154  }
155 #endif
156 
157 #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
158  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
160  delete transientVector_.load(std::memory_order_acquire);
161  }
162 #endif
163 
164  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
167  return transientVector()[ n ];
168  }
169 
170  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
171  inline typename CVal::const_reference
173  KeyRef keyRef = KeyReferenceHelper::get(k, ref_.id());
174  checkForWrongProduct(keyRef.id(), ref_.id());
175  return data_[ keyRef.key() ];
176  }
177 
178  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
179  template< typename K>
180  inline typename CVal::const_reference
182 #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
183  static_assert(std::is_base_of<K,key_type>::value, "edm::Ptr's key type is not a base class of AssociationVector's item type");
184 #endif
185  checkForWrongProduct(k.id(), ref_.id());
186  return data_[ k.key() ];
187  }
188 
189  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
190  template< typename K>
191  typename CVal::const_reference
193 #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
194  static_assert(std::is_base_of<K,key_type>::value,"edm::RefToBase's key type is not a base class of AssociationVector's item type");
195 #endif
196  checkForWrongProduct(k.id(), ref_.id());
197  return data_[ k.key() ];
198  }
199 
200 
201 #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
202  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
203  inline typename CVal::reference
205  KeyRef keyRef = KeyReferenceHelper::get(k, ref_.id());
206  auto t = transientVector_.exchange(nullptr,std::memory_order_acq_rel);
207  delete t;
208  checkForWrongProduct(keyRef.id(), ref_.id());
209  return data_[ keyRef.key() ];
210  }
211 #endif
212 
213 #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
214  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
217  if(this == &o) {
218  return *this;
219  }
220  data_ = o.data_;
221  ref_ = o.ref_;
222  auto t =transientVector_.exchange(nullptr, std::memory_order_acq_rel);
223  delete t;
224  return *this;
225  }
226 
227  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
229  data_[ i ] = val;
230  KeyRef ref(ref_, i);
231  auto t = transientVector_.load(std::memory_order_acquire);
232  (*t)[ i ].first = ref;
233  (*t)[ i ].second = data_[ i ];
234  }
235 #endif
236 
237  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
240  return data_.size();
241  }
242 
243  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
245  return data_.empty();
246  }
247 
248 #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
249  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
251  data_.clear();
252  auto t = transientVector_.load(std::memory_order_acquire);
253  if(t) t->clear();
254  ref_ = KeyRefProd();
255  }
256 
257  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
259  data_.swap(other.data_);
260  other.transientVector_.store(transientVector_.exchange(other.transientVector_.load(std::memory_order_acquire),std::memory_order_acq_rel),std::memory_order_release);
261  ref_.swap(other.ref_);
262  }
263 
264  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
266  if (nullptr == transientVector_.load(std::memory_order_acquire)) {
267  std::unique_ptr<transient_vector_type> newT {new transient_vector_type(size()) };
268  for(size_type i = 0; i != size(); ++i) {
269  (*newT)[ i ] = std::make_pair(KeyRef(ref_, i), data_[ i ]);
270  }
271  transient_vector_type* expected = nullptr;
272  if(transientVector_.compare_exchange_strong(expected, newT.get()) ) {
273  newT.release();
274  }
275  }
276  }
277 #endif
278 
279  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
281  std::vector<void const*>& pointers,
282  FillViewHelperVector& helpers) const
283  {
284  detail::reallyFillView(*this, id, pointers, helpers);
285 // pointers.reserve(this->size());
286 // for(typename CVal::const_iterator i=data_.begin(), e=data_.end(); i!=e; ++i)
287 // pointers.push_back(&(*i));
288 // // helpers is not yet filled in.
289 // //Exception::throwThis(errors::UnimplementedFeature, "AssociationVector<T>::fillView(...)");
290  }
291 
292  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
295  a.swap(b);
296  }
297 
298  //----------------------------------------------------------------------
299  //
300  // Free function template to support creation of Views.
301 
302  template <typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
303  inline
304  void
306  ProductID const& id,
307  std::vector<void const*>& pointers,
308  FillViewHelperVector& helpers) {
309  obj.fillView(id, pointers, helpers);
310  }
311 
312  template <typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
313  struct has_fillView<AssociationVector<KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper> > {
314  static bool const value = true;
315  };
316 
317 }
318 
319 #endif
void checkForWrongProduct(ProductID const &keyID, ProductID const &refID)
tuple t
Definition: tree.py:139
int i
Definition: DBlmapReader.cc:9
void fillView(ProductID const &id, std::vector< void const * > &pointers, FillViewHelperVector &helpers) const
transient_vector_type::const_iterator const_iterator
key_type key() const
Definition: Ptr.h:186
void reallyFillView(COLLECTION const &coll, ProductID const &id, std::vector< void const * > &ptrs, FillViewHelperVector &helpers)
Definition: FillView.h:28
Ref< typename RefProd< C >::product_type > ref_type
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
ProductID id() const
Definition: RefToBase.h:233
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
size_t key() const
Definition: RefToBase.h:241
std::pair< KeyRef, typename CVal::value_type > value_type
BOOST_STATIC_ASSERT((boost::is_convertible< SizeType, typename CVal::size_type >::value))
void fillView(AssociationVector< KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper > const &obj, ProductID const &id, std::vector< void const * > &pointers, FillViewHelperVector &helpers)
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
ProductID id() const
Accessor for product ID.
Definition: Ptr.h:181
#define private
Definition: FWFileEntry.h:17
double a
Definition: hdecay.h:121
std::atomic< transient_vector_type * > transientVector_
KeyRefProd const & keyProduct() const
ProductIndex id() const
Definition: ProductID.h:38
transient_vector_type const & transientVector() const
long double T
void setValue(size_type i, typename CVal::value_type const &val)
const_iterator begin() const
std::vector< std::pair< edm::ProductID, unsigned long > > FillViewHelperVector
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