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 namespace edm { namespace refhelper { template<typename T> struct FindForNewDetSetVector; } }
22 
23 //FIXME remove New when ready
24 namespace edmNew {
25  typedef uint32_t det_id_type;
26 
27  namespace dslv {
28  template< typename T> class LazyGetter;
29  }
30 
31  /* transient component of DetSetVector
32  * for pure conviniency of dictioanary declaration
33  */
34  namespace dstvdetails {
37  bool filling;
39 
40 
41  void swap(DetSetVectorTrans& rh) {
44  }
45 
46  typedef unsigned int size_type; // for persistency
47  typedef unsigned int id_type;
48 
49  struct Item {
50  Item(id_type i=0, int io=-1, size_type is=0) : id(i), offset(io), size(is){}
51  bool isValid() const { return offset>=0;}
53  int offset;
55  bool operator<(Item const &rh) const { return id<rh.id;}
56  operator id_type() const { return id;}
57  };
58 
59  };
60 
61  void errorFilling();
62  void errorIdExists(det_id_type iid);
63  void throw_range(det_id_type iid);
64  }
65 
76  template<typename T>
77  class DetSetVector : private dstvdetails::DetSetVectorTrans {
78  public:
80  typedef Trans::Item Item;
81  typedef unsigned int size_type; // for persistency
82  typedef unsigned int id_type;
83  typedef T data_type;
87  // FIXME not sure make sense....
88  typedef DetSet value_type;
89  typedef id_type key_type;
90 
91 
92  typedef std::vector<Item> IdContainer;
93  typedef std::vector<data_type> DataContainer;
94  typedef typename IdContainer::iterator IdIter;
95  typedef typename std::vector<data_type>::iterator DataIter;
96  typedef std::pair<IdIter,DataIter> IterPair;
97  typedef typename IdContainer::const_iterator const_IdIter;
98  typedef typename std::vector<data_type>::const_iterator const_DataIter;
99  typedef std::pair<const_IdIter,const_DataIter> const_IterPair;
100 
102 
103  struct IterHelp {
105  // IterHelp() : v(0),update(true){}
106  IterHelp() : v(0),update(false){}
107  IterHelp(DetSetVector<T> const & iv, bool iup) : v(&iv), update(iup){}
108 
109  result_type & operator()(Item const& item) const {
110  detset.set(*v,item,update);
111  return detset;
112  }
113  private:
116  bool update;
117  };
118 
119  typedef boost::transform_iterator<IterHelp,const_IdIter> const_iterator;
120  typedef std::pair<const_iterator,const_iterator> Range;
121 
122  /* fill the lastest inserted DetSet
123  */
124  class FastFiller {
125  public:
130 
131  FastFiller(DetSetVector<T> & iv, id_type id, bool isaveEmpty=false) :
132  v(iv), item(v.push_back(id)), saveEmpty(isaveEmpty) {
133  if (v.filling) dstvdetails::errorFilling();
134  v.filling=true;
135  }
136  FastFiller(DetSetVector<T> & iv, typename DetSetVector<T>::Item & it, bool isaveEmpty=false) :
137  v(iv), item(it), saveEmpty(isaveEmpty) {
138  if (v.filling) dstvdetails::errorFilling();
139  v.filling=true;
140  }
142  if (!saveEmpty && item.size==0) {
143  v.pop_back(item.id);
144  }
145  v.filling=false;
146  }
147 
148  void abort() {
149  v.pop_back(item.id);
150  saveEmpty=true; // avoid mess in destructor
151  }
152 
154  v.m_data.reserve(item.offset+s);
155  }
156 
157 
159  v.m_data.resize(item.offset+s);
160  item.size=s;
161  }
162 
163  id_type id() const { return item.id;}
164  size_type size() const { return item.size;}
165  bool empty() const { return item.size==0;}
166 
168  return v.m_data[item.offset+i];
169  }
170  DataIter begin() { return v.m_data.begin()+ item.offset;}
171  DataIter end() { return v.m_data.end();}
172 
173  void push_back(data_type const & d) {
174  v.m_data.push_back(d);
175  item.size++;
176  }
177 #ifndef CMS_NOCXX11
178  void push_back(data_type && d) {
179  v.m_data.push_back(std::move(d));
180  item.size++;
181  }
182 #endif
183 
184  data_type & back() { return v.m_data.back();}
185 
186  private:
189  bool saveEmpty;
190  };
191  friend class FastFiller;
192 
193  class FindForDetSetVector : public std::binary_function<const edmNew::DetSetVector<T>&, unsigned int, const T*> {
194  public:
195  typedef FindForDetSetVector self;
196  typename self::result_type operator()(typename self::first_argument_type iContainer, typename self::second_argument_type iIndex) {
197  return &(iContainer.m_data[iIndex]);
198  }
199  };
200  friend class FindForDetSetVector;
201 
202  explicit DetSetVector(int isubdet=0) :
203  m_subdetId(isubdet) {}
204 
205  DetSetVector(std::shared_ptr<dslv::LazyGetter<T> > iGetter, const std::vector<det_id_type>& iDets,
206  int isubdet=0);
207 
208 
210  // delete content if T is pointer...
211  }
212 
213 
214  bool onDemand() const { return !getter.empty();}
215 
216  void swap(DetSetVector & rh) {
218  std::swap(m_subdetId,rh.m_subdetId);
219  std::swap(m_ids,rh.m_ids);
220  std::swap(m_data,rh.m_data);
221  }
222 
223  void swap(IdContainer & iic, DataContainer & idc) {
224  std::swap(m_ids,iic);
225  std::swap(m_data,idc);
226  }
227 
228  void reserve(size_t isize, size_t dsize) {
229  m_ids.reserve(isize);
230  m_data.reserve(dsize);
231  }
232 
233  void shrink_to_fit() {
234 #ifndef CMS_NOCXX11
235  m_ids.shrink_to_fit();
236  m_data.shrink_to_fit();
237 #endif
238  }
239 
240  void resize(size_t isize, size_t dsize) {
241  m_ids.resize(isize);
242  m_data.resize(dsize);
243  }
244 
245  // FIXME not sure what the best way to add one cell to cont
246  DetSet insert(id_type iid, data_type const * idata, size_type isize) {
247  Item & item = addItem(iid,isize);
248  m_data.resize(m_data.size()+isize);
249  std::copy(idata,idata+isize,m_data.begin()+item.offset);
250  return DetSet(*this,item,false);
251  }
252  //make space for it
254  Item & item = addItem(iid,isize);
255  m_data.resize(m_data.size()+isize);
256  return DetSet(*this,item,false);
257  }
258 
259  // to be used with a FastFiller
261  return addItem(iid,0);
262  }
263 
264  // remove last entry (usually only if empty...)
265  void pop_back(id_type iid) {
266  const_IdIter p = findItem(iid);
267  if (p==m_ids.end()) return; //bha!
268  // sanity checks... (shall we throw or assert?)
269  if ((*p).size>0&& (*p).offset>-1 &&
270  m_data.size()==(*p).offset+(*p).size)
271  m_data.resize((*p).offset);
272  m_ids.erase( m_ids.begin()+(p-m_ids.begin()));
273  }
274 
275  private:
276 
277  Item & addItem(id_type iid, size_type isize) {
278  Item it(iid,size_type(m_data.size()),isize);
279  IdIter p = std::lower_bound(m_ids.begin(),
280  m_ids.end(),
281  it);
282  if (p!=m_ids.end() && !(it<*p)) dstvdetails::errorIdExists(iid);
283  return *m_ids.insert(p,it);
284  }
285 
286 
287 
288  public:
289 
290 
291  //---------------------------------------------------------
292 
293  bool exists(id_type i) const {
294  return findItem(i)!=m_ids.end();
295  }
296 
297  bool isValid(id_type i) const {
298  const_IdIter p = findItem(i);
299  return p!=m_ids.end() && (*p).offset!=-1;
300  }
301 
302  /*
303  DetSet operator[](id_type i) {
304  const_IdIter p = findItem(i);
305  if (p==m_ids.end()) what???
306  return DetSet(*this,p-m_ids.begin());
307  }
308  */
309 
310 
312  const_IdIter p = findItem(i);
313  if (p==m_ids.end()) dstvdetails::throw_range(i);
314  return DetSet(*this,*p,true);
315  }
316 
317  // slow interface
318  // const_iterator find(id_type i, bool update=true) const {
319  const_iterator find(id_type i, bool update=false) const {
320  const_IdIter p = findItem(i);
321  return (p==m_ids.end()) ? end() :
322  boost::make_transform_iterator(p,
323  IterHelp(*this,update));
324  }
325 
326  // slow interface
328  std::pair<const_IdIter,const_IdIter> p =
329  std::equal_range(m_ids.begin(),m_ids.end(),Item(i));
330  return (p.first!=p.second) ? p.first : m_ids.end();
331  }
332 
333  // const_iterator begin(bool update=true) const {
334  const_iterator begin(bool update=false) const {
335  return boost::make_transform_iterator(m_ids.begin(),
336  IterHelp(*this,update));
337  }
338 
339  // const_iterator end(bool update=true) const {
340  const_iterator end(bool update=false) const {
341  return boost::make_transform_iterator(m_ids.end(),
342  IterHelp(*this,update));
343  }
344 
345 
346  // return an iterator range (implemented here to avoid dereference of detset)
347  template<typename CMP>
348  // Range equal_range(id_type i, CMP cmp, bool update=true) const {
349  Range equal_range(id_type i, CMP cmp, bool update=false) const {
350  std::pair<const_IdIter,const_IdIter> p =
351  std::equal_range(m_ids.begin(),m_ids.end(),i,cmp);
352  return Range(boost::make_transform_iterator(p.first,IterHelp(*this,update)),
353  boost::make_transform_iterator(p.second,IterHelp(*this,update))
354  );
355  }
356 
357  int subdetId() const { return m_subdetId; }
358 
359  bool empty() const { return m_ids.empty();}
360 
361 
362  size_type dataSize() const { return m_data.size(); }
363 
364  size_type size() const { return m_ids.size();}
365 
366  //FIXME fast interfaces, not consistent with associative nature of container....
367 
368  data_type operator()(size_t cell, size_t frame) const {
369  return m_data[m_ids[cell].offset+frame];
370  }
371 
372  data_type const * data(size_t cell) const {
373  return &m_data[m_ids[cell].offset];
374  }
375 
376  size_type detsetSize(size_t cell) const { return m_ids[cell].size; }
377 
378  id_type id(size_t cell) const {
379  return m_ids[cell].id;
380  }
381 
382  Item const & item(size_t cell) const {
383  return m_ids[cell];
384  }
385 
386  //------------------------------
387 
388  IdContainer const & ids() const { return m_ids;}
389  DataContainer const & data() const { return m_data;}
390 
391 
392  void update(Item const & item) const {
393  const_cast<self*>(this)->updateImpl(const_cast<Item&>(item));
394  }
395 
396  //Used by ROOT storage
398 
399  private:
400 
401  void updateImpl(Item & item);
402 
403  private:
404  // subdetector id (as returned by DetId::subdetId())
406 
407 
410 
411  };
412 
413  namespace dslv {
414  template< typename T>
415  class LazyGetter {
416  public:
417  virtual ~LazyGetter() {}
418  virtual void fill(typename DetSetVector<T>::FastFiller&) = 0;
419  };
420  }
421 
422 
423 
424  template<typename T>
425  inline DetSetVector<T>::DetSetVector(std::shared_ptr<Getter> iGetter,
426  const std::vector<det_id_type>& iDets,
427  int isubdet):
428  m_subdetId(isubdet) {
429  getter=iGetter;
430 
431  m_ids.reserve(iDets.size());
432  det_id_type sanityCheck = 0;
433  for(std::vector<det_id_type>::const_iterator itDetId = iDets.begin(), itDetIdEnd = iDets.end();
434  itDetId != itDetIdEnd;
435  ++itDetId) {
436  assert(sanityCheck < *itDetId && "vector of det_id_type was not ordered");
437  sanityCheck = *itDetId;
438  m_ids.push_back(*itDetId);
439  }
440  }
441 
442  template<typename T>
443  inline void DetSetVector<T>::updateImpl(Item & item) {
444  // no getter or already updated
445  if (getter.empty()) assert(item.offset>=0);
446  if (item.offset!=-1 || getter.empty() ) return;
447  item.offset = int(m_data.size());
448  FastFiller ff(*this,item,true);
449  (*boost::any_cast<std::shared_ptr<Getter> >(&getter))->fill(ff);
450  }
451 
452 
453 
454 
455  template<typename T>
456  inline void DetSet<T>::set(DetSetVector<T> const & icont,
457  typename Container::Item const & item, bool update) {
458  if (update) {
459  icont.update(item);
460  assert(item.offset>=0);
461  }
462  m_id=item.id;
463  m_data=&icont.data();
464  m_offset = item.offset;
465  m_size=item.size;
466  }
467 
468 }
469 
471 #include <boost/mpl/assert.hpp>
472 #include <boost/type_traits/is_same.hpp>
473 
474 //specialize behavior of edm::Ref to get access to the 'Det'
475 namespace edm {
476  /* Reference to an item inside a new DetSetVector ... */
477  namespace refhelper {
478  template<typename T>
479  struct FindTrait<typename edmNew::DetSetVector<T>,T> {
481  };
482  }
483  /* ... as there was one for the original DetSetVector*/
484 
485  /* Probably this one is not that useful .... */
486  namespace refhelper {
487  template<typename T>
488  struct FindSetForNewDetSetVector : public std::binary_function<const edmNew::DetSetVector<T>&, unsigned int, edmNew::DetSet<T> > {
490  typename self::result_type operator()(typename self::first_argument_type iContainer, typename self::second_argument_type iIndex) {
491  return &(iContainer[iIndex]);
492  }
493  };
494 
495  template<typename T>
496  struct FindTrait<edmNew::DetSetVector<T>, edmNew::DetSet<T> > {
498  };
499  }
500  /* ... implementation is provided, just in case it's needed */
501 }
502 
503 namespace edmNew {
504  //helper function to make it easier to create a edm::Ref to a new DSV
505  template<class HandleT>
507  makeRefTo(const HandleT& iHandle,
508  typename HandleT::element_type::value_type::const_iterator itIter) {
509  BOOST_MPL_ASSERT((boost::is_same<typename HandleT::element_type, DetSetVector<typename HandleT::element_type::value_type::value_type> >));
510  typename HandleT::element_type::size_type index = (itIter - &*iHandle->data().begin());
511  return edm::Ref<typename HandleT::element_type,
513  (iHandle,index);
514  }
515 }
516 
518 
519 namespace edm {
520  template<typename T>
521  class ContainerMaskTraits<edmNew::DetSetVector<T> > {
522  public:
523  typedef T value_type;
524 
525  static size_t size(const edmNew::DetSetVector<T>* iContainer) { return iContainer->dataSize();}
526  static unsigned int indexFor(const value_type* iElement, const edmNew::DetSetVector<T>* iContainer) {
527  return iElement-&(iContainer->data().front());
528  }
529  };
530 }
531 
532 #endif
533 
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
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 set(Container const &icont, typename Container::Item const &item, bool update=true)
edmNew::DetSetVector< T >::FindForDetSetVector value
std::vector< data_type >::const_iterator const_DataIter
void swap(DetSetVector &rh)
void throw_range(det_id_type iid)
list namespace
Definition: asciidump.py:379
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)
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
data_type const * data(size_t cell) const
FastFiller(DetSetVector< T > &iv, id_type id, bool isaveEmpty=false)
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)
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
#define private
Definition: FWFileEntry.h:17
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