Skip to content

Commit d5690e4

Browse files
committed
Increase by a minimum of x1.5 of existing capacity (uped to bin size)
1 parent 98b0a6c commit d5690e4

File tree

2 files changed

+16
-4
lines changed

2 files changed

+16
-4
lines changed

library/alloc/src/raw_vec.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -396,8 +396,12 @@ impl<T, A: Allocator> RawVec<T, A> {
396396

397397
// Nothing we can really do about these checks, sadly.
398398
let required_cap = len.checked_add(additional).ok_or(CapacityOverflow)?;
399+
// The addition cannot overflow because `cap <= isize::MAX` and the type of `cap` is `usize`.
400+
// By minimum we increase the cap by 1/2, which combined with rounding up
401+
// to the next bin should result in rougly doubling (increase between x1.5, and x2.5).
402+
let wanted_cap = cmp::max(self.cap + self.cap / 2, required_cap);
399403

400-
let cap = if let Some(alloc_size) = required_cap
404+
let cap = if let Some(alloc_size) = wanted_cap
401405
.checked_mul(mem::size_of::<T>())
402406
.and_then(
403407
// Add the overhead
@@ -419,9 +423,8 @@ impl<T, A: Allocator> RawVec<T, A> {
419423
// Align the capacity to fit the bin
420424
aligned_alloc_size / mem::size_of::<T>()
421425
} else {
422-
// Calculating alloc_size overflowed. Use old way to preserve behavior around overflows.
423-
// The doubling cannot overflow because `cap <= isize::MAX` and the type of `cap` is `usize`.
424-
cmp::max(self.cap * 2, required_cap)
426+
// Calculating alloc_size overflowed. We just use `wanted_cap` to preserve behavior around cap `isize` overflows.
427+
wanted_cap
425428
};
426429

427430
let new_layout = Layout::array::<T>(cap);

library/alloc/src/raw_vec/tests.rs

+9
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,15 @@ fn grow_amortized_power_of_two_bins() {
9191
assert_eq!(cap_for::<u8>(32), v.capacity());
9292
}
9393

94+
{
95+
let mut v: RawVec<u8> = RawVec::new();
96+
v.reserve_exact(0, 6);
97+
assert_eq!(6, v.capacity());
98+
v.reserve(0, 8);
99+
// increase all the way to 32 (instead of just 32), due to minimum capacity increase
100+
assert_eq!(cap_for::<u8>(32), v.capacity());
101+
}
102+
94103
{
95104
let mut v: RawVec<[u8; 5]> = RawVec::new();
96105
v.reserve(0, 1);

0 commit comments

Comments
 (0)