/* * 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