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