CMS 3D CMS Logo

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 #include <atomic>
26 #include <type_traits>
27 #include <memory>
28 
29 namespace edm {
30  template<class T> class Ptr;
31 
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>
63  static_assert(std::is_convertible<SizeType, typename CVal::size_type>::value, "Can not convert container size_type to unsigned int.");
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;
81  const_reference operator[](size_type n) const;
82  typename CVal::const_reference operator[](KeyRef const& k) const;
83  typename CVal::reference operator[](KeyRef const& k);
84 
85  template< typename K>
86  typename CVal::const_reference operator[](edm::Ptr<K> const& k) const;
87  template< typename K>
88  typename CVal::const_reference operator[](edm::RefToBase<K> const& k) const;
89 
90  self& operator=(self const&);
91 
92  void clear();
93  void swap(self& other);
94  KeyRefProd const& keyProduct() const { return ref_; }
95  KeyRef key(size_type i) const { return KeyRef(ref_, i); }
96  typename CVal::value_type const value(size_type i) const { return data_[ i ]; }
97  void setValue(size_type i, typename CVal::value_type const& val);
98  void fillView(ProductID const& id,
99  std::vector<void const*>& pointers,
101 
102  typedef typename transient_vector_type::const_iterator const_iterator;
103 
104  const_iterator begin() const { return transientVector().begin(); }
105  const_iterator end() const { return transientVector().end(); }
106 
107  //Used by ROOT storage
109 
110  private:
111  enum CacheState { kUnset, kFilling, kSet };
112  CVal data_;
113  KeyRefProd ref_;
114  mutable std::atomic<transient_vector_type*> transientVector_;
115 
116  transient_vector_type const& transientVector() const;
117  void fixup() const;
118  };
119 
120  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
123  fixup();
124  return *(transientVector_.load(std::memory_order_acquire)); }
125 
126  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
128  data_(), ref_(), transientVector_(nullptr) { }
129 
130  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
132  CKey const* coll) :
133  data_(coll == 0 ? ref->size() : coll->size()), ref_(ref),
134  transientVector_( new transient_vector_type(coll == 0 ? ref->size() : coll->size())) { }
135 
136  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
139  data_(o.data_), ref_(o.ref_), transientVector_() {
140  auto t = o.transientVector_.load(std::memory_order_acquire);
141  if(t) {
142  transientVector_.store( new transient_vector_type(*t), std::memory_order_release);
143  }
144  }
145 
146  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
148  delete transientVector_.load(std::memory_order_acquire);
149  }
150 
151  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
154  return transientVector()[ n ];
155  }
156 
157  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
158  inline typename CVal::const_reference
160  KeyRef keyRef = KeyReferenceHelper::get(k, ref_.id());
161  checkForWrongProduct(keyRef.id(), ref_.id());
162  return data_[ keyRef.key() ];
163  }
164 
165  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
166  template< typename K>
167  inline typename CVal::const_reference
169  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");
170  checkForWrongProduct(k.id(), ref_.id());
171  return data_[ k.key() ];
172  }
173 
174  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
175  template< typename K>
176  typename CVal::const_reference
178  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");
179  checkForWrongProduct(k.id(), ref_.id());
180  return data_[ k.key() ];
181  }
182 
183  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
184  inline typename CVal::reference
186  KeyRef keyRef = KeyReferenceHelper::get(k, ref_.id());
187  auto t = transientVector_.exchange(nullptr,std::memory_order_acq_rel);
188  delete t;
189  checkForWrongProduct(keyRef.id(), ref_.id());
190  return data_[ keyRef.key() ];
191  }
192 
193  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
196  if(this == &o) {
197  return *this;
198  }
199  data_ = o.data_;
200  ref_ = o.ref_;
201  auto t =transientVector_.exchange(nullptr, std::memory_order_acq_rel);
202  delete t;
203  return *this;
204  }
205 
206  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
208  data_[ i ] = val;
209  KeyRef ref(ref_, i);
210  auto t = transientVector_.load(std::memory_order_acquire);
211  (*t)[ i ].first = ref;
212  (*t)[ i ].second = data_[ i ];
213  }
214 
215  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
218  return data_.size();
219  }
220 
221  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
223  return data_.empty();
224  }
225 
226  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
228  data_.clear();
229  auto t = transientVector_.load(std::memory_order_acquire);
230  if(t) t->clear();
231  ref_ = KeyRefProd();
232  }
233 
234  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
236  data_.swap(other.data_);
237  other.transientVector_.store(transientVector_.exchange(other.transientVector_.load(std::memory_order_acquire),std::memory_order_acq_rel),std::memory_order_release);
238  ref_.swap(other.ref_);
239  }
240 
241  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
243  if (nullptr == transientVector_.load(std::memory_order_acquire)) {
244  std::unique_ptr<transient_vector_type> newT {new transient_vector_type(size()) };
245  for(size_type i = 0; i != size(); ++i) {
246  (*newT)[ i ] = std::make_pair(KeyRef(ref_, i), data_[ i ]);
247  }
248  transient_vector_type* expected = nullptr;
249  if(transientVector_.compare_exchange_strong(expected, newT.get()) ) {
250  newT.release();
251  }
252  }
253  }
254 
255  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
257  std::vector<void const*>& pointers,
259  {
260  detail::reallyFillView(*this, id, pointers, helpers);
261 // pointers.reserve(this->size());
262 // for(typename CVal::const_iterator i=data_.begin(), e=data_.end(); i!=e; ++i)
263 // pointers.push_back(&(*i));
264 // // helpers is not yet filled in.
265 // //Exception::throwThis(errors::UnimplementedFeature, "AssociationVector<T>::fillView(...)");
266  }
267 
268  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
271  a.swap(b);
272  }
273 
274  //----------------------------------------------------------------------
275  //
276  // Free function template to support creation of Views.
277 
278  template <typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
279  inline
280  void
282  ProductID const& id,
283  std::vector<void const*>& pointers,
285  obj.fillView(id, pointers, helpers);
286  }
287 
288  template <typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
289  struct has_fillView<AssociationVector<KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper> > {
290  static bool const value = true;
291  };
292 
293 }
294 
295 #endif
size
Write out results.
void checkForWrongProduct(ProductID const &keyID, ProductID const &refID)
void fillView(ProductID const &id, std::vector< void const * > &pointers, FillViewHelperVector &helpers) const
Definition: helper.py:1
transient_vector_type::const_iterator const_iterator
key_type key() const
Definition: Ptr.h:185
void reallyFillView(COLLECTION const &coll, ProductID const &id, std::vector< void const * > &ptrs, FillViewHelperVector &helpers)
Definition: FillView.h:27
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:242
bool setValue(Container &, const reco::JetBaseRef &, const JetExtendedData &)
associate jet with value. Returns false and associate nothing if jet is already associated ...
AssociationIdenticalKeyReference type
const char * kSet
void swap(IndexRangeAssociation &lhs, IndexRangeAssociation &rhs)
value_type const & const_reference
const_reference operator[](size_type n) const
size_t key() const
Definition: RefToBase.h:250
std::pair< KeyRef, typename CVal::value_type > value_type
void clear(CLHEP::HepGenMatrix &m)
Helper function: Reset all elements of a matrix to 0.
Definition: matutil.cc:167
void fillView(AssociationVector< KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper > const &obj, ProductID const &id, std::vector< void const * > &pointers, FillViewHelperVector &helpers)
void swap(self &other)
T operator[](int i) const
Definition: value.py:1
CVal::value_type const value(size_type i) const
KeyRefProd::product_type CKey
KeyRef key(size_type i) const
int k[5][pyjets_maxn]
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:180
HLT enums.
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
std::vector< std::pair< edm::ProductID, unsigned long > > FillViewHelperVector
T get(const Candidate &c)
Definition: component.h:55
size_type size() const