13f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Histogram is an object that aggregates statistics, and can summarize them in 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// various forms, including ASCII graphical, HTML, and numerically (as a 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// vector of numbers corresponding to each of the aggregating buckets). 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// It supports calls to accumulate either time intervals (which are processed 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// as integral number of milliseconds), or arbitrary integral units. 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// The default layout of buckets is exponential. For example, buckets might 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// contain (sequentially) the count of values in the following intervals: 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// [0,1), [1,2), [2,4), [4,8), [8,16), [16,32), [32,64), [64,infinity) 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// That bucket allocation would actually result from construction of a histogram 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// for values between 1 and 64, with 8 buckets, such as: 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Histogram count(L"some name", 1, 64, 8); 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Note that the underflow bucket [0,1) and the overflow bucket [64,infinity) 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// are not counted by the constructor in the user supplied "bucket_count" 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// argument. 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// The above example has an exponential ratio of 2 (doubling the bucket width 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// in each consecutive bucket. The Histogram class automatically calculates 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// the smallest ratio that it can use to construct the number of buckets 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// selected in the constructor. An another example, if you had 50 buckets, 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// and millisecond time values from 1 to 10000, then the ratio between 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// consecutive bucket widths will be approximately somewhere around the 50th 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// root of 10000. This approach provides very fine grain (narrow) buckets 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// at the low end of the histogram scale, but allows the histogram to cover a 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// gigantic range with the addition of very few buckets. 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Histograms use a pattern involving a function static variable, that is a 32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// pointer to a histogram. This static is explicitly initialized on any thread 33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// that detects a uninitialized (NULL) pointer. The potentially racy 34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// initialization is not a problem as it is always set to point to the same 35ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// value (i.e., the FactoryGet always returns the same value). FactoryGet 36ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// is also completely thread safe, which results in a completely thread safe, 37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// and relatively fast, set of counters. To avoid races at shutdown, the static 38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// pointer is NOT deleted, and we leak the histograms at process termination. 39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 40731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#ifndef BASE_METRICS_HISTOGRAM_H_ 41731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#define BASE_METRICS_HISTOGRAM_H_ 423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <map> 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <string> 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <vector> 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/base_api.h" 49513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "base/gtest_prod_util.h" 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/logging.h" 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/time.h" 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 53731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickclass Pickle; 54731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 55731df977c0511bca2206b5f333555b1205ff1f43Iain Merricknamespace base { 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 573f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenclass Lock; 583f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//------------------------------------------------------------------------------ 60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Provide easy general purpose histogram in a macro, just like stats counters. 61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// The first four macros use 50 buckets. 62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define HISTOGRAM_TIMES(name, sample) HISTOGRAM_CUSTOM_TIMES( \ 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott name, sample, base::TimeDelta::FromMilliseconds(1), \ 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::TimeDelta::FromSeconds(10), 50) 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define HISTOGRAM_COUNTS(name, sample) HISTOGRAM_CUSTOM_COUNTS( \ 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott name, sample, 1, 1000000, 50) 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define HISTOGRAM_COUNTS_100(name, sample) HISTOGRAM_CUSTOM_COUNTS( \ 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott name, sample, 1, 100, 50) 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define HISTOGRAM_COUNTS_10000(name, sample) HISTOGRAM_CUSTOM_COUNTS( \ 74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott name, sample, 1, 10000, 50) 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count) do { \ 77ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static base::Histogram* counter(NULL); \ 78ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!counter) \ 79ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen counter = base::Histogram::FactoryGet(name, min, max, bucket_count, \ 80ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::Histogram::kNoFlags); \ 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_EQ(name, counter->histogram_name()); \ 82ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen counter->Add(sample); \ 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } while (0) 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define HISTOGRAM_PERCENTAGE(name, under_one_hundred) \ 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HISTOGRAM_ENUMERATION(name, under_one_hundred, 101) 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// For folks that need real specific times, use this to select a precise range 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// of times you want plotted, and the number of buckets you want used. 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define HISTOGRAM_CUSTOM_TIMES(name, sample, min, max, bucket_count) do { \ 91ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static base::Histogram* counter(NULL); \ 92ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!counter) \ 93ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen counter = base::Histogram::FactoryTimeGet(name, min, max, bucket_count, \ 94ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::Histogram::kNoFlags); \ 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_EQ(name, counter->histogram_name()); \ 96ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen counter->AddTime(sample); \ 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } while (0) 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// DO NOT USE THIS. It is being phased out, in favor of HISTOGRAM_CUSTOM_TIMES. 100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define HISTOGRAM_CLIPPED_TIMES(name, sample, min, max, bucket_count) do { \ 101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static base::Histogram* counter(NULL); \ 102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!counter) \ 103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen counter = base::Histogram::FactoryTimeGet(name, min, max, bucket_count, \ 104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::Histogram::kNoFlags); \ 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_EQ(name, counter->histogram_name()); \ 106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if ((sample) < (max)) counter->AddTime(sample); \ 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } while (0) 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Support histograming of an enumerated value. The samples should always be 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// less than boundary_value. 111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define HISTOGRAM_ENUMERATION(name, sample, boundary_value) do { \ 113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static base::Histogram* counter(NULL); \ 114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!counter) \ 115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen counter = base::LinearHistogram::FactoryGet(name, 1, boundary_value, \ 116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen boundary_value + 1, base::Histogram::kNoFlags); \ 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_EQ(name, counter->histogram_name()); \ 118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen counter->Add(sample); \ 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } while (0) 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define HISTOGRAM_CUSTOM_ENUMERATION(name, sample, custom_ranges) do { \ 122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static base::Histogram* counter(NULL); \ 123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!counter) \ 124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen counter = base::CustomHistogram::FactoryGet(name, custom_ranges, \ 125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::Histogram::kNoFlags); \ 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_EQ(name, counter->histogram_name()); \ 127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen counter->Add(sample); \ 128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } while (0) 129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//------------------------------------------------------------------------------ 132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Define Debug vs non-debug flavors of macros. 133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef NDEBUG 134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define DHISTOGRAM_TIMES(name, sample) HISTOGRAM_TIMES(name, sample) 136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define DHISTOGRAM_COUNTS(name, sample) HISTOGRAM_COUNTS(name, sample) 137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define DHISTOGRAM_PERCENTAGE(name, under_one_hundred) HISTOGRAM_PERCENTAGE(\ 138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott name, under_one_hundred) 139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define DHISTOGRAM_CUSTOM_TIMES(name, sample, min, max, bucket_count) \ 140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HISTOGRAM_CUSTOM_TIMES(name, sample, min, max, bucket_count) 141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define DHISTOGRAM_CLIPPED_TIMES(name, sample, min, max, bucket_count) \ 142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HISTOGRAM_CLIPPED_TIMES(name, sample, min, max, bucket_count) 143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define DHISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count) \ 144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count) 145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define DHISTOGRAM_ENUMERATION(name, sample, boundary_value) \ 146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HISTOGRAM_ENUMERATION(name, sample, boundary_value) 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define DHISTOGRAM_CUSTOM_ENUMERATION(name, sample, custom_ranges) \ 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HISTOGRAM_CUSTOM_ENUMERATION(name, sample, custom_ranges) 149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#else // NDEBUG 151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define DHISTOGRAM_TIMES(name, sample) do {} while (0) 153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define DHISTOGRAM_COUNTS(name, sample) do {} while (0) 154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define DHISTOGRAM_PERCENTAGE(name, under_one_hundred) do {} while (0) 155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define DHISTOGRAM_CUSTOM_TIMES(name, sample, min, max, bucket_count) \ 156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott do {} while (0) 157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define DHISTOGRAM_CLIPPED_TIMES(name, sample, min, max, bucket_count) \ 158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott do {} while (0) 159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define DHISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count) \ 160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott do {} while (0) 161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define DHISTOGRAM_ENUMERATION(name, sample, boundary_value) do {} while (0) 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define DHISTOGRAM_CUSTOM_ENUMERATION(name, sample, custom_ranges) \ 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch do {} while (0) 164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif // NDEBUG 166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//------------------------------------------------------------------------------ 168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// The following macros provide typical usage scenarios for callers that wish 169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// to record histogram data, and have the data submitted/uploaded via UMA. 170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Not all systems support such UMA, but if they do, the following macros 171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// should work with the service. 172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define UMA_HISTOGRAM_TIMES(name, sample) UMA_HISTOGRAM_CUSTOM_TIMES( \ 174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott name, sample, base::TimeDelta::FromMilliseconds(1), \ 175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::TimeDelta::FromSeconds(10), 50) 176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define UMA_HISTOGRAM_MEDIUM_TIMES(name, sample) UMA_HISTOGRAM_CUSTOM_TIMES( \ 178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott name, sample, base::TimeDelta::FromMilliseconds(10), \ 179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::TimeDelta::FromMinutes(3), 50) 180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use this macro when times can routinely be much longer than 10 seconds. 182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define UMA_HISTOGRAM_LONG_TIMES(name, sample) UMA_HISTOGRAM_CUSTOM_TIMES( \ 183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott name, sample, base::TimeDelta::FromMilliseconds(1), \ 184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::TimeDelta::FromHours(1), 50) 185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define UMA_HISTOGRAM_CUSTOM_TIMES(name, sample, min, max, bucket_count) do { \ 187ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static base::Histogram* counter(NULL); \ 188ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!counter) \ 189ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen counter = base::Histogram::FactoryTimeGet(name, min, max, bucket_count, \ 190731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick base::Histogram::kUmaTargetedHistogramFlag); \ 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_EQ(name, counter->histogram_name()); \ 192ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen counter->AddTime(sample); \ 193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } while (0) 194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// DO NOT USE THIS. It is being phased out, in favor of HISTOGRAM_CUSTOM_TIMES. 196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define UMA_HISTOGRAM_CLIPPED_TIMES(name, sample, min, max, bucket_count) do { \ 197ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static base::Histogram* counter(NULL); \ 198ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!counter) \ 199ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen counter = base::Histogram::FactoryTimeGet(name, min, max, bucket_count, \ 200ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::Histogram::kUmaTargetedHistogramFlag); \ 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_EQ(name, counter->histogram_name()); \ 202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if ((sample) < (max)) counter->AddTime(sample); \ 203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } while (0) 204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define UMA_HISTOGRAM_COUNTS(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \ 206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott name, sample, 1, 1000000, 50) 207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define UMA_HISTOGRAM_COUNTS_100(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \ 209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott name, sample, 1, 100, 50) 210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define UMA_HISTOGRAM_COUNTS_10000(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \ 212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott name, sample, 1, 10000, 50) 213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count) do { \ 215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static base::Histogram* counter(NULL); \ 216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!counter) \ 217ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen counter = base::Histogram::FactoryGet(name, min, max, bucket_count, \ 218ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::Histogram::kUmaTargetedHistogramFlag); \ 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_EQ(name, counter->histogram_name()); \ 220ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen counter->Add(sample); \ 221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } while (0) 222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define UMA_HISTOGRAM_MEMORY_KB(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \ 224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott name, sample, 1000, 500000, 50) 225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define UMA_HISTOGRAM_MEMORY_MB(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \ 227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott name, sample, 1, 1000, 50) 228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define UMA_HISTOGRAM_PERCENTAGE(name, under_one_hundred) \ 230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott UMA_HISTOGRAM_ENUMERATION(name, under_one_hundred, 101) 231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 232ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define UMA_HISTOGRAM_BOOLEAN(name, sample) do { \ 233ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static base::Histogram* counter(NULL); \ 234ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!counter) \ 235ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen counter = base::BooleanHistogram::FactoryGet(name, \ 236ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::Histogram::kUmaTargetedHistogramFlag); \ 237ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK_EQ(name, counter->histogram_name()); \ 238ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen counter->AddBoolean(sample); \ 239ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } while (0) 240ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define UMA_HISTOGRAM_ENUMERATION(name, sample, boundary_value) do { \ 242ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static base::Histogram* counter(NULL); \ 243ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!counter) \ 244ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen counter = base::LinearHistogram::FactoryGet(name, 1, boundary_value, \ 245ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen boundary_value + 1, base::Histogram::kUmaTargetedHistogramFlag); \ 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_EQ(name, counter->histogram_name()); \ 247ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen counter->Add(sample); \ 248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } while (0) 249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define UMA_HISTOGRAM_CUSTOM_ENUMERATION(name, sample, custom_ranges) do { \ 251ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static base::Histogram* counter(NULL); \ 252ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!counter) \ 253ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen counter = base::CustomHistogram::FactoryGet(name, custom_ranges, \ 254ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::Histogram::kUmaTargetedHistogramFlag); \ 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_EQ(name, counter->histogram_name()); \ 256ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen counter->Add(sample); \ 257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } while (0) 258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//------------------------------------------------------------------------------ 260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass BooleanHistogram; 262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass CustomHistogram; 263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass Histogram; 264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass LinearHistogram; 265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 266ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass BASE_API Histogram { 267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott typedef int Sample; // Used for samples (and ranges of samples). 269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott typedef int Count; // Used to count samples in a bucket. 270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static const Sample kSampleType_MAX = INT_MAX; 271dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Initialize maximum number of buckets in histograms as 16,384. 272dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen static const size_t kBucketCount_MAX; 273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott typedef std::vector<Count> Counts; 275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott typedef std::vector<Sample> Ranges; 276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 277513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // These enums are used to facilitate deserialization of renderer histograms 278513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // into the browser. 279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott enum ClassType { 280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HISTOGRAM, 281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LINEAR_HISTOGRAM, 282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott BOOLEAN_HISTOGRAM, 283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CUSTOM_HISTOGRAM, 284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott NOT_VALID_IN_RENDERER 285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott enum BucketLayout { 288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPONENTIAL, 289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LINEAR, 290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CUSTOM 291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott enum Flags { 294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kNoFlags = 0, 295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kUmaTargetedHistogramFlag = 0x1, // Histogram should be UMA uploaded. 296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Indicate that the histogram was pickled to be sent across an IPC Channel. 298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If we observe this flag on a histogram being aggregated into after IPC, 299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // then we are running in a single process mode, and the aggregation should 300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // not take place (as we would be aggregating back into the source 301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // histogram!). 302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kIPCSerializationSourceFlag = 0x10, 303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kHexRangePrintingFlag = 0x8000, // Fancy bucket-naming supported. 305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 307513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch enum Inconsistencies { 308513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch NO_INCONSISTENCIES = 0x0, 309513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch RANGE_CHECKSUM_ERROR = 0x1, 310513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch BUCKET_ORDER_ERROR = 0x2, 311513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch COUNT_HIGH_ERROR = 0x4, 312513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch COUNT_LOW_ERROR = 0x8, 313513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 314513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch NEVER_EXCEEDED_VALUE = 0x10 315513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch }; 316513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct DescriptionPair { 318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Sample sample; 319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char* description; // Null means end of a list of pairs. 320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott //---------------------------------------------------------------------------- 323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Statistic values, developed over the life of the histogram. 324c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 325ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen class BASE_API SampleSet { 326c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott explicit SampleSet(); 3283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ~SampleSet(); 3293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Adjust size of counts_ for use with given histogram. 331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void Resize(const Histogram& histogram); 332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void CheckSize(const Histogram& histogram) const; 333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Accessor for histogram to make routine additions. 335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void Accumulate(Sample value, Count count, size_t index); 336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Accessor methods. 338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Count counts(size_t i) const { return counts_[i]; } 339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Count TotalCount() const; 340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int64 sum() const { return sum_; } 341513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch int64 redundant_count() const { return redundant_count_; } 342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Arithmetic manipulation of corresponding elements of the set. 344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void Add(const SampleSet& other); 345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void Subtract(const SampleSet& other); 346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool Serialize(Pickle* pickle) const; 348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool Deserialize(void** iter, const Pickle& pickle); 349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott protected: 351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Actual histogram data is stored in buckets, showing the count of values 352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // that fit into each bucket. 353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Counts counts_; 354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Save simple stats locally. Note that this MIGHT get done in base class 356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // without shared memory at some point. 357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int64 sum_; // sum of samples. 358513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 359513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch private: 360513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Allow tests to corrupt our innards for testing purposes. 361513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch FRIEND_TEST(HistogramTest, CorruptSampleCounts); 362513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 363513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // To help identify memory corruption, we reduntantly save the number of 364513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // samples we've accumulated into all of our buckets. We can compare this 365513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // count to the sum of the counts in all buckets, and detect problems. Note 366513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // that due to races in histogram accumulation (if a histogram is indeed 367513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // updated on several threads simultaneously), the tallies might mismatch, 368513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // and also the snapshotting code may asynchronously get a mismatch (though 369513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // generally either race based mismatch cause is VERY rare). 370513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch int64 redundant_count_; 371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 372513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 373c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott //---------------------------------------------------------------------------- 374c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // minimum should start from 1. 0 is invalid as a minimum. 0 is an implicit 375c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // default underflow bucket. 376ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static Histogram* FactoryGet(const std::string& name, 377ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Sample minimum, 378ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Sample maximum, 379ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen size_t bucket_count, 380ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Flags flags); 381ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static Histogram* FactoryTimeGet(const std::string& name, 382ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta minimum, 383ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta maximum, 384ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen size_t bucket_count, 385ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Flags flags); 386c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 387c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void Add(int value); 388c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // This method is an interface, used only by BooleanHistogram. 3903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick virtual void AddBoolean(bool value); 391c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 392c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Accept a TimeDelta to increment. 393731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick void AddTime(TimeDelta time) { 394c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Add(static_cast<int>(time.InMilliseconds())); 395c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 396c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 397c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void AddSampleSet(const SampleSet& sample); 398c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 399c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // This method is an interface, used only by LinearHistogram. 4003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick virtual void SetRangeDescriptions(const DescriptionPair descriptions[]); 401c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 402c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The following methods provide graphical histogram displays. 403c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void WriteHTMLGraph(std::string* output) const; 404c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void WriteAscii(bool graph_it, const std::string& newline, 405c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string* output) const; 406c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 407c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Support generic flagging of Histograms. 408c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 0x1 Currently used to mark this histogram to be recorded by UMA.. 409c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 0x8000 means print ranges in hex. 410c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void SetFlags(Flags flags) { flags_ = static_cast<Flags> (flags_ | flags); } 411c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void ClearFlags(Flags flags) { flags_ = static_cast<Flags>(flags_ & ~flags); } 412c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int flags() const { return flags_; } 413c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 414c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Convenience methods for serializing/deserializing the histograms. 415c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Histograms from Renderer process are serialized and sent to the browser. 416c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Browser process reconstructs the histogram from the pickled version 417c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // accumulates the browser-side shadow copy of histograms (that mirror 418c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // histograms created in the renderer). 419c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 420c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Serialize the given snapshot of a Histogram into a String. Uses 421c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Pickle class to flatten the object. 422c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static std::string SerializeHistogramInfo(const Histogram& histogram, 423c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const SampleSet& snapshot); 424c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The following method accepts a list of pickled histograms and 425c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // builds a histogram and updates shadow copy of histogram data in the 426c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // browser process. 427c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static bool DeserializeHistogramInfo(const std::string& histogram_info); 428c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 429513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Check to see if bucket ranges, counts and tallies in the snapshot are 430513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // consistent with the bucket ranges and checksums in our histogram. This can 431513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // produce a false-alarm if a race occurred in the reading of the data during 432513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // a SnapShot process, but should otherwise be false at all times (unless we 433513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // have memory over-writes, or DRAM failures). 434513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch virtual Inconsistencies FindCorruption(const SampleSet& snapshot) const; 435513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 436c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott //---------------------------------------------------------------------------- 437c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Accessors for factory constuction, serialization and testing. 438c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott //---------------------------------------------------------------------------- 43921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen virtual ClassType histogram_type() const; 440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& histogram_name() const { return histogram_name_; } 441c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Sample declared_min() const { return declared_min_; } 442c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Sample declared_max() const { return declared_max_; } 44321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen virtual Sample ranges(size_t i) const; 444dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen uint32 range_checksum() const { return range_checksum_; } 44521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen virtual size_t bucket_count() const; 446c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Snapshot the current complete set of sample data. 447c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Override with atomic/locked snapshot if needed. 448c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void SnapshotSample(SampleSet* sample) const; 449c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 450c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual bool HasConstructorArguments(Sample minimum, Sample maximum, 4513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick size_t bucket_count); 452c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 453731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick virtual bool HasConstructorTimeDeltaArguments(TimeDelta minimum, 454731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TimeDelta maximum, 4553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick size_t bucket_count); 456dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Return true iff the range_checksum_ matches current ranges_ vector. 457dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen bool HasValidRangeChecksum() const; 458c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 459c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott protected: 460c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Histogram(const std::string& name, Sample minimum, 461c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Sample maximum, size_t bucket_count); 462731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick Histogram(const std::string& name, TimeDelta minimum, 463731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TimeDelta maximum, size_t bucket_count); 464c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 465c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual ~Histogram(); 466c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 467dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Initialize ranges_ mapping. 468dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen void InitializeBucketRange(); 469dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 470c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Method to override to skip the display of the i'th bucket if it's empty. 4713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick virtual bool PrintEmptyBucket(size_t index) const; 472c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 473c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott //---------------------------------------------------------------------------- 474c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Methods to override to create histogram with different bucket widths. 475c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott //---------------------------------------------------------------------------- 476c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Find bucket to increment for sample value. 477c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual size_t BucketIndex(Sample value) const; 478c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Get normalized size, relative to the ranges_[i]. 479c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual double GetBucketSize(Count current, size_t i) const; 480c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 481513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Recalculate range_checksum_. 482513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch void ResetRangeChecksum(); 483513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 484c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Return a string description of what goes in a given bucket. 485c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Most commonly this is the numeric value, but in derived classes it may 486c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // be a name (or string description) given to the bucket. 487c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual const std::string GetAsciiBucketRange(size_t it) const; 488c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 489c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott //---------------------------------------------------------------------------- 490c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Methods to override to create thread safe histogram. 491c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott //---------------------------------------------------------------------------- 492c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Update all our internal data, including histogram 493c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void Accumulate(Sample value, Count count, size_t index); 494c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 495c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott //---------------------------------------------------------------------------- 496c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Accessors for derived classes. 497c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott //---------------------------------------------------------------------------- 498c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void SetBucketRange(size_t i, Sample value); 499c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 500c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Validate that ranges_ was created sensibly (top and bottom range 501c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // values relate properly to the declared_min_ and declared_max_).. 502c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool ValidateBucketRanges() const; 503c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 504dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen virtual uint32 CalculateRangeChecksum() const; 505dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 506c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 507513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Allow tests to corrupt our innards for testing purposes. 508513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch FRIEND_TEST(HistogramTest, CorruptBucketBounds); 509513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch FRIEND_TEST(HistogramTest, CorruptSampleCounts); 510dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen FRIEND_TEST(HistogramTest, Crc32SampleHash); 511dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen FRIEND_TEST(HistogramTest, Crc32TableTest); 512513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 513ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen friend class StatisticsRecorder; // To allow it to delete duplicates. 514ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 515c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Post constructor initialization. 516c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void Initialize(); 517c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 518dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Checksum function for accumulating range values into a checksum. 519dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen static uint32 Crc32(uint32 sum, Sample range); 520513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 521c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott //---------------------------------------------------------------------------- 522c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Helpers for emitting Ascii graphic. Each method appends data to output. 523c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 524c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Find out how large the (graphically) the largest bucket will appear to be. 525c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott double GetPeakBucketSize(const SampleSet& snapshot) const; 526c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 527c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Write a common header message describing this histogram. 528c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void WriteAsciiHeader(const SampleSet& snapshot, 529c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Count sample_count, std::string* output) const; 530c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 531c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Write information about previous, current, and next buckets. 532c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Information such as cumulative percentage, etc. 533c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void WriteAsciiBucketContext(const int64 past, const Count current, 534c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const int64 remaining, const size_t i, 535c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string* output) const; 536c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 537c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Write textual description of the bucket contents (relative to histogram). 538c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Output is the count in the buckets, as well as the percentage. 539c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void WriteAsciiBucketValue(Count current, double scaled_sum, 540c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string* output) const; 541c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 542c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Produce actual graph (set of blank vs non blank char's) for a bucket. 543c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void WriteAsciiBucketGraph(double current_size, double max_size, 544c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string* output) const; 545c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 546c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott //---------------------------------------------------------------------------- 547dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Table for generating Crc32 values. 548dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen static const uint32 kCrcTable[256]; 549dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen //---------------------------------------------------------------------------- 550c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Invariant values set at/near construction time 551c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 552c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // ASCII version of original name given to the constructor. All identically 553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // named instances will be coalesced cross-project. 554c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const std::string histogram_name_; 555c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Sample declared_min_; // Less than this goes into counts_[0] 556c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Sample declared_max_; // Over this goes into counts_[bucket_count_ - 1]. 557c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t bucket_count_; // Dimension of counts_[]. 558c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 559c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Flag the histogram for recording by UMA via metric_services.h. 560c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Flags flags_; 561c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 562c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // For each index, show the least value that can be stored in the 563c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // corresponding bucket. We also append one extra element in this array, 564c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // containing kSampleType_MAX, to make calculations easy. 565c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The dimension of ranges_ is bucket_count + 1. 566c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Ranges ranges_; 567c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 568dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // For redundancy, we store a checksum of all the sample ranges when ranges 569dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // are generated. If ever there is ever a difference, then the histogram must 570513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // have been corrupted. 571dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen uint32 range_checksum_; 572513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 573c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Finally, provide the state that changes with the addition of each new 574c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // sample. 575c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SampleSet sample_; 576c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 577c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DISALLOW_COPY_AND_ASSIGN(Histogram); 578c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 579c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 580c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//------------------------------------------------------------------------------ 581c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 582c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// LinearHistogram is a more traditional histogram, with evenly spaced 583c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// buckets. 584ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass BASE_API LinearHistogram : public Histogram { 585c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 5863f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen virtual ~LinearHistogram(); 587c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 588c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* minimum should start from 1. 0 is as minimum is invalid. 0 is an implicit 589c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott default underflow bucket. */ 590ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static Histogram* FactoryGet(const std::string& name, 591ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Sample minimum, 592ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Sample maximum, 593ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen size_t bucket_count, 594ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Flags flags); 595ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static Histogram* FactoryTimeGet(const std::string& name, 596ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen TimeDelta minimum, 597ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen TimeDelta maximum, 598ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen size_t bucket_count, 599ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Flags flags); 600c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 6013f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // Overridden from Histogram: 6023f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen virtual ClassType histogram_type() const; 6033f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 6043f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // Store a list of number/text values for use in rendering the histogram. 6053f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // The last element in the array has a null in its "description" slot. 6063f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen virtual void SetRangeDescriptions(const DescriptionPair descriptions[]); 6073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 608c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott protected: 609c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LinearHistogram(const std::string& name, Sample minimum, 610c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Sample maximum, size_t bucket_count); 611c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 612731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick LinearHistogram(const std::string& name, TimeDelta minimum, 613731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TimeDelta maximum, size_t bucket_count); 614c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 615c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Initialize ranges_ mapping. 616dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen void InitializeBucketRange(); 617c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual double GetBucketSize(Count current, size_t i) const; 618c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 619c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If we have a description for a bucket, then return that. Otherwise 620c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // let parent class provide a (numeric) description. 621c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual const std::string GetAsciiBucketRange(size_t i) const; 622c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 623c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Skip printing of name for numeric range if we have a name (and if this is 624c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // an empty bucket). 625c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual bool PrintEmptyBucket(size_t index) const; 626c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 627c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 628c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // For some ranges, we store a printable description of a bucket range. 629c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If there is no desciption, then GetAsciiBucketRange() uses parent class 630c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // to provide a description. 631c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott typedef std::map<Sample, std::string> BucketDescriptionMap; 632c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott BucketDescriptionMap bucket_description_; 633c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 634c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DISALLOW_COPY_AND_ASSIGN(LinearHistogram); 635c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 636c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 637c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//------------------------------------------------------------------------------ 638c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 639c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// BooleanHistogram is a histogram for booleans. 640ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass BASE_API BooleanHistogram : public LinearHistogram { 641c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 642ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static Histogram* FactoryGet(const std::string& name, Flags flags); 643c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 6443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick virtual ClassType histogram_type() const; 645c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 6463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick virtual void AddBoolean(bool value); 647c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 648c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 6493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick explicit BooleanHistogram(const std::string& name); 650c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 651c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DISALLOW_COPY_AND_ASSIGN(BooleanHistogram); 652c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 653c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 654c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//------------------------------------------------------------------------------ 655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// CustomHistogram is a histogram for a set of custom integers. 657ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass BASE_API CustomHistogram : public Histogram { 658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 660ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static Histogram* FactoryGet(const std::string& name, 661ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const std::vector<Sample>& custom_ranges, 662ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Flags flags); 663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6643f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // Overridden from Histogram: 6653f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen virtual ClassType histogram_type() const; 6663f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected: 668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CustomHistogram(const std::string& name, 669513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const std::vector<Sample>& custom_ranges); 670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Initialize ranges_ mapping. 672dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen void InitializedCustomBucketRange(const std::vector<Sample>& custom_ranges); 673c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual double GetBucketSize(Count current, size_t i) const; 674c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(CustomHistogram); 676c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 677c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//------------------------------------------------------------------------------ 679c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// StatisticsRecorder handles all histograms in the system. It provides a 680c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// general place for histograms to register, and supports a global API for 681c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// accessing (i.e., dumping, or graphing) the data in all the histograms. 682c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 683ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass BASE_API StatisticsRecorder { 684c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 685ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen typedef std::vector<Histogram*> Histograms; 686c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 687c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott StatisticsRecorder(); 688c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 689c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ~StatisticsRecorder(); 690c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 691c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Find out if histograms can now be registered into our list. 69221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen static bool IsActive(); 693c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 694dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Register, or add a new histogram to the collection of statistics. If an 695dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // identically named histogram is already registered, then the argument 696ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // |histogram| will deleted. The returned value is always the registered 697ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // histogram (either the argument, or the pre-existing registered histogram). 698ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static Histogram* RegisterOrDeleteDuplicate(Histogram* histogram); 699c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 700c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Methods for printing histograms. Only histograms which have query as 701c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // a substring are written to output (an empty string will process all 702c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // registered histograms). 703c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static void WriteHTMLGraph(const std::string& query, std::string* output); 704c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static void WriteGraph(const std::string& query, std::string* output); 705c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 706c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Method for extracting histograms which were marked for use by UMA. 707c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static void GetHistograms(Histograms* output); 708c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 709c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Find a histogram by name. It matches the exact name. This method is thread 710c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // safe. If a matching histogram is not found, then the |histogram| is 711c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // not changed. 712ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static bool FindHistogram(const std::string& query, Histogram** histogram); 713c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 714c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static bool dump_on_exit() { return dump_on_exit_; } 715c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 716c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static void set_dump_on_exit(bool enable) { dump_on_exit_ = enable; } 717c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 718c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // GetSnapshot copies some of the pointers to registered histograms into the 719c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // caller supplied vector (Histograms). Only histograms with names matching 720c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // query are returned. The query must be a substring of histogram name for its 721c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // pointer to be copied. 722c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static void GetSnapshot(const std::string& query, Histograms* snapshot); 723c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 724c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 725c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 726c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We keep all registered histograms in a map, from name to histogram. 727ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen typedef std::map<std::string, Histogram*> HistogramMap; 728c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 729c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static HistogramMap* histograms_; 730c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 731c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // lock protects access to the above map. 7323f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen static base::Lock* lock_; 733c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 734c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Dump all known histograms to log. 735c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static bool dump_on_exit_; 736c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 737c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DISALLOW_COPY_AND_ASSIGN(StatisticsRecorder); 738c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 739c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 740731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} // namespace base 741731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 742731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#endif // BASE_METRICS_HISTOGRAM_H_ 743