CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
LazyGetter.h
Go to the documentation of this file.
1 #ifndef DataFormats_Common_LazyGetter_h
2 #define DataFormats_Common_LazyGetter_h
3 
4 #include <algorithm>
5 #include <vector>
6 #include "boost/concept_check.hpp"
7 #include "boost/iterator/transform_iterator.hpp"
8 #include <memory>
15 
16 namespace edm {
17 
18  class Event;
19 
20  //------------------------------------------------------------
21 
22  template <class T> class LazyAdapter;
23  template <class T> class LazyGetter;
24  template <class T> class FindValue;
25 
26  //------------------------------------------------------------
27 
28  namespace lazydetail {
29  inline
30  void _throw_range(uint32_t region)
31  {
33  "LazyGetter::"
34  "find(uint32_t,uint32_t) called with index not in collection;\n"
35  "index value: ",
36  region);
37  }
38  }
39  //------------------------------------------------------------
40 
41  template<class T>
42  class RegionIndex {
43 
44  friend class LazyAdapter<T>;
45 
46  public:
47 
48  typedef typename std::vector<T>::const_iterator const_iterator;
49  typedef std::pair<const_iterator,const_iterator> pair_iterator;
50 
52  RegionIndex();
53 
55  RegionIndex(uint32_t region, uint32_t start, uint32_t finish, const LazyGetter<T>* theLazyGetter);
56 
58  uint32_t region() const;
59 
61  uint32_t start() const;
62 
64  uint32_t finish() const;
65 
67  bool unpacked() const;
68 
70  const_iterator begin() const;
71 
73  const_iterator end() const;
74 
76  RegionIndex<T>& updateLazyGetter(const LazyGetter<T>* newLazyGetter);
77 
79  pair_iterator find(uint32_t id) const;
80 
81  //Used by ROOT storage
83 
84  private:
85 
87  void start(uint32_t);
88 
90  void finish(uint32_t);
91 
93  void unpacked(bool);
94 
95  uint32_t region_;
96  uint32_t start_;
97  uint32_t finish_;
98  bool unpacked_;
100  };
101 
102  //------------------------------------------------------------
103 
104  template <class T>
105  inline
107  region_(0),
108  start_(0),
109  finish_(0),
110  unpacked_(false),
111  getter_(NULL)
112  {}
113 
114  template <class T>
115  inline
116  RegionIndex<T>::RegionIndex(uint32_t region, uint32_t start, uint32_t finish, const LazyGetter<T>* theLazyGetter) :
117  region_(region),
118  start_(start),
119  finish_(finish),
120  unpacked_(false),
121  getter_(theLazyGetter)
122  {}
123 
124  template <class T>
125  inline
126  uint32_t
128  {
129  return region_;
130  }
131 
132  template <class T>
133  inline
134  uint32_t
136  {
137  return start_;
138  }
139 
140  template <class T>
141  inline
142  uint32_t RegionIndex<T>::finish() const
143  {
144  return finish_;
145  }
146 
147  template <class T>
148  inline
149  bool
151  {
152  return unpacked_;
153  }
154 
155  template <class T>
156  inline
157  void
158  RegionIndex<T>::start(uint32_t newstart)
159  {
160  start_=newstart;
161  }
162 
163  template <class T>
164  inline
165  void
166  RegionIndex<T>::finish(uint32_t newfinish)
167  {
168  finish_=newfinish;
169  }
170 
171  template <class T>
172  inline
173  void
174  RegionIndex<T>::unpacked(bool newunpacked)
175  {
176  unpacked_=newunpacked;
177  }
178 
179  template <class T>
180  inline
183  {
184  //check pointer here and throw if null
185  return getter_->begin_record()+start_;
186  }
187 
188  template <class T>
189  inline
192  {
193  //check pointer here and throw if null
194  return getter_->begin_record()+finish_;
195  }
196 
197  template <class T>
198  inline
201  {
202  getter_ = newGetter;
203  return *this;
204  }
205 
206  template <class T>
207  inline
209  RegionIndex<T>::find(uint32_t id) const
210  {
211  return std::equal_range(begin(),end(),id);
212  }
213 
214  //------------------------------------------------------------
215 
216  template<typename T>
217  class LazyUnpacker {
218  public:
219  typedef std::vector<T> record_type;
220  virtual void fill(const uint32_t&, record_type&)=0;
221  virtual ~LazyUnpacker() {}
222  // This a temporary fix for the bug caused by the bad design
223  // in EcalUnpackerWorker (used through derived class
224  // EcalToRecHitLazyUnpacker) and should be removed as soon
225  // as no longer necessary. Do not use this for anything else.
226  virtual void setEvent(edm::Event const& e) const {};
227  };
228 
229  //------------------------------------------------------------
230 
231  template<typename T>
232  class LazyAdapter : public std::unary_function<const RegionIndex<T>&, const RegionIndex<T>& > {
233  public:
234 
235  typedef std::vector<T> record_type;
236 
238  LazyAdapter(const LazyUnpacker<T>*,const record_type*, const LazyGetter<T>*);
239 
241  const RegionIndex<T>& operator()(const RegionIndex<T>& region) const;
242 
243  private:
247  };
248 
249  template <class T>
250  inline
251  LazyAdapter<T>::LazyAdapter(const LazyUnpacker<T>* iunpacker, const record_type* irecord, const LazyGetter<T>* getter) :
252  unpacker_(const_cast< LazyUnpacker<T>* >(iunpacker)),
253  record_(const_cast<record_type*>(irecord)),
254  getter_(getter) {}
255 
256  template <class T>
257  inline
258  const RegionIndex<T>&
260  {
261  RegionIndex<T>& indexref = const_cast< RegionIndex<T>& >(index);
262  if (!index.unpacked()) {
263  indexref.start(record_->size());
264  unpacker_->fill(index.region(),*record_);
265  indexref.unpacked(true);
266  indexref.finish(record_->size());
267  indexref.updateLazyGetter(getter_);
268  }
269  return index;
270  }
271 
272  //------------------------------------------------------------
273 
274  template<typename T> class UpdateGetterAdapter : public std::unary_function<const RegionIndex<T>&, const RegionIndex<T>& > {
275 
276  public:
277 
280 
282  const RegionIndex<T>& operator()(const RegionIndex<T>&) const;
283 
284  private:
285 
287  };
288 
289  template <class T>
290  inline
292  : getter_(getter) {}
293 
294  template <class T>
295  inline
296  const RegionIndex<T>&
298  {
299  RegionIndex<T>& indexref = const_cast< RegionIndex<T>& >(index);
300  indexref.updateLazyGetter(getter_);
301  return index;
302  }
303 
304  //------------------------------------------------------------
305 
306  template <class T>
307  class LazyGetter
308  {
309 
310  BOOST_CLASS_REQUIRE(T, boost, LessThanComparableConcept);
311 
312  public:
313 
314  typedef std::vector< RegionIndex<T> > register_type;
315  typedef std::vector<T> record_type;
316  typedef boost::transform_iterator< UpdateGetterAdapter<T>, typename register_type::const_iterator > register_iterator;
317  typedef typename record_type::const_iterator record_iterator;
318  typedef boost::transform_iterator< LazyAdapter<T>, typename register_type::const_iterator > const_iterator;
320 
322  LazyGetter();
323 
325  LazyGetter(uint32_t, const std::shared_ptr< LazyUnpacker<T> >&);
326 
328  uint32_t regions() const;
329 
331  const_iterator find(uint32_t index) const;
332 
334  const RegionIndex<T>& operator[](uint32_t index) const;
335 
337  const_iterator begin() const;
338 
340  const_iterator end() const;
341 
344 
347 
350  bool unpacked(uint32_t) const;
351 
354 
356  record_iterator end_record() const;
357 
359  uint32_t size() const;
360 
362  bool empty() const;
363 
365  void swap(LazyGetter& other);
366 
367  // This a temporary fix for the bug caused by the bad design
368  // in EcalUnpackerWorker (used through derived class
369  // EcalToRecHitLazyUnpacker) and should be removed as soon
370  // as no longer necessary. Do not use this for anything else.
371  void setEvent(Event const& e) const { unpacker_->setEvent(e); }
372 
373  //Used by ROOT storage
375 
376  private:
377 
378  std::shared_ptr< LazyUnpacker<T> > unpacker_;
379  std::vector<T> record_;
380  std::vector< RegionIndex<T> > register_;
381  };
382 
383  template <class T>
384  inline
385  LazyGetter<T>::LazyGetter() : unpacker_(), record_(), register_()
386  {}
387 
388  template <class T>
389  inline
390  LazyGetter<T>::LazyGetter(uint32_t nregions,const std::shared_ptr< LazyUnpacker<T> > & unpacker) : unpacker_(unpacker), record_(), register_()
391  {
392  //Reserve 100,000 to absorb event-by-event fluctuations.
393  record_.reserve(100000);
394  register_.reserve(nregions);
395  for (uint32_t iregion=0;iregion<nregions;iregion++) {
396  register_.push_back(RegionIndex<T>(iregion,0,0,this));
397  }
398  }
399 
400  template <class T>
401  inline
402  void
404  {
405  std::swap(unpacker_,other.unpacker_);
406  std::swap(record_,other.record_);
407  std::swap(register_,other.register_);
408  }
409 
410  template <class T>
411  inline
412  uint32_t
414  {
415  return register_.size();
416  }
417 
418  template <class T>
419  inline
421  LazyGetter<T>::find(uint32_t index) const
422  {
423  if (index>=regions()) return end();
424  typename register_type::const_iterator it = register_.begin()+index;
425  const LazyAdapter<T> adapter(unpacker_.get(),&record_,this);
426  return boost::make_transform_iterator(it,adapter);
427  }
428 
429  template <class T>
430  inline
431  const RegionIndex<T>&
433  {
434  if (index>=regions()) edm::lazydetail::_throw_range(index);
435  typename register_type::const_iterator it = register_.begin()+index;
436  const LazyAdapter<T> adapter(unpacker_.get(),&record_,this);
437  return *(boost::make_transform_iterator(it,adapter));
438  }
439 
440  template <class T>
441  inline
444  {
445  const LazyAdapter<T> adapter(unpacker_.get(),&record_,this);
446  return boost::make_transform_iterator(register_.begin(),adapter);
447  }
448 
449  template <class T>
450  inline
453  {
454  const LazyAdapter<T> adapter(unpacker_.get(),&record_,this);
455  return boost::make_transform_iterator(register_.end(),adapter);
456  }
457 
458  template <class T>
459  inline
462  {
463  const UpdateGetterAdapter<T> adapter(this);
464  return boost::make_transform_iterator(register_.begin(),adapter);
465  }
466 
467  template <class T>
468  inline
471  {
472  const UpdateGetterAdapter<T> adapter(this);
473  return boost::make_transform_iterator(register_.end(),adapter);
474  }
475 
476  template <class T>
477  inline
478  bool
480  {
481  return (index<regions()) ? register_[index].unpacked() : false;
482  }
483 
484  template <class T>
485  inline
488  {
489  return record_.begin();
490  }
491 
492  template <class T>
493  inline
496  {
497  return record_.end();
498  }
499 
500  template <class T>
501  inline
502  uint32_t
504  {
505  return record_.size();
506  }
507 
508  template <class T>
509  inline
510  bool
512  {
513  return record_.empty();
514  }
515 
516  template <class T>
517  inline
518  void
520  {
521  a.swap(b);
522  }
523 
524  //------------------------------------------------------------
525 
526 
527  //------------------------------------------------------------
528 
529  template<typename T> struct FindRegion : public std::binary_function< const LazyGetter<T>&, const uint32_t, const RegionIndex<T>* > {
531  //return &(const_cast< RegionIndex<T>& >(*(const_cast< LazyGetter<T>& >(iContainer).begin()+iIndex)).updateLazyGetter(&iContainer));
532  return &(const_cast< RegionIndex<T>& >(*(const_cast< LazyGetter<T>& >(iContainer).begin()+iIndex)));
533  }
534  };
535 
536  //------------------------------------------------------------
537 
538  template<typename T> struct FindValue : public std::binary_function< const LazyGetter<T>&, const uint32_t, const T* > {
539  typename FindValue<T>::result_type operator()(typename FindValue<T>::first_argument_type container, typename FindValue<T>::second_argument_type index) const {return &*(container.begin_record()+index);}
540  };
541 
542  //------------------------------------------------------------
543 
544  template<typename T> Ref< LazyGetter<T>, T, FindValue<T> >
546 
547  //------------------------------------------------------------
548 
549 }
551 
552 namespace edm {
553  template<typename T>
554  class ContainerMaskTraits<edm::LazyGetter<T> > {
555  public:
556  typedef T value_type;
557 
558  static size_t size(const edm::LazyGetter<T>* iContainer) { return iContainer->size();}
559  static unsigned int indexFor(const value_type* iElement, const edm::LazyGetter<T>* iContainer) {
560  return iElement-&(*(iContainer->begin_record()));
561  }
562  };
563 }
564 
565 
566 #endif
567 
568 
569 
uint32_t regions() const
Returns the size of LazyUnpacker::register_.
Definition: LazyGetter.h:413
LazyGetter()
Default constructor.
Definition: LazyGetter.h:385
RegionIndex()
Default constructor.
Definition: LazyGetter.h:106
register_iterator end_nounpack() const
Returns the off-the-end iter.
Definition: LazyGetter.h:470
UpdateGetterAdapter(const LazyGetter< T > *)
Constructor.
Definition: LazyGetter.h:291
virtual ~LazyUnpacker()
Definition: LazyGetter.h:221
bool empty() const
Returns true if record_ is empty.
Definition: LazyGetter.h:511
record_iterator end_record() const
Returns an off-the-end iterator.
Definition: LazyGetter.h:495
const LazyGetter< T > * getter_
Definition: LazyGetter.h:286
std::vector< T > record_type
Definition: LazyGetter.h:315
FindValue< T >::result_type operator()(typename FindValue< T >::first_argument_type container, typename FindValue< T >::second_argument_type index) const
Definition: LazyGetter.h:539
std::shared_ptr< LazyUnpacker< T > > unpacker_
Definition: LazyGetter.h:378
const_iterator end() const
Get off the end iterator.
Definition: LazyGetter.h:191
RegionIndex< T > & updateLazyGetter(const LazyGetter< T > *newLazyGetter)
Update the pointer to the lazyGetter.
Definition: LazyGetter.h:200
#define NULL
Definition: scimark2.h:8
record_iterator begin_record() const
Returns an iterator to the start of record_.
Definition: LazyGetter.h:487
uint32_t finish_
Definition: LazyGetter.h:97
LazyUnpacker< T > * unpacker_
Definition: LazyGetter.h:244
#define CMS_CLASS_VERSION(_version_)
Definition: classes.h:31
uint32_t region_
Definition: LazyGetter.h:95
bool unpacked(uint32_t) const
Definition: LazyGetter.h:479
void swap(Association< C > &lhs, Association< C > &rhs)
Definition: Association.h:116
const_iterator end() const
Returns the off-the-end iterator.
Definition: LazyGetter.h:452
static void throwThis(Code category, char const *message0="", char const *message1="", char const *message2="", char const *message3="", char const *message4="")
virtual void fill(const uint32_t &, record_type &)=0
record_type::const_iterator record_iterator
Definition: LazyGetter.h:317
std::vector< RegionIndex< T > > register_
Definition: LazyGetter.h:380
void setEvent(Event const &e) const
Definition: LazyGetter.h:371
pair_iterator find(uint32_t id) const
Get range of T on on det.
Definition: LazyGetter.h:209
std::vector< T > record_type
Definition: LazyGetter.h:219
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
void _throw_range(uint32_t region)
Definition: LazyGetter.h:30
const_iterator find(uint32_t index) const
Returns an iterator to the register_ for a given index.
Definition: LazyGetter.h:421
std::vector< T > record_type
Definition: LazyGetter.h:235
tuple handle
Definition: patZpeak.py:22
Ref< LazyGetter< T >, T, FindValue< T > > makeRefToLazyGetter(const Handle< LazyGetter< T > > &handle, const uint32_t index)
Definition: LazyGetter.h:545
uint32_t finish() const
Get off-the-end finish index.
Definition: LazyGetter.h:142
#define end
Definition: vmac.h:37
const LazyGetter< T > * getter_
Definition: LazyGetter.h:99
Ref< LazyGetter< T >, T, FindValue< T > > value_ref
Definition: LazyGetter.h:319
static unsigned int indexFor(const value_type *iElement, const edm::LazyGetter< T > *iContainer)
Definition: LazyGetter.h:559
const_iterator begin() const
Get begin iterator.
Definition: LazyGetter.h:182
std::pair< const_iterator, const_iterator > pair_iterator
Definition: LazyGetter.h:49
const RegionIndex< T > & operator[](uint32_t index) const
Returns a reference to the register_ for a given index.
Definition: LazyGetter.h:432
register_iterator begin_nounpack() const
Returns an iterator to the start of the register_ without unpacking.
Definition: LazyGetter.h:461
std::vector< T >::const_iterator const_iterator
Definition: LazyGetter.h:48
uint32_t start_
Definition: LazyGetter.h:96
const RegionIndex< T > & operator()(const RegionIndex< T > &region) const
() operator for construction of iterator
Definition: LazyGetter.h:259
FindRegion< T >::result_type operator()(typename FindRegion< T >::first_argument_type iContainer, typename FindRegion< T >::second_argument_type iIndex)
Definition: LazyGetter.h:530
uint32_t size() const
Returns the size of the record_.
Definition: LazyGetter.h:503
double b
Definition: hdecay.h:120
uint32_t region() const
Get region number.
Definition: LazyGetter.h:127
string const
Definition: compareJSON.py:14
std::vector< RegionIndex< T > > register_type
Definition: LazyGetter.h:314
void swap(LazyGetter &other)
Swap contents of class.
Definition: LazyGetter.h:403
#define private
Definition: FWFileEntry.h:17
record_type * record_
Definition: LazyGetter.h:245
uint32_t start() const
Get start index.
Definition: LazyGetter.h:135
#define begin
Definition: vmac.h:30
double a
Definition: hdecay.h:121
const RegionIndex< T > & operator()(const RegionIndex< T > &) const
() operator for construction of iterator
Definition: LazyGetter.h:297
std::vector< T > record_
Definition: LazyGetter.h:379
virtual void setEvent(edm::Event const &e) const
Definition: LazyGetter.h:226
volatile std::atomic< bool > shutdown_flag false
boost::transform_iterator< UpdateGetterAdapter< T >, typename register_type::const_iterator > register_iterator
Definition: LazyGetter.h:316
bool unpacked() const
Get unpacking status.
Definition: LazyGetter.h:150
const LazyGetter< T > * getter_
Definition: LazyGetter.h:246
static size_t size(const edm::LazyGetter< T > *iContainer)
Definition: LazyGetter.h:558
long double T
boost::transform_iterator< LazyAdapter< T >, typename register_type::const_iterator > const_iterator
Definition: LazyGetter.h:318
BOOST_CLASS_REQUIRE(T, boost, LessThanComparableConcept)
LazyAdapter(const LazyUnpacker< T > *, const record_type *, const LazyGetter< T > *)
Constructor.
Definition: LazyGetter.h:251
def template
Definition: svgfig.py:520
const_iterator begin() const
Returns an iterator to the first register_.
Definition: LazyGetter.h:443