From b46d3fd32ebdf2059cd29b98aaecd0c79ccbaa2b Mon Sep 17 00:00:00 2001
From: Carl Lerche <me@carllerche.com>
Date: Mon, 20 Feb 2017 21:07:25 -0800
Subject: [PATCH] Tweak growth algorithm in BytesMut::reserve

---
 src/bytes.rs        |  4 ++--
 tests/test_bytes.rs | 14 ++++++++++++--
 2 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/src/bytes.rs b/src/bytes.rs
index f65f772..d830b97 100644
--- a/src/bytes.rs
+++ b/src/bytes.rs
@@ -1695,12 +1695,12 @@ impl Inner {
                 // asking for more than the initial buffer capacity. Allocate more
                 // than requested if `new_cap` is not much bigger than the current
                 // capacity.
-                new_cap = cmp::max(len << 1, new_cap);
+                new_cap = cmp::max(v.capacity() << 1, new_cap);
             }
         }
 
         // Create a new vector to store the data
-        let mut v = Vec::with_capacity(new_cap);
+        let mut v = Vec::with_capacity(new_cap.next_power_of_two());
 
         // Copy the bytes
         v.extend_from_slice(self.as_ref());
diff --git a/tests/test_bytes.rs b/tests/test_bytes.rs
index 89bddaf..2343fea 100644
--- a/tests/test_bytes.rs
+++ b/tests/test_bytes.rs
@@ -207,7 +207,7 @@ fn fns_defined_for_bytes_mut() {
 }
 
 #[test]
-fn reserve() {
+fn reserve_convert() {
     // Inline -> Vec
     let mut bytes = BytesMut::with_capacity(8);
     bytes.put("hello");
@@ -236,11 +236,21 @@ fn reserve() {
     let a = bytes.drain_to(30);
 
     bytes.reserve(128);
-    assert_eq!(bytes.capacity(), bytes.len() + 128);
+    assert_eq!(bytes.capacity(), (bytes.len() + 128).next_power_of_two());
 
     drop(a);
 }
 
+#[test]
+fn reserve_growth() {
+    let mut bytes = BytesMut::with_capacity(64);
+    bytes.put("hello world");
+    let _ = bytes.drain();
+
+    bytes.reserve(65);
+    assert_eq!(bytes.capacity(), 128);
+}
+
 #[test]
 fn inline_storage() {
     let mut bytes = BytesMut::with_capacity(inline_cap());
-- 
GitLab