• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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