18 #include <type_traits> 35 template <
typename COUNTER, std::
size_t NCounters>
40 using Array_t = std::array<Counter_t, NCounters>;
49 Array_t::operator[](index) =
value;
55 std::fill(Array_t::data() + begin, Array_t::data() + begin + n, value);
60 template <
typename KEY,
typename COUNTER,
size_t SIZE>
67 static constexpr
size_t NCounters = SIZE;
79 template <
typename Alloc>
80 using BaseMap_t = std::map<Key_t, CounterBlock_t, std::less<Key_t>, Alloc>;
124 template <
typename KEY,
129 unsigned int SUBCOUNTERS = 1>
131 static_assert(SUBCOUNTERS == 1,
"subcounters not implemented yet");
132 static_assert(
IsPowerOf2(SIZE),
"the size of the cluster of counters must be a power of 2");
146 static constexpr
size_t NCounters = Traits_t::NCounters;
149 static constexpr
size_t NSubcounters = NCounters * SUBCOUNTERS;
157 using BaseMap_t =
typename Traits_t::template
BaseMap_t<
typename std::allocator_traits<
158 Allocator_t>::template rebind_alloc<typename Traits_t::MapValue_t>>;
228 bool empty()
const {
return counter_map.empty(); }
233 return counter_map.size() * NSubcounters;
253 template <
typename OALLOC>
255 Key_t& first_difference)
const;
262 template <
typename OALLOC>
266 return is_equal(to, dummy);
296 operator Key_t()
const {
return Key(); }
300 if (++counter == MinorKeyRange) next_block();
305 if (counter-- == 0) {
307 counter = MinorKeyRange - 1;
334 block -= MinorKeyRange;
335 return start_block();
341 block += MinorKeyRange;
342 return start_block();
346 static constexpr
Key_t MinorKeyRange = NSubcounters;
352 static constexpr
Key_t MinorKeyMask = MinorKeyRange - 1;
354 static_assert(MinorKeyBits > 0,
"Wrong COUNTER value for lar::CountersMap");
401 namespace counters_map {
419 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SUB>
422 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SUB>
429 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SUB>
450 if (++index >= NSubcounters) {
467 index = NSubcounters - 1;
482 return (iter == as.
iter) && (index == as.
index);
486 return (iter != as.
iter) || (index != as.
index);
502 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SUB>
510 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SUB>
517 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SUB>
524 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SUB>
531 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SUB>
538 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SUB>
539 template <
typename OALLOC>
542 Key_t& first_difference)
const 545 using CompMap_t =
const std::map<Key_t, SubCounter_t, std::less<Key_t>, OALLOC>;
549 if (to_iter != to_end) {
552 if (p.first > to_iter->first) {
553 first_difference = to_iter->first;
564 if (p.first == to_iter->first) {
567 if (to_iter->second != p.second) {
571 first_difference = to_iter->first;
576 else if (p.first < to_iter->first) {
582 first_difference = p.first;
597 first_difference = p.first;
606 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SUB>
611 return (iBlock == counter_map.end()) ? 0 : iBlock->second[key.
counter];
614 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SUB>
621 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SUB>
629 if (iBlock != counter_map.end()) {
630 if (iBlock->first == key.
block) {
639 counter_map.insert(iBlock, {key.
block, {key.
counter, value}});
643 template <
typename K,
typename C,
size_t S,
typename A,
unsigned int SUB>
651 if (iBlock != counter_map.end()) {
652 if (iBlock->first == key.
block) {
653 return iBlock->second[key.
counter] += delta;
661 counter_map.insert(iBlock, {key.
block, {key.
counter, delta}});
667 #endif // BULKALLOCATOR_H
SubCounter_t operator[](Key_t key) const
Read-only access to an element; returns 0 if no counter is present.
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.
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.
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
static const_iterator make_const_iterator(typename BaseMap_t::const_iterator it, size_t ix)
Creates a const_iterator (useful in derived classes)
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.
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
BlockKey_t block
key of the counter block
bool operator==(const iterator_type &as) const
typename PlainBaseMap_t::allocator_type DefaultAllocator_t
Type of allocator for the plain map.
auto counter(T begin, T end)
Returns an object to iterate values from begin to end in a range-for loop.
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.
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++()
bool is_equal(const std::map< Key_t, SubCounter_t, std::less< Key_t >, OALLOC > &to) const
Returns whether the counters in this map are equivalent to another.
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.
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
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.
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
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.
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.
bool operator!=(const iterator_type &as) const