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_SPARSE_HISTOGRAM_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BASE_METRICS_SPARSE_HISTOGRAM_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/base_export.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram_base.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/metrics/sample_map.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/lock.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The common code for different SparseHistogram macros.
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define HISTOGRAM_SPARSE_COMMON(name, sample, flag) \
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    do { \
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::HistogramBase* histogram( \
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          base::SparseHistogram::FactoryGet(name, flag)); \
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DCHECK_EQ(histogram->histogram_name(), name); \
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      histogram->Add(sample); \
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } while (0)
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define HISTOGRAM_SPARSE_SLOWLY(name, sample) \
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    HISTOGRAM_SPARSE_COMMON(name, sample, base::HistogramBase::kNoFlags)
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define UMA_HISTOGRAM_SPARSE_SLOWLY(name, sample) \
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    HISTOGRAM_SPARSE_COMMON(name, sample, \
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            base::HistogramBase::kUmaTargetedHistogramFlag)
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//------------------------------------------------------------------------------
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Define debug only version of macros.
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NDEBUG
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define DHISTOGRAM_SPARSE_SLOWLY(name, sample) \
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    HISTOGRAM_SPARSE_SLOWLY(name, sample)
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else  // NDEBUG
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define DHISTOGRAM_SPARSE_SLOWLY(name, sample) \
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    while (0) { \
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      static_cast<void>(name); \
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      static_cast<void>(sample); \
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif  // NDEBUG
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class HistogramSamples;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BASE_EXPORT_PRIVATE SparseHistogram : public HistogramBase {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If there's one with same name, return the existing one. If not, create a
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // new one.
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static HistogramBase* FactoryGet(const std::string& name, int32 flags);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~SparseHistogram();
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HistogramBase implementation:
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual HistogramType GetHistogramType() const OVERRIDE;
67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  virtual bool HasConstructionArguments(
68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      Sample expected_minimum,
69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      Sample expected_maximum,
70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      size_t expected_bucket_count) const OVERRIDE;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Add(Sample value) OVERRIDE;
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void AddSamples(const HistogramSamples& samples) OVERRIDE;
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool AddSamplesFromPickle(PickleIterator* iter) OVERRIDE;
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual scoped_ptr<HistogramSamples> SnapshotSamples() const OVERRIDE;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void WriteHTMLGraph(std::string* output) const OVERRIDE;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void WriteAscii(std::string* output) const OVERRIDE;
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // HistogramBase implementation:
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool SerializeInfoImpl(Pickle* pickle) const OVERRIDE;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Clients should always use FactoryGet to create SparseHistogram.
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit SparseHistogram(const std::string& name);
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  friend BASE_EXPORT_PRIVATE HistogramBase* DeserializeHistogramInfo(
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      PickleIterator* iter);
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static HistogramBase* DeserializeInfoImpl(PickleIterator* iter);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetParameters(DictionaryValue* params) const OVERRIDE;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetCountAndBucketData(Count* count,
92b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                     int64* sum,
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     ListValue* buckets) const OVERRIDE;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Helpers for emitting Ascii graphic.  Each method appends data to output.
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void WriteAsciiImpl(bool graph_it,
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                      const std::string& newline,
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                      std::string* output) const;
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Write a common header message describing this histogram.
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void WriteAsciiHeader(const Count total_count,
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                        std::string* output) const;
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // For constuctor calling.
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  friend class SparseHistogramTest;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Protects access to |samples_|.
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mutable base::Lock lock_;
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SampleMap samples_;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SparseHistogram);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace base
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // BASE_METRICS_SPARSE_HISTOGRAM_H_
118