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 }