diff --git a/src/bytes_mut.rs b/src/bytes_mut.rs index d43e0ef..868b955 100644 --- a/src/bytes_mut.rs +++ b/src/bytes_mut.rs @@ -644,21 +644,37 @@ impl BytesMut { self.ptr = vptr(ptr); self.cap = v.capacity(); + } else { + // calculate offset + let off = v.capacity() - self.cap; - return; + // new_cap is calculated in terms of `BytesMut`, not the underlying + // `Vec`, so it does not take the offset into account. + // + // Thus we have to manually add it here. + new_cap = new_cap.checked_add(off).expect("overflow"); + + // The vector capacity is not sufficient. The reserve request is + // asking for more than the initial buffer capacity. Allocate more + // than requested if `new_cap` is not much bigger than the current + // capacity. + // + // There are some situations, using `reserve_exact` that the + // buffer capacity could be below `original_capacity`, so do a + // check. + let double = v.capacity().checked_shl(1).unwrap_or(new_cap); + + new_cap = cmp::max(double, new_cap); + + // No space - allocate more + v.reserve(new_cap - v.len()); + + // Update the info + self.ptr = vptr(v.as_mut_ptr().add(off)); + self.cap = v.capacity() - off; } - // The vector capacity is not sufficient. The reserve request is - // asking for more than the initial buffer capacity. Allocate more - // than requested if `new_cap` is not much bigger than the current - // capacity. - // - // There are some situations, using `reserve_exact` that the - // buffer capacity could be below `original_capacity`, so do a - // check. - let double = v.capacity().checked_shl(1).unwrap_or(new_cap); - - new_cap = cmp::max(cmp::max(double, new_cap), original_capacity); + return; } else { new_cap = cmp::max(new_cap, original_capacity); } diff --git a/tests/test_bytes.rs b/tests/test_bytes.rs index 860474a..76f6513 100644 --- a/tests/test_bytes.rs +++ b/tests/test_bytes.rs @@ -443,7 +443,7 @@ fn reserve_growth() { let _ = bytes.split(); bytes.reserve(65); - assert_eq!(bytes.capacity(), 128); + assert_eq!(bytes.capacity(), 117); } #[test]