1 /* 2 * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #ifndef TEST_PC_E2E_ANALYZER_VIDEO_MULTI_HEAD_QUEUE_H_ 12 #define TEST_PC_E2E_ANALYZER_VIDEO_MULTI_HEAD_QUEUE_H_ 13 14 #include <deque> 15 #include <memory> 16 #include <vector> 17 18 #include "absl/types/optional.h" 19 #include "rtc_base/checks.h" 20 21 namespace webrtc { 22 namespace webrtc_pc_e2e { 23 24 // A queue that allows more than one reader. Readers are independent, and all 25 // readers will see all elements; an inserted element stays in the queue until 26 // all readers have extracted it. Elements are copied and copying is assumed to 27 // be cheap. 28 template <typename T> 29 class MultiHeadQueue { 30 public: 31 // Creates queue with exactly |readers_count| readers. MultiHeadQueue(size_t readers_count)32 explicit MultiHeadQueue(size_t readers_count) { 33 for (size_t i = 0; i < readers_count; ++i) { 34 queues_.push_back(std::deque<T>()); 35 } 36 } 37 38 // Add value to the end of the queue. Complexity O(readers_count). PushBack(T value)39 void PushBack(T value) { 40 for (auto& queue : queues_) { 41 queue.push_back(value); 42 } 43 } 44 45 // Extract element from specified head. Complexity O(1). PopFront(size_t index)46 absl::optional<T> PopFront(size_t index) { 47 RTC_CHECK_LT(index, queues_.size()); 48 if (queues_[index].empty()) { 49 return absl::nullopt; 50 } 51 T out = queues_[index].front(); 52 queues_[index].pop_front(); 53 return out; 54 } 55 56 // Returns element at specified head. Complexity O(1). Front(size_t index)57 absl::optional<T> Front(size_t index) const { 58 RTC_CHECK_LT(index, queues_.size()); 59 if (queues_[index].empty()) { 60 return absl::nullopt; 61 } 62 return queues_[index].front(); 63 } 64 65 // Returns true if for specified head there are no more elements in the queue 66 // or false otherwise. Complexity O(1). IsEmpty(size_t index)67 bool IsEmpty(size_t index) const { 68 RTC_CHECK_LT(index, queues_.size()); 69 return queues_[index].empty(); 70 } 71 72 // Returns size of the longest queue between all readers. 73 // Complexity O(readers_count). size()74 size_t size() const { 75 size_t size = 0; 76 for (auto& queue : queues_) { 77 if (queue.size() > size) { 78 size = queue.size(); 79 } 80 } 81 return size; 82 } 83 84 // Returns size of the specified queue. Complexity O(1). size(size_t index)85 size_t size(size_t index) const { 86 RTC_CHECK_LT(index, queues_.size()); 87 return queues_[index].size(); 88 } 89 readers_count()90 size_t readers_count() const { return queues_.size(); } 91 92 private: 93 std::vector<std::deque<T>> queues_; 94 }; 95 96 } // namespace webrtc_pc_e2e 97 } // namespace webrtc 98 99 #endif // TEST_PC_E2E_ANALYZER_VIDEO_MULTI_HEAD_QUEUE_H_ 100