1*6dbdd20aSAndroid Build Coastguard Worker /* 2*6dbdd20aSAndroid Build Coastguard Worker * Copyright (C) 2023 The Android Open Source Project 3*6dbdd20aSAndroid Build Coastguard Worker * 4*6dbdd20aSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*6dbdd20aSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*6dbdd20aSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*6dbdd20aSAndroid Build Coastguard Worker * 8*6dbdd20aSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*6dbdd20aSAndroid Build Coastguard Worker * 10*6dbdd20aSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*6dbdd20aSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*6dbdd20aSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*6dbdd20aSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*6dbdd20aSAndroid Build Coastguard Worker * limitations under the License. 15*6dbdd20aSAndroid Build Coastguard Worker */ 16*6dbdd20aSAndroid Build Coastguard Worker 17*6dbdd20aSAndroid Build Coastguard Worker #ifndef SRC_TRACING_SERVICE_HISTOGRAM_H_ 18*6dbdd20aSAndroid Build Coastguard Worker #define SRC_TRACING_SERVICE_HISTOGRAM_H_ 19*6dbdd20aSAndroid Build Coastguard Worker 20*6dbdd20aSAndroid Build Coastguard Worker #include <stddef.h> 21*6dbdd20aSAndroid Build Coastguard Worker #include <stdint.h> 22*6dbdd20aSAndroid Build Coastguard Worker 23*6dbdd20aSAndroid Build Coastguard Worker #include <limits> 24*6dbdd20aSAndroid Build Coastguard Worker 25*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/base/logging.h" 26*6dbdd20aSAndroid Build Coastguard Worker 27*6dbdd20aSAndroid Build Coastguard Worker namespace perfetto { 28*6dbdd20aSAndroid Build Coastguard Worker 29*6dbdd20aSAndroid Build Coastguard Worker using HistValue = int64_t; 30*6dbdd20aSAndroid Build Coastguard Worker 31*6dbdd20aSAndroid Build Coastguard Worker // Usage: 32*6dbdd20aSAndroid Build Coastguard Worker // Histogram<10, 100, 1000> h; // A histogram with 3 + 1 (overflow) bucket. 33*6dbdd20aSAndroid Build Coastguard Worker // h.Add(value); 34*6dbdd20aSAndroid Build Coastguard Worker // h.GetBucketSum(0); // Returns SUM(x) for 0 < x <= 10 35*6dbdd20aSAndroid Build Coastguard Worker // h.GetBucketSum(1); // Returns SUM(x) for 10 < x <= 100 36*6dbdd20aSAndroid Build Coastguard Worker // h.GetBucketSum(2); // Returns SUM(x) for 100 < x <= 1000 37*6dbdd20aSAndroid Build Coastguard Worker // h.GetBucketSum(3); // Returns SUM(x) for x > 1000 38*6dbdd20aSAndroid Build Coastguard Worker // Likewise h.GetBucketCount(x) returns the COUNT(x). 39*6dbdd20aSAndroid Build Coastguard Worker template <HistValue... thresholds> 40*6dbdd20aSAndroid Build Coastguard Worker class Histogram { 41*6dbdd20aSAndroid Build Coastguard Worker public: 42*6dbdd20aSAndroid Build Coastguard Worker // 1+ is for the overflow bucket (anything > the last threshold). 43*6dbdd20aSAndroid Build Coastguard Worker static constexpr size_t kNumBuckets = 1 + sizeof...(thresholds); 44*6dbdd20aSAndroid Build Coastguard Worker Add(HistValue value)45*6dbdd20aSAndroid Build Coastguard Worker void Add(HistValue value) { 46*6dbdd20aSAndroid Build Coastguard Worker size_t bucket = BucketForValue(value); 47*6dbdd20aSAndroid Build Coastguard Worker bucket_sum_[bucket] += value; 48*6dbdd20aSAndroid Build Coastguard Worker ++bucket_count_[bucket]; 49*6dbdd20aSAndroid Build Coastguard Worker } 50*6dbdd20aSAndroid Build Coastguard Worker num_buckets()51*6dbdd20aSAndroid Build Coastguard Worker static constexpr size_t num_buckets() { return kNumBuckets; } 52*6dbdd20aSAndroid Build Coastguard Worker GetBucketThres(size_t n)53*6dbdd20aSAndroid Build Coastguard Worker HistValue GetBucketThres(size_t n) const { 54*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_DCHECK(n < kNumBuckets); 55*6dbdd20aSAndroid Build Coastguard Worker return bucket_thres_[n]; 56*6dbdd20aSAndroid Build Coastguard Worker } 57*6dbdd20aSAndroid Build Coastguard Worker GetBucketCount(size_t n)58*6dbdd20aSAndroid Build Coastguard Worker uint64_t GetBucketCount(size_t n) const { 59*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_DCHECK(n < kNumBuckets); 60*6dbdd20aSAndroid Build Coastguard Worker return bucket_count_[n]; 61*6dbdd20aSAndroid Build Coastguard Worker } 62*6dbdd20aSAndroid Build Coastguard Worker GetBucketSum(size_t n)63*6dbdd20aSAndroid Build Coastguard Worker HistValue GetBucketSum(size_t n) const { 64*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_DCHECK(n < kNumBuckets); 65*6dbdd20aSAndroid Build Coastguard Worker return bucket_sum_[n]; 66*6dbdd20aSAndroid Build Coastguard Worker } 67*6dbdd20aSAndroid Build Coastguard Worker Merge(const Histogram & other)68*6dbdd20aSAndroid Build Coastguard Worker void Merge(const Histogram& other) { 69*6dbdd20aSAndroid Build Coastguard Worker for (size_t i = 0; i < kNumBuckets; ++i) { 70*6dbdd20aSAndroid Build Coastguard Worker bucket_sum_[i] += other.bucket_sum_[i]; 71*6dbdd20aSAndroid Build Coastguard Worker bucket_count_[i] += other.bucket_count_[i]; 72*6dbdd20aSAndroid Build Coastguard Worker } 73*6dbdd20aSAndroid Build Coastguard Worker } 74*6dbdd20aSAndroid Build Coastguard Worker 75*6dbdd20aSAndroid Build Coastguard Worker private: BucketForValue(HistValue value)76*6dbdd20aSAndroid Build Coastguard Worker static size_t BucketForValue(HistValue value) { 77*6dbdd20aSAndroid Build Coastguard Worker for (size_t i = 0; i < kNumBuckets - 1; i++) { 78*6dbdd20aSAndroid Build Coastguard Worker if (value <= bucket_thres_[i]) 79*6dbdd20aSAndroid Build Coastguard Worker return i; 80*6dbdd20aSAndroid Build Coastguard Worker } 81*6dbdd20aSAndroid Build Coastguard Worker return kNumBuckets - 1; 82*6dbdd20aSAndroid Build Coastguard Worker } 83*6dbdd20aSAndroid Build Coastguard Worker 84*6dbdd20aSAndroid Build Coastguard Worker static constexpr HistValue bucket_thres_[kNumBuckets]{ 85*6dbdd20aSAndroid Build Coastguard Worker thresholds..., std::numeric_limits<HistValue>::max()}; 86*6dbdd20aSAndroid Build Coastguard Worker 87*6dbdd20aSAndroid Build Coastguard Worker HistValue bucket_sum_[kNumBuckets]{}; 88*6dbdd20aSAndroid Build Coastguard Worker uint64_t bucket_count_[kNumBuckets]{}; 89*6dbdd20aSAndroid Build Coastguard Worker }; 90*6dbdd20aSAndroid Build Coastguard Worker 91*6dbdd20aSAndroid Build Coastguard Worker } // namespace perfetto 92*6dbdd20aSAndroid Build Coastguard Worker 93*6dbdd20aSAndroid Build Coastguard Worker #endif // SRC_TRACING_SERVICE_HISTOGRAM_H_ 94