func (t *TopK) insert(data []byte, freq uint64) {
	for _, element := range *t.elements {
		if bytes.Compare(data, element.Data) == 0 {
			element.Freq = freq
			return
		}
	}
	if t.elements.Len() == int(t.k) {
		heap.Pop(t.elements)
	}
	heap.Push(t.elements, &Element{Data: data, Freq: freq})
}
insert adds the data to the top-k heap. If the data is already an element,
the frequency is updated. If the heap already has k elements, the element
with the minimum frequency is removed.
package boom
import (
	"bytes"
	"container/heap"
)
type Element struct {
	Data []byte
	Freq uint64
}
type elementHeap []*Element
func (e elementHeap) Len() int           { return len(e) }
func (e elementHeap) Less(i, j int) bool { return e[i].Freq < e[j].Freq }
func (e elementHeap) Swap(i, j int)      { e[i], e[j] = e[j], e[i] }
func (e *elementHeap) Push(x interface{}) {
	*e = append(*e, x.(*Element))
}
func (e *elementHeap) Pop() interface{} {
	old := *e
	n := len(old)
	x := old[n-1]
	*e = old[0 : n-1]
	return x
}
type TopK struct {
	cms      *CountMinSketch
	k        uint
	n        uint
	elements *elementHeap
}
func NewTopK(epsilon, delta float64, k uint) *TopK {
	elements := make(elementHeap, 0, k)
	heap.Init(&elements)
	return &TopK{
		cms:      NewCountMinSketch(epsilon, delta),
		k:        k,
		elements: &elements,
	}
}
func (t *TopK) Add(data []byte) *TopK {
	t.cms.Add(data)
	t.n++
	freq := t.cms.Count(data)
	if t.isTop(freq) {
		t.insert(data, freq)
	}
	return t
}
func (t *TopK) Elements() []*Element {
	if t.elements.Len() == 0 {
		return make([]*Element, 0)
	}
	elements := make(elementHeap, t.elements.Len())
	copy(elements, *t.elements)
	heap.Init(&elements)
	topK := make([]*Element, 0, t.k)
	for elements.Len() > 0 {
		topK = append(topK, heap.Pop(&elements).(*Element))
	}
	return topK
}
func (t *TopK) Reset() *TopK {
	t.cms.Reset()
	elements := make(elementHeap, 0, t.k)
	heap.Init(&elements)
	t.elements = &elements
	t.n = 0
	return t
}
func (t *TopK) isTop(freq uint64) bool {
	if t.elements.Len() < int(t.k) {
		return true
	}
	return freq >= (*t.elements)[0].Freq
}