CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
DetSetVectorNew.h
Go to the documentation of this file.
1 #ifndef DataFormats_Common_DetSetVectorNew_h
2 #define DataFormats_Common_DetSetVectorNew_h
3 
5 // #include "DataFormats/Common/interface/DetSet.h" // to get det_id_type
8 
9 #include <boost/iterator_adaptors.hpp>
10 #include <boost/iterator/transform_iterator.hpp>
11 #include <boost/iterator/counting_iterator.hpp>
12 #include <boost/any.hpp>
13 #include <memory>
16 
17 
18 #include<vector>
19 #include <cassert>
20 
21 class TestDetSet;
22 
23 namespace edm { namespace refhelper { template<typename T> struct FindForNewDetSetVector; } }
24 
25 //FIXME remove New when ready
26 namespace edmNew {
27  typedef uint32_t det_id_type;
28 
29  struct CapacityExaustedException : public cms::Exception { CapacityExaustedException(): cms::Exception("Capacity exausted in DetSetVectorNew"){} };
30 
31  namespace dslv {
32  template< typename T> class LazyGetter;
33  }
34 
35  /* transient component of DetSetVector
36  * for pure conviniency of dictioanary declaration
37  */
38  namespace dstvdetails {
41  bool filling;
43 
44 
45  void swap(DetSetVectorTrans& rh) {
48  }
49 
50  typedef unsigned int size_type; // for persistency
51  typedef unsigned int id_type;
52 
53  struct Item {
54  Item(id_type i=0, int io=-1, size_type is=0) : id(i), offset(io), size(is){}
55  bool isValid() const { return offset>=0;}
57  int offset;
59  bool operator<(Item const &rh) const { return id<rh.id;}
60  operator id_type() const { return id;}
61  };
62 
63  };
64 
65  void errorFilling();
66  void errorIdExists(det_id_type iid);
67  void throw_range(det_id_type iid);
69 
70 
71  }
72 
83  template<typename T>
84  class DetSetVector : private dstvdetails::DetSetVectorTrans {
85  public:
87  typedef Trans::Item Item;
88  typedef unsigned int size_type; // for persistency
89  typedef unsigned int id_type;
90  typedef T data_type;
94  // FIXME not sure make sense....
95  typedef DetSet value_type;
96  typedef id_type key_type;
97 
98 
99  typedef std::vector<Item> IdContainer;
100  typedef std::vector<data_type> DataContainer;
101  typedef typename IdContainer::iterator IdIter;
102  typedef typename std::vector<data_type>::iterator DataIter;
103  typedef std::pair<IdIter,DataIter> IterPair;
104  typedef typename IdContainer::const_iterator const_IdIter;
105  typedef typename std::vector<data_type>::const_iterator const_DataIter;
106  typedef std::pair<const_IdIter,const_DataIter> const_IterPair;
107 
109 
110  struct IterHelp {
112  // IterHelp() : v(0),update(true){}
113  IterHelp() : v(0),update(false){}
114  IterHelp(DetSetVector<T> const & iv, bool iup) : v(&iv), update(iup){}
115 
116  result_type & operator()(Item const& item) const {
117  detset.set(*v,item,update);
118  return detset;
119  }
120  private:
123  bool update;
124  };
125 
126  typedef boost::transform_iterator<IterHelp,const_IdIter> const_iterator;
127  typedef std::pair<const_iterator,const_iterator> Range;
128 
129  /* fill the lastest inserted DetSet
130  */
131  class FastFiller {
132  public:
137 
138  FastFiller(DetSetVector<T> & iv, id_type id, bool isaveEmpty=false) :
139  v(iv), item(v.push_back(id)), saveEmpty(isaveEmpty) {
140  if (v.filling) dstvdetails::errorFilling();
141  v.filling=true;
142  }
143  FastFiller(DetSetVector<T> & iv, typename DetSetVector<T>::Item & it, bool isaveEmpty=false) :
144  v(iv), item(it), saveEmpty(isaveEmpty) {
145  if (v.filling) dstvdetails::errorFilling();
146  v.filling=true;
147  }
149  if (!saveEmpty && item.size==0) {
150  v.pop_back(item.id);
151  }
152  v.filling=false;
153  }
154 
155  void abort() {
156  v.pop_back(item.id);
157  saveEmpty=true; // avoid mess in destructor
158  }
159 
160  void checkCapacityExausted() const {
161  if (v.onDemand() && v.m_data.size()==v.m_data.capacity()) dstvdetails::throwCapacityExausted();
162  }
163 
165  if (v.onDemand() && v.m_data.size()+s>v.m_data.capacity()) dstvdetails::throwCapacityExausted();
166  }
167 
168 
170  if (item.offset+s <= v.m_data.capacity()) return;
171  if (v.onDemand()) dstvdetails::throwCapacityExausted();
172  v.m_data.reserve(item.offset+s);
173  }
174 
175 
178  v.m_data.resize(item.offset+s);
179  item.size=s;
180  }
181 
182  id_type id() const { return item.id;}
183  size_type size() const { return item.size;}
184  bool empty() const { return item.size==0;}
185 
187  return v.m_data[item.offset+i];
188  }
189  DataIter begin() { return v.m_data.begin()+ item.offset;}
190  DataIter end() { return v.m_data.end();}
191 
192  void push_back(data_type const & d) {
194  v.m_data.push_back(d);
195  item.size++;
196  }
197 #ifndef CMS_NOCXX11
198  void push_back(data_type && d) {
200  v.m_data.push_back(std::move(d));
201  item.size++;
202  }
203 #endif
204 
205  data_type & back() { return v.m_data.back();}
206 
207  private:
208  //for testing
209  friend class ::TestDetSet;
210 
213  bool saveEmpty;
214  };
215  friend class FastFiller;
216 
217  class FindForDetSetVector : public std::binary_function<const edmNew::DetSetVector<T>&, unsigned int, const T*> {
218  public:
219  typedef FindForDetSetVector self;
220  typename self::result_type operator()(typename self::first_argument_type iContainer, typename self::second_argument_type iIndex) {
221  return &(iContainer.m_data[iIndex]);
222  }
223  };
224  friend class FindForDetSetVector;
225 
226  explicit DetSetVector(int isubdet=0) :
227  m_subdetId(isubdet) {}
228 
229  DetSetVector(std::shared_ptr<dslv::LazyGetter<T> > iGetter, const std::vector<det_id_type>& iDets,
230  int isubdet=0);
231 
232 
234  // delete content if T is pointer...
235  }
236 
237 
238  bool onDemand() const { return !getter.empty();}
239 
240  void swap(DetSetVector & rh) {
242  std::swap(m_subdetId,rh.m_subdetId);
243  std::swap(m_ids,rh.m_ids);
244  std::swap(m_data,rh.m_data);
245  }
246 
247  void swap(IdContainer & iic, DataContainer & idc) {
248  std::swap(m_ids,iic);
249  std::swap(m_data,idc);
250  }
251 
252  void reserve(size_t isize, size_t dsize) {
253  m_ids.reserve(isize);
254  m_data.reserve(dsize);
255  }
256 
257  void shrink_to_fit() {
258 #ifndef CMS_NOCXX11
259  m_ids.shrink_to_fit();
260  m_data.shrink_to_fit();
261 #endif
262  }
263 
264  void resize(size_t isize, size_t dsize) {
265  m_ids.resize(isize);
266  m_data.resize(dsize);
267  }
268 
269  // FIXME not sure what the best way to add one cell to cont
270  DetSet insert(id_type iid, data_type const * idata, size_type isize) {
271  Item & item = addItem(iid,isize);
272  m_data.resize(m_data.size()+isize);
273  std::copy(idata,idata+isize,m_data.begin()+item.offset);
274  return DetSet(*this,item,false);
275  }
276  //make space for it
278  Item & item = addItem(iid,isize);
279  m_data.resize(m_data.size()+isize);
280  return DetSet(*this,item,false);
281  }
282 
283  // to be used with a FastFiller
285  return addItem(iid,0);
286  }
287 
288  // remove last entry (usually only if empty...)
289  void pop_back(id_type iid) {
290  const_IdIter p = findItem(iid);
291  if (p==m_ids.end()) return; //bha!
292  // sanity checks... (shall we throw or assert?)
293  if ((*p).size>0&& (*p).offset>-1 &&
294  m_data.size()==(*p).offset+(*p).size)
295  m_data.resize((*p).offset);
296  m_ids.erase( m_ids.begin()+(p-m_ids.begin()));
297  }
298 
299  private:
300 
301  Item & addItem(id_type iid, size_type isize) {
302  Item it(iid,size_type(m_data.size()),isize);
303  IdIter p = std::lower_bound(m_ids.begin(),
304  m_ids.end(),
305  it);
306  if (p!=m_ids.end() && !(it<*p)) dstvdetails::errorIdExists(iid);
307  return *m_ids.insert(p,it);
308  }
309 
310 
311 
312  public:
313 
314 
315  //---------------------------------------------------------
316 
317  bool exists(id_type i) const {
318  return findItem(i)!=m_ids.end();
319  }
320 
321  bool isValid(id_type i) const {
322  const_IdIter p = findItem(i);
323  return p!=m_ids.end() && (*p).offset!=-1;
324  }
325 
326  /*
327  DetSet operator[](id_type i) {
328  const_IdIter p = findItem(i);
329  if (p==m_ids.end()) what???
330  return DetSet(*this,p-m_ids.begin());
331  }
332  */
333 
334 
336  const_IdIter p = findItem(i);
337  if (p==m_ids.end()) dstvdetails::throw_range(i);
338  return DetSet(*this,*p,true);
339  }
340 
341  // slow interface
342  // const_iterator find(id_type i, bool update=true) const {
343  const_iterator find(id_type i, bool update=false) const {
344  const_IdIter p = findItem(i);
345  return (p==m_ids.end()) ? end() :
346  boost::make_transform_iterator(p,
347  IterHelp(*this,update));
348  }
349 
350  // slow interface
352  std::pair<const_IdIter,const_IdIter> p =
353  std::equal_range(m_ids.begin(),m_ids.end(),Item(i));
354  return (p.first!=p.second) ? p.first : m_ids.end();
355  }
356 
357  // const_iterator begin(bool update=true) const {
358  const_iterator begin(bool update=false) const {
359  return boost::make_transform_iterator(m_ids.begin(),
360  IterHelp(*this,update));
361  }
362 
363  // const_iterator end(bool update=true) const {
364  const_iterator end(bool update=false) const {
365  return boost::make_transform_iterator(m_ids.end(),
366  IterHelp(*this,update));
367  }
368 
369 
370  // return an iterator range (implemented here to avoid dereference of detset)
371  template<typename CMP>
372  // Range equal_range(id_type i, CMP cmp, bool update=true) const {
373  Range equal_range(id_type i, CMP cmp, bool update=false) const {
374  std::pair<const_IdIter,const_IdIter> p =
375  std::equal_range(m_ids.begin(),m_ids.end(),i,cmp);
376  return Range(boost::make_transform_iterator(p.first,IterHelp(*this,update)),
377  boost::make_transform_iterator(p.second,IterHelp(*this,update))
378  );
379  }
380 
381  int subdetId() const { return m_subdetId; }
382 
383  bool empty() const { return m_ids.empty();}
384 
385 
386  size_type dataSize() const { return m_data.size(); }
387 
388  size_type size() const { return m_ids.size();}
389 
390  //FIXME fast interfaces, not consistent with associative nature of container....
391 
392  data_type operator()(size_t cell, size_t frame) const {
393  return m_data[m_ids[cell].offset+frame];
394  }
395 
396  data_type const * data(size_t cell) const {
397  return &m_data[m_ids[cell].offset];
398  }
399 
400  size_type detsetSize(size_t cell) const { return m_ids[cell].size; }
401 
402  id_type id(size_t cell) const {
403  return m_ids[cell].id;
404  }
405 
406  Item const & item(size_t cell) const {
407  return m_ids[cell];
408  }
409 
410  //------------------------------
411 
412  IdContainer const & ids() const { return m_ids;}
413  DataContainer const & data() const { return m_data;}
414 
415 
416  void update(Item const & item) const {
417  const_cast<self*>(this)->updateImpl(const_cast<Item&>(item));
418  }
419 
420  //Used by ROOT storage
422 
423  private:
424 
425  void updateImpl(Item & item);
426 
427  private:
428  //for testing
429  friend class ::TestDetSet;
430 
431  // subdetector id (as returned by DetId::subdetId())
433 
434 
435  // Workaround for ROOT 6 bug.
436  // ROOT6 has a problem with this IdContainer typedef
437  //IdContainer m_ids;
438  std::vector<Trans::Item> m_ids;
440 
441  };
442 
443  namespace dslv {
444  template< typename T>
445  class LazyGetter {
446  public:
447  virtual ~LazyGetter() {}
448  virtual void fill(typename DetSetVector<T>::FastFiller&) = 0;
449  };
450  }
451 
452 
453 
454  template<typename T>
455  inline DetSetVector<T>::DetSetVector(std::shared_ptr<Getter> iGetter,
456  const std::vector<det_id_type>& iDets,
457  int isubdet):
458  m_subdetId(isubdet) {
459  getter=iGetter;
460 
461  m_ids.reserve(iDets.size());
462  det_id_type sanityCheck = 0;
463  for(std::vector<det_id_type>::const_iterator itDetId = iDets.begin(), itDetIdEnd = iDets.end();
464  itDetId != itDetIdEnd;
465  ++itDetId) {
466  assert(sanityCheck < *itDetId && "vector of det_id_type was not ordered");
467  sanityCheck = *itDetId;
468  m_ids.push_back(*itDetId);
469  }
470  }
471 
472  template<typename T>
473  inline void DetSetVector<T>::updateImpl(Item & item) {
474  // no getter or already updated
475  if (getter.empty()) assert(item.offset>=0);
476  if (item.offset!=-1 || getter.empty() ) return;
477  item.offset = int(m_data.size());
478  FastFiller ff(*this,item,true);
479  (*boost::any_cast<std::shared_ptr<Getter> >(&getter))->fill(ff);
480  }
481 
482 
483 
484 
485  template<typename T>
486  inline void DetSet<T>::set(DetSetVector<T> const & icont,
487  typename Container::Item const & item, bool update) {
488  if (update) {
489  icont.update(item);
490  assert(item.offset>=0);
491  }
492  m_id=item.id;
493  m_data=&icont.data();
494  m_offset = item.offset;
495  m_size=item.size;
496  }
497 
498 }
499 
501 #include <boost/mpl/assert.hpp>
502 #include <boost/type_traits/is_same.hpp>
503 
504 //specialize behavior of edm::Ref to get access to the 'Det'
505 namespace edm {
506  /* Reference to an item inside a new DetSetVector ... */
507  namespace refhelper {
508  template<typename T>
509  struct FindTrait<typename edmNew::DetSetVector<T>,T> {
511  };
512  }
513  /* ... as there was one for the original DetSetVector*/
514 
515  /* Probably this one is not that useful .... */
516  namespace refhelper {
517  template<typename T>
518  struct FindSetForNewDetSetVector : public std::binary_function<const edmNew::DetSetVector<T>&, unsigned int, edmNew::DetSet<T> > {
520  typename self::result_type operator()(typename self::first_argument_type iContainer, typename self::second_argument_type iIndex) {
521  return &(iContainer[iIndex]);
522  }
523  };
524 
525  template<typename T>
526  struct FindTrait<edmNew::DetSetVector<T>, edmNew::DetSet<T> > {
528  };
529  }
530  /* ... implementation is provided, just in case it's needed */
531 }
532 
533 namespace edmNew {
534  //helper function to make it easier to create a edm::Ref to a new DSV
535  template<class HandleT>
537  makeRefTo(const HandleT& iHandle,
538  typename HandleT::element_type::value_type::const_iterator itIter) {
539  BOOST_MPL_ASSERT((boost::is_same<typename HandleT::element_type, DetSetVector<typename HandleT::element_type::value_type::value_type> >));
540  typename HandleT::element_type::size_type index = (itIter - &*iHandle->data().begin());
541  return edm::Ref<typename HandleT::element_type,
543  (iHandle,index);
544  }
545 }
546 
548 
549 namespace edm {
550  template<typename T>
551  class ContainerMaskTraits<edmNew::DetSetVector<T> > {
552  public:
553  typedef T value_type;
554 
555  static size_t size(const edmNew::DetSetVector<T>* iContainer) { return iContainer->dataSize();}
556  static unsigned int indexFor(const value_type* iElement, const edmNew::DetSetVector<T>* iContainer) {
557  return iElement-&(iContainer->data().front());
558  }
559  };
560 }
561 
562 #endif
563 
void swap(ora::Record &rh, ora::Record &lh)
Definition: Record.h:70
bool isValid(id_type i) const
DataContainer const & data() const
edm::Ref< typename HandleT::element_type, typename HandleT::element_type::value_type::value_type > makeRefTo(const HandleT &iHandle, typename HandleT::element_type::value_type::const_iterator itIter)
static unsigned int indexFor(const value_type *iElement, const edmNew::DetSetVector< T > *iContainer)
int i
Definition: DBlmapReader.cc:9
void swap(DetSetVectorTrans &rh)
void push_back(data_type const &d)
void update(Item const &item) const
boost::transform_iterator< IterHelp, const_IdIter > const_iterator
const_iterator end(bool update=false) const
size_type dataSize() const
string fill
Definition: lumiContext.py:319
DetSetVector< T >::id_type id_type
Range equal_range(id_type i, CMP cmp, bool update=false) const
std::vector< data_type > DataContainer
Item & push_back(id_type iid)
const_IdIter findItem(id_type i) const
std::vector< Trans::Item > m_ids
bool any(const std::vector< T > &v, const T &what)
Definition: ECalSD.cc:34
IdContainer::iterator IdIter
unsigned int det_id_type
Definition: DetSetNew.h:10
void checkCapacityExausted(size_type s) const
void set(Container const &icont, typename Container::Item const &item, bool update=true)
assert(m_qm.get())
edmNew::DetSetVector< T >::FindForDetSetVector value
std::vector< data_type >::const_iterator const_DataIter
void swap(DetSetVector &rh)
void throw_range(det_id_type iid)
std::pair< const_IdIter, const_DataIter > const_IterPair
DetSetVector(int isubdet=0)
std::pair< const_iterator, const_iterator > Range
void pop_back(id_type iid)
#define CMS_CLASS_VERSION(_version_)
Definition: classes.h:31
id_type id(size_t cell) const
uint16_t size_type
dstvdetails::DetSetVectorTrans Trans
self::result_type operator()(typename self::first_argument_type iContainer, typename self::second_argument_type iIndex)
tuple d
Definition: ztail.py:151
Item const & item(size_t cell) const
DetSetVector< T > const * v
bool onDemand() const
IterHelp(DetSetVector< T > const &iv, bool iup)
Item & addItem(id_type iid, size_type isize)
DetSetVector< T >::data_type value_type
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
bool exists(id_type i) const
IdContainer const & ids() const
def move
Definition: eostools.py:510
data_type const * data(size_t cell) const
FastFiller(DetSetVector< T > &iv, id_type id, bool isaveEmpty=false)
#define private
Definition: FWEveView.cc:22
Item(id_type i=0, int io=-1, size_type is=0)
DetSetVector< T >::Item & item
void swap(IdContainer &iic, DataContainer &idc)
Container::value_type value_type
DetSetVector< T >::id_type key_type
static size_t size(const edmNew::DetSetVector< T > *iContainer)
void resize(size_t isize, size_t dsize)
size_type detsetSize(size_t cell) const
DetSet insert(id_type iid, data_type const *idata, size_type isize)
m_id("(unknown)")
std::vector< Item > IdContainer
friend class FindForDetSetVector
dslv::LazyGetter< T > Getter
void errorIdExists(det_id_type iid)
void reserve(size_t isize, size_t dsize)
std::vector< data_type >::iterator DataIter
result_type & operator()(Item const &item) const
const_iterator find(id_type i, bool update=false) const
DetSet insert(id_type iid, size_type isize)
size_type size() const
#define update(a, b)
std::pair< IdIter, DataIter > IterPair
void updateImpl(Item &item)
IdContainer::const_iterator const_IdIter
data_type operator()(size_t cell, size_t frame) const
self::result_type operator()(typename self::first_argument_type iContainer, typename self::second_argument_type iIndex)
edmNew::DetSet< T > DetSet
volatile std::atomic< bool > shutdown_flag false
FastFiller(DetSetVector< T > &iv, typename DetSetVector< T >::Item &it, bool isaveEmpty=false)
data_type & operator[](size_type i)
edm::refhelper::FindForNewDetSetVector< data_type > RefFinder
long double T
DetSetVector< T >::size_type size_type
DetSet operator[](id_type i) const
const_iterator begin(bool update=false) const
unsigned int size_type