github.com/goplus/llgo@v0.8.3/internal/runtime/slice.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package runtime 6 7 // nextslicecap computes the next appropriate slice length. 8 func nextslicecap(newLen, oldCap int) int { 9 newcap := oldCap 10 doublecap := newcap + newcap 11 if newLen > doublecap { 12 return newLen 13 } 14 15 const threshold = 256 16 if oldCap < threshold { 17 return doublecap 18 } 19 for { 20 // Transition from growing 2x for small slices 21 // to growing 1.25x for large slices. This formula 22 // gives a smooth-ish transition between the two. 23 newcap += (newcap + 3*threshold) >> 2 24 25 // We need to check `newcap >= newLen` and whether `newcap` overflowed. 26 // newLen is guaranteed to be larger than zero, hence 27 // when newcap overflows then `uint(newcap) > uint(newLen)`. 28 // This allows to check for both with the same comparison. 29 if uint(newcap) >= uint(newLen) { 30 break 31 } 32 } 33 34 // Set newcap to the requested cap when 35 // the newcap calculation overflowed. 36 if newcap <= 0 { 37 return newLen 38 } 39 return newcap 40 }