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_ |