CMS 3D CMS Logo

AssociationMap.h
Go to the documentation of this file.
1 #ifndef DataFormats_Common_AssociationMap_h
2 #define DataFormats_Common_AssociationMap_h
3 
39 
40 #include <utility>
41 #include "oneapi/tbb/concurrent_unordered_map.h"
42 
43 namespace edm {
44 
45  class EDProductGetter;
46 
47  template <typename Tag>
51  typedef typename Tag::val_type internal_val_type;
52 
53  public:
55  typedef AssociationMap<Tag> self;
57  typedef Tag tag_type;
59  typedef typename Tag::index_type index_type;
61  typedef typename Tag::key_type key_type;
63  typedef typename Tag::data_type data_type;
65  typedef typename Tag::ref_type ref_type;
67  typedef typename Tag::map_type map_type;
69  typedef typename map_type::size_type size_type;
75  typedef typename oneapi::tbb::concurrent_unordered_map<index_type, value_type> internal_transient_map_type;
76 
78  struct const_iterator {
79  typedef typename self::value_type value_type;
80  typedef ptrdiff_t difference_type;
81  typedef value_type* pointer;
83  typedef typename map_type::const_iterator::iterator_category iterator_category;
84  const_iterator() : map_(nullptr) {}
85  const_iterator(const self* map, typename map_type::const_iterator mi) : map_(map), i(mi) {}
87  ++i;
88  return *this;
89  }
91  const_iterator ci = *this;
92  ++i;
93  return ci;
94  }
96  --i;
97  return *this;
98  }
100  const_iterator ci = *this;
101  --i;
102  return ci;
103  }
104  bool operator==(const const_iterator& ci) const { return i == ci.i; }
105  bool operator!=(const const_iterator& ci) const { return i != ci.i; }
106  const value_type& operator*() const { return map_->get(i->first); }
107  const value_type* operator->() const { return &operator*(); }
108 
109  private:
110  const self* map_;
111  typename map_type::const_iterator i;
112  };
113 
116 
117  // You will see better performance if you use other constructors.
118  // Use this when the arguments the other constructors require are
119  // not easily available.
120  explicit AssociationMap(EDProductGetter const* getter) : ref_(getter) {}
121 
122  // It is rare for this to be useful
123  explicit AssociationMap(const ref_type& ref) : ref_(ref) {}
124 
125  // In most cases this is the best constructor to use.
126  // This constructor should be passed 2 arguments, except in the
127  // case where the template parameter is OneToValue where it should
128  // be passed 1 argument. In most cases, the arguments will be valid
129  // Handle's to the containers. Internally, the AssociationMap holds
130  // a RefProd for each container. An argument passed here is forwarded
131  // to a RefProd constructor. Alternatively, you can pass in
132  // a RefProd or anything else a RefProd can be constructed from.
133  // The exceptional case is when the container template argument
134  // is a View (For your peace of mind, I suggest you stop reading
135  // this comment here if you are not dealing with the View case).
136  // Usually one would not pass a Handle argument in the View
137  // case. Then internally AssociationMap holds a RefToBaseProd
138  // for each container instead of a RefProd and one would pass a
139  // RefToBaseProd as an argument in that case. Also see the comments
140  // at the top of this file that are relevant to the View case.
141  // In the View case, the code would sometimes look similar to
142  // the following:
143  //
144  // typedef edm::AssociationMap<edm::OneToOne<edm::View<X>, edm::View<Y> > > AssocOneToOneView;
145  // edm::Handle<edm::View<X> > inputView1;
146  // event.getByToken(inputToken1V_, inputView1);
147  // edm::Handle<edm::View<Y> > inputView2;
148  // event.getByToken(inputToken2V_, inputView2);
149  // // If you are certain the Views are not empty!
150  // std::unique_ptr<AssocOneToOneView> assoc8(new AssocOneToOneView(
151  // edm::makeRefToBaseProdFrom(inputView1->refAt(0), event),
152  // edm::makeRefToBaseProdFrom(inputView2->refAt(0), event)
153  // ));
154 
155  template <typename... Args>
156  AssociationMap(Args... args) : ref_(std::forward<Args>(args)...) {}
157 
159  void clear() {
160  map_.clear();
161  transientMap_.clear();
162  }
164  size_type size() const { return map_.size(); }
166  bool empty() const { return map_.empty(); }
168  void insert(const key_type& k, const data_type& v) { Tag::insert(ref_, map_, k, v); }
169  void insert(const value_type& kv) { Tag::insert(ref_, map_, kv.key, kv.val); }
171  const_iterator begin() const { return const_iterator(this, map_.begin()); }
173  const_iterator end() const { return const_iterator(this, map_.end()); }
175  const_iterator find(const key_type& k) const {
176  if (ref_.key.id() != k.id())
177  return end();
178  return find(k.key());
179  }
182  index_type i = k.key();
183  transientMap_.unsafe_erase(i);
184  return map_.erase(i);
185  }
187  const result_type& operator[](const key_type& k) const {
188  helpers::checkRef(ref_.key, k);
189  return get(k.key()).val;
190  }
191 
192  template <typename K>
193  const result_type& operator[](const K& k) const {
194  helpers::checkRef(ref_.key, k);
195  return get(k.key()).val;
196  }
197 
200  if (ref_.key.id() != k.id())
201  return 0;
202  typename map_type::const_iterator f = map_.find(k.key());
203  if (f == map_.end())
204  return 0;
205  return Tag::size(f->second);
206  }
207 
208  template <typename K>
209  size_type numberOfAssociations(const K& k) const {
210  if (ref_.key.id() != k.id())
211  return 0;
212  typename map_type::const_iterator f = map_.find(k.key());
213  if (f == map_.end())
214  return 0;
215  return Tag::size(f->second);
216  }
217 
219  const ref_type& refProd() const { return ref_; }
220 
223  typename Tag::transient_map_type map() { return Tag::transientMap(ref_, map_); }
226  typename Tag::transient_key_vector keys() { return Tag::transientKeyVector(ref_, map_); }
229  typename Tag::transient_val_vector values() { return Tag::transientValVector(ref_, map_); }
232 
233  // Find should be private! However, generated reflex dictionaries do not compile
234  // if Find is private.
236  struct Find {
237  using first_argument_type = const self&;
239  using result_type = const value_type*;
240 
242  };
243 
244  //Used by ROOT storage
246 
247  private:
256  typename map_type::const_iterator f = map_.find(i);
257  if (f == map_.end())
258  return end();
259  return const_iterator(this, f);
260  }
262  const value_type& get(size_type i) const {
263  typename internal_transient_map_type::const_iterator tf = transientMap_.find(i);
264  if (tf == transientMap_.end()) {
265  typename map_type::const_iterator f = map_.find(i);
266  if (f == map_.end())
267  Exception::throwThis(edm::errors::InvalidReference, "can't find reference in AssociationMap at position ", i);
268  value_type v(key_type(ref_.key, i), Tag::val(ref_, f->second));
269  std::pair<typename internal_transient_map_type::const_iterator, bool> ins =
270  transientMap_.insert(std::make_pair(i, v));
271  return ins.first->second;
272  } else {
273  return tf->second;
274  }
275  }
276  friend struct const_iterator;
277  friend struct Find;
279  template <typename, typename, typename>
280  friend class OneToValue;
281  template <typename, typename, typename>
282  friend class OneToOne;
283  template <typename, typename, typename>
284  friend class OneToMany;
285  template <typename, typename, typename, typename>
286  friend class OneToManyWithQuality;
287  };
288 
289  namespace refhelper {
290  template <typename Tag>
291  struct FindTrait<AssociationMap<Tag>, typename AssociationMap<Tag>::value_type> {
293  };
294  } // namespace refhelper
295 
296 } // namespace edm
297 #endif
size
Write out results.
::ecal::reco::ComputationScalarType data_type
const result_type operator()(first_argument_type c, second_argument_type i)
Tag::index_type index_type
index type
friend struct const_iterator
internal_transient_map_type transientMap_
transient reference map
Tag::data_type data_type
insert data type
AssociationMap(const ref_type &ref)
void clear()
clear map
helpers::KeyVal< key_type, internal_val_type > value_type
type returned by dereferenced iterator, also can be inserted
Tag::transient_val_vector values()
Tag::key_type key_type
insert key type
const ref_type & refProd() const
return ref-prod structure
ref_type ref_
reference set
bool empty() const
return true if empty
#define CMS_CLASS_VERSION(_version_)
uint16_t size_type
value_type::value_type result_type
type return by operator[]
ins
Definition: cuy.py:313
const_iterator find(const key_type &k) const
find element with specified reference key
bool operator==(const const_iterator &ci) const
static void throwThis(Code category, char const *message0="", char const *message1="", char const *message2="", char const *message3="", char const *message4="")
Definition: EDMException.cc:86
const_iterator end() const
last iterator over the map (read only)
size_type erase(const key_type &k)
erase the element whose key is k
size_type size() const
map size
const result_type & operator[](const key_type &k) const
find element with specified reference key
const_iterator(const self *map, typename map_type::const_iterator mi)
void post_insert()
post insert action
size_type numberOfAssociations(const K &k) const
double f[11][100]
bool insert(Storage &iStorage, ItemType *iItem, const IdTag &iIdTag)
Definition: HCMethods.h:50
const result_type & operator[](const K &k) const
Tag::transient_key_vector keys()
oneapi::tbb::concurrent_unordered_map< index_type, value_type > internal_transient_map_type
transient map type
size_type numberOfAssociations(const key_type &k) const
number of associations to a key
Tag::val_type internal_val_type
map_type map_
index map
void insert(const key_type &k, const data_type &v)
insert an association
const value_type & get(size_type i) const
return value_typeelement with key i
AssociationMap(Args... args)
AssociationMap(EDProductGetter const *getter)
const_iterator begin() const
first iterator over the map (read only)
HLT enums.
map_type::const_iterator::iterator_category iterator_category
Tag::ref_type ref_type
Holds the RefProd or RefToBaseProd of 1 or 2 collections.
Tag::map_type map_type
map type
void insert(const value_type &kv)
Tag tag_type
tag/association type
AssociationMap()
default constructor
const value_type * operator->() const
void checkRef(const RP &rp, const R &r)
throw if r hasn&#39;t the same id as rp
friend struct Find
bool operator!=(const const_iterator &ci) const
const value_type & operator*() const
Tag::transient_map_type map()
map_type::size_type size_type
size type