internal/pkg/queue/queue.go (49 lines of code) (raw):

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 // Package queue provides a generic priority queue. package queue import "container/heap" // Lesser is an interface to enable generic structs to be elements of a priority queue. // Any struct can become a priority queue element by defining the LessThan method // and initializing a new PriorityQueue. // // (s myStruct) LessThan(other myStruct) bool // q := NewPriorityQueue[myStruct]() type Lesser[T any] interface { LessThan(T) bool } // PriorityQueue implements a priority queue. type PriorityQueue[T Lesser[T]] struct { pq pq[T] } // Push adds a new element to the queue and puts it in the correct place. func (p *PriorityQueue[T]) Push(x T) { heap.Push(&p.pq, x) } // Pop removes the top element of the queue and restructures it in log(n) time. func (p *PriorityQueue[T]) Pop() (*T, bool) { if p.pq.Len() == 0 { return nil, false } v := heap.Pop(&p.pq).(T) return &v, true } // Len returns the length of the queue. func (p *PriorityQueue[T]) Len() int { return p.pq.Len() } type pq[T Lesser[T]] []T // NewPriorityQueue returns an empty priority queue. func NewPriorityQueue[T Lesser[T]]() *PriorityQueue[T] { var arr pq[T] = make([]T, 0) heap.Init(&arr) return &PriorityQueue[T]{ pq: arr, } } // Len returns the length of the data structure. func (p *pq[T]) Len() int { return len(*p) } // Less returns whether element i is less than element j, using the generic type's LessThan function. func (p *pq[T]) Less(i, j int) bool { return (*p)[i].LessThan((*p)[j]) } // Swap swaps the positions of two elements in the priority queue. func (p *pq[T]) Swap(i, j int) { (*p)[i], (*p)[j] = (*p)[j], (*p)[i] } // Push appends a new element to the back of the underlying array. func (p *pq[T]) Push(x any) { *p = append(*p, x.(T)) } // Pop removes the last element from the array. func (p *pq[T]) Pop() any { old := *p n := len(old) res := old[n-1] *p = old[:n-1] return res } // Compile-time check that the PriorityQueue type works on a generic type. type comparableInt int func (c comparableInt) LessThan(a comparableInt) bool { return c < a } var _ heap.Interface = (*pq[comparableInt])(nil)