Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
container/heap: use sort.Interface where possible
Functions heap.Pop(), heap.Push() and heap.Remove() use type heap.Interface. This type is equal to sort.Interface, with Push() and Pop() methods added. This is necessary, because these functions affect the size of the resulting heap. Functions heap.Fix() and heap.Init() are different. They may compare and swap elements in the underlying container, but never alter its size. It is therefore possible to just use sort.Interface. This would make these functions a lot more pleasant to use in situations where you know the number of elements in the heap is fixed. Consider the case where you use these functions to merge the results of n infinitely long monotonically increasing sequences. For example, logs received from multiple sources that need to be turned into a single stream of events sorted by time. This can now be implemented as follows: type Value ... type Sequence <-chan Value type PeekedSequence struct { First Value Remainder Sequence } type SequenceHeap []PeekedSequence func (h SequenceHeap) Len() int { return len(h) } func (h SequenceHeap) Less(i, j int) bool { return h[i].First < h[j].First } func (h SequenceHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } func MergeSequences(sequences []Sequence, out chan<- Value) { h := make(SequenceHeap, 0, len(sequences)) for _, s := range sequences { h = append(h, PeekedSequence{ First: <-s, Remainder: s, }) } heap.Init(h) for { out <- h[0].First h[0].First = <-h[0].Remainder heap.Fix(h, 0) } } Before this change was made, SequenceHeap had to provide Pop() and Push() methods that are known to be unused.
- Loading branch information