github.com/haraldrudell/parl@v0.4.176/nb-chan-scavenge.go (about)

     1  /*
     2  © 2023–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/)
     3  ISC License
     4  */
     5  
     6  package parl
     7  
     8  // Scavenge attempts to set capacity of the two queues to setCapacity
     9  //   - Scavenge allows for reducing queue capacity thus reduce memory leaks
    10  //   - queue capacities are reduced to the setCapacity value,
    11  //     while ensuring enough capacity for current elements
    12  //   - unused queue elements are set to zero-value to prevent memory leaks
    13  func (n *NBChan[T]) Scavenge(setCapacity int) {
    14  	// holding [NBChan.outputLock] prevents queue swap
    15  	n.outputLock.Lock()
    16  	defer n.outputLock.Unlock()
    17  
    18  	var capacity = n.reduceQueue(&n.outputQueue, setCapacity)
    19  	n.outputCapacity.Store(uint64(capacity))
    20  
    21  	n.inputLock.Lock()
    22  	defer n.inputLock.Unlock()
    23  
    24  	capacity = n.reduceQueue(&n.inputQueue, setCapacity)
    25  	n.inputCapacity.Store(uint64(capacity))
    26  }
    27  
    28  // reduceQueue reduces the capacity of a queue to avoid memory leaks
    29  func (n *NBChan[T]) reduceQueue(queuep *[]T, setCapacity int) (capacity int) {
    30  
    31  	// check for small or unallocated queue
    32  	var q = *queuep
    33  	capacity = cap(q)
    34  	if capacity <= setCapacity {
    35  		return // unallocated or small enough queue return
    36  	}
    37  
    38  	// ensure enough for length
    39  	var length = len(q)
    40  	if length > setCapacity {
    41  		if setCapacity = length; setCapacity == capacity {
    42  			return // queue capacity cannot be reduced return
    43  		}
    44  	}
    45  
    46  	// reduce queue capacity
    47  	var newQueue = make([]T, setCapacity)
    48  	copy(newQueue, q)
    49  	*queuep = newQueue[:length]
    50  	capacity = cap(newQueue)
    51  
    52  	return
    53  }