41 lines
1.1 KiB
Go
41 lines
1.1 KiB
Go
// Copyright 2009 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package runtime
|
|
|
|
// nextslicecap computes the next appropriate slice length.
|
|
func nextslicecap(newLen, oldCap int) int {
|
|
newcap := oldCap
|
|
doublecap := newcap + newcap
|
|
if newLen > doublecap {
|
|
return newLen
|
|
}
|
|
|
|
const threshold = 256
|
|
if oldCap < threshold {
|
|
return doublecap
|
|
}
|
|
for {
|
|
// Transition from growing 2x for small slices
|
|
// to growing 1.25x for large slices. This formula
|
|
// gives a smooth-ish transition between the two.
|
|
newcap += (newcap + 3*threshold) >> 2
|
|
|
|
// We need to check `newcap >= newLen` and whether `newcap` overflowed.
|
|
// newLen is guaranteed to be larger than zero, hence
|
|
// when newcap overflows then `uint(newcap) > uint(newLen)`.
|
|
// This allows to check for both with the same comparison.
|
|
if uint(newcap) >= uint(newLen) {
|
|
break
|
|
}
|
|
}
|
|
|
|
// Set newcap to the requested cap when
|
|
// the newcap calculation overflowed.
|
|
if newcap <= 0 {
|
|
return newLen
|
|
}
|
|
return newcap
|
|
}
|