blob: eef862b8fc4f5359d2de746ba9f8028a49ad0143 [file] [log] [blame]
/*
* Copyright (c) 2019 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 TEST_PC_E2E_ANALYZER_VIDEO_MULTI_HEAD_QUEUE_H_
#define TEST_PC_E2E_ANALYZER_VIDEO_MULTI_HEAD_QUEUE_H_
#include <deque>
#include <memory>
#include <vector>
#include "absl/types/optional.h"
#include "rtc_base/checks.h"
namespace webrtc {
// A queue that allows more than one reader. Readers are independent, and all
// readers will see all elements; an inserted element stays in the queue until
// all readers have extracted it. Elements are copied and copying is assumed to
// be cheap.
template <typename T>
class MultiHeadQueue {
public:
// Creates queue with exactly `readers_count` readers.
explicit MultiHeadQueue(size_t readers_count) {
for (size_t i = 0; i < readers_count; ++i) {
queues_.push_back(std::deque<T>());
}
}
// Creates a copy of an existing head. Complexity O(MultiHeadQueue::size()).
// `copy_index` - index of the queue that will be used as a source for
// copying.
void AddHead(size_t copy_index) { queues_.push_back(queues_[copy_index]); }
// Add value to the end of the queue. Complexity O(readers_count).
void PushBack(T value) {
for (auto& queue : queues_) {
queue.push_back(value);
}
}
// Extract element from specified head. Complexity O(1).
absl::optional<T> PopFront(size_t index) {
RTC_CHECK_LT(index, queues_.size());
if (queues_[index].empty()) {
return absl::nullopt;
}
T out = queues_[index].front();
queues_[index].pop_front();
return out;
}
// Returns element at specified head. Complexity O(1).
absl::optional<T> Front(size_t index) const {
RTC_CHECK_LT(index, queues_.size());
if (queues_[index].empty()) {
return absl::nullopt;
}
return queues_[index].front();
}
// Returns true if for specified head there are no more elements in the queue
// or false otherwise. Complexity O(1).
bool IsEmpty(size_t index) const {
RTC_CHECK_LT(index, queues_.size());
return queues_[index].empty();
}
// Returns size of the longest queue between all readers.
// Complexity O(readers_count).
size_t size() const {
size_t size = 0;
for (auto& queue : queues_) {
if (queue.size() > size) {
size = queue.size();
}
}
return size;
}
// Returns size of the specified queue. Complexity O(1).
size_t size(size_t index) const {
RTC_CHECK_LT(index, queues_.size());
return queues_[index].size();
}
size_t readers_count() const { return queues_.size(); }
private:
std::vector<std::deque<T>> queues_;
};
} // namespace webrtc
#endif // TEST_PC_E2E_ANALYZER_VIDEO_MULTI_HEAD_QUEUE_H_