|                                                      | 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162 | // histogram.hpp
// Copyright (C) 2006 - 2009 MicroNeil Research Corporation
// Class to capture a histogram of events using a <set>
#ifndef mn_histogram_included
#define mn_histogram_included
#include <set>
/** The Histogram class is managed set of HistogramRecords.
*** We play some naughty tricks with pointers to break the rules and
*** directly manipulate the counts of HistogramRecords stored in the
*** set - thus saving space, complexity, and cycles. The set allows us
*** to add new records as needed and locate existing records quickly.
*** At any point in time, the set contains all of the event (hit) counts
*** ordered by key.
**/
namespace CodeDweller {
class HistogramRecord {                                                         // A record to assocate a key and count.
  public:
    int Key;                                                                    // Here is the key.
    int Count;                                                                  // Here is the count.
    HistogramRecord(const int NewKey) :                                         // We must have a key to make one.
      Key(NewKey), Count(0) {}                                                  // and a new one starts at count 0.
    bool operator<(const HistogramRecord& Right) const {                        // To live in a set we need to <
        return (Key < Right.Key);                                               // properly based on the key.
    }
};
class Histogram : public std::set<HistogramRecord> {                            // A Histogram is a set of HistogramRecords
  private:                                                                      // and a private hit counter...
    int HitCount;
  public:
    Histogram() : HitCount(0) {}
                                                                                // with a few extra public functions. The
    int hit(const int EventKey, const int Adjustment = 1) {                     // hit() method increments a specific count.
        HistogramRecord E(EventKey);                                            // First, make a record for the event key.
        insert(E);                                                              // Insert the new record (if it's not there).
        std::set<HistogramRecord>::iterator iE =                                // Find either the pre-existing or the new
          find(E);                                                              // record for this key.
        int* C;                                                                 // Play naughty pointer games to access
        C = const_cast<int*>(&((*iE).Count));                                   // the Count for this record inside the
        (*C) += Adjustment;                                                     // set and add our Adjustment to it.
        HitCount += Adjustment;                                                 // Accumulate the adjustments overall.
        return(*C);                                                             // Return the count for this key.
    }
    int Hits() { return HitCount; }                                             // Return the sum of hits so far.
    void reset() {                                                              // Reset the histogram to zero.
        HitCount = 0;                                                           // That means no counts, and
        clear();                                                                // an empty set of records.
    }
};
} // namespace CodeDweller.
#endif
 |