CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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 "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  public:
54  typedef AssociationMap<Tag> self;
56  typedef typename Tag::index_type index_type;
58  typedef typename Tag::key_type key_type;
60  typedef typename Tag::data_type data_type;
62  typedef typename Tag::ref_type ref_type;
64  typedef typename Tag::map_type map_type;
66  typedef typename map_type::size_type size_type;
72  typedef typename tbb::concurrent_unordered_map<index_type, value_type> internal_transient_map_type;
73 
75  struct const_iterator {
76  typedef typename self::value_type value_type;
77  typedef ptrdiff_t difference_type;
78  typedef value_type * pointer;
79  typedef value_type & reference;
80  typedef typename map_type::const_iterator::iterator_category iterator_category;
81  const_iterator(): map_(0) { }
82  const_iterator(const self * map, typename map_type::const_iterator mi) :
83  map_(map), i(mi) { }
84  const_iterator& operator++() { ++i; return *this; }
85  const_iterator operator++(int) { const_iterator ci = *this; ++i; return ci; }
86  const_iterator& operator--() { --i; return *this; }
87  const_iterator operator--(int) { const_iterator ci = *this; --i; return ci; }
88  bool operator==(const const_iterator& ci) const { return i == ci.i; }
89  bool operator!=(const const_iterator& ci) const { return i != ci.i; }
90  const value_type & operator *() const { return map_->get( i->first ); }
91  const value_type * operator->() const { return &operator *(); }
92  private:
93  const self * map_;
94  typename map_type::const_iterator i;
95  };
96 
99 
100 #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
101  // You will see better performance if you use other constructors.
102  // Use this when the arguments the other constructors require are
103  // not easily available.
104  explicit
106  ref_(getter) { }
107 #endif
108 
109  // It is rare for this to be useful
110  explicit
111  AssociationMap(const ref_type & ref) : ref_(ref) { }
112 
113 #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
114  // In most cases this is the best constructor to use.
115  // This constructor should be passed 2 arguments, except in the
116  // case where the template parameter is OneToValue where it should
117  // be passed 1 argument. In most cases, the arguments will be valid
118  // Handle's to the containers. Internally, the AssociationMap holds
119  // a RefProd for each container. An argument passed here is forwarded
120  // to a RefProd constructor. Alternatively, you can pass in
121  // a RefProd or anything else a RefProd can be constructed from.
122  // The exceptional case is when the container template argument
123  // is a View (For your peace of mind, I suggest you stop reading
124  // this comment here if you are not dealing with the View case).
125  // Usually one would not pass a Handle argument in the View
126  // case. Then internally AssociationMap holds a RefToBaseProd
127  // for each container instead of a RefProd and one would pass a
128  // RefToBaseProd as an argument in that case. Also see the comments
129  // at the top of this file that are relevant to the View case.
130  // In the View case, the code would sometimes look similar to
131  // the following:
132  //
133  // typedef edm::AssociationMap<edm::OneToOne<edm::View<X>, edm::View<Y> > > AssocOneToOneView;
134  // edm::Handle<edm::View<X> > inputView1;
135  // event.getByToken(inputToken1V_, inputView1);
136  // edm::Handle<edm::View<Y> > inputView2;
137  // event.getByToken(inputToken2V_, inputView2);
138  // // If you are certain the Views are not empty!
139  // std::auto_ptr<AssocOneToOneView> assoc8(new AssocOneToOneView(
140  // edm::makeRefToBaseProdFrom(inputView1->refAt(0), event),
141  // edm::makeRefToBaseProdFrom(inputView2->refAt(0), event)
142  // ));
143 
144  template<typename... Args>
145  AssociationMap(Args... args) : ref_(std::forward<Args>(args)...) {}
146 #endif
147 
149  void clear() { map_.clear(); transientMap_.clear(); }
151  size_type size() const { return map_.size(); }
153  bool empty() const { return map_.empty(); }
155  void insert(const key_type & k, const data_type & v) {
156  Tag::insert(ref_, map_, k, v);
157  }
158  void insert(const value_type & kv) {
159  Tag::insert(ref_, map_, kv.key, kv.val);
160  }
162  const_iterator begin() const { return const_iterator(this, map_.begin()); }
164  const_iterator end() const { return const_iterator(this, map_.end()); }
166  const_iterator find(const key_type & k) const {
167  if (ref_.key.id() != k.id()) return end();
168  return find(k.key());
169  }
172  index_type i = k.key();
173  transientMap_.unsafe_erase(i);
174  return map_.erase(i);
175  }
177  const result_type & operator[](const key_type & k) const {
178  helpers::checkRef(ref_.key, k);
179  return get(k.key()).val;
180  }
181 
182  template<typename K>
183  const result_type& operator[](const K& k) const {
184  helpers::checkRef(ref_.key,k);
185  return get(k.key()).val;
186  }
187 
190  if (ref_.key.id() != k.id()) return 0;
191  typename map_type::const_iterator f = map_.find(k.key());
192  if (f == map_.end()) return 0;
193  return Tag::size(f->second);
194  }
195 
196  template<typename K>
197  size_type numberOfAssociations(const K & k) const {
198  if (ref_.key.id() != k.id()) return 0;
199  typename map_type::const_iterator f = map_.find(k.key());
200  if (f == map_.end()) return 0;
201  return Tag::size(f->second);
202  }
203 
205  const ref_type & refProd() const { return ref_; }
206 
209  typename Tag::transient_map_type map() {
210  return Tag::transientMap( ref_, map_ );
211  }
214  typename Tag::transient_key_vector keys() {
215  return Tag::transientKeyVector( ref_, map_ );
216  }
219  typename Tag::transient_val_vector values() {
220  return Tag::transientValVector( ref_, map_ );
221  }
224 
225  // Find should be private! However, generated reflex dictionaries do not compile
226  // if Find is private.
228  struct Find :
229  public std::binary_function<const self&, size_type, const value_type *> {
230  typedef Find self;
231  const value_type * operator()(typename self::first_argument_type c,
232  typename self::second_argument_type i) {
233  return &(*c.find(i));
234  }
235  };
236 
237  //Used by ROOT storage
239 
240  private:
249  typename map_type::const_iterator f = map_.find(i);
250  if (f == map_.end()) return end();
251  return const_iterator(this, f);
252  }
254  const value_type & get(size_type i) const {
255  typename internal_transient_map_type::const_iterator tf = transientMap_.find(i);
256  if (tf == transientMap_.end()) {
257  typename map_type::const_iterator f = map_.find(i);
258  if (f == map_.end())
259  Exception::throwThis(edm::errors::InvalidReference, "can't find reference in AssociationMap at position ", i);
260  value_type v(key_type(ref_.key, i), Tag::val(ref_, f->second));
261  std::pair<typename internal_transient_map_type::const_iterator, bool> ins =
262  transientMap_.insert(std::make_pair(i, v));
263  return ins.first->second;
264  } else {
265  return tf->second;
266  }
267  }
268  friend struct const_iterator;
269  friend struct Find;
271  template<typename, typename, typename> friend class OneToValue;
272  template<typename, typename, typename> friend class OneToOne;
273  template<typename, typename, typename> friend class OneToMany;
274  template<typename, typename, typename, typename> friend class OneToManyWithQuality;
275  };
276 
277  namespace refhelper {
278  template<typename Tag>
280  typename AssociationMap<Tag>::value_type> {
282  };
283  }
284 
285 }
286 #endif
int i
Definition: DBlmapReader.cc:9
Tag::index_type index_type
index type
friend struct const_iterator
const_iterator end() const
last iterator over the map (read only)
const result_type & operator[](const K &k) const
internal_transient_map_type transientMap_
transient reference map
bool empty() const
return true if empty
const_iterator find(const key_type &k) const
find element with specified reference key
tbb::concurrent_unordered_map< index_type, value_type > internal_transient_map_type
transient map type
Tag::data_type data_type
insert data type
const value_type * operator->() const
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
key_type key() const
Accessor for product key.
Definition: Ref.h:264
ref_type ref_
reference set
#define CMS_CLASS_VERSION(_version_)
Definition: classes.h:31
uint16_t size_type
value_type::value_type result_type
type return by operator[]
ProductID id() const
Accessor for product ID.
Definition: Ref.h:258
size_type numberOfAssociations(const key_type &k) const
number of associations to a key
static void throwThis(Code category, char const *message0="", char const *message1="", char const *message2="", char const *message3="", char const *message4="")
size_type erase(const key_type &k)
erase the element whose key is k
bool operator!=(const const_iterator &ci) const
map_type::const_iterator i
const_iterator(const self *map, typename map_type::const_iterator mi)
const ref_type & refProd() const
return ref-prod structure
void post_insert()
post insert action
#define private
Definition: FWEveView.cc:22
tuple ins
Definition: cuy.py:312
double f[11][100]
bool insert(Storage &iStorage, ItemType *iItem, const IdTag &iIdTag)
Definition: HCMethods.h:49
Container::value_type value_type
Tag::transient_key_vector keys()
bool operator==(const const_iterator &ci) const
Tag::val_type internal_val_type
size_type size() const
map size
map_type map_
index map
void insert(const key_type &k, const data_type &v)
insert an association
AssociationMap(Args...args)
AssociationMap(EDProductGetter const *getter)
const value_type * operator()(typename self::first_argument_type c, typename self::second_argument_type i)
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)
AssociationMap()
default constructor
const_iterator begin() const
first iterator over the map (read only)
const result_type & operator[](const key_type &k) const
find element with specified reference key
void checkRef(const RP &rp, const R &r)
throw if r hasn&#39;t the same id as rp
friend struct Find
size_type numberOfAssociations(const K &k) const
tuple size
Write out results.
const value_type & get(size_type i) const
return value_typeelement with key i
Tag::transient_map_type map()
const value_type & operator*() const
map_type::size_type size_type
size type