1 #ifndef DataFormats_Common_DetSetVectorNew_h 2 #define DataFormats_Common_DetSetVectorNew_h 9 #include <boost/iterator/transform_iterator.hpp> 10 #include <boost/any.hpp> 14 #if !defined(__ROOTCLING__) 15 #define DSVN_USE_ATOMIC 47 namespace dstvdetails {
66 #ifdef DSVN_USE_ATOMIC 76 assert(rh.m_filling==
false);
78 #ifdef DSVN_USE_ATOMIC 79 m_dataSize.store(rh.m_dataSize.exchange(m_dataSize.load()));
86 assert(m_filling==
false); assert(rh.m_filling==
false);
88 #ifdef DSVN_USE_ATOMIC 89 m_dataSize.store(rh.m_dataSize.exchange(m_dataSize.load()));
97 #ifdef DSVN_USE_ATOMIC 100 mutable size_type m_dataSize;
105 assert(m_filling==
false); assert(rh.
m_filling==
false);
108 #ifdef DSVN_USE_ATOMIC 109 m_dataSize.store(rh.
m_dataSize.exchange(m_dataSize.load()));
134 #ifdef DSVN_USE_ATOMIC 138 return offset.compare_exchange_strong(expected,-2);
145 bool uninitialized()
const {
return (-1)==
offset;}
149 operator id_type()
const {
return id;}
152 #ifdef DSVN_USE_ATOMIC 155 if (!m_filling.compare_exchange_strong(expected,
true))
errorFilling();
159 bool ready()
const {
return true;}
195 typedef typename IdContainer::iterator
IdIter;
196 typedef typename std::vector<data_type>::iterator
DataIter;
211 m_detset.
set(*m_v,item,m_update);
221 typedef std::pair<const_iterator,const_iterator>
Range;
238 m_v(iv), m_item(m_v.ready()? m_v.push_back(id):
dummy()),m_saveEmpty(isaveEmpty) {
243 m_v(iv), m_item(it), m_saveEmpty(isaveEmpty) {
245 if(m_v.ready()) m_item.offset =
int(m_v.m_data.size());
249 if (!m_saveEmpty && m_item.size==0) {
250 m_v.pop_back(m_item.id);
252 assert(m_v.m_filling==
true);
259 m_v.pop_back(m_item.id);
273 if (m_item.offset+s <= m_v.m_data.capacity())
return;
275 m_v.m_data.reserve(m_item.offset+s);
280 checkCapacityExausted(s);
281 m_v.m_data.resize(m_item.offset+s);
282 m_v.m_dataSize = m_v.m_data.size();
286 id_type
id()
const {
return m_item.id;}
287 size_type
size()
const {
return m_item.size;}
288 bool empty()
const {
return m_item.size==0;}
291 return m_v.m_data[m_item.offset+
i];
293 DataIter
begin() {
return m_v.m_data.begin()+ m_item.offset;}
297 checkCapacityExausted();
298 m_v.m_data.push_back(d);
303 checkCapacityExausted();
309 data_type &
back() {
return m_v.m_data.back();}
313 friend class ::TestDetSet;
329 #ifdef DSVN_USE_ATOMIC 337 m_v(iv), m_item(m_v.ready()? iv.push_back(id):
dummy()) { assert(m_v.m_filling==
true); m_v.m_filling =
false;}
340 m_v(iv), m_item(it) {
345 while (!m_v.m_filling.compare_exchange_weak(expected,
true)) { expected=
false; nanosleep(
nullptr,
nullptr);}
346 int offset = m_v.m_data.size();
347 if (m_v.onDemand() &&
full()) {
348 m_v.m_filling =
false;
351 std::move(m_lv.begin(), m_lv.end(), std::back_inserter(m_v.m_data));
352 m_item.size=m_lv.size();
355 m_v.m_dataSize = m_v.m_data.size();
356 assert(m_v.m_filling==
true);
357 m_v.m_filling =
false;
363 int offset = m_v.m_dataSize;
364 return m_v.m_data.capacity()<offset+m_lv.size();
379 id_type
id()
const {
return m_item.id;}
380 size_type
size()
const {
return m_lv.size();}
381 bool empty()
const {
return m_lv.empty();}
386 DataIter
begin() {
return m_lv.begin();}
387 DataIter
end() {
return m_lv.end();}
396 data_type &
back() {
return m_lv.back();}
400 friend class ::TestDetSet;
409 friend class FastFiller;
410 friend class TSFastFiller;
413 class FindForDetSetVector :
public std::binary_function<const edmNew::DetSetVector<T>&, unsigned int, const T*> {
416 typename self::result_type
operator()(
typename self::first_argument_type iContainer,
typename self::second_argument_type iIndex)
417 #ifdef DSVN_USE_ATOMIC 420 while (!iContainer.m_filling.compare_exchange_weak(expected,
true,std::memory_order_acq_rel)) { expected=
false; nanosleep(
nullptr,
nullptr);}
421 typename self::result_type item = &(iContainer.m_data[iIndex]);
422 assert(iContainer.m_filling==
true);
423 iContainer.m_filling =
false;
430 friend class FindForDetSetVector;
433 m_subdetId(isubdet) {}
464 void swap(IdContainer & iic, DataContainer & idc) {
470 m_ids.reserve(isize);
471 m_data.reserve(dsize);
476 m_ids.shrink_to_fit();
477 m_data.shrink_to_fit();
480 void resize(
size_t isize,
size_t dsize) {
482 m_data.resize(dsize);
483 m_dataSize = m_data.size();
487 m_ids.erase(std::remove_if(m_ids.begin(),m_ids.end(),[](Item
const&
m){
return 0==
m.size;}),m_ids.end());
491 DetSet
insert(id_type iid, data_type
const * idata, size_type isize) {
492 Item & item = addItem(iid,isize);
493 m_data.resize(m_data.size()+isize);
495 m_dataSize = m_data.size();
496 return DetSet(*
this,item,
false);
499 DetSet
insert(id_type iid, size_type isize) {
500 Item & item = addItem(iid,isize);
501 m_data.resize(m_data.size()+isize);
502 m_dataSize = m_data.size();
503 return DetSet(*
this,item,
false);
508 return addItem(iid,0);
513 const_IdIter
p = findItem(iid);
514 if (p==m_ids.end())
return;
516 if ( (*p).isValid() && (*p).size>0 &&
517 m_data.size()==(*p).offset+(*p).size) {
518 m_data.resize((*p).offset);
519 m_dataSize = m_data.size();
521 m_ids.erase(m_ids.begin()+(p-m_ids.begin()));
526 Item &
addItem(id_type iid, size_type isize) {
527 Item it(iid,
size_type(m_data.size()),isize);
528 IdIter
p = std::lower_bound(m_ids.begin(),
543 return findItem(i)!=m_ids.end();
547 const_IdIter
p = findItem(i);
548 return p!=m_ids.end() && (*p).isValid();
561 const_IdIter
p = findItem(i);
563 return DetSet(*
this,*p,
true);
569 const_IdIter
p = findItem(i);
570 return (p==m_ids.end()) ?
end() :
571 boost::make_transform_iterator(p,
577 std::pair<const_IdIter,const_IdIter>
p =
578 std::equal_range(m_ids.begin(),m_ids.end(),Item(i));
579 return (p.first!=p.second) ? p.first : m_ids.end();
584 return boost::make_transform_iterator(m_ids.begin(),
590 return boost::make_transform_iterator(m_ids.end(),
596 template<
typename CMP>
599 std::pair<const_IdIter,const_IdIter>
p =
600 std::equal_range(m_ids.begin(),m_ids.end(),
i,cmp);
601 return Range(boost::make_transform_iterator(p.first,IterHelp(*
this,
update)),
602 boost::make_transform_iterator(p.second,IterHelp(*
this,
update))
608 bool empty()
const {
return m_ids.empty();}
613 size_type
size()
const {
return m_ids.size();}
618 return m_data[m_ids[cell].offset+frame];
621 data_type
const *
data(
size_t cell)
const {
622 return &m_data[m_ids[cell].offset];
625 size_type
detsetSize(
size_t cell)
const {
return m_ids[cell].size; }
627 id_type
id(
size_t cell)
const {
628 return m_ids[cell].id;
631 Item
const &
item(
size_t cell)
const {
637 IdContainer
const &
ids()
const {
return m_ids;}
638 DataContainer
const &
data()
const {
return m_data;}
646 friend class ::TestDetSet;
648 void update(Item const & item) const;
656 std::vector<Trans::Item> m_ids;
662 template<
typename T>
673 const std::vector<det_id_type>& iDets,
675 m_subdetId(isubdet) {
678 m_ids.reserve(iDets.size());
679 det_id_type sanityCheck = 0;
680 for(std::vector<det_id_type>::const_iterator itDetId = iDets.begin(), itDetIdEnd = iDets.end();
681 itDetId != itDetIdEnd;
683 assert(sanityCheck < *itDetId &&
"vector of det_id_type was not ordered");
684 sanityCheck = *itDetId;
685 m_ids.push_back(*itDetId);
689 #ifdef DSVN_USE_ATOMIC 693 if (m_getter.empty()) { assert(item.
isValid());
return;}
698 (*boost::any_cast<std::shared_ptr<Getter> >(&m_getter))->fill(ff);
706 #ifdef DSVN_USE_ATOMIC 711 if (update) icont.
update(item);
713 m_data=&icont.
data();
722 #include <type_traits> 727 namespace refhelper {
736 namespace refhelper {
740 typename self::result_type
operator()(
typename self::first_argument_type iContainer,
typename self::second_argument_type iIndex) {
741 return &(iContainer[iIndex]);
755 template<
class HandleT>
759 typename HandleT::element_type::value_type::const_iterator itIter) {
761 auto index = itIter - &iHandle->data().front();
762 return edm::Ref<
typename HandleT::element_type,
764 (iHandle.id(), &(*itIter),
index);
778 static size_t size(
const edmNew::DetSetVector<T>* iContainer) {
return iContainer->
dataSize();}
779 static unsigned int indexFor(
const value_type* iElement,
const edmNew::DetSetVector<T>* iContainer) {
780 return iElement-&(iContainer->
data().front());
785 #ifdef DSVN_USE_ATOMIC 786 #undef DSVN_USE_ATOMIC
bool isValid(id_type i) const
DataContainer const & data() const
static unsigned int indexFor(const value_type *iElement, const edmNew::DetSetVector< T > *iContainer)
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
static DetSetVector< T >::Item & dummy()
size_type dataSize() const
DetSetVector< T >::id_type id_type
void reserve(size_type s)
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
PixelRecoRange< float > Range
bool any(const std::vector< T > &v, const T &what)
IdContainer::iterator IdIter
void checkCapacityExausted(size_type s) const
void set(Container const &icont, typename Container::Item const &item, bool update=true)
void push_back(data_type &&d)
void throwCapacityExausted()
void reserve(size_type s)
edmNew::DetSetVector< T >::FindForDetSetVector value
std::vector< data_type >::const_iterator const_DataIter
void push_back(data_type &&d)
void swap(DetSetVector &rh)
void throw_range(det_id_type iid)
std::pair< const_IdIter, const_DataIter > const_IterPair
Item & operator=(Item &&rh)
DetSetVector(int isubdet=0)
std::pair< const_iterator, const_iterator > Range
TSFastFiller(DetSetVector< T > const &iv, typename DetSetVector< T >::Item const &it)
void pop_back(id_type iid)
#define CMS_CLASS_VERSION(_version_)
id_type id(size_t cell) const
DetSetVectorTrans(const DetSetVectorTrans &rh)
DetSetVector< T > const & m_v
bool operator<(Item const &rh) const
void swap(Association< C > &lhs, Association< C > &rhs)
DetSetVector< T > const * m_v
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
void checkCapacityExausted() const
Container::value_type value_type
IterHelp(DetSetVector< T > const &iv, bool iup)
Ref< typename HandleT::element_type, typename HandleT::element_type::value_type::value_type > makeRefTo(const HandleT &iHandle, det_id_type iDetID, typename HandleT::element_type::value_type::const_iterator itIter)
Item & addItem(id_type iid, size_type isize)
DetSetVector< T >::data_type value_type
static DetSetVector< T >::Item const & dummy()
DetSetVectorTrans & operator=(DetSetVectorTrans &&rh)
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
DetSetVector< T >::Item & m_item
bool exists(id_type i) const
void push_back(data_type const &d)
IdContainer const & ids() const
bool initializing() const
data_type const * data(size_t cell) const
FastFiller(DetSetVector< T > &iv, id_type id, bool isaveEmpty=false)
#define CMS_THREAD_GUARD(_var_)
FindSetForNewDetSetVector< T > value
DetSetVector< T >::size_type size_type
Item(id_type i=0, int io=-1, size_type is=0)
DetSetVector< T >::Item const & m_item
void swap(IdContainer &iic, DataContainer &idc)
DetSetVector< T >::id_type key_type
static size_t size(const edmNew::DetSetVector< T > *iContainer)
void resize(size_t isize, size_t dsize)
TSFastFiller(DetSetVector< T > &iv, id_type id)
size_type detsetSize(size_t cell) const
std::atomic< int > offset
DetSetVector()
Create an empty DetSetVector.
DetSet insert(id_type iid, data_type const *idata, size_type isize)
std::vector< Item > IdContainer
dslv::LazyGetter< T > Getter
DetSetVector< T >::id_type key_type
void errorIdExists(det_id_type iid)
void reserve(size_t isize, size_t dsize)
data_type & operator[](size_type i)
std::vector< data_type >::iterator DataIter
result_type & operator()(Item const &item) const
const_iterator find(id_type i, bool update=false) const
CapacityExaustedException()
Item & operator=(Item const &rh)
DetSet insert(id_type iid, size_type isize)
std::pair< IdIter, DataIter > IterPair
std::atomic< size_type > m_dataSize
std::atomic< bool > m_filling
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
FastFiller(DetSetVector< T > &iv, typename DetSetVector< T >::Item &it, bool isaveEmpty=false)
data_type & operator[](size_type i)
edm::refhelper::FindForNewDetSetVector< data_type > RefFinder
DetSetVectorTrans(DetSetVectorTrans &&rh)
DetSetVector< T >::size_type size_type
DetSetVector< T >::id_type id_type
DetSet operator[](id_type i) const
DetSetVector< T >::data_type value_type
const_iterator begin(bool update=false) const