Prints one histogram of all data in recent history

A call to dumpsys media.log causes the program to read
timestamp data from the circular buffer stored in local memory
to a local data structure which stores this data in a
compressed format.

The current code is a temporary step towards the ultimate
goal (described below). The timestamp data is turned into
historgrams of a small, fixed size, and added to a vector
of histograms. When the vector reaches a given number of
histograms, the oldest one is popped. When dump() is called,
all the short histograms are combined into one large one and
printed. The advantage of this approach is to not delete
data from memory until it is overwritten. Ultimately, this
data structure should be a circular buffer. A second data
structure should be added which keeps a more long-term analysis
of the data.

Test: dumpsys media.log

Change-Id: I39c4818e7d1221d5023a4355b8b57fadd9451de5
diff --git a/media/libnbaio/include/NBLog.h b/media/libnbaio/include/NBLog.h
index 785b9c2..f3e6ca4 100644
--- a/media/libnbaio/include/NBLog.h
+++ b/media/libnbaio/include/NBLog.h
@@ -25,6 +25,7 @@
 #include <utils/threads.h>
 
 #include <map>
+#include <deque>
 #include <set>
 #include <vector>
 
@@ -457,6 +458,9 @@
     bool     isFindGlitch() const;
 
 private:
+
+    static const int kShortHistSize = 50; // number of samples in a short-term histogram
+    static const int kRecentHistsCapacity = 100; // number of short-term histograms stored in memory
     static const std::set<Event> startingTypes;
     static const std::set<Event> endingTypes;
     /*const*/ Shared* const mShared;    // raw pointer to shared memory, actually const but not
@@ -469,10 +473,23 @@
     audio_utils_fifo_reader * const mFifoReader;    // used to read from FIFO,
                                                     // non-NULL unless constructor fails
 
+    // stores a short-term histogram of size determined by kShortHistSize
+    // TODO: unsigned, unsigned
+    using short_histogram = std::map<int, int>;
+
     // each pair contains a sequence of timestamps (one histogram's worth)
     // pair's log_hash_t is the hash of the source code location where the timestamp was taken
     // pair's int points to the Reader that originated the entry
     std::map<std::pair<log_hash_t, int>, std::vector<int64_t>> mHists;
+
+    // mHistsCopy stores timestamp vectors whose key is the reader thread index.
+    // TODO remove old mHists after changing the code
+    std::map<int, std::vector<int64_t>> mTimeStampSeries;
+
+    // stores fixed-size short buffer period histograms with hash and thread data
+    // TODO: Turn it into a circular buffer for better data flow
+    std::deque<std::pair<int, short_histogram>> mRecentHists;
+
     // TODO: it might be clearer, instead of a direct map from source location to vector of
     // timestamps, if we instead first mapped from source location to an object that
     // represented that location. And one_of its fields would be a vector of timestamps.
@@ -488,6 +505,11 @@
     static void drawHistogram(String8 *body, const std::vector<int64_t> &samples,
                               bool logScale, int indent = 0, int maxHeight = 10);
 
+    static void reportPerformance(String8 *body,
+                                  const std::deque<std::pair
+                                         <int, short_histogram>> &shortHists,
+                                  int maxHeight = 10);
+
     // Searches for the last entry of type <type> in the range [front, back)
     // back has to be entry-aligned. Returns nullptr if none enconuntered.
     static const uint8_t *findLastEntryOfTypes(const uint8_t *front, const uint8_t *back,