Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(149)

Unified Diff: webrtc/base/buffer.h

Issue 2078873005: rtc::Buffer: Grow capacity by at least 1.5x to prevent quadratic behavior (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | webrtc/base/buffer_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webrtc/base/buffer.h
diff --git a/webrtc/base/buffer.h b/webrtc/base/buffer.h
index cdaab544a7352e8d2df089b6070d47765dde3e47..545ddb2be7cc91df5b2b695948d1610abe9fe331 100644
--- a/webrtc/base/buffer.h
+++ b/webrtc/base/buffer.h
@@ -219,7 +219,7 @@ class BufferT {
void AppendData(const U* data, size_t size) {
RTC_DCHECK(IsConsistent());
const size_t new_size = size_ + size;
- EnsureCapacity(new_size);
+ EnsureCapacityWithHeadroom(new_size, true);
static_assert(sizeof(T) == sizeof(U), "");
std::memcpy(data_.get() + size_, data, size * sizeof(U));
size_ = new_size;
@@ -272,7 +272,7 @@ class BufferT {
// the existing contents will be kept and the new space will be
// uninitialized.
void SetSize(size_t size) {
- EnsureCapacity(size);
+ EnsureCapacityWithHeadroom(size, true);
sprang_webrtc 2016/06/20 09:27:44 Do we really want with headroom here, as it's an e
kwiberg-webrtc 2016/06/20 09:51:31 It's an explicit *size* request, but the caller do
sprang_webrtc 2016/06/20 09:56:28 Acknowledged.
size_ = size;
}
@@ -280,14 +280,9 @@ class BufferT {
// further reallocation. (Of course, this operation might need to reallocate
// the buffer.)
void EnsureCapacity(size_t capacity) {
- RTC_DCHECK(IsConsistent());
- if (capacity <= capacity_)
- return;
- std::unique_ptr<T[]> new_data(new T[capacity]);
- std::memcpy(new_data.get(), data_.get(), size_ * sizeof(T));
- data_ = std::move(new_data);
- capacity_ = capacity;
- RTC_DCHECK(IsConsistent());
+ // Don't allocate extra headroom, since the user is asking for a specific
+ // capacity.
+ EnsureCapacityWithHeadroom(capacity, false);
}
// Resets the buffer to zero size without altering capacity. Works even if the
@@ -306,6 +301,27 @@ class BufferT {
}
private:
+ void EnsureCapacityWithHeadroom(size_t capacity, bool extra_headroom) {
+ RTC_DCHECK(IsConsistent());
+ if (capacity <= capacity_)
+ return;
+
+ // If the caller asks for extra headroom, ensure that the new capacity is
+ // >= 1.5 times the old capacity. Any constant > 1 is sufficient to prevent
+ // quadratic behavior; as to why we pick 1.5 in particular, see
+ // https://github.com/facebook/folly/blob/master/folly/docs/FBVector.md and
+ // http://www.gahcep.com/cpp-internals-stl-vector-part-1/.
+ const size_t new_capacity =
+ extra_headroom ? std::max(capacity, capacity_ + capacity_ / 2)
+ : capacity;
sprang_webrtc 2016/06/20 09:27:44 This seems a little odd. If capacity > 1.5 * capac
kwiberg-webrtc 2016/06/20 09:51:31 capacity is the requested capacity. If that's >= 1
sprang_webrtc 2016/06/20 09:56:28 OK, fair enough.
+
+ std::unique_ptr<T[]> new_data(new T[new_capacity]);
+ std::memcpy(new_data.get(), data_.get(), size_ * sizeof(T));
+ data_ = std::move(new_data);
+ capacity_ = new_capacity;
+ RTC_DCHECK(IsConsistent());
+ }
+
// Precondition for all methods except Clear and the destructor.
// Postcondition for all methods except move construction and move
// assignment, which leave the moved-from object in a possibly inconsistent
« no previous file with comments | « no previous file | webrtc/base/buffer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698