blob: e13f2346008621a7e72ca1d63b8750007bd93427 [file] [log] [blame]
Yabin Cuib64a8632016-05-24 18:23:33 -07001/*
2 * Copyright (C) 2016 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 SIMPLE_PERF_SAMPLE_COMPARATOR_H_
18#define SIMPLE_PERF_SAMPLE_COMPARATOR_H_
19
20#include <string.h>
21
22#include <vector>
23
Yabin Cuifaa7b922021-01-11 17:35:57 -080024namespace simpleperf {
25
Yabin Cuib64a8632016-05-24 18:23:33 -070026// The compare functions below are used to compare two samples by their item
27// content.
28
29template <typename T>
30int Compare(const T& a, const T& b) {
31 if (a != b) {
32 return a < b ? -1 : 1;
33 }
34 return 0;
35}
36
37#define BUILD_COMPARE_VALUE_FUNCTION(function_name, compare_part) \
38 template <typename EntryT> \
39 int function_name(const EntryT* sample1, const EntryT* sample2) { \
40 return Compare(sample1->compare_part, sample2->compare_part); \
41 }
42
43#define BUILD_COMPARE_VALUE_FUNCTION_REVERSE(function_name, compare_part) \
44 template <typename EntryT> \
45 int function_name(const EntryT* sample1, const EntryT* sample2) { \
46 return Compare(sample2->compare_part, sample1->compare_part); \
47 }
48
49#define BUILD_COMPARE_STRING_FUNCTION(function_name, compare_part) \
50 template <typename EntryT> \
51 int function_name(const EntryT* sample1, const EntryT* sample2) { \
52 return strcmp(sample1->compare_part, sample2->compare_part); \
53 }
54
Yabin Cui847f3fd2019-05-02 12:58:05 -070055BUILD_COMPARE_VALUE_FUNCTION(ComparePid, pid);
56BUILD_COMPARE_VALUE_FUNCTION(CompareTid, tid);
Yabin Cuib64a8632016-05-24 18:23:33 -070057BUILD_COMPARE_VALUE_FUNCTION_REVERSE(CompareSampleCount, sample_count);
58BUILD_COMPARE_STRING_FUNCTION(CompareComm, thread_comm);
Yabin Cuie32ed2b2020-07-23 15:30:14 -070059BUILD_COMPARE_STRING_FUNCTION(CompareDso, map->dso->GetReportPath().data());
Yabin Cuib64a8632016-05-24 18:23:33 -070060BUILD_COMPARE_STRING_FUNCTION(CompareSymbol, symbol->DemangledName());
Thiébaud Weksteen4848ee02020-10-23 16:06:59 +020061BUILD_COMPARE_STRING_FUNCTION(CompareDsoFrom, branch_from.map->dso->GetReportPath().data());
62BUILD_COMPARE_STRING_FUNCTION(CompareSymbolFrom, branch_from.symbol->DemangledName());
Yabin Cui0c093f32017-04-19 11:48:44 -070063BUILD_COMPARE_VALUE_FUNCTION(CompareCallGraphDuplicated, callchain.duplicated);
Yabin Cuib64a8632016-05-24 18:23:33 -070064
65template <typename EntryT>
66int CompareTotalPeriod(const EntryT* sample1, const EntryT* sample2) {
67 uint64_t period1 = sample1->period + sample1->accumulated_period;
68 uint64_t period2 = sample2->period + sample2->accumulated_period;
69 return Compare(period2, period1);
70}
71
Yabin Cui0c093f32017-04-19 11:48:44 -070072template <typename EntryT>
73int ComparePeriod(const EntryT* sample1, const EntryT* sample2) {
74 return Compare(sample2->period, sample1->period);
75}
76
Yabin Cuib64a8632016-05-24 18:23:33 -070077// SampleComparator is a class using a collection of compare functions to
78// compare two samples.
79
80template <typename EntryT>
81class SampleComparator {
82 public:
83 typedef int (*compare_sample_func_t)(const EntryT*, const EntryT*);
84
Thiébaud Weksteen4848ee02020-10-23 16:06:59 +020085 void AddCompareFunction(compare_sample_func_t func) { compare_v_.push_back(func); }
Yabin Cuib64a8632016-05-24 18:23:33 -070086
87 void AddComparator(const SampleComparator<EntryT>& other) {
Thiébaud Weksteen4848ee02020-10-23 16:06:59 +020088 compare_v_.insert(compare_v_.end(), other.compare_v_.begin(), other.compare_v_.end());
Yabin Cuib64a8632016-05-24 18:23:33 -070089 }
90
Yabin Cui9970a232016-06-29 12:18:11 -070091 bool operator()(const EntryT* sample1, const EntryT* sample2) const {
Yabin Cuib64a8632016-05-24 18:23:33 -070092 for (const auto& func : compare_v_) {
93 int ret = func(sample1, sample2);
94 if (ret != 0) {
95 return ret < 0;
96 }
97 }
98 return false;
99 }
100
Yabin Cuif53f7162020-06-19 15:16:31 -0700101 bool operator()(const EntryT& sample1, const EntryT& sample2) const {
102 for (const auto& func : compare_v_) {
103 int ret = func(&sample1, &sample2);
104 if (ret != 0) {
105 return ret < 0;
106 }
107 }
108 return false;
109 }
110
Yabin Cui9970a232016-06-29 12:18:11 -0700111 bool IsSameSample(const EntryT* sample1, const EntryT* sample2) const {
112 for (const auto& func : compare_v_) {
113 if (func(sample1, sample2) != 0) {
114 return false;
115 }
116 }
117 return true;
118 }
119
Yabin Cuib64a8632016-05-24 18:23:33 -0700120 bool empty() const { return compare_v_.empty(); }
121
122 private:
123 std::vector<compare_sample_func_t> compare_v_;
124};
125
Yabin Cuifaa7b922021-01-11 17:35:57 -0800126} // namespace simpleperf
127
Yabin Cuib64a8632016-05-24 18:23:33 -0700128#endif // SIMPLE_PERF_SAMPLE_COMPARATOR_H_