1 /* 2 * Copyright (C) 2018 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 #include <iterator> 18 19 #include "perf_data.pb.h" 20 21 namespace android { 22 namespace perfprofd { 23 namespace quipper { 24 25 template<typename Iterator, typename Predicate> 26 class FilteredIterator { 27 public: 28 using value_type = typename std::iterator_traits<Iterator>::value_type; 29 using difference_type = typename std::iterator_traits<Iterator>::difference_type; 30 using reference = typename std::iterator_traits<Iterator>::reference; 31 using pointer = typename std::iterator_traits<Iterator>::pointer; 32 FilteredIterator(const Iterator & begin,const Iterator & end,const Predicate & pred)33 FilteredIterator(const Iterator& begin, const Iterator& end, const Predicate& pred) 34 : iter_(begin), end_(end), pred_(pred) { 35 filter(); 36 } 37 38 reference operator*() const { 39 return *iter_; 40 } 41 pointer operator->() const { 42 return std::addressof(*iter_); 43 } 44 45 FilteredIterator& operator++() { 46 ++iter_; 47 filter(); 48 return *this; 49 } 50 end()51 FilteredIterator end() { 52 return FilteredIterator(end_, end_, pred_); 53 } 54 55 bool operator==(const FilteredIterator& rhs) const { 56 return iter_ == rhs.iter_; 57 } 58 bool operator!=(const FilteredIterator& rhs) const { 59 return !(operator==(rhs)); 60 } 61 62 private: filter()63 void filter() { 64 while (iter_ != end_ && !pred_(*iter_)) { 65 ++iter_; 66 } 67 } 68 69 Iterator iter_; 70 Iterator end_; 71 Predicate pred_; 72 }; 73 74 template <typename Predicate> 75 using EventFilteredIterator = FilteredIterator< 76 decltype(static_cast<::quipper::PerfDataProto*>(nullptr)->events().begin()), 77 Predicate>; 78 79 struct CommEventPredicate { operatorCommEventPredicate80 bool operator()(const ::quipper::PerfDataProto_PerfEvent& evt) { 81 return evt.has_comm_event(); 82 } 83 }; 84 struct CommEventIterator : public EventFilteredIterator<CommEventPredicate> { CommEventIteratorCommEventIterator85 explicit CommEventIterator(const ::quipper::PerfDataProto& proto) 86 : EventFilteredIterator<CommEventPredicate>(proto.events().begin(), 87 proto.events().end(), 88 CommEventPredicate()) { 89 } 90 }; 91 92 struct MmapEventPredicate { operatorMmapEventPredicate93 bool operator()(const ::quipper::PerfDataProto_PerfEvent& evt) { 94 return evt.has_mmap_event(); 95 } 96 }; 97 struct MmapEventIterator : public EventFilteredIterator<MmapEventPredicate> { MmapEventIteratorMmapEventIterator98 explicit MmapEventIterator(const ::quipper::PerfDataProto& proto) 99 : EventFilteredIterator<MmapEventPredicate>(proto.events().begin(), 100 proto.events().end(), 101 MmapEventPredicate()) { 102 } 103 }; 104 105 struct SampleEventPredicate { operatorSampleEventPredicate106 bool operator()(const ::quipper::PerfDataProto_PerfEvent& evt) { 107 return evt.has_sample_event(); 108 } 109 }; 110 struct SampleEventIterator : public EventFilteredIterator<SampleEventPredicate> { SampleEventIteratorSampleEventIterator111 explicit SampleEventIterator(const ::quipper::PerfDataProto& proto) 112 : EventFilteredIterator<SampleEventPredicate>(proto.events().begin(), 113 proto.events().end(), 114 SampleEventPredicate()) { 115 } 116 }; 117 118 struct ForkEventPredicate { operatorForkEventPredicate119 bool operator()(const ::quipper::PerfDataProto_PerfEvent& evt) { 120 return evt.has_fork_event(); 121 } 122 }; 123 struct ForkEventIterator : public EventFilteredIterator<ForkEventPredicate> { ForkEventIteratorForkEventIterator124 explicit ForkEventIterator(const ::quipper::PerfDataProto& proto) 125 : EventFilteredIterator<ForkEventPredicate>(proto.events().begin(), 126 proto.events().end(), 127 ForkEventPredicate()) { 128 } 129 }; 130 131 struct ExitEventPredicate { operatorExitEventPredicate132 bool operator()(const ::quipper::PerfDataProto_PerfEvent& evt) { 133 return evt.has_exit_event(); 134 } 135 }; 136 struct ExitEventIterator : public EventFilteredIterator<ExitEventPredicate> { ExitEventIteratorExitEventIterator137 explicit ExitEventIterator(const ::quipper::PerfDataProto& proto) 138 : EventFilteredIterator<ExitEventPredicate>(proto.events().begin(), 139 proto.events().end(), 140 ExitEventPredicate()) { 141 } 142 }; 143 144 } // namespace quipper 145 } // namespace perfprofd 146 } // namespace android 147