| /* |
| * Copyright (C) 2018 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include <iterator> |
| |
| #include "perf_data.pb.h" |
| |
| namespace android { |
| namespace perfprofd { |
| namespace quipper { |
| |
| template<typename Iterator, typename Predicate> |
| class FilteredIterator { |
| public: |
| using value_type = typename std::iterator_traits<Iterator>::value_type; |
| using difference_type = typename std::iterator_traits<Iterator>::difference_type; |
| using reference = typename std::iterator_traits<Iterator>::reference; |
| using pointer = typename std::iterator_traits<Iterator>::pointer; |
| |
| FilteredIterator(const Iterator& begin, const Iterator& end, const Predicate& pred) |
| : iter_(begin), end_(end), pred_(pred) { |
| filter(); |
| } |
| |
| reference operator*() const { |
| return *iter_; |
| } |
| pointer operator->() const { |
| return std::addressof(*iter_); |
| } |
| |
| FilteredIterator& operator++() { |
| ++iter_; |
| filter(); |
| return *this; |
| } |
| |
| FilteredIterator end() { |
| return FilteredIterator(end_, end_, pred_); |
| } |
| |
| bool operator==(const FilteredIterator& rhs) const { |
| return iter_ == rhs.iter_; |
| } |
| bool operator!=(const FilteredIterator& rhs) const { |
| return !(operator==(rhs)); |
| } |
| |
| private: |
| void filter() { |
| while (iter_ != end_ && !pred_(*iter_)) { |
| ++iter_; |
| } |
| } |
| |
| Iterator iter_; |
| Iterator end_; |
| Predicate pred_; |
| }; |
| |
| template <typename Predicate> |
| using EventFilteredIterator = FilteredIterator< |
| decltype(static_cast<::quipper::PerfDataProto*>(nullptr)->events().begin()), |
| Predicate>; |
| |
| struct CommEventPredicate { |
| bool operator()(const ::quipper::PerfDataProto_PerfEvent& evt) { |
| return evt.has_comm_event(); |
| } |
| }; |
| struct CommEventIterator : public EventFilteredIterator<CommEventPredicate> { |
| explicit CommEventIterator(const ::quipper::PerfDataProto& proto) |
| : EventFilteredIterator<CommEventPredicate>(proto.events().begin(), |
| proto.events().end(), |
| CommEventPredicate()) { |
| } |
| }; |
| |
| struct MmapEventPredicate { |
| bool operator()(const ::quipper::PerfDataProto_PerfEvent& evt) { |
| return evt.has_mmap_event(); |
| } |
| }; |
| struct MmapEventIterator : public EventFilteredIterator<MmapEventPredicate> { |
| explicit MmapEventIterator(const ::quipper::PerfDataProto& proto) |
| : EventFilteredIterator<MmapEventPredicate>(proto.events().begin(), |
| proto.events().end(), |
| MmapEventPredicate()) { |
| } |
| }; |
| |
| struct SampleEventPredicate { |
| bool operator()(const ::quipper::PerfDataProto_PerfEvent& evt) { |
| return evt.has_sample_event(); |
| } |
| }; |
| struct SampleEventIterator : public EventFilteredIterator<SampleEventPredicate> { |
| explicit SampleEventIterator(const ::quipper::PerfDataProto& proto) |
| : EventFilteredIterator<SampleEventPredicate>(proto.events().begin(), |
| proto.events().end(), |
| SampleEventPredicate()) { |
| } |
| }; |
| |
| struct ForkEventPredicate { |
| bool operator()(const ::quipper::PerfDataProto_PerfEvent& evt) { |
| return evt.has_fork_event(); |
| } |
| }; |
| struct ForkEventIterator : public EventFilteredIterator<ForkEventPredicate> { |
| explicit ForkEventIterator(const ::quipper::PerfDataProto& proto) |
| : EventFilteredIterator<ForkEventPredicate>(proto.events().begin(), |
| proto.events().end(), |
| ForkEventPredicate()) { |
| } |
| }; |
| |
| struct ExitEventPredicate { |
| bool operator()(const ::quipper::PerfDataProto_PerfEvent& evt) { |
| return evt.has_exit_event(); |
| } |
| }; |
| struct ExitEventIterator : public EventFilteredIterator<ExitEventPredicate> { |
| explicit ExitEventIterator(const ::quipper::PerfDataProto& proto) |
| : EventFilteredIterator<ExitEventPredicate>(proto.events().begin(), |
| proto.events().end(), |
| ExitEventPredicate()) { |
| } |
| }; |
| |
| } // namespace quipper |
| } // namespace perfprofd |
| } // namespace android |