Chromium Code Reviews| 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 |