Chromium Code Reviews| Index: webrtc/modules/audio_processing/swap_queue.h |
| diff --git a/webrtc/modules/audio_processing/swap_queue.h b/webrtc/modules/audio_processing/swap_queue.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..ff63c669a6286568c771ff4ed535ac9526637df4 |
| --- /dev/null |
| +++ b/webrtc/modules/audio_processing/swap_queue.h |
| @@ -0,0 +1,131 @@ |
| +/* |
| + * Copyright (c) 2015 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 WEBRTC_MODULES_AUDIO_PROCESSING_SWAPPED_NONBLOCKING_QUEUE_H_ |
| +#define WEBRTC_MODULES_AUDIO_PROCESSING_SWAPPED_NONBLOCKING_QUEUE_H_ |
|
kwiberg-webrtc
2015/10/12 14:05:48
The include guard name needs updating.
peah-webrtc
2015/10/13 11:56:13
Done.
|
| + |
| +#include <algorithm> |
| +#include <utility> |
| +#include <vector> |
| + |
| +#include "webrtc/base/checks.h" |
| +#include "webrtc/base/criticalsection.h" |
| + |
| +namespace webrtc { |
| + |
| +// This class is to be used as a one-way queue where data is |
|
kwiberg-webrtc
2015/10/12 14:05:48
It actually *is* a one-way queue.
peah-webrtc
2015/10/13 11:56:13
Done.
|
| +// written from one end and read from the other end. |
| +// It is safe to access the class concurrently from multiple threads. |
|
The Sun (google.com)
2015/10/13 07:53:05
Will git cl format fix the alignment of comment li
peah-webrtc
2015/10/13 11:56:13
You mean whether multiline comments are rearranged
the sun
2015/10/13 12:34:27
yes
peah-webrtc
2015/10/26 08:56:56
Acknowledged.
|
| +// The queueable objects must all be swappable. |
| +// |
| +// When T is a vector, one way of us using this class is by leveraging that |
|
The Sun (google.com)
2015/10/13 07:53:05
What you describe is the general intention of this
peah-webrtc
2015/10/13 11:56:13
I fully agree. I revised the description, and adde
|
| +// the vector returned (via a swap) when doing an Insert can be reused if |
| +// the queue is properly initialized. For instance, if the queue is initialized |
| +// with N elements sized vectors, and the vectors passed to the Insert and |
| +// Remove methods also are always N elements long, the vector returned from |
| +// the Insert method always have a size of N, allowing for a cheap scheme of |
| +// avoiding vector reallocations. |
| +template <typename T> |
| +class SwapQueue { |
|
kwiberg-webrtc
2015/10/12 14:05:48
It might be a good idea to reflect the threadsafen
The Sun (google.com)
2015/10/13 07:53:05
+1 -1
I think that is a good idea assuming we are
kwiberg-webrtc
2015/10/13 09:59:53
OK. Then I suggest to err on the side of brevity.
peah-webrtc
2015/10/13 11:56:12
How about omitting threadsafety in the name, but o
kwiberg-webrtc
2015/10/13 12:09:07
Dynamically taking locks or not would make the cod
peah-webrtc
2015/10/26 08:56:56
Acknowledged.
|
| + public: |
| + // Creates a queue of size size. |
|
kwiberg-webrtc
2015/10/12 14:05:48
Document that this fills the queue with the specif
peah-webrtc
2015/10/13 11:56:13
Done.
|
| + explicit SwapQueue(size_t size) { queue_.resize(size); } |
|
kwiberg-webrtc
2015/10/12 14:05:48
explicit SwapQueue(size_t size) : queue_(size) {}
peah-webrtc
2015/10/13 11:56:13
Done.
|
| + |
| + // Creates a queue of size size and initializes each element |
| + // to have the same size and content of initializer (useful to |
| + // ensure a certain initial size when T is a vector). |
| + explicit SwapQueue<T>(size_t size, const T& initializer) |
| + : SwapQueue<T>(size) { |
|
The Sun (google.com)
2015/10/13 07:53:05
: queue_(size, initializer) {
i.e. don't default-
peah-webrtc
2015/10/13 11:56:13
Done.
|
| + queue_ = std::vector<T>(size, initializer); |
| + } |
|
kwiberg-webrtc
2015/10/12 14:05:48
"explicit" is only needed for one-argument constru
peah-webrtc
2015/10/13 11:56:13
I removed this constructor.
the sun
2015/10/13 12:34:26
But why? Supplying a prototype object which is cop
kwiberg-webrtc
2015/10/13 14:08:36
Sure, it might be a convenient shortcut.
|
| + |
| + // Ensures that the internal queue elements of type vector |
| + // are formed as in the supplied empty slots input |
|
kwiberg-webrtc
2015/10/12 14:05:48
Maybe just
// Create a queue with "empty" Ts fr
peah-webrtc
2015/10/13 11:56:13
Excellent suggestion.
peah-webrtc
2015/10/13 11:56:13
Done.
|
| + // TODO(peah): Change to std::vector<T>&& when we have a C++11 |
| + // standard library. |
|
kwiberg-webrtc
2015/10/12 15:39:10
Actually, I realized on the way home that we only
peah-webrtc
2015/10/13 11:56:12
Nice! But I get a cl upload warning that the below
|
| + // |
| + // If using the above described scheme that ensures that all elements in the |
| + // queue are of the same size, this is achieved if the following constructor |
| + // is used with an input of vectors having the same size. |
|
kwiberg-webrtc
2015/10/12 14:05:48
You repeat this several times. Maybe just once, in
The Sun (google.com)
2015/10/13 07:53:05
It is confusing that you talk about "input of vect
kwiberg-webrtc
2015/10/13 09:59:53
We don't. std::vector is less convenient than it c
peah-webrtc
2015/10/13 11:56:13
I made an attempt to do that. Could you please hav
peah-webrtc
2015/10/13 11:56:13
I agree about repetition, and I removed that part.
|
| + explicit SwapQueue(std::vector<T>* empty_slots) { |
| + RTC_CHECK_GE(empty_slots->size(), 1u); |
| + using std::swap; |
|
The Sun (google.com)
2015/10/13 07:53:05
Why not just do std::swap on the line below?
kwiberg-webrtc
2015/10/13 09:59:53
Because the author of T might have defined a swap(
peah-webrtc
2015/10/13 11:56:13
I kept it as it is for now. Please let me know if
peah-webrtc
2015/10/13 11:56:13
Acknowledged.
the sun
2015/10/13 12:34:27
Great! Thanks for the explanation.
|
| + swap(queue_, *empty_slots); |
| + } |
| + |
| + // Resets the queue to have zero content. |
| + void Clear() { |
| + rtc::CritScope cs(&crit_queue_); |
| + last_write_index_ = 0; |
| + last_read_index_ = 0; |
| + num_elements_ = 0; |
| + } |
| + |
| + // Inserts a chunk of data into the queue in a thread safe manner. |
|
kwiberg-webrtc
2015/10/12 14:05:48
Document thread safety once, in the class descript
peah-webrtc
2015/10/13 11:56:12
Done.
|
| + // The input is swapped with the next available value of type T |
| + // present in the queue. |
| + // Returns false if the queue is full, and true if not. |
|
kwiberg-webrtc
2015/10/12 14:05:48
Document that the operation is a no-op iff it retu
peah-webrtc
2015/10/13 11:56:13
Done.
|
| + // |
| + // Note that in the case of T being a vector, if using the above described |
|
The Sun (google.com)
2015/10/13 07:53:05
Please remove these comments. Too much text will m
peah-webrtc
2015/10/13 11:56:13
Done.
|
| + // scheme to ensure that all elements in the queue are of the same size, the |
| + // resulting content in input after the swap also has the same size. |
| + bool Insert(T* input) { |
| + rtc::CritScope cs(&crit_queue_); |
| + |
| + // Early return if the queue is full. |
| + if (num_elements_ == queue_.size()) |
| + return false; |
| + |
| + last_write_index_ = |
| + (last_write_index_ < (queue_.size() - 1) ? last_write_index_ + 1 : 0); |
| + |
| + using std::swap; |
| + swap(*input, queue_[last_write_index_]); |
| + |
| + num_elements_++; |
| + return true; |
| + } |
| + |
| + // Removes a chunk of data from the queue in a thread safe manner. |
| + // The queue element is swapped with the previous content of output. |
| + // Returns false if the queue is empty, and true if not. |
|
kwiberg-webrtc
2015/10/12 14:05:48
Same as above: document thread safety once, and sa
peah-webrtc
2015/10/13 11:56:13
Done.
|
| + // |
| + // Note that in the case of T being a vector, if using the above described |
| + // scheme to ensure that all elements in the queue are of the same size, |
| + // it is important to ensure that the initial content of output has the |
| + // same size as the content in the queue. |
| + bool Remove(T* output) { |
| + rtc::CritScope cs(&crit_queue_); |
| + |
| + // Early return for empty queue. |
| + if (num_elements_ == 0) |
| + return false; |
| + |
| + last_read_index_ = |
| + (last_read_index_ < (queue_.size() - 1) ? last_read_index_ + 1 : 0); |
|
The Sun (google.com)
2015/10/13 07:53:05
I'd rather you
last_read_index_++;
if (last_read_
peah-webrtc
2015/10/13 11:56:13
Done.
|
| + output->swap(queue_[last_read_index_]); |
|
kwiberg-webrtc
2015/10/12 14:05:48
Use the same swap idiom as above.
peah-webrtc
2015/10/13 11:56:13
Done.
|
| + |
| + num_elements_--; |
| + return true; |
| + } |
| + |
| + private: |
| + std::vector<T> queue_ GUARDED_BY(crit_queue_); |
| + size_t last_write_index_ GUARDED_BY(crit_queue_) = 0; |
| + size_t last_read_index_ GUARDED_BY(crit_queue_) = 0; |
| + size_t num_elements_ GUARDED_BY(crit_queue_) = 0; |
|
kwiberg-webrtc
2015/10/12 14:05:48
Document the invariants: queue_.size() never chang
peah-webrtc
2015/10/13 11:56:13
Done.
peah-webrtc
2015/10/13 11:56:13
Good point! I changed to using next, and added the
|
| + rtc::CriticalSection crit_queue_; |
| + |
| + RTC_DISALLOW_COPY_AND_ASSIGN(SwapQueue); |
| +}; |
| + |
| +} // namespace webrtc |
| + |
| +#endif // WEBRTC_MODULES_AUDIO_PROCESSING_SWAPPED_NONBLOCKING_QUEUE_H_ |