15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef BASE_METRICS_HISTOGRAM_BASE_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BASE_METRICS_HISTOGRAM_BASE_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
91e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include <vector>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/atomicops.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/base_export.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class Pickle;
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class PickleIterator;
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DictionaryValue;
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class HistogramBase;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class HistogramSamples;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ListValue;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// These enums are used to facilitate deserialization of histograms from other
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// processes into the browser. If you create another class that inherits from
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// HistogramBase, add new histogram types and names below.
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum BASE_EXPORT HistogramType {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HISTOGRAM,
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LINEAR_HISTOGRAM,
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BOOLEAN_HISTOGRAM,
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CUSTOM_HISTOGRAM,
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SPARSE_HISTOGRAM,
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string HistogramTypeToString(HistogramType type);
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Create or find existing histogram that matches the pickled info.
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Returns NULL if the pickled data has problems.
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)BASE_EXPORT_PRIVATE HistogramBase* DeserializeHistogramInfo(
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PickleIterator* iter);
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BASE_EXPORT HistogramBase {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
5158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  typedef int Sample;                   // Used for samples.
5258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  typedef subtle::Atomic32 Count;     // Used to count samples.
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const Sample kSampleType_MAX;  // INT_MAX
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum Flags {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kNoFlags = 0,
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kUmaTargetedHistogramFlag = 0x1,  // Histogram should be UMA uploaded.
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Indicate that the histogram was pickled to be sent across an IPC Channel.
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If we observe this flag on a histogram being aggregated into after IPC,
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // then we are running in a single process mode, and the aggregation should
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // not take place (as we would be aggregating back into the source
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // histogram!).
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kIPCSerializationSourceFlag = 0x10,
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Only for Histogram and its sub classes: fancy bucket-naming support.
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kHexRangePrintingFlag = 0x8000,
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Histogram data inconsistency types.
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  enum Inconsistency {
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NO_INCONSISTENCIES = 0x0,
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RANGE_CHECKSUM_ERROR = 0x1,
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BUCKET_ORDER_ERROR = 0x2,
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    COUNT_HIGH_ERROR = 0x4,
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    COUNT_LOW_ERROR = 0x8,
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NEVER_EXCEEDED_VALUE = 0x10
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit HistogramBase(const std::string& name);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~HistogramBase();
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string histogram_name() const { return histogram_name_; }
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Operations with Flags enum.
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32 flags() const { return flags_; }
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetFlags(int32 flags);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ClearFlags(int32 flags);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual HistogramType GetHistogramType() const = 0;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Whether the histogram has construction arguments as parameters specified.
95eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // For histograms that don't have the concept of minimum, maximum or
96eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // bucket_count, this function always returns false.
97eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  virtual bool HasConstructionArguments(Sample expected_minimum,
98eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                        Sample expected_maximum,
99eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                        size_t expected_bucket_count) const = 0;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Add(Sample value) = 0;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // 2 convenient functions that call Add(Sample).
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AddTime(const TimeDelta& time);
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AddBoolean(bool value);
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void AddSamples(const HistogramSamples& samples) = 0;
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool AddSamplesFromPickle(PickleIterator* iter) = 0;
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Serialize the histogram info into |pickle|.
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Note: This only serializes the construction arguments of the histogram, but
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // does not serialize the samples.
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool SerializeInfo(Pickle* pickle) const;
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Try to find out data corruption from histogram and the samples.
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The returned value is a combination of Inconsistency enum.
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual int FindCorruption(const HistogramSamples& samples) const;
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Snapshot the current complete set of sample data.
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Override with atomic/locked snapshot if needed.
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual scoped_ptr<HistogramSamples> SnapshotSamples() const = 0;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The following methods provide graphical histogram displays.
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void WriteHTMLGraph(std::string* output) const = 0;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void WriteAscii(std::string* output) const = 0;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Produce a JSON representation of the histogram. This is implemented with
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the help of GetParameters and GetCountAndBucketData; overwrite them to
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // customize the output.
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void WriteJSON(std::string* output) const;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)protected:
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Subclasses should implement this function to make SerializeInfo work.
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool SerializeInfoImpl(Pickle* pickle) const = 0;
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Writes information about the construction parameters in |params|.
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetParameters(DictionaryValue* params) const = 0;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Writes information about the current (non-empty) buckets and their sample
140b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // counts to |buckets|, the total sample count to |count| and the total sum
141b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // to |sum|.
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetCountAndBucketData(Count* count,
143b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                     int64* sum,
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     ListValue* buckets) const = 0;
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //// Produce actual graph (set of blank vs non blank char's) for a bucket.
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void WriteAsciiBucketGraph(double current_size,
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             double max_size,
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             std::string* output) const;
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Return a string description of what goes in a given bucket.
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const std::string GetSimpleAsciiBucketRange(Sample sample) const;
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Write textual description of the bucket contents (relative to histogram).
155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Output is the count in the buckets, as well as the percentage.
156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void WriteAsciiBucketValue(Count current,
157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             double scaled_sum,
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             std::string* output) const;
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string histogram_name_;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32 flags_;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(HistogramBase);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace base
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // BASE_METRICS_HISTOGRAM_BASE_H_
170