summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/logging/rtc_event_log/rtc_event_processor.h
diff options
context:
space:
mode:
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.h131
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_