You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. // histogram.hpp
  2. //
  3. // Copyright (C) 2004-2020 MicroNeil Research Corporation.
  4. //
  5. // This software is released under the MIT license. See LICENSE.TXT.
  6. #pragma once
  7. #include <set>
  8. namespace codedweller {
  9. /** The Histogram class is managed set of HistogramRecords.
  10. *** We play some naughty tricks with pointers to break the rules and
  11. *** directly manipulate the counts of HistogramRecords stored in the
  12. *** set - thus saving space, complexity, and cycles. The set allows us
  13. *** to add new records as needed and locate existing records quickly.
  14. *** At any point in time, the set contains all of the event (hit) counts
  15. *** ordered by key.
  16. **/
  17. class HistogramRecord { // A record to assocate a key and count.
  18. public:
  19. int Key; // Here is the key.
  20. mutable int Count; // Here is the count.
  21. HistogramRecord(const int NewKey) : // We must have a key to make one.
  22. Key(NewKey), Count(0) {} // and a new one starts at count 0.
  23. bool operator<(const HistogramRecord& Right) const { // To live in a set we need to <
  24. return (Key < Right.Key); // properly based on the key.
  25. }
  26. };
  27. class Histogram : public std::set<HistogramRecord> { // A Histogram is a set of HistogramRecords
  28. private: // and a private hit counter...
  29. int HitCount;
  30. public:
  31. Histogram() : HitCount(0) {}
  32. // with a few extra public functions. The
  33. int hit(const int EventKey, const int Adjustment = 1) { // hit() method increments a specific count.
  34. HistogramRecord E(EventKey); // First, make a record for the event key.
  35. insert(E); // Insert the new record (if it's not there).
  36. std::set<HistogramRecord>::iterator iE = // Find either the pre-existing or the new
  37. find(E); // record for this key.
  38. int* C; // Play naughty pointer games to access
  39. C = const_cast<int*>(&((*iE).Count)); // the Count for this record inside the
  40. (*C) += Adjustment; // set and add our Adjustment to it.
  41. HitCount += Adjustment; // Accumulate the adjustments overall.
  42. return(*C); // Return the count for this key.
  43. }
  44. int Hits() { return HitCount; } // Return the sum of hits so far.
  45. void reset() { // Reset the histogram to zero.
  46. HitCount = 0; // That means no counts, and
  47. clear(); // an empty set of records.
  48. }
  49. };
  50. } // End namespace codedweller