diff --git a/internal/mlq/mlq.go b/internal/mlq/mlq.go index e2def65..e7c2732 100644 --- a/internal/mlq/mlq.go +++ b/internal/mlq/mlq.go @@ -95,6 +95,14 @@ func (m *MultiLevelQueue[T]) popLocked(keyExtractor func(T) uint32) (T, int, boo q.Items[0] = zero q.Items = q.Items[1:] + // Compact the backing array when it becomes significantly oversized + // to prevent unbounded memory growth from repeated push/pop cycles. + if cap(q.Items) > 64 && len(q.Items) < cap(q.Items)/4 { + compact := make([]T, len(q.Items)) + copy(compact, q.Items) + q.Items = compact + } + // Update census and bitmask if keyExtractor != nil { delete(m.census, keyExtractor(item)) @@ -193,6 +201,13 @@ func (m *MultiLevelQueue[T]) PopIf(priority int, predicate func(T) bool, keyExtr q.Items[0] = zero // Memory safety q.Items = q.Items[1:] + // Compact the backing array when it becomes significantly oversized + if cap(q.Items) > 64 && len(q.Items) < cap(q.Items)/4 { + compact := make([]T, len(q.Items)) + copy(compact, q.Items) + q.Items = compact + } + if keyExtractor != nil { delete(m.census, keyExtractor(item)) }