github.com/haraldrudell/parl@v0.4.176/pslices/trim-left.go (about)

     1  /*
     2  © 2023–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/)
     3  ISC License
     4  */
     5  
     6  package pslices
     7  
     8  // TrimLeft removes count bytes from the start of slicep, copying remaining bytes to its beginning.
     9  //   - slicep’s length is adjusted
    10  //   - if count < 1 or slicep is empty or nil, nothing is done
    11  //   - if count >= len(slicep) slicep is emptied
    12  //   - no allocation or free is triggered
    13  //   - —
    14  //   - copy versus slice-away-and-alloc: if slice byte-length is 640 bytes or larger, use alloc
    15  //   - TrimLeft(&slice, 1) vs. slice = slice[1:]
    16  //   - one small slice alloc equals copy of 3,072 bytes: trimleft_bench_test.go
    17  //   - copy count of n elements one at a time is ∑n: [n(n+1)]/2
    18  //   - optimal strategy is slice-away slice[1:] and on append, try to avoid alloc by
    19  //     copy recuperating the obsoleted capacity
    20  func TrimLeft[E any](slicep *[]E, count int, noZero ...bool) {
    21  
    22  	// get valid length and count
    23  	s := *slicep
    24  	length := len(s)
    25  	if count < 1 || length == 0 {
    26  		return // nothing to do return
    27  	} else if count > length {
    28  		count = length
    29  	}
    30  
    31  	// delete the count first element from slice of length length
    32  	//	- count is 1…length
    33  	//	- length is len(*slicep)
    34  	if count < length {
    35  		// move the element at the end that will be kept
    36  		copy(s, s[count:])
    37  	}
    38  
    39  	// zero out deleted element at end
    40  	newLength := length - count
    41  	doZero := true
    42  	if len(noZero) > 0 {
    43  		doZero = !noZero[0]
    44  	}
    45  	if doZero {
    46  		var e E
    47  		for i := newLength; i < length; i++ {
    48  			s[i] = e
    49  		}
    50  	}
    51  
    52  	// adjust slice length
    53  	*slicep = s[:newLength]
    54  }