All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CountersMap.h
Go to the documentation of this file.
1 /**
2  * @file CountersMap.h
3  * @brief Map of counters, stored compactly
4  * @author Gianluca Petrillo (petrillo@fnal.gov)
5  * @date August 22th, 2014
6  */
7 
8 #ifndef COUNTERSMAP_H
9 #define COUNTERSMAP_H
10 
11 // interface include
12 #include <cstddef> // std::ptrdiff_t
13 #include <map>
14 #include <array>
15 #include <functional> // std::less<>
16 #include <memory> // std::allocator<>
17 #include <utility> // std::pair<>
18 #include <iterator> // std::bidirectional_iterator_tag
19 #include <type_traits> // std::make_unsigned
20 
21 
22 namespace lar {
23 
24  /// Returns true if the argument is a power of 2
25  constexpr bool IsPowerOf2(unsigned long long int v)
26  { return v & 1? v == 1: IsPowerOf2(v >> 1); }
27 
28  /// Returns the position of the first set bit (0 for LSB)
29  constexpr int LowestSetBit(unsigned long long int v);
30 
31 
32  namespace details {
33 
34  /// Type of block of counters (just a STL array until SUBCOUNTERS are in)
35  template <typename COUNTER, std::size_t NCounters>
36  class CounterBlock: public std::array<COUNTER, NCounters> {
37  public:
38  using Counter_t = COUNTER;
39 
40  using Array_t = std::array<Counter_t, NCounters>; ///< type of base class
41  using value_type = typename Array_t::value_type;
42 
43  /// Default constructor: initializes the array to 0
45 
46  /// Convenience constructor: initializes all counters to 0, except one
48  { Array_t::operator[](index) = value; }
49 
50  void fill(const value_type& value) { Array_t::fill(value); }
51  void fill(size_t begin, size_t n, const value_type& value)
52  {
53  std::fill
54  (Array_t::data() + begin, Array_t::data() + begin + n, value);
55  }
56 
57  }; // CounterBlock
58 
59  template <
60  typename KEY,
61  typename COUNTER,
62  size_t SIZE
63  >
65 
66  using Key_t = KEY; ///< Type of counter key in the map.
67  using Counter_t = COUNTER; ///< Type of the single counter.
68 
69  /// Number of counters in one counter block.
70  static constexpr size_t NCounters = SIZE;
71 
72  /// Type of counter block actually stored.
74 
75  /// General type of map (no special allocator specified).
76  using PlainBaseMap_t = std::map<Key_t, CounterBlock_t, std::less<Key_t>>;
77 
78  /// Type of allocator for the plain map.
79  using DefaultAllocator_t = typename PlainBaseMap_t::allocator_type;
80 
81  /// Base type of map, allowing a custom allocator.
82  template <typename Alloc>
83  using BaseMap_t
84  = std::map<Key_t, CounterBlock_t, std::less<Key_t>, Alloc>;
85 
86  /// Type of value in the map.
87  using MapValue_t = typename PlainBaseMap_t::value_type;
88 
89  }; // struct CountersMapTraits
90 
91  } // namespace details
92 
93 
94 
95  /**
96  * @brief Map storing counters in a compact way
97  * @param KEY the type of the key of the counters map
98  * @param COUNTER the type of a basic counter (can be signed or unsigned)
99  * @param BLOCKSIZE the number of counters in a cluster
100  * @param ALLOC allocator for the underlying STL map
101  * @param SUBCOUNTERS split each counter in subcounters (not implemented yet)
102  *
103  * This class is designed for the need of a vast number of counters with
104  * a integral numerical key, when the counter keys are usually clustered.
105  * This can be more or less efficient than a straight counters STL map
106  * according to how often the counters are clustered (if that does not happen
107  * often, CountersMap can have considerable memory overhead).
108  *
109  * Counters are allocated in contiguous blocks of BLOCKSIZE counters.
110  * The selling point here is that a map node has some overhead (typically
111  * at least 3 pointers) and dynamically allocating it costs a lot (40 bytes
112  * have been observed). If you need a counter with a range of 100 (1 byte),
113  * that's far from optimal in many aspects (memory allocation also takes
114  * time).
115  *
116  * The requirement of the key to be numerical is so that the concept of
117  * "next counter" is well defined and we can store contiguous counters
118  * in a fixed structure.
119  *
120  * <h3>Subcounters</h3>
121  * The idea behind subcounters is that you migt want to split a counter into
122  * subcounters to save memory if the maximum counter value is smaller than
123  * the range of the counter type.
124  * <strong>The implementation is delayed</strong> since in the end the same
125  * effect can be achieved by using a small counter type (e.g. signed char),
126  * unless the range is smaller that 16 (or 4, or 2), in which case the
127  * character can be split into bits. That will cause some overhead for
128  * increment and decrement instructions.
129  */
130  template <
131  typename KEY,
132  typename COUNTER,
133  size_t SIZE,
134  typename ALLOC
136  unsigned int SUBCOUNTERS=1
137  >
138  class CountersMap {
139  static_assert(SUBCOUNTERS == 1, "subcounters not implemented yet");
140  static_assert(IsPowerOf2(SIZE),
141  "the size of the cluster of counters must be a power of 2");
142 
143  /// Set of data types pertaining this counter.
145 
146  public:
147  using Key_t = KEY; ///< type of counter key in the map
148  using Counter_t = COUNTER; ///< type of the single counter
149  using Allocator_t = ALLOC; ///< type of the single counter
150 
151  /// This class
153 
154 
155  /// Number of counters in one counter block
156  static constexpr size_t NCounters = Traits_t::NCounters;
157 
158  /// Number of subcounters in one counter block
159  static constexpr size_t NSubcounters = NCounters * SUBCOUNTERS;
160 
161  /// Type of the subcounter (that is, the actual counter)
163 
164 
166 
167  /// Type of the map used in the implementation
168  using BaseMap_t = typename Traits_t::template BaseMap_t<
169  typename std::allocator_traits<Allocator_t>::template rebind_alloc
170  <typename Traits_t::MapValue_t>
171  >;
172 
173  /*
174  /// Iterator through the allocated elements
175  using const_iterator = double_fwd_const_iterator<
176  typename BaseMap_t::const_iterator,
177  PairSecond<typename BaseMap_t::value_type>
178  >;
179  */
180 
181  ///@{
182  /// @name STL type definitions
184  using allocator_type = Allocator_t; ///< type of the single counter
185  // TODO others are missing
186  ///@}
187 
188  using value_type = std::pair<const Key_t, SubCounter_t>;
189 
190  /// Iterator through the counters (shown as value_type)
191  class const_iterator;
192 
193 
194  /// Default constructor (empty map)
196 
197  /// Constructor, specifies an allocator
199 
200 
201  /// Read-only access to an element; returns 0 if no counter is present
202  SubCounter_t operator[] (Key_t key) const { return GetSubCounter(key); }
203 
204  /**
205  * @brief Sets the specified counter to a count
206  * @param key key of the counter to be increased
207  * @param value count value to be set
208  * @return new value of the counter
209  *
210  * Given the complex underlying structure (especially when subcounters are
211  * involved), a special method is used to set the value of a counter.
212  * This is equivalent to map's operator[] in non-constant version, but the
213  * creation of a new counter is explicit.
214  */
216 
217  /**
218  * @brief Increments by 1 the specified counter
219  * @param key key of the counter to be increased
220  * @return new value of the counter
221  */
223 
224  /**
225  * @brief Decrements by 1 the specified counter
226  * @param key key of the counter to be decreased
227  * @return new value of the counter
228  */
230 
231 
232  ///@{
233  /// @name Iterators (experimental)
234  // this stuff needs serious work to be completed
235 
236  /// Returns an iterator to the begin of the counters
237  const_iterator begin() const;
238 
239  /// Returns an iterator past-the-end of the counters
240  const_iterator end() const;
241  ///@}
242 
243 
244  /// Returns whether the map has no counters
245  bool empty() const { return counter_map.empty(); }
246 
247 
248  /// Returns the number of allocated counters
250  { return counter_map.size() * NSubcounters; }
251 
252 
253  /**
254  * @brief Returns whether the counters in this map are equivalent to another
255  * @param to a STL map
256  * @param first_difference key of the first difference
257  * @return whether the counters are equivalent
258  *
259  * The maps are considered equal if all keys in each are present in the
260  * other, and their counters have the same value, with one exception:
261  * counters in CountersMap can not to exist in the other map, but only if
262  * their count is 0 (these should be plenty of them since counters are
263  * created in blocks).
264  *
265  * If there is a key in one map but not in the other, first_difference
266  * stores that key; if a counter is present in both maps but with a
267  * different count, first_difference reports the key of that counter.
268  * If no difference is found, first_difference is left untouched.
269  */
270  template <typename OALLOC>
271  bool is_equal(
272  const std::map<Key_t, SubCounter_t, std::less<Key_t>, OALLOC>& to,
273  Key_t& first_difference
274  ) const;
275 
276 
277  /**
278  * @brief Returns whether the counters in this map are equivalent to another
279  * @param to a STL map
280  * @return whether the counters are equivalent
281  */
282  template <typename OALLOC>
283  bool is_equal
284  (const std::map<Key_t, SubCounter_t, std::less<Key_t>, OALLOC>& to) const
285  { Key_t dummy; return is_equal(to, dummy); }
286 
287 
288  protected:
289 
290  using BlockKey_t = Key_t; ///< type of block key
292  ///< type of index in the block
293 
294 
295  /// Structure with the index of the counter, split as needed
296  struct CounterKey_t {
297  BlockKey_t block; ///< key of the counter block
298  CounterIndex_t counter; ///< index of the counter in the block
299  // there should be a subcluster index here too
300 
302 
303  /// Constructor from a pair
305  block(major), counter(minor) {}
306 
307  /// Initialize from a mangled key
309  // CounterKey_t(key >> MinorKeyBits, key & MinorKeyMask) {}
310  CounterKey_t(key & ~MinorKeyMask, key & MinorKeyMask) {}
311 
312  /// Returns the full key
313  // Key_t Key() const { return (block << MinorKeyBits) + counter; }
314  Key_t Key() const { return block + counter; }
315 
316  /// Conversion of this key into a number (@see Key())
317  operator Key_t() const { return Key(); }
318 
319 
321  { if (++counter == MinorKeyRange) next_block(); return *this; }
323  {
324  if (counter-- == 0) { prev_block(); counter = MinorKeyRange - 1; }
325  return *this;
326  } // operator--()
328  { CounterKey_t old(*this); this->operator++(); return old; }
330  { CounterKey_t old(*this); this->operator--(); return old; }
331 
332  /// Skips to the beginning of this block
333  CounterKey_t& start_block() { counter = 0; return *this; }
334 
335  /// Skips to the beginning of the previous block
337  { block -= MinorKeyRange; return start_block(); }
338 
339  /// Skips to the beginning of the next block
341  { block += MinorKeyRange; return start_block(); }
342 
343 
344  /// Number of values of the minor key
345  static constexpr Key_t MinorKeyRange = NSubcounters;
346 
347  /// Number of bits for the minor key
349 
350  /// Bit mask for the minor key
351  static constexpr Key_t MinorKeyMask = MinorKeyRange - 1;
352 
353  static_assert
354  (MinorKeyBits > 0, "Wrong COUNTER value for lar::CountersMap");
355 
356  }; // struct CounterKey_t
357 
358 
359  BaseMap_t counter_map; ///< the actual data structure for counters
360 
361 
362  /// Returns the value of the counter at the specified split key
363  Counter_t GetCounter(CounterKey_t key) const;
364 
365  /// Returns the value of the subcounter at the specified split key
366  // Since subcounters are not implemented yet, this is a no-op
368  { return GetCounter(key); }
369 
370  /// Returns the counter at the specified split key
371  Counter_t& GetOrCreateCounter(CounterKey_t key);
372 
373 
374  /// Returns a split key corresponding to the specified key
375  static CounterKey_t SplitKey(Key_t key) { return key; }
376 
377  /// Creates a const_iterator (useful in derived classes)
378  static const_iterator make_const_iterator
379  (typename BaseMap_t::const_iterator it, size_t ix)
380  { return { it, ix }; }
381 
382  private:
383 
384  /// Sets the specified counter to a value (no check on value range)
385  SubCounter_t unchecked_set(CounterKey_t key, SubCounter_t delta);
386 
387  /// Adds a delta to the specified counter (no check on underflow/overflow)
388  SubCounter_t unchecked_add(CounterKey_t key, SubCounter_t delta);
389 
390  }; // class CountersMap
391 
392 
393 } // namespace lar
394 
395 
396 //------------------------------------------------------------------------------
397 
398 namespace lar {
399 
400  namespace details {
401  /// Internally used by LowestSetBit
402  inline constexpr int LowestSetBitScaler(unsigned long long int v, int b)
403  { return (v & 1)? b: LowestSetBitScaler(v >> 1, b + 1); }
404 
405  namespace counters_map {
406  static constexpr bool bDebug = true;
407 
408 
409  } // namespace counters_map
410  } // namespace details
411 
412 
413  inline constexpr int LowestSetBit(unsigned long long int v)
414  { return (v == 0)? -1: details::LowestSetBitScaler(v, 0); }
415 
416  // providing "definitions" of the static constants;
417  // these are required if the code is going to take the address of these
418  // constants, which is most often due to the use of "const size_t&" in some
419  // function, where "size_t" is a template argument type
420  // (or else the reference would not be needed).
421  // I am not providing the same for the protected and private members
422  // (just because of laziness).
423  template <typename K, typename C, size_t S, typename A, unsigned int SUB>
424  constexpr size_t CountersMap<K, C, S, A, SUB>::NCounters;
425 
426  template <typename K, typename C, size_t S, typename A, unsigned int SUB>
427  constexpr size_t CountersMap<K, C, S, A, SUB>::NSubcounters;
428 
429 
430  // CountersMap<>::const_iterator does not fully implement the STL iterator
431  // interface, since it does not implement operator-> () (for technical reason:
432  // the value does not actually exist and it does not have an address),
433  // in addition to std::swap().
434  template <typename K, typename C, size_t S, typename A, unsigned int SUB>
435  class CountersMap<K, C, S, A, SUB>::const_iterator:
436  public std::bidirectional_iterator_tag
437  {
439 
440  public:
441  using value_type = typename CounterMap_t::value_type; ///< value type: pair
442  using difference_type = std::ptrdiff_t;
443  using pointer = const value_type*;
444  using reference = const value_type&;
445  using iterator_category = std::bidirectional_iterator_tag;
446 
448 
449  /// Default constructor
450  const_iterator() = default;
451 
452  /// Access to the pointed pair
453  value_type operator*() const { return { key(), iter->second[index] }; }
454 
456  {
457  if (++index >= NSubcounters) { ++iter; index = 0; }
458  return *this;
459  } // operator++
461  { iterator_type old(*this); this->operator++(); return old; }
462 
464  {
465  if (index == 0) { --iter; index = NSubcounters - 1; }
466  else --index;
467  return *this;
468  } // operator--()
470  { iterator_type old(*this); this->operator--(); return old; }
471 
472  bool operator== (const iterator_type& as) const
473  { return (iter == as.iter) && (index == as.index); }
474  bool operator!= (const iterator_type& as) const
475  { return (iter != as.iter) || (index != as.index); }
476 
477 
478  /// Returns the key of the pointed item as a CounterKey_t
479  CounterKey_t key() const { return { iter->first, index }; }
480 
481  protected:
482  typename BaseMap_t::const_iterator iter;
483  ///< iterator to the block of counters
484  CounterIndex_t index; ///< index of the counted in the subblock
485 
486  /// Private constructor (from a map iterator and a block index)
487  const_iterator(typename BaseMap_t::const_iterator it, size_t ix):
488  iter(it), index(ix) {}
489 
490  }; // CountersMap<>::const_iterator
491 
492 
493  template <typename K, typename C, size_t S, typename A, unsigned int SUB>
496  { return unchecked_set(CounterKey_t(key), value); }
497 
498  template <typename K, typename C, size_t S, typename A, unsigned int SUB>
501  { return unchecked_add(CounterKey_t(key), +1); }
502 
503  template <typename K, typename C, size_t S, typename A, unsigned int SUB>
506  { return unchecked_add(CounterKey_t(key), -1); }
507 
508 
509  template <typename K, typename C, size_t S, typename A, unsigned int SUB>
512  { return const_iterator{ counter_map.begin(), 0 }; }
513 
514  template <typename K, typename C, size_t S, typename A, unsigned int SUB>
517  { return const_iterator{ counter_map.end(), 0 }; }
518 
519 
520  template <typename K, typename C, size_t S, typename A, unsigned int SUB>
521  template <typename OALLOC>
523  const std::map<Key_t, SubCounter_t, std::less<Key_t>, OALLOC>& to,
524  Key_t& first_difference
525  ) const {
526  // this function is not optimised
527  using CompMap_t
528  = const std::map<Key_t, SubCounter_t, std::less<Key_t>, OALLOC>;
529  typename CompMap_t::const_iterator to_iter = to.begin(), to_end = to.end();
530  for (const typename const_iterator::value_type& p: *this) {
531 
532  if (to_iter != to_end) { // we have still counters to find
533  // if counter is already beyond the next non-empty one froml STL map,
534  // then we are missing some
535  if (p.first > to_iter->first) {
536  first_difference = to_iter->first;
537  return false;
538  }
539  // while (p.first > to_iter->first) {
540  // ++nMissingKeys;
541  // std::cout << "ERROR missing key " << to_iter->first << std::endl;
542  // if (++to_iter == to_end) break;
543  // } // while
544  // } // if
545  //
546  // if (to_iter != to_end) { // we have still counters to find
547  if (p.first == to_iter->first) {
548  // if the counter is in SLT map, the two counts must match
549  // std::cout << " " << p.first << " " << p.second << std::endl;
550  if (to_iter->second != p.second) {
551  // std::cout << "ERROR wrong counter value " << p.second
552  // << ", expected " << to_iter->second << std::endl;
553  // ++nMismatchValue;
554  first_difference = to_iter->first;
555  return false;
556  }
557  ++to_iter; // done with it
558  }
559  else if (p.first < to_iter->first) {
560  // if the counter is not in STL map, then it must be 0
561  if (p.second != 0) {
562  // ++nExtraKeys;
563  // std::cout << "ERROR extra key " << p.first << " (" << p.second << ")"
564  // << std::endl;
565  first_difference = p.first;
566  return false;
567  }
568  // else {
569  // std::cout << " " << p.first << " " << p.second << " (not in STL)"
570  // << std::endl;
571  // }
572  }
573  }
574  else { // if we are at the end of compared map
575  // no more keys in STL map
576  if (p.second != 0) {
577  // ++nExtraKeys;
578  // std::cout << "ERROR extra key " << p.first << " (" << p.second << ")"
579  // << std::endl;
580  first_difference = p.first;
581  return false;
582  }
583  }
584  } // for element in map
585 
586  return true;
587  } // CountersMap<>::is_equal()
588 
589 
590  template <typename K, typename C, size_t S, typename A, unsigned int SUB>
593  {
594  typename BaseMap_t::const_iterator iBlock = counter_map.find(key.block);
595  return (iBlock == counter_map.end())? 0: iBlock->second[key.counter];
596  } // CountersMap<>::GetCounter() const
597 
598 
599  template <typename K, typename C, size_t S, typename A, unsigned int SUB>
602  { return counter_map[key.block][key.counter]; }
603 
604 
605  template <typename K, typename C, size_t S, typename A, unsigned int SUB>
609  {
610  // take it low level here
611  // first get the iterator to the block
612  typename BaseMap_t::iterator iBlock = counter_map.lower_bound(key.block);
613  if (iBlock != counter_map.end()) {
614  if (iBlock->first == key.block) { // sweet, we have that counter already
615  return iBlock->second[key.counter] = value;
616  }
617  }
618  // no counter there yet: create one;
619  // hint to insert before the block in the position we jave already found
620  // (this is optimal in STL map for C++11);
621  // create a block using the special constructor;
622  // the temporary value created here is moved to the map
623  counter_map.insert(iBlock, { key.block, { key.counter, value } } );
624  return value;
625  } // CountersMap<>::unchecked_add() const
626 
627 
628  template <typename K, typename C, size_t S, typename A, unsigned int SUB>
632  {
633  // take it low level here
634  // first get the iterator to the block
635  typename BaseMap_t::iterator iBlock = counter_map.lower_bound(key.block);
636  if (iBlock != counter_map.end()) {
637  if (iBlock->first == key.block) { // sweet, we have that counter already
638  return iBlock->second[key.counter] += delta;
639  }
640  }
641  // no counter there yet: create one;
642  // hint to insert before the block in the position we jave already found
643  // (this is optimal in STL map for C++11);
644  // create a block using the special constructor;
645  // the temporary value created here is moved to the map
646  counter_map.insert(iBlock, { key.block, { key.counter, delta } } );
647  return delta;
648  } // CountersMap<>::unchecked_add() const
649 
650 
651 } // namespace lar
652 
653 
654 #endif // BULKALLOCATOR_H
SubCounter_t operator[](Key_t key) const
Read-only access to an element; returns 0 if no counter is present.
Definition: CountersMap.h:202
CounterKey_t & operator--(int)
Definition: CountersMap.h:329
Key_t Key() const
Returns the full key.
Definition: CountersMap.h:314
Type of block of counters (just a STL array until SUBCOUNTERS are in)
Definition: CountersMap.h:36
const_iterator end() const
Returns an iterator past-the-end of the counters.
Definition: CountersMap.h:516
see a below echo S(symbol in a section other than those above)
CounterKey_t & operator++(int)
Definition: CountersMap.h:327
typename Traits_t::CounterBlock_t CounterBlock_t
Definition: CountersMap.h:165
std::make_unsigned< Key_t >::type n_counters() const
Returns the number of allocated counters.
Definition: CountersMap.h:249
void fill(const value_type &value)
Definition: CountersMap.h:50
CountersMap(Allocator_t alloc)
Constructor, specifies an allocator.
Definition: CountersMap.h:198
static constexpr bool bDebug
Definition: CountersMap.h:406
CounterIndex_t counter
index of the counter in the block
Definition: CountersMap.h:298
KEY Key_t
type of counter key in the map
Definition: CountersMap.h:147
typename std::make_unsigned< Key_t >::type CounterIndex_t
type of index in the block
Definition: CountersMap.h:292
value_type operator*() const
Access to the pointed pair.
Definition: CountersMap.h:453
SubCounter_t increment(Key_t key)
Increments by 1 the specified counter.
Definition: CountersMap.h:500
Allocator_t allocator_type
type of the single counter
Definition: CountersMap.h:184
CounterBlock< Counter_t, NCounters > CounterBlock_t
Type of counter block actually stored.
Definition: CountersMap.h:73
pdgs p
Definition: selectors.fcl:22
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.
Definition: CountersMap.h:522
CounterIndex_t index
index of the counted in the subblock
Definition: CountersMap.h:484
typename CounterMap_t::value_type value_type
value type: pair
Definition: CountersMap.h:441
typename Array_t::value_type value_type
Definition: CountersMap.h:41
static constexpr Key_t MinorKeyRange
Number of values of the minor key.
Definition: CountersMap.h:345
typename PlainBaseMap_t::value_type MapValue_t
Type of value in the map.
Definition: CountersMap.h:87
static CounterKey_t SplitKey(Key_t key)
Returns a split key corresponding to the specified key.
Definition: CountersMap.h:375
std::bidirectional_iterator_tag iterator_category
Definition: CountersMap.h:445
BaseMap_t::const_iterator iter
iterator to the block of counters
Definition: CountersMap.h:482
static const_iterator make_const_iterator(typename BaseMap_t::const_iterator it, size_t ix)
Creates a const_iterator (useful in derived classes)
Definition: CountersMap.h:379
void fill(size_t begin, size_t n, const value_type &value)
Definition: CountersMap.h:51
CounterKey_t & next_block()
Skips to the beginning of the next block.
Definition: CountersMap.h:340
COUNTER Counter_t
Type of the single counter.
Definition: CountersMap.h:67
BlockKey_t block
key of the counter block
Definition: CountersMap.h:297
typename PlainBaseMap_t::allocator_type DefaultAllocator_t
Type of allocator for the plain map.
Definition: CountersMap.h:79
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.
Definition: CountersMap.h:171
then echo ***************************************echo array
Definition: find_fhicl.sh:28
Key_t BlockKey_t
type of block key
Definition: CountersMap.h:290
CountersMap()
Default constructor (empty map)
Definition: CountersMap.h:195
iterator_type operator--(int)
Definition: CountersMap.h:469
Counter_t & GetOrCreateCounter(CounterKey_t key)
Returns the counter at the specified split key.
Definition: CountersMap.h:601
constexpr int LowestSetBitScaler(unsigned long long int v, int b)
Internally used by LowestSetBit.
Definition: CountersMap.h:402
SubCounter_t GetSubCounter(CounterKey_t key) const
Returns the value of the subcounter at the specified split key.
Definition: CountersMap.h:367
CounterKey_t(BlockKey_t major, CounterIndex_t minor)
Constructor from a pair.
Definition: CountersMap.h:304
CounterBlock()
Default constructor: initializes the array to 0.
Definition: CountersMap.h:44
CounterKey_t & start_block()
Skips to the beginning of this block.
Definition: CountersMap.h:333
bool operator!=(base_iterator< ValueL > const &a, base_iterator< ValueR > const &b)
COUNTER Counter_t
type of the single counter
Definition: CountersMap.h:148
CounterKey_t(Key_t key)
Initialize from a mangled key.
Definition: CountersMap.h:308
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.
Definition: CountersMap.h:592
const_iterator begin() const
Returns an iterator to the begin of the counters.
Definition: CountersMap.h:511
std::map< Key_t, CounterBlock_t, std::less< Key_t >, Alloc > BaseMap_t
Base type of map, allowing a custom allocator.
Definition: CountersMap.h:84
SubCounter_t decrement(Key_t key)
Decrements by 1 the specified counter.
Definition: CountersMap.h:505
const value_type & reference
Definition: CountersMap.h:444
std::array< Counter_t, NCounters > Array_t
type of base class
Definition: CountersMap.h:40
BaseMap_t counter_map
the actual data structure for counters
Definition: CountersMap.h:359
const_iterator(typename BaseMap_t::const_iterator it, size_t ix)
Private constructor (from a map iterator and a block index)
Definition: CountersMap.h:487
auto begin(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:573
ALLOC Allocator_t
type of the single counter
Definition: CountersMap.h:149
Structure with the index of the counter, split as needed.
Definition: CountersMap.h:296
static constexpr size_t NSubcounters
Number of subcounters in one counter block.
Definition: CountersMap.h:159
SubCounter_t unchecked_set(CounterKey_t key, SubCounter_t delta)
Sets the specified counter to a value (no check on value range)
Definition: CountersMap.h:608
SubCounter_t mapped_type
Definition: CountersMap.h:183
static constexpr size_t NCounters
Number of counters in one counter block.
Definition: CountersMap.h:70
iterator_type operator++(int)
Definition: CountersMap.h:460
CounterKey_t key() const
Returns the key of the pointed item as a CounterKey_t.
Definition: CountersMap.h:479
std::map< Key_t, CounterBlock_t, std::less< Key_t >> PlainBaseMap_t
General type of map (no special allocator specified).
Definition: CountersMap.h:76
CounterBlock(size_t index, Counter_t value)
Convenience constructor: initializes all counters to 0, except one.
Definition: CountersMap.h:47
static constexpr Key_t MinorKeyMask
Bit mask for the minor key.
Definition: CountersMap.h:351
KEY Key_t
Type of counter key in the map.
Definition: CountersMap.h:66
Map storing counters in a compact way.
Definition: CountersMap.h:138
static constexpr Key_t MinorKeyBits
Number of bits for the minor key.
Definition: CountersMap.h:348
temporary value
bool empty() const
Returns whether the map has no counters.
Definition: CountersMap.h:245
SubCounter_t unchecked_add(CounterKey_t key, SubCounter_t delta)
Adds a delta to the specified counter (no check on underflow/overflow)
Definition: CountersMap.h:631
Counter_t SubCounter_t
Type of the subcounter (that is, the actual counter)
Definition: CountersMap.h:162
constexpr int LowestSetBit(unsigned long long int v)
Returns the position of the first set bit (0 for LSB)
Definition: CountersMap.h:413
static constexpr size_t NCounters
Number of counters in one counter block.
Definition: CountersMap.h:156
float A
Definition: dedx.py:137
SubCounter_t set(Key_t key, SubCounter_t value)
Sets the specified counter to a count.
Definition: CountersMap.h:495
CounterKey_t & prev_block()
Skips to the beginning of the previous block.
Definition: CountersMap.h:336
bool operator==(infinite_endcount_iterator< T > const &, count_iterator< T > const &)
Definition: counter.h:269
std::pair< const Key_t, SubCounter_t > value_type
Definition: CountersMap.h:188
constexpr bool IsPowerOf2(unsigned long long int v)
Returns true if the argument is a power of 2.
Definition: CountersMap.h:25