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 "boost/shared_ptr.hpp"
15 
16 namespace edm {
17 
18  //------------------------------------------------------------
19 
20  template <class T> class LazyAdapter;
21  template <class T> class LazyGetter;
22  template <class T> class FindValue;
23 
24  //------------------------------------------------------------
25 
26  namespace lazydetail {
27  inline
28  void _throw_range(uint32_t region)
29  {
31  "LazyGetter::"
32  "find(uint32_t,uint32_t) called with index not in collection;\n"
33  "index value: ",
34  region);
35  }
36  }
37  //------------------------------------------------------------
38 
39  template<class T>
40  class RegionIndex {
41 
42  friend class LazyAdapter<T>;
43 
44  public:
45 
46  typedef typename std::vector<T>::const_iterator const_iterator;
47  typedef std::pair<const_iterator,const_iterator> pair_iterator;
48 
50  RegionIndex();
51 
53  RegionIndex(uint32_t region, uint32_t start, uint32_t finish, const LazyGetter<T>* theLazyGetter);
54 
56  uint32_t region() const;
57 
59  uint32_t start() const;
60 
62  uint32_t finish() const;
63 
65  bool unpacked() const;
66 
68  const_iterator begin() const;
69 
71  const_iterator end() const;
72 
74  RegionIndex<T>& updateLazyGetter(const LazyGetter<T>* newLazyGetter);
75 
77  pair_iterator find(uint32_t id) const;
78 
79  //Used by ROOT storage
81 
82  private:
83 
85  void start(uint32_t);
86 
88  void finish(uint32_t);
89 
91  void unpacked(bool);
92 
93  uint32_t region_;
94  uint32_t start_;
95  uint32_t finish_;
96  bool unpacked_;
98  };
99 
100  //------------------------------------------------------------
101 
102  template <class T>
103  inline
105  region_(0),
106  start_(0),
107  finish_(0),
108  unpacked_(false),
109  getter_(NULL)
110  {}
111 
112  template <class T>
113  inline
114  RegionIndex<T>::RegionIndex(uint32_t region, uint32_t start, uint32_t finish, const LazyGetter<T>* theLazyGetter) :
115  region_(region),
116  start_(start),
117  finish_(finish),
118  unpacked_(false),
119  getter_(theLazyGetter)
120  {}
121 
122  template <class T>
123  inline
124  uint32_t
126  {
127  return region_;
128  }
129 
130  template <class T>
131  inline
132  uint32_t
134  {
135  return start_;
136  }
137 
138  template <class T>
139  inline
140  uint32_t RegionIndex<T>::finish() const
141  {
142  return finish_;
143  }
144 
145  template <class T>
146  inline
147  bool
149  {
150  return unpacked_;
151  }
152 
153  template <class T>
154  inline
155  void
156  RegionIndex<T>::start(uint32_t newstart)
157  {
158  start_=newstart;
159  }
160 
161  template <class T>
162  inline
163  void
164  RegionIndex<T>::finish(uint32_t newfinish)
165  {
166  finish_=newfinish;
167  }
168 
169  template <class T>
170  inline
171  void
172  RegionIndex<T>::unpacked(bool newunpacked)
173  {
174  unpacked_=newunpacked;
175  }
176 
177  template <class T>
178  inline
181  {
182  //check pointer here and throw if null
183  return getter_->begin_record()+start_;
184  }
185 
186  template <class T>
187  inline
190  {
191  //check pointer here and throw if null
192  return getter_->begin_record()+finish_;
193  }
194 
195  template <class T>
196  inline
199  {
200  getter_ = newGetter;
201  return *this;
202  }
203 
204  template <class T>
205  inline
207  RegionIndex<T>::find(uint32_t id) const
208  {
209  return std::equal_range(begin(),end(),id);
210  }
211 
212  //------------------------------------------------------------
213 
214  template<typename T>
215  class LazyUnpacker {
216  public:
217  typedef std::vector<T> record_type;
218  virtual void fill(const uint32_t&, record_type&)=0;
219  virtual ~LazyUnpacker() {}
220  };
221 
222  //------------------------------------------------------------
223 
224  template<typename T>
225  class LazyAdapter : public std::unary_function<const RegionIndex<T>&, const RegionIndex<T>& > {
226  public:
227 
228  typedef std::vector<T> record_type;
229 
231  LazyAdapter(const LazyUnpacker<T>*,const record_type*, const LazyGetter<T>*);
232 
234  const RegionIndex<T>& operator()(const RegionIndex<T>& region) const;
235 
236  private:
240  };
241 
242  template <class T>
243  inline
244  LazyAdapter<T>::LazyAdapter(const LazyUnpacker<T>* iunpacker, const record_type* irecord, const LazyGetter<T>* getter) :
245  unpacker_(const_cast< LazyUnpacker<T>* >(iunpacker)),
246  record_(const_cast<record_type*>(irecord)),
247  getter_(getter) {}
248 
249  template <class T>
250  inline
251  const RegionIndex<T>&
253  {
254  RegionIndex<T>& indexref = const_cast< RegionIndex<T>& >(index);
255  if (!index.unpacked()) {
256  indexref.start(record_->size());
257  unpacker_->fill(index.region(),*record_);
258  indexref.unpacked(true);
259  indexref.finish(record_->size());
260  indexref.updateLazyGetter(getter_);
261  }
262  return index;
263  }
264 
265  //------------------------------------------------------------
266 
267  template<typename T> class UpdateGetterAdapter : public std::unary_function<const RegionIndex<T>&, const RegionIndex<T>& > {
268 
269  public:
270 
273 
275  const RegionIndex<T>& operator()(const RegionIndex<T>&) const;
276 
277  private:
278 
280  };
281 
282  template <class T>
283  inline
285  : getter_(getter) {}
286 
287  template <class T>
288  inline
289  const RegionIndex<T>&
291  {
292  RegionIndex<T>& indexref = const_cast< RegionIndex<T>& >(index);
293  indexref.updateLazyGetter(getter_);
294  return index;
295  }
296 
297  //------------------------------------------------------------
298 
299  template <class T>
300  class LazyGetter
301  {
302 
303  BOOST_CLASS_REQUIRE(T, boost, LessThanComparableConcept);
304 
305  public:
306 
307  typedef std::vector< RegionIndex<T> > register_type;
308  typedef std::vector<T> record_type;
309  typedef boost::transform_iterator< UpdateGetterAdapter<T>, typename register_type::const_iterator > register_iterator;
310  typedef typename record_type::const_iterator record_iterator;
311  typedef boost::transform_iterator< LazyAdapter<T>, typename register_type::const_iterator > const_iterator;
313 
315  LazyGetter();
316 
318  LazyGetter(uint32_t, const boost::shared_ptr< LazyUnpacker<T> >&);
319 
321  uint32_t regions() const;
322 
324  const_iterator find(uint32_t index) const;
325 
327  const RegionIndex<T>& operator[](uint32_t index) const;
328 
330  const_iterator begin() const;
331 
333  const_iterator end() const;
334 
337 
340 
343  bool unpacked(uint32_t) const;
344 
347 
349  record_iterator end_record() const;
350 
352  uint32_t size() const;
353 
355  bool empty() const;
356 
358  void swap(LazyGetter& other);
359 
360  //Used by ROOT storage
362 
363  private:
364 
365  boost::shared_ptr< LazyUnpacker<T> > unpacker_;
366  std::vector<T> record_;
367  std::vector< RegionIndex<T> > register_;
368  };
369 
370  template <class T>
371  inline
372  LazyGetter<T>::LazyGetter() : unpacker_(), record_(), register_()
373  {}
374 
375  template <class T>
376  inline
377  LazyGetter<T>::LazyGetter(uint32_t nregions,const boost::shared_ptr< LazyUnpacker<T> > & unpacker) : unpacker_(unpacker), record_(), register_()
378  {
379  //Reserve 100,000 to absorb event-by-event fluctuations.
380  record_.reserve(100000);
381  register_.reserve(nregions);
382  for (uint32_t iregion=0;iregion<nregions;iregion++) {
383  register_.push_back(RegionIndex<T>(iregion,0,0,this));
384  }
385  }
386 
387  template <class T>
388  inline
389  void
391  {
392  std::swap(unpacker_,other.unpacker_);
393  std::swap(record_,other.record_);
394  std::swap(register_,other.register_);
395  }
396 
397  template <class T>
398  inline
399  uint32_t
401  {
402  return register_.size();
403  }
404 
405  template <class T>
406  inline
408  LazyGetter<T>::find(uint32_t index) const
409  {
410  if (index>=regions()) return end();
411  typename register_type::const_iterator it = register_.begin()+index;
412  const LazyAdapter<T> adapter(unpacker_.get(),&record_,this);
413  return boost::make_transform_iterator(it,adapter);
414  }
415 
416  template <class T>
417  inline
418  const RegionIndex<T>&
420  {
421  if (index>=regions()) edm::lazydetail::_throw_range(index);
422  typename register_type::const_iterator it = register_.begin()+index;
423  const LazyAdapter<T> adapter(unpacker_.get(),&record_,this);
424  return *(boost::make_transform_iterator(it,adapter));
425  }
426 
427  template <class T>
428  inline
431  {
432  const LazyAdapter<T> adapter(unpacker_.get(),&record_,this);
433  return boost::make_transform_iterator(register_.begin(),adapter);
434  }
435 
436  template <class T>
437  inline
440  {
441  const LazyAdapter<T> adapter(unpacker_.get(),&record_,this);
442  return boost::make_transform_iterator(register_.end(),adapter);
443  }
444 
445  template <class T>
446  inline
449  {
450  const UpdateGetterAdapter<T> adapter(this);
451  return boost::make_transform_iterator(register_.begin(),adapter);
452  }
453 
454  template <class T>
455  inline
458  {
459  const UpdateGetterAdapter<T> adapter(this);
460  return boost::make_transform_iterator(register_.end(),adapter);
461  }
462 
463  template <class T>
464  inline
465  bool
467  {
468  return (index<regions()) ? register_[index].unpacked() : false;
469  }
470 
471  template <class T>
472  inline
475  {
476  return record_.begin();
477  }
478 
479  template <class T>
480  inline
483  {
484  return record_.end();
485  }
486 
487  template <class T>
488  inline
489  uint32_t
491  {
492  return record_.size();
493  }
494 
495  template <class T>
496  inline
497  bool
499  {
500  return record_.empty();
501  }
502 
503  template <class T>
504  inline
505  void
507  {
508  a.swap(b);
509  }
510 
511  //------------------------------------------------------------
512 
513 
514  //------------------------------------------------------------
515 
516  template<typename T> struct FindRegion : public std::binary_function< const LazyGetter<T>&, const uint32_t, const RegionIndex<T>* > {
518  //return &(const_cast< RegionIndex<T>& >(*(const_cast< LazyGetter<T>& >(iContainer).begin()+iIndex)).updateLazyGetter(&iContainer));
519  return &(const_cast< RegionIndex<T>& >(*(const_cast< LazyGetter<T>& >(iContainer).begin()+iIndex)));
520  }
521  };
522 
523  //------------------------------------------------------------
524 
525  template<typename T> struct FindValue : public std::binary_function< const LazyGetter<T>&, const uint32_t, const T* > {
526  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);}
527  };
528 
529  //------------------------------------------------------------
530 
531  template<typename T> Ref< LazyGetter<T>, T, FindValue<T> >
533 
534  //------------------------------------------------------------
535 
536 }
538 
539 namespace edm {
540  template<typename T>
541  class ContainerMaskTraits<edm::LazyGetter<T> > {
542  public:
543  typedef T value_type;
544 
545  static size_t size(const edm::LazyGetter<T>* iContainer) { return iContainer->size();}
546  static unsigned int indexFor(const value_type* iElement, const edm::LazyGetter<T>* iContainer) {
547  return iElement-&(*(iContainer->begin_record()));
548  }
549  };
550 }
551 
552 
553 #endif
554 
555 
556 
uint32_t regions() const
Returns the size of LazyUnpacker::register_.
Definition: LazyGetter.h:400
LazyGetter()
Default constructor.
Definition: LazyGetter.h:372
RegionIndex()
Default constructor.
Definition: LazyGetter.h:104
register_iterator end_nounpack() const
Returns the off-the-end iter.
Definition: LazyGetter.h:457
UpdateGetterAdapter(const LazyGetter< T > *)
Constructor.
Definition: LazyGetter.h:284
virtual ~LazyUnpacker()
Definition: LazyGetter.h:219
bool empty() const
Returns true if record_ is empty.
Definition: LazyGetter.h:498
record_iterator end_record() const
Returns an off-the-end iterator.
Definition: LazyGetter.h:482
const LazyGetter< T > * getter_
Definition: LazyGetter.h:279
std::vector< T > record_type
Definition: LazyGetter.h:308
FindValue< T >::result_type operator()(typename FindValue< T >::first_argument_type container, typename FindValue< T >::second_argument_type index) const
Definition: LazyGetter.h:526
boost::shared_ptr< LazyUnpacker< T > > unpacker_
Definition: LazyGetter.h:365
const_iterator end() const
Get off the end iterator.
Definition: LazyGetter.h:189
RegionIndex< T > & updateLazyGetter(const LazyGetter< T > *newLazyGetter)
Update the pointer to the lazyGetter.
Definition: LazyGetter.h:198
#define NULL
Definition: scimark2.h:8
record_iterator begin_record() const
Returns an iterator to the start of record_.
Definition: LazyGetter.h:474
uint32_t finish_
Definition: LazyGetter.h:95
LazyUnpacker< T > * unpacker_
Definition: LazyGetter.h:237
#define CMS_CLASS_VERSION(_version_)
uint32_t region_
Definition: LazyGetter.h:93
bool unpacked(uint32_t) const
Definition: LazyGetter.h:466
void swap(Association< C > &lhs, Association< C > &rhs)
Definition: Association.h:117
const_iterator end() const
Returns the off-the-end iterator.
Definition: LazyGetter.h:439
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:310
std::vector< RegionIndex< T > > register_
Definition: LazyGetter.h:367
pair_iterator find(uint32_t id) const
Get range of T on on det.
Definition: LazyGetter.h:207
std::vector< T > record_type
Definition: LazyGetter.h:217
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
void _throw_range(uint32_t region)
Definition: LazyGetter.h:28
const_iterator find(uint32_t index) const
Returns an iterator to the register_ for a given index.
Definition: LazyGetter.h:408
std::vector< T > record_type
Definition: LazyGetter.h:228
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:532
uint32_t finish() const
Get off-the-end finish index.
Definition: LazyGetter.h:140
#define end
Definition: vmac.h:38
const LazyGetter< T > * getter_
Definition: LazyGetter.h:97
Ref< LazyGetter< T >, T, FindValue< T > > value_ref
Definition: LazyGetter.h:312
static unsigned int indexFor(const value_type *iElement, const edm::LazyGetter< T > *iContainer)
Definition: LazyGetter.h:546
const_iterator begin() const
Get begin iterator.
Definition: LazyGetter.h:180
std::pair< const_iterator, const_iterator > pair_iterator
Definition: LazyGetter.h:47
const RegionIndex< T > & operator[](uint32_t index) const
Returns a reference to the register_ for a given index.
Definition: LazyGetter.h:419
register_iterator begin_nounpack() const
Returns an iterator to the start of the register_ without unpacking.
Definition: LazyGetter.h:448
std::vector< T >::const_iterator const_iterator
Definition: LazyGetter.h:46
uint32_t start_
Definition: LazyGetter.h:94
const RegionIndex< T > & operator()(const RegionIndex< T > &region) const
() operator for construction of iterator
Definition: LazyGetter.h:252
FindRegion< T >::result_type operator()(typename FindRegion< T >::first_argument_type iContainer, typename FindRegion< T >::second_argument_type iIndex)
Definition: LazyGetter.h:517
uint32_t size() const
Returns the size of the record_.
Definition: LazyGetter.h:490
double b
Definition: hdecay.h:120
uint32_t region() const
Get region number.
Definition: LazyGetter.h:125
string const
Definition: compareJSON.py:14
std::vector< RegionIndex< T > > register_type
Definition: LazyGetter.h:307
void swap(LazyGetter &other)
Swap contents of class.
Definition: LazyGetter.h:390
#define private
Definition: FWFileEntry.h:18
record_type * record_
Definition: LazyGetter.h:238
uint32_t start() const
Get start index.
Definition: LazyGetter.h:133
#define begin
Definition: vmac.h:31
double a
Definition: hdecay.h:121
const RegionIndex< T > & operator()(const RegionIndex< T > &) const
() operator for construction of iterator
Definition: LazyGetter.h:290
std::vector< T > record_
Definition: LazyGetter.h:366
boost::transform_iterator< UpdateGetterAdapter< T >, typename register_type::const_iterator > register_iterator
Definition: LazyGetter.h:309
bool unpacked() const
Get unpacking status.
Definition: LazyGetter.h:148
const LazyGetter< T > * getter_
Definition: LazyGetter.h:239
static size_t size(const edm::LazyGetter< T > *iContainer)
Definition: LazyGetter.h:545
long double T
boost::transform_iterator< LazyAdapter< T >, typename register_type::const_iterator > const_iterator
Definition: LazyGetter.h:311
BOOST_CLASS_REQUIRE(T, boost, LessThanComparableConcept)
LazyAdapter(const LazyUnpacker< T > *, const record_type *, const LazyGetter< T > *)
Constructor.
Definition: LazyGetter.h:244
def template
Definition: svgfig.py:520
const_iterator begin() const
Returns an iterator to the first register_.
Definition: LazyGetter.h:430