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  }