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