19 #include <type_traits> 35 template <
typename COUNTER, std::
size_t NCounters>
40 using Array_t = std::array<Counter_t, NCounters>;
48 { Array_t::operator[](index) =
value; }
54 (Array_t::data() + begin, Array_t::data() + begin + n, value);
70 static constexpr
size_t NCounters = SIZE;
82 template <
typename Alloc>
84 = std::map<Key_t, CounterBlock_t, std::less<Key_t>, Alloc>;
136 unsigned int SUBCOUNTERS=1
139 static_assert(SUBCOUNTERS == 1,
"subcounters not implemented yet");
141 "the size of the cluster of counters must be a power of 2");
156 static constexpr
size_t NCounters = Traits_t::NCounters;
159 static constexpr
size_t NSubcounters = NCounters * SUBCOUNTERS;
169 typename std::allocator_traits<Allocator_t>::template rebind_alloc
245 bool empty()
const {
return counter_map.empty(); }
250 {
return counter_map.size() * NSubcounters; }
270 template <
typename OALLOC>
273 Key_t& first_difference
282 template <
typename OALLOC>
285 {
Key_t dummy;
return is_equal(to, dummy); }
305 block(major), counter(minor) {}
310 CounterKey_t(key & ~MinorKeyMask, key & MinorKeyMask) {}
317 operator Key_t()
const {
return Key(); }
321 {
if (++counter == MinorKeyRange) next_block();
return *
this; }
324 if (counter-- == 0) { prev_block(); counter = MinorKeyRange - 1; }
328 {
CounterKey_t old(*
this); this->operator++();
return old; }
330 {
CounterKey_t old(*
this); this->operator--();
return old; }
337 { block -= MinorKeyRange;
return start_block(); }
341 { block += MinorKeyRange;
return start_block(); }
345 static constexpr
Key_t MinorKeyRange = NSubcounters;
351 static constexpr
Key_t MinorKeyMask = MinorKeyRange - 1;
354 (MinorKeyBits > 0,
"Wrong COUNTER value for lar::CountersMap");
368 {
return GetCounter(key); }
380 {
return { it, ix }; }
405 namespace counters_map {
423 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SUB>
426 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SUB>
434 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SUB>
436 public std::bidirectional_iterator_tag
457 if (++index >= NSubcounters) { ++iter; index = 0; }
461 {
iterator_type old(*
this); this->operator++();
return old; }
465 if (index == 0) { --iter; index = NSubcounters - 1; }
470 {
iterator_type old(*
this); this->operator--();
return old; }
473 {
return (iter == as.
iter) && (index == as.
index); }
475 {
return (iter != as.
iter) || (index != as.
index); }
488 iter(it), index(ix) {}
493 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SUB>
498 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SUB>
503 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SUB>
509 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SUB>
514 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SUB>
520 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SUB>
521 template <
typename OALLOC>
524 Key_t& first_difference
528 =
const std::map<Key_t, SubCounter_t, std::less<Key_t>, OALLOC>;
530 for (
const typename const_iterator::value_type& p: *
this) {
532 if (to_iter != to_end) {
535 if (p.first > to_iter->first) {
536 first_difference = to_iter->first;
547 if (p.first == to_iter->first) {
550 if (to_iter->second != p.second) {
554 first_difference = to_iter->first;
559 else if (p.first < to_iter->first) {
565 first_difference = p.first;
580 first_difference = p.first;
590 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SUB>
595 return (iBlock == counter_map.end())? 0: iBlock->second[key.
counter];
599 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SUB>
605 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SUB>
613 if (iBlock != counter_map.end()) {
614 if (iBlock->first == key.
block) {
623 counter_map.insert(iBlock, { key.
block, { key.
counter, value } } );
628 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SUB>
636 if (iBlock != counter_map.end()) {
637 if (iBlock->first == key.
block) {
638 return iBlock->second[key.
counter] += delta;
646 counter_map.insert(iBlock, { key.
block, { key.
counter, delta } } );
654 #endif // BULKALLOCATOR_H CounterKey_t & operator--(int)
Key_t Key() const
Returns the full key.
Type of block of counters (just a STL array until SUBCOUNTERS are in)
const_iterator end() const
Returns an iterator past-the-end of the counters.
CounterKey_t & operator++(int)
typename Traits_t::CounterBlock_t CounterBlock_t
std::make_unsigned< Key_t >::type n_counters() const
Returns the number of allocated counters.
void fill(const value_type &value)
CountersMap(Allocator_t alloc)
Constructor, specifies an allocator.
static constexpr bool bDebug
CounterIndex_t counter
index of the counter in the block
KEY Key_t
type of counter key in the map
typename std::make_unsigned< Key_t >::type CounterIndex_t
type of index in the block
value_type operator*() const
Access to the pointed pair.
SubCounter_t increment(Key_t key)
Increments by 1 the specified counter.
Allocator_t allocator_type
type of the single counter
bool is_equal(const std::map< Key_t, SubCounter_t, std::less< Key_t >, OALLOC > &to, Key_t &first_difference) const
Returns whether the counters in this map are equivalent to another.
CounterIndex_t index
index of the counted in the subblock
typename CounterMap_t::value_type value_type
value type: pair
typename Array_t::value_type value_type
iterator_type & operator--()
typename PlainBaseMap_t::value_type MapValue_t
Type of value in the map.
static CounterKey_t SplitKey(Key_t key)
Returns a split key corresponding to the specified key.
std::bidirectional_iterator_tag iterator_category
BaseMap_t::const_iterator iter
iterator to the block of counters
void fill(size_t begin, size_t n, const value_type &value)
CounterKey_t & next_block()
Skips to the beginning of the next block.
COUNTER Counter_t
Type of the single counter.
BlockKey_t block
key of the counter block
typename PlainBaseMap_t::allocator_type DefaultAllocator_t
Type of allocator for the plain map.
typename Traits_t::template BaseMap_t< typename std::allocator_traits< Allocator_t >::template rebind_alloc< typename Traits_t::MapValue_t > > BaseMap_t
Type of the map used in the implementation.
auto array(Array const &a)
Returns a manipulator which will print the specified array.
Key_t BlockKey_t
type of block key
CountersMap()
Default constructor (empty map)
iterator_type operator--(int)
Counter_t & GetOrCreateCounter(CounterKey_t key)
Returns the counter at the specified split key.
constexpr int LowestSetBitScaler(unsigned long long int v, int b)
Internally used by LowestSetBit.
std::vector< evd::details::RawDigitInfo_t >::const_iterator begin(RawDigitCacheDataClass const &cache)
SubCounter_t GetSubCounter(CounterKey_t key) const
Returns the value of the subcounter at the specified split key.
CounterKey_t(BlockKey_t major, CounterIndex_t minor)
Constructor from a pair.
CounterBlock()
Default constructor: initializes the array to 0.
CounterKey_t & start_block()
Skips to the beginning of this block.
COUNTER Counter_t
type of the single counter
CounterKey_t(Key_t key)
Initialize from a mangled key.
void fill(const art::PtrVector< recob::Hit > &hits, int only_plane)
Counter_t GetCounter(CounterKey_t key) const
Returns the value of the counter at the specified split key.
const_iterator begin() const
Returns an iterator to the begin of the counters.
CounterKey_t & operator++()
std::map< Key_t, CounterBlock_t, std::less< Key_t >, Alloc > BaseMap_t
Base type of map, allowing a custom allocator.
SubCounter_t decrement(Key_t key)
Decrements by 1 the specified counter.
const value_type & reference
std::array< Counter_t, NCounters > Array_t
type of base class
BaseMap_t counter_map
the actual data structure for counters
const_iterator(typename BaseMap_t::const_iterator it, size_t ix)
Private constructor (from a map iterator and a block index)
ALLOC Allocator_t
type of the single counter
Structure with the index of the counter, split as needed.
bool operator!=(geometry_element_iterator< GEOIDITER > const &iter, GEOIDITER const &id_iter)
Comparison operator: geometry ID and element point to different IDs.
SubCounter_t unchecked_set(CounterKey_t key, SubCounter_t delta)
Sets the specified counter to a value (no check on value range)
SubCounter_t mapped_type
type of the single counter
std::string value(boost::any const &)
LArSoft-specific namespace.
iterator_type operator++(int)
CounterKey_t key() const
Returns the key of the pointed item as a CounterKey_t.
std::map< Key_t, CounterBlock_t, std::less< Key_t >> PlainBaseMap_t
General type of map (no special allocator specified).
const value_type * pointer
CounterBlock(size_t index, Counter_t value)
Convenience constructor: initializes all counters to 0, except one.
KEY Key_t
Type of counter key in the map.
iterator_type & operator++()
std::ptrdiff_t difference_type
Map storing counters in a compact way.
std::vector< evd::details::RawDigitInfo_t >::const_iterator end(RawDigitCacheDataClass const &cache)
bool empty() const
Returns whether the map has no counters.
SubCounter_t unchecked_add(CounterKey_t key, SubCounter_t delta)
Adds a delta to the specified counter (no check on underflow/overflow)
CounterKey_t & operator--()
Counter_t SubCounter_t
Type of the subcounter (that is, the actual counter)
constexpr int LowestSetBit(unsigned long long int v)
Returns the position of the first set bit (0 for LSB)
SubCounter_t set(Key_t key, SubCounter_t value)
Sets the specified counter to a count.
CounterKey_t & prev_block()
Skips to the beginning of the previous block.
bool operator==(geometry_element_iterator< GEOIDITER > const &iter, GEOIDITER const &id_iter)
Comparison operator: geometry ID and element point to the same ID.
std::pair< const Key_t, SubCounter_t > value_type
constexpr bool IsPowerOf2(unsigned long long int v)
Returns true if the argument is a power of 2.