• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
24 namespace simpleperf {
25 
26 // The compare functions below are used to compare two samples by their item
27 // content.
28 
29 template <typename T>
Compare(const T & a,const T & b)30 int 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 
55 BUILD_COMPARE_VALUE_FUNCTION(ComparePid, pid);
56 BUILD_COMPARE_VALUE_FUNCTION(CompareTid, tid);
57 BUILD_COMPARE_VALUE_FUNCTION_REVERSE(CompareSampleCount, sample_count);
58 BUILD_COMPARE_STRING_FUNCTION(CompareComm, thread_comm);
59 BUILD_COMPARE_STRING_FUNCTION(CompareDso, map->dso->GetReportPath().data());
60 BUILD_COMPARE_STRING_FUNCTION(CompareSymbol, symbol->DemangledName());
61 BUILD_COMPARE_STRING_FUNCTION(CompareDsoFrom, branch_from.map->dso->GetReportPath().data());
62 BUILD_COMPARE_STRING_FUNCTION(CompareSymbolFrom, branch_from.symbol->DemangledName());
63 BUILD_COMPARE_VALUE_FUNCTION(CompareCallGraphDuplicated, callchain.duplicated);
64 
65 template <typename EntryT>
CompareTotalPeriod(const EntryT * sample1,const EntryT * sample2)66 int 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 
72 template <typename EntryT>
ComparePeriod(const EntryT * sample1,const EntryT * sample2)73 int ComparePeriod(const EntryT* sample1, const EntryT* sample2) {
74   return Compare(sample2->period, sample1->period);
75 }
76 
77 // SampleComparator is a class using a collection of compare functions to
78 // compare two samples.
79 
80 template <typename EntryT>
81 class SampleComparator {
82  public:
83   typedef int (*compare_sample_func_t)(const EntryT*, const EntryT*);
84 
AddCompareFunction(compare_sample_func_t func)85   void AddCompareFunction(compare_sample_func_t func) { compare_v_.push_back(func); }
86 
AddComparator(const SampleComparator<EntryT> & other)87   void AddComparator(const SampleComparator<EntryT>& other) {
88     compare_v_.insert(compare_v_.end(), other.compare_v_.begin(), other.compare_v_.end());
89   }
90 
operator()91   bool operator()(const EntryT* sample1, const EntryT* sample2) const {
92     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 
operator()101   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 
IsSameSample(const EntryT * sample1,const EntryT * sample2)111   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 
empty()120   bool empty() const { return compare_v_.empty(); }
121 
122  private:
123   std::vector<compare_sample_func_t> compare_v_;
124 };
125 
126 }  // namespace simpleperf
127 
128 #endif  // SIMPLE_PERF_SAMPLE_COMPARATOR_H_
129