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 {
65 #ifdef DSVN_USE_ATOMIC 68 mutable size_type m_dataSize;
73 assert(m_filling==
false); assert(rh.
m_filling==
false);
76 #ifdef DSVN_USE_ATOMIC 77 m_dataSize.store(rh.
m_dataSize.exchange(m_dataSize.load()));
102 #ifdef DSVN_USE_ATOMIC 106 return offset.compare_exchange_strong(expected,-2);
113 bool uninitialized()
const {
return (-1)==
offset;}
117 operator id_type()
const {
return id;}
120 #ifdef DSVN_USE_ATOMIC 123 if (!m_filling.compare_exchange_strong(expected,
true))
errorFilling();
127 bool ready()
const {
return true;}
163 typedef typename IdContainer::iterator
IdIter;
164 typedef typename std::vector<data_type>::iterator
DataIter;
179 m_detset.
set(*m_v,item,m_update);
189 typedef std::pair<const_iterator,const_iterator>
Range;
206 m_v(iv), m_item(m_v.ready()? m_v.push_back(id):
dummy()),m_saveEmpty(isaveEmpty) {
211 m_v(iv), m_item(it), m_saveEmpty(isaveEmpty) {
213 if(m_v.ready()) m_item.offset =
int(m_v.m_data.size());
217 if (!m_saveEmpty && m_item.size==0) {
218 m_v.pop_back(m_item.id);
220 assert(m_v.m_filling==
true);
227 m_v.pop_back(m_item.id);
241 if (m_item.offset+s <= m_v.m_data.capacity())
return;
243 m_v.m_data.reserve(m_item.offset+s);
248 checkCapacityExausted(s);
249 m_v.m_data.resize(m_item.offset+s);
250 m_v.m_dataSize = m_v.m_data.size();
254 id_type
id()
const {
return m_item.id;}
255 size_type
size()
const {
return m_item.size;}
256 bool empty()
const {
return m_item.size==0;}
259 return m_v.m_data[m_item.offset+
i];
261 DataIter
begin() {
return m_v.m_data.begin()+ m_item.offset;}
265 checkCapacityExausted();
266 m_v.m_data.push_back(d);
271 checkCapacityExausted();
277 data_type &
back() {
return m_v.m_data.back();}
281 friend class ::TestDetSet;
297 #ifdef DSVN_USE_ATOMIC 305 m_v(iv), m_item(m_v.ready()? iv.push_back(id):
dummy()) { assert(m_v.m_filling==
true); m_v.m_filling =
false;}
308 m_v(iv), m_item(it) {
313 while (!m_v.m_filling.compare_exchange_weak(expected,
true)) { expected=
false; nanosleep(0,0);}
314 int offset = m_v.m_data.size();
315 if (m_v.onDemand() &&
full()) {
316 m_v.m_filling =
false;
319 std::move(m_lv.begin(), m_lv.end(), std::back_inserter(m_v.m_data));
320 m_item.size=m_lv.size();
323 m_v.m_dataSize = m_v.m_data.size();
324 assert(m_v.m_filling==
true);
325 m_v.m_filling =
false;
331 int offset = m_v.m_dataSize;
332 return m_v.m_data.capacity()<offset+m_lv.size();
347 id_type
id()
const {
return m_item.id;}
348 size_type
size()
const {
return m_lv.size();}
349 bool empty()
const {
return m_lv.empty();}
354 DataIter
begin() {
return m_lv.begin();}
355 DataIter
end() {
return m_lv.end();}
364 data_type &
back() {
return m_lv.back();}
368 friend class ::TestDetSet;
377 friend class FastFiller;
378 friend class TSFastFiller;
381 class FindForDetSetVector :
public std::binary_function<const edmNew::DetSetVector<T>&, unsigned int, const T*> {
384 typename self::result_type
operator()(
typename self::first_argument_type iContainer,
typename self::second_argument_type iIndex)
385 #ifdef DSVN_USE_ATOMIC 388 while (!iContainer.m_filling.compare_exchange_weak(expected,
true,std::memory_order_acq_rel)) { expected=
false; nanosleep(0,0);}
389 typename self::result_type item = &(iContainer.m_data[iIndex]);
390 assert(iContainer.m_filling==
true);
391 iContainer.m_filling =
false;
398 friend class FindForDetSetVector;
401 m_subdetId(isubdet) {}
428 void swap(IdContainer & iic, DataContainer & idc) {
434 m_ids.reserve(isize);
435 m_data.reserve(dsize);
440 m_ids.shrink_to_fit();
441 m_data.shrink_to_fit();
444 void resize(
size_t isize,
size_t dsize) {
446 m_data.resize(dsize);
447 m_dataSize = m_data.size();
451 m_ids.erase(std::remove_if(m_ids.begin(),m_ids.end(),[](Item
const&
m){
return 0==
m.size;}),m_ids.end());
455 DetSet
insert(id_type iid, data_type
const * idata, size_type isize) {
456 Item & item = addItem(iid,isize);
457 m_data.resize(m_data.size()+isize);
459 m_dataSize = m_data.size();
460 return DetSet(*
this,item,
false);
463 DetSet
insert(id_type iid, size_type isize) {
464 Item & item = addItem(iid,isize);
465 m_data.resize(m_data.size()+isize);
466 m_dataSize = m_data.size();
467 return DetSet(*
this,item,
false);
472 return addItem(iid,0);
477 const_IdIter
p = findItem(iid);
478 if (p==m_ids.end())
return;
480 if ( (*p).isValid() && (*p).size>0 &&
481 m_data.size()==(*p).offset+(*p).size) {
482 m_data.resize((*p).offset);
483 m_dataSize = m_data.size();
485 m_ids.erase(m_ids.begin()+(p-m_ids.begin()));
490 Item &
addItem(id_type iid, size_type isize) {
491 Item it(iid,
size_type(m_data.size()),isize);
492 IdIter
p = std::lower_bound(m_ids.begin(),
507 return findItem(i)!=m_ids.end();
511 const_IdIter
p = findItem(i);
512 return p!=m_ids.end() && (*p).isValid();
525 const_IdIter
p = findItem(i);
527 return DetSet(*
this,*p,
true);
533 const_IdIter
p = findItem(i);
534 return (p==m_ids.end()) ?
end() :
535 boost::make_transform_iterator(p,
541 std::pair<const_IdIter,const_IdIter>
p =
542 std::equal_range(m_ids.begin(),m_ids.end(),Item(i));
543 return (p.first!=p.second) ? p.first : m_ids.end();
548 return boost::make_transform_iterator(m_ids.begin(),
554 return boost::make_transform_iterator(m_ids.end(),
560 template<
typename CMP>
563 std::pair<const_IdIter,const_IdIter>
p =
564 std::equal_range(m_ids.begin(),m_ids.end(),
i,cmp);
565 return Range(boost::make_transform_iterator(p.first,IterHelp(*
this,
update)),
566 boost::make_transform_iterator(p.second,IterHelp(*
this,
update))
572 bool empty()
const {
return m_ids.empty();}
577 size_type
size()
const {
return m_ids.size();}
582 return m_data[m_ids[cell].offset+frame];
585 data_type
const *
data(
size_t cell)
const {
586 return &m_data[m_ids[cell].offset];
589 size_type
detsetSize(
size_t cell)
const {
return m_ids[cell].size; }
591 id_type
id(
size_t cell)
const {
592 return m_ids[cell].id;
595 Item
const &
item(
size_t cell)
const {
601 IdContainer
const &
ids()
const {
return m_ids;}
602 DataContainer
const &
data()
const {
return m_data;}
610 friend class ::TestDetSet;
612 void update(Item const & item) const;
620 std::vector<Trans::Item> m_ids;
621 CMS_THREAD_GUARD("dstvdetails::DetSetVectorTrans::m_filling") mutable DataContainer m_data;
626 template<
typename T>
637 const std::vector<det_id_type>& iDets,
639 m_subdetId(isubdet) {
642 m_ids.reserve(iDets.size());
643 det_id_type sanityCheck = 0;
644 for(std::vector<det_id_type>::const_iterator itDetId = iDets.begin(), itDetIdEnd = iDets.end();
645 itDetId != itDetIdEnd;
647 assert(sanityCheck < *itDetId &&
"vector of det_id_type was not ordered");
648 sanityCheck = *itDetId;
649 m_ids.push_back(*itDetId);
653 #ifdef DSVN_USE_ATOMIC 657 if (m_getter.empty()) { assert(item.
isValid());
return;}
662 (*boost::any_cast<std::shared_ptr<Getter> >(&m_getter))->fill(ff);
670 #ifdef DSVN_USE_ATOMIC 675 if (update) icont.
update(item);
677 m_data=&icont.
data();
686 #include <boost/mpl/assert.hpp> 687 #include <boost/type_traits/is_same.hpp> 692 namespace refhelper {
701 namespace refhelper {
705 typename self::result_type
operator()(
typename self::first_argument_type iContainer,
typename self::second_argument_type iIndex) {
706 return &(iContainer[iIndex]);
720 template<
class HandleT>
724 typename HandleT::element_type::value_type::const_iterator itIter) {
726 auto index = itIter - &iHandle->data().front();
727 return edm::Ref<
typename HandleT::element_type,
729 (iHandle.id(), &(*itIter),
index);
743 static size_t size(
const edmNew::DetSetVector<T>* iContainer) {
return iContainer->
dataSize();}
744 static unsigned int indexFor(
const value_type* iElement,
const edmNew::DetSetVector<T>* iContainer) {
745 return iElement-&(iContainer->
data().front());
750 #ifdef DSVN_USE_ATOMIC 751 #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
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
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)
PixelRecoRange< float > Range
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()
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
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