1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2013 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker *
4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker *
8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker *
10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker */
16*795d594fSAndroid Build Coastguard Worker
17*795d594fSAndroid Build Coastguard Worker #ifndef ART_LIBARTBASE_BASE_HISTOGRAM_INL_H_
18*795d594fSAndroid Build Coastguard Worker #define ART_LIBARTBASE_BASE_HISTOGRAM_INL_H_
19*795d594fSAndroid Build Coastguard Worker
20*795d594fSAndroid Build Coastguard Worker #include <algorithm>
21*795d594fSAndroid Build Coastguard Worker #include <cmath>
22*795d594fSAndroid Build Coastguard Worker #include <limits>
23*795d594fSAndroid Build Coastguard Worker #include <ostream>
24*795d594fSAndroid Build Coastguard Worker
25*795d594fSAndroid Build Coastguard Worker #include "histogram.h"
26*795d594fSAndroid Build Coastguard Worker
27*795d594fSAndroid Build Coastguard Worker #include <android-base/logging.h>
28*795d594fSAndroid Build Coastguard Worker
29*795d594fSAndroid Build Coastguard Worker #include "bit_utils.h"
30*795d594fSAndroid Build Coastguard Worker #include "time_utils.h"
31*795d594fSAndroid Build Coastguard Worker #include "utils.h"
32*795d594fSAndroid Build Coastguard Worker
33*795d594fSAndroid Build Coastguard Worker namespace art {
34*795d594fSAndroid Build Coastguard Worker
AddValue(Value value)35*795d594fSAndroid Build Coastguard Worker template <class Value> inline void Histogram<Value>::AddValue(Value value) {
36*795d594fSAndroid Build Coastguard Worker CHECK_GE(value, static_cast<Value>(0));
37*795d594fSAndroid Build Coastguard Worker if (value >= max_) {
38*795d594fSAndroid Build Coastguard Worker Value new_max = ((value + 1) / bucket_width_ + 1) * bucket_width_;
39*795d594fSAndroid Build Coastguard Worker DCHECK_GT(new_max, max_);
40*795d594fSAndroid Build Coastguard Worker GrowBuckets(new_max);
41*795d594fSAndroid Build Coastguard Worker }
42*795d594fSAndroid Build Coastguard Worker BucketiseValue(value);
43*795d594fSAndroid Build Coastguard Worker }
44*795d594fSAndroid Build Coastguard Worker
AdjustAndAddValue(Value value)45*795d594fSAndroid Build Coastguard Worker template <class Value> inline void Histogram<Value>::AdjustAndAddValue(Value value) {
46*795d594fSAndroid Build Coastguard Worker AddValue(value / kAdjust);
47*795d594fSAndroid Build Coastguard Worker }
48*795d594fSAndroid Build Coastguard Worker
Histogram(const char * name)49*795d594fSAndroid Build Coastguard Worker template <class Value> inline Histogram<Value>::Histogram(const char* name)
50*795d594fSAndroid Build Coastguard Worker : kAdjust(0),
51*795d594fSAndroid Build Coastguard Worker kInitialBucketCount(0),
52*795d594fSAndroid Build Coastguard Worker name_(name),
53*795d594fSAndroid Build Coastguard Worker max_buckets_(0),
54*795d594fSAndroid Build Coastguard Worker sample_size_(0) {
55*795d594fSAndroid Build Coastguard Worker }
56*795d594fSAndroid Build Coastguard Worker
57*795d594fSAndroid Build Coastguard Worker template <class Value>
Histogram(const char * name,Value initial_bucket_width,size_t max_buckets)58*795d594fSAndroid Build Coastguard Worker inline Histogram<Value>::Histogram(const char* name, Value initial_bucket_width,
59*795d594fSAndroid Build Coastguard Worker size_t max_buckets)
60*795d594fSAndroid Build Coastguard Worker : kAdjust(1000),
61*795d594fSAndroid Build Coastguard Worker kInitialBucketCount(kMinBuckets),
62*795d594fSAndroid Build Coastguard Worker name_(name),
63*795d594fSAndroid Build Coastguard Worker max_buckets_(max_buckets),
64*795d594fSAndroid Build Coastguard Worker bucket_width_(initial_bucket_width) {
65*795d594fSAndroid Build Coastguard Worker CHECK_GE(max_buckets, kInitialBucketCount);
66*795d594fSAndroid Build Coastguard Worker CHECK_EQ(max_buckets_ % 2, 0u);
67*795d594fSAndroid Build Coastguard Worker Reset();
68*795d594fSAndroid Build Coastguard Worker }
69*795d594fSAndroid Build Coastguard Worker
70*795d594fSAndroid Build Coastguard Worker template <class Value>
GrowBuckets(Value new_max)71*795d594fSAndroid Build Coastguard Worker inline void Histogram<Value>::GrowBuckets(Value new_max) {
72*795d594fSAndroid Build Coastguard Worker while (max_ < new_max) {
73*795d594fSAndroid Build Coastguard Worker // If we have reached the maximum number of buckets, merge buckets together.
74*795d594fSAndroid Build Coastguard Worker DCHECK_LE(frequency_.size(), max_buckets_);
75*795d594fSAndroid Build Coastguard Worker if (frequency_.size() == max_buckets_) {
76*795d594fSAndroid Build Coastguard Worker DCHECK_EQ(frequency_.size() % 2, 0u);
77*795d594fSAndroid Build Coastguard Worker // We double the width of each bucket to reduce the number of buckets by a factor of 2.
78*795d594fSAndroid Build Coastguard Worker bucket_width_ *= 2;
79*795d594fSAndroid Build Coastguard Worker const size_t limit = frequency_.size() / 2;
80*795d594fSAndroid Build Coastguard Worker // Merge the frequencies by adding each adjacent two together.
81*795d594fSAndroid Build Coastguard Worker for (size_t i = 0; i < limit; ++i) {
82*795d594fSAndroid Build Coastguard Worker frequency_[i] = frequency_[i * 2] + frequency_[i * 2 + 1];
83*795d594fSAndroid Build Coastguard Worker }
84*795d594fSAndroid Build Coastguard Worker // Remove frequencies in the second half of the array which were added to the first half.
85*795d594fSAndroid Build Coastguard Worker while (frequency_.size() > limit) {
86*795d594fSAndroid Build Coastguard Worker frequency_.pop_back();
87*795d594fSAndroid Build Coastguard Worker }
88*795d594fSAndroid Build Coastguard Worker }
89*795d594fSAndroid Build Coastguard Worker max_ += bucket_width_;
90*795d594fSAndroid Build Coastguard Worker frequency_.push_back(0);
91*795d594fSAndroid Build Coastguard Worker }
92*795d594fSAndroid Build Coastguard Worker }
93*795d594fSAndroid Build Coastguard Worker
FindBucket(Value val)94*795d594fSAndroid Build Coastguard Worker template <class Value> inline size_t Histogram<Value>::FindBucket(Value val) const {
95*795d594fSAndroid Build Coastguard Worker // Since this is only a linear histogram, bucket index can be found simply with
96*795d594fSAndroid Build Coastguard Worker // dividing the value by the bucket width.
97*795d594fSAndroid Build Coastguard Worker DCHECK_GE(val, min_);
98*795d594fSAndroid Build Coastguard Worker DCHECK_LE(val, max_);
99*795d594fSAndroid Build Coastguard Worker const size_t bucket_idx = static_cast<size_t>((val - min_) / bucket_width_);
100*795d594fSAndroid Build Coastguard Worker DCHECK_GE(bucket_idx, 0ul);
101*795d594fSAndroid Build Coastguard Worker DCHECK_LE(bucket_idx, GetBucketCount());
102*795d594fSAndroid Build Coastguard Worker return bucket_idx;
103*795d594fSAndroid Build Coastguard Worker }
104*795d594fSAndroid Build Coastguard Worker
105*795d594fSAndroid Build Coastguard Worker template <class Value>
BucketiseValue(Value val)106*795d594fSAndroid Build Coastguard Worker inline void Histogram<Value>::BucketiseValue(Value val) {
107*795d594fSAndroid Build Coastguard Worker CHECK_LT(val, max_);
108*795d594fSAndroid Build Coastguard Worker sum_ += val;
109*795d594fSAndroid Build Coastguard Worker sum_of_squares_ += val * val;
110*795d594fSAndroid Build Coastguard Worker ++sample_size_;
111*795d594fSAndroid Build Coastguard Worker ++frequency_[FindBucket(val)];
112*795d594fSAndroid Build Coastguard Worker max_value_added_ = std::max(val, max_value_added_);
113*795d594fSAndroid Build Coastguard Worker min_value_added_ = std::min(val, min_value_added_);
114*795d594fSAndroid Build Coastguard Worker }
115*795d594fSAndroid Build Coastguard Worker
Initialize()116*795d594fSAndroid Build Coastguard Worker template <class Value> inline void Histogram<Value>::Initialize() {
117*795d594fSAndroid Build Coastguard Worker for (size_t idx = 0; idx < kInitialBucketCount; idx++) {
118*795d594fSAndroid Build Coastguard Worker frequency_.push_back(0);
119*795d594fSAndroid Build Coastguard Worker }
120*795d594fSAndroid Build Coastguard Worker // Cumulative frequency and ranges has a length of 1 over frequency.
121*795d594fSAndroid Build Coastguard Worker max_ = bucket_width_ * GetBucketCount();
122*795d594fSAndroid Build Coastguard Worker }
123*795d594fSAndroid Build Coastguard Worker
GetBucketCount()124*795d594fSAndroid Build Coastguard Worker template <class Value> inline size_t Histogram<Value>::GetBucketCount() const {
125*795d594fSAndroid Build Coastguard Worker return frequency_.size();
126*795d594fSAndroid Build Coastguard Worker }
127*795d594fSAndroid Build Coastguard Worker
Reset()128*795d594fSAndroid Build Coastguard Worker template <class Value> inline void Histogram<Value>::Reset() {
129*795d594fSAndroid Build Coastguard Worker sum_of_squares_ = 0;
130*795d594fSAndroid Build Coastguard Worker sample_size_ = 0;
131*795d594fSAndroid Build Coastguard Worker min_ = 0;
132*795d594fSAndroid Build Coastguard Worker sum_ = 0;
133*795d594fSAndroid Build Coastguard Worker min_value_added_ = std::numeric_limits<Value>::max();
134*795d594fSAndroid Build Coastguard Worker max_value_added_ = std::numeric_limits<Value>::min();
135*795d594fSAndroid Build Coastguard Worker frequency_.clear();
136*795d594fSAndroid Build Coastguard Worker Initialize();
137*795d594fSAndroid Build Coastguard Worker }
138*795d594fSAndroid Build Coastguard Worker
GetRange(size_t bucket_idx)139*795d594fSAndroid Build Coastguard Worker template <class Value> inline Value Histogram<Value>::GetRange(size_t bucket_idx) const {
140*795d594fSAndroid Build Coastguard Worker DCHECK_LE(bucket_idx, GetBucketCount());
141*795d594fSAndroid Build Coastguard Worker return min_ + bucket_idx * bucket_width_;
142*795d594fSAndroid Build Coastguard Worker }
143*795d594fSAndroid Build Coastguard Worker
Mean()144*795d594fSAndroid Build Coastguard Worker template <class Value> inline double Histogram<Value>::Mean() const {
145*795d594fSAndroid Build Coastguard Worker DCHECK_GT(sample_size_, 0ull);
146*795d594fSAndroid Build Coastguard Worker return static_cast<double>(sum_) / static_cast<double>(sample_size_);
147*795d594fSAndroid Build Coastguard Worker }
148*795d594fSAndroid Build Coastguard Worker
Variance()149*795d594fSAndroid Build Coastguard Worker template <class Value> inline double Histogram<Value>::Variance() const {
150*795d594fSAndroid Build Coastguard Worker DCHECK_GT(sample_size_, 0ull);
151*795d594fSAndroid Build Coastguard Worker // Using algorithms for calculating variance over a population:
152*795d594fSAndroid Build Coastguard Worker // http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance
153*795d594fSAndroid Build Coastguard Worker Value sum_squared = sum_ * sum_;
154*795d594fSAndroid Build Coastguard Worker double sum_squared_by_n_squared =
155*795d594fSAndroid Build Coastguard Worker static_cast<double>(sum_squared) /
156*795d594fSAndroid Build Coastguard Worker static_cast<double>(sample_size_ * sample_size_);
157*795d594fSAndroid Build Coastguard Worker double sum_of_squares_by_n =
158*795d594fSAndroid Build Coastguard Worker static_cast<double>(sum_of_squares_) / static_cast<double>(sample_size_);
159*795d594fSAndroid Build Coastguard Worker return sum_of_squares_by_n - sum_squared_by_n_squared;
160*795d594fSAndroid Build Coastguard Worker }
161*795d594fSAndroid Build Coastguard Worker
162*795d594fSAndroid Build Coastguard Worker template <class Value>
PrintBins(std::ostream & os,const CumulativeData & data)163*795d594fSAndroid Build Coastguard Worker inline void Histogram<Value>::PrintBins(std::ostream& os, const CumulativeData& data) const {
164*795d594fSAndroid Build Coastguard Worker DCHECK_GT(sample_size_, 0ull);
165*795d594fSAndroid Build Coastguard Worker for (size_t bin_idx = 0; bin_idx < data.freq_.size(); ++bin_idx) {
166*795d594fSAndroid Build Coastguard Worker if (bin_idx > 0 && data.perc_[bin_idx] == data.perc_[bin_idx - 1]) {
167*795d594fSAndroid Build Coastguard Worker bin_idx++;
168*795d594fSAndroid Build Coastguard Worker continue;
169*795d594fSAndroid Build Coastguard Worker }
170*795d594fSAndroid Build Coastguard Worker os << GetRange(bin_idx) << ": " << data.freq_[bin_idx] << "\t"
171*795d594fSAndroid Build Coastguard Worker << data.perc_[bin_idx] * 100.0 << "%\n";
172*795d594fSAndroid Build Coastguard Worker }
173*795d594fSAndroid Build Coastguard Worker }
174*795d594fSAndroid Build Coastguard Worker
175*795d594fSAndroid Build Coastguard Worker template <class Value>
DumpBins(std::ostream & os)176*795d594fSAndroid Build Coastguard Worker inline void Histogram<Value>::DumpBins(std::ostream& os) const {
177*795d594fSAndroid Build Coastguard Worker DCHECK_GT(sample_size_, 0ull);
178*795d594fSAndroid Build Coastguard Worker bool dumped_one = false;
179*795d594fSAndroid Build Coastguard Worker for (size_t bin_idx = 0; bin_idx < frequency_.size(); ++bin_idx) {
180*795d594fSAndroid Build Coastguard Worker if (frequency_[bin_idx] != 0U) {
181*795d594fSAndroid Build Coastguard Worker if (dumped_one) {
182*795d594fSAndroid Build Coastguard Worker // Prepend a comma if not the first bin.
183*795d594fSAndroid Build Coastguard Worker os << ",";
184*795d594fSAndroid Build Coastguard Worker } else {
185*795d594fSAndroid Build Coastguard Worker dumped_one = true;
186*795d594fSAndroid Build Coastguard Worker }
187*795d594fSAndroid Build Coastguard Worker os << GetRange(bin_idx) << ":" << frequency_[bin_idx];
188*795d594fSAndroid Build Coastguard Worker }
189*795d594fSAndroid Build Coastguard Worker }
190*795d594fSAndroid Build Coastguard Worker }
191*795d594fSAndroid Build Coastguard Worker
192*795d594fSAndroid Build Coastguard Worker template <class Value>
PrintConfidenceIntervals(std::ostream & os,double interval,const CumulativeData & data)193*795d594fSAndroid Build Coastguard Worker inline void Histogram<Value>::PrintConfidenceIntervals(std::ostream &os, double interval,
194*795d594fSAndroid Build Coastguard Worker const CumulativeData& data) const {
195*795d594fSAndroid Build Coastguard Worker static constexpr size_t kFractionalDigits = 3;
196*795d594fSAndroid Build Coastguard Worker DCHECK_GT(interval, 0);
197*795d594fSAndroid Build Coastguard Worker DCHECK_LT(interval, 1.0);
198*795d594fSAndroid Build Coastguard Worker const double per_0 = (1.0 - interval) / 2.0;
199*795d594fSAndroid Build Coastguard Worker const double per_1 = per_0 + interval;
200*795d594fSAndroid Build Coastguard Worker const TimeUnit unit = GetAppropriateTimeUnit(Mean() * kAdjust);
201*795d594fSAndroid Build Coastguard Worker os << Name() << ":\tSum: " << PrettyDuration(Sum() * kAdjust) << " "
202*795d594fSAndroid Build Coastguard Worker << (interval * 100) << "% C.I. " << FormatDuration(Percentile(per_0, data) * kAdjust, unit,
203*795d594fSAndroid Build Coastguard Worker kFractionalDigits)
204*795d594fSAndroid Build Coastguard Worker << "-" << FormatDuration(Percentile(per_1, data) * kAdjust, unit, kFractionalDigits) << " "
205*795d594fSAndroid Build Coastguard Worker << "Avg: " << FormatDuration(Mean() * kAdjust, unit, kFractionalDigits) << " Max: "
206*795d594fSAndroid Build Coastguard Worker << FormatDuration(Max() * kAdjust, unit, kFractionalDigits) << std::endl;
207*795d594fSAndroid Build Coastguard Worker }
208*795d594fSAndroid Build Coastguard Worker
209*795d594fSAndroid Build Coastguard Worker template <class Value>
PrintMemoryUse(std::ostream & os)210*795d594fSAndroid Build Coastguard Worker inline void Histogram<Value>::PrintMemoryUse(std::ostream &os) const {
211*795d594fSAndroid Build Coastguard Worker os << Name();
212*795d594fSAndroid Build Coastguard Worker if (sample_size_ != 0u) {
213*795d594fSAndroid Build Coastguard Worker os << ": Avg: " << PrettySize(Mean()) << " Max: "
214*795d594fSAndroid Build Coastguard Worker << PrettySize(Max()) << " Min: " << PrettySize(Min()) << "\n";
215*795d594fSAndroid Build Coastguard Worker } else {
216*795d594fSAndroid Build Coastguard Worker os << ": <no data>\n";
217*795d594fSAndroid Build Coastguard Worker }
218*795d594fSAndroid Build Coastguard Worker }
219*795d594fSAndroid Build Coastguard Worker
220*795d594fSAndroid Build Coastguard Worker template <class Value>
CreateHistogram(CumulativeData * out_data)221*795d594fSAndroid Build Coastguard Worker inline void Histogram<Value>::CreateHistogram(CumulativeData* out_data) const {
222*795d594fSAndroid Build Coastguard Worker DCHECK_GT(sample_size_, 0ull);
223*795d594fSAndroid Build Coastguard Worker out_data->freq_.clear();
224*795d594fSAndroid Build Coastguard Worker out_data->perc_.clear();
225*795d594fSAndroid Build Coastguard Worker uint64_t accumulated = 0;
226*795d594fSAndroid Build Coastguard Worker out_data->freq_.push_back(accumulated);
227*795d594fSAndroid Build Coastguard Worker out_data->perc_.push_back(0.0);
228*795d594fSAndroid Build Coastguard Worker for (size_t idx = 0; idx < frequency_.size(); idx++) {
229*795d594fSAndroid Build Coastguard Worker accumulated += frequency_[idx];
230*795d594fSAndroid Build Coastguard Worker out_data->freq_.push_back(accumulated);
231*795d594fSAndroid Build Coastguard Worker out_data->perc_.push_back(static_cast<double>(accumulated) / static_cast<double>(sample_size_));
232*795d594fSAndroid Build Coastguard Worker }
233*795d594fSAndroid Build Coastguard Worker DCHECK_EQ(out_data->freq_.back(), sample_size_);
234*795d594fSAndroid Build Coastguard Worker DCHECK_LE(std::abs(out_data->perc_.back() - 1.0), 0.001);
235*795d594fSAndroid Build Coastguard Worker }
236*795d594fSAndroid Build Coastguard Worker
237*795d594fSAndroid Build Coastguard Worker #pragma clang diagnostic push
238*795d594fSAndroid Build Coastguard Worker #pragma clang diagnostic ignored "-Wfloat-equal"
239*795d594fSAndroid Build Coastguard Worker
240*795d594fSAndroid Build Coastguard Worker template <class Value>
Percentile(double per,const CumulativeData & data)241*795d594fSAndroid Build Coastguard Worker inline double Histogram<Value>::Percentile(double per, const CumulativeData& data) const {
242*795d594fSAndroid Build Coastguard Worker DCHECK_GT(data.perc_.size(), 0ull);
243*795d594fSAndroid Build Coastguard Worker size_t upper_idx = 0, lower_idx = 0;
244*795d594fSAndroid Build Coastguard Worker for (size_t idx = 0; idx < data.perc_.size(); idx++) {
245*795d594fSAndroid Build Coastguard Worker if (per <= data.perc_[idx]) {
246*795d594fSAndroid Build Coastguard Worker upper_idx = idx;
247*795d594fSAndroid Build Coastguard Worker break;
248*795d594fSAndroid Build Coastguard Worker }
249*795d594fSAndroid Build Coastguard Worker
250*795d594fSAndroid Build Coastguard Worker if (per >= data.perc_[idx] && idx != 0 && data.perc_[idx] != data.perc_[idx - 1]) {
251*795d594fSAndroid Build Coastguard Worker lower_idx = idx;
252*795d594fSAndroid Build Coastguard Worker }
253*795d594fSAndroid Build Coastguard Worker }
254*795d594fSAndroid Build Coastguard Worker
255*795d594fSAndroid Build Coastguard Worker const double lower_perc = data.perc_[lower_idx];
256*795d594fSAndroid Build Coastguard Worker const double lower_value = static_cast<double>(GetRange(lower_idx));
257*795d594fSAndroid Build Coastguard Worker if (per == lower_perc) {
258*795d594fSAndroid Build Coastguard Worker return lower_value;
259*795d594fSAndroid Build Coastguard Worker }
260*795d594fSAndroid Build Coastguard Worker
261*795d594fSAndroid Build Coastguard Worker const double upper_perc = data.perc_[upper_idx];
262*795d594fSAndroid Build Coastguard Worker const double upper_value = static_cast<double>(GetRange(upper_idx));
263*795d594fSAndroid Build Coastguard Worker if (per == upper_perc) {
264*795d594fSAndroid Build Coastguard Worker return upper_value;
265*795d594fSAndroid Build Coastguard Worker }
266*795d594fSAndroid Build Coastguard Worker DCHECK_GT(upper_perc, lower_perc);
267*795d594fSAndroid Build Coastguard Worker
268*795d594fSAndroid Build Coastguard Worker double value = lower_value + (upper_value - lower_value) *
269*795d594fSAndroid Build Coastguard Worker (per - lower_perc) / (upper_perc - lower_perc);
270*795d594fSAndroid Build Coastguard Worker
271*795d594fSAndroid Build Coastguard Worker if (value < min_value_added_) {
272*795d594fSAndroid Build Coastguard Worker value = min_value_added_;
273*795d594fSAndroid Build Coastguard Worker } else if (value > max_value_added_) {
274*795d594fSAndroid Build Coastguard Worker value = max_value_added_;
275*795d594fSAndroid Build Coastguard Worker }
276*795d594fSAndroid Build Coastguard Worker
277*795d594fSAndroid Build Coastguard Worker return value;
278*795d594fSAndroid Build Coastguard Worker }
279*795d594fSAndroid Build Coastguard Worker
280*795d594fSAndroid Build Coastguard Worker #pragma clang diagnostic pop
281*795d594fSAndroid Build Coastguard Worker
282*795d594fSAndroid Build Coastguard Worker } // namespace art
283*795d594fSAndroid Build Coastguard Worker #endif // ART_LIBARTBASE_BASE_HISTOGRAM_INL_H_
284