xref: /aosp_15_r20/external/perfetto/src/tracing/service/histogram.h (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
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