diff options
Diffstat (limited to 'third_party/libwebrtc/logging/rtc_event_log/rtc_event_processor.h')
-rw-r--r-- | third_party/libwebrtc/logging/rtc_event_log/rtc_event_processor.h | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/third_party/libwebrtc/logging/rtc_event_log/rtc_event_processor.h b/third_party/libwebrtc/logging/rtc_event_log/rtc_event_processor.h new file mode 100644 index 0000000000..9bf4c9c5db --- /dev/null +++ b/third_party/libwebrtc/logging/rtc_event_log/rtc_event_processor.h @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef LOGGING_RTC_EVENT_LOG_RTC_EVENT_PROCESSOR_H_ +#define LOGGING_RTC_EVENT_LOG_RTC_EVENT_PROCESSOR_H_ + +#include <stdint.h> + +#include <algorithm> +#include <memory> +#include <utility> +#include <vector> + +#include "api/function_view.h" +#include "rtc_base/checks.h" + +namespace webrtc { + +// This file contains helper class used to process the elements of two or more +// sorted lists in timestamp order. The effect is the same as doing a merge step +// in the merge-sort algorithm but without copying the elements or modifying the +// lists. + +namespace event_processor_impl { +// Interface to allow "merging" lists of different types. ProcessNext() +// processes the next unprocesses element in the list. IsEmpty() checks if all +// elements have been processed. GetNextTime returns the timestamp of the next +// unprocessed element. +class ProcessableEventListInterface { + public: + virtual ~ProcessableEventListInterface() = default; + virtual void ProcessNext() = 0; + virtual bool IsEmpty() const = 0; + virtual int64_t GetNextTime() const = 0; + virtual int GetTieBreaker() const = 0; +}; + +// ProcessableEventList encapsulates a list of events and a function that will +// be applied to each element of the list. +template <typename Iterator, typename T> +class ProcessableEventList : public ProcessableEventListInterface { + public: + ProcessableEventList(Iterator begin, + Iterator end, + std::function<void(const T&)> f, + int tie_breaker) + : begin_(begin), end_(end), f_(f), tie_breaker_(tie_breaker) {} + + void ProcessNext() override { + RTC_DCHECK(!IsEmpty()); + f_(*begin_); + ++begin_; + } + + bool IsEmpty() const override { return begin_ == end_; } + + int64_t GetNextTime() const override { + RTC_DCHECK(!IsEmpty()); + return begin_->log_time_us(); + } + int GetTieBreaker() const override { return tie_breaker_; } + + private: + Iterator begin_; + Iterator end_; + std::function<void(const T&)> f_; + int tie_breaker_; +}; +} // namespace event_processor_impl + +// Helper class used to "merge" two or more lists of ordered RtcEventLog events +// so that they can be treated as a single ordered list. Since the individual +// lists may have different types, we need to access the lists via pointers to +// the common base class. +// +// Usage example: +// ParsedRtcEventLogNew log; +// auto incoming_handler = [] (LoggedRtcpPacketIncoming elem) { ... }; +// auto outgoing_handler = [] (LoggedRtcpPacketOutgoing elem) { ... }; +// +// RtcEventProcessor processor; +// processor.AddEvents(log.incoming_rtcp_packets(), +// incoming_handler); +// processor.AddEvents(log.outgoing_rtcp_packets(), +// outgoing_handler); +// processor.ProcessEventsInOrder(); +class RtcEventProcessor { + public: + RtcEventProcessor(); + ~RtcEventProcessor(); + // The elements of each list is processed in the index order. To process all + // elements in all lists in timestamp order, each list needs to be sorted in + // timestamp order prior to insertion. + // N.B. `iterable` is not owned by RtcEventProcessor. The caller must ensure + // that the iterable outlives RtcEventProcessor and it must not be modified + // until processing has finished. + template <typename Iterable> + void AddEvents( + const Iterable& iterable, + std::function<void(const typename Iterable::value_type&)> handler) { + if (iterable.begin() == iterable.end()) + return; + event_lists_.push_back( + std::make_unique<event_processor_impl::ProcessableEventList< + typename Iterable::const_iterator, typename Iterable::value_type>>( + iterable.begin(), iterable.end(), handler, + insertion_order_index_++)); + std::push_heap(event_lists_.begin(), event_lists_.end(), Cmp); + } + + void ProcessEventsInOrder(); + + private: + using ListPtrType = + std::unique_ptr<event_processor_impl::ProcessableEventListInterface>; + int insertion_order_index_ = 0; + std::vector<ListPtrType> event_lists_; + // Comparison function to make `event_lists_` into a min heap. + static bool Cmp(const ListPtrType& a, const ListPtrType& b); +}; + +} // namespace webrtc + +#endif // LOGGING_RTC_EVENT_LOG_RTC_EVENT_PROCESSOR_H_ |