package utils import ( "sync" ) const minQueueCapacity = 1 // Queue is a thread-safe bounded FIFO queue. When full, the oldest item is dropped. type Queue[T any] struct { mu sync.Mutex data []T capacity int } const minCapacity = 1 // New creates a new Queue with the specified capacity. // Capacity must be greater than zero. func New[T any](capacity int) *Queue[T] { if capacity <= 0 { capacity = minCapacity } return &Queue[T]{ data: make([]T, 0, capacity), capacity: capacity, } } // Push adds an item to the queue. If the queue is full, the oldest item is dropped. func (q *Queue[T]) Push(item T) { q.mu.Lock() defer q.mu.Unlock() // Non-positive capacity means the queue is effectively disabled. if q.capacity <= 0 { return } if len(q.data) >= q.capacity { var zero T q.data[0] = zero q.data = q.data[1:] } q.data = append(q.data, item) } func normalizeCapacity(capacity int) int { if capacity < minCapacity { return minCapacity } return capacity } // Pop removes and returns the oldest item from the queue. // Returns zero value and false if empty. func (q *Queue[T]) Pop() (T, bool) { q.mu.Lock() defer q.mu.Unlock() if len(q.data) == 0 { var zero T return zero, false } item := q.data[0] var zero T q.data[0] = zero q.data = q.data[1:] return item, true } // Peek returns the oldest item without removing it. func (q *Queue[T]) Peek() (T, bool) { q.mu.Lock() defer q.mu.Unlock() if len(q.data) == 0 { var zero T return zero, false } return q.data[0], true } // Len returns the current number of items. func (q *Queue[T]) Len() int { q.mu.Lock() defer q.mu.Unlock() return len(q.data) } // IsEmpty returns true if the queue is empty. func (q *Queue[T]) IsEmpty() bool { q.mu.Lock() defer q.mu.Unlock() return len(q.data) == 0 } // Items returns a copy of all items in the queue in FIFO order. func (q *Queue[T]) Items() []T { q.mu.Lock() defer q.mu.Unlock() if len(q.data) == 0 { return nil } cp := make([]T, len(q.data)) copy(cp, q.data) return cp } func sanitizeCapacity(capacity int) int { if capacity < minQueueCapacity { return minQueueCapacity } return capacity }