promql: use faster heap method for topk/bottomk
Call `Fix()` instead of `Pop()` followed by `Push()`. This is slightly faster. Signed-off-by: Bryan Boreham <bjboreham@gmail.com>
This commit is contained in:
parent
cf54a14f9c
commit
f2fd85df82
|
@ -2508,39 +2508,39 @@ func (ev *evaluator) aggregation(op parser.ItemType, grouping []string, without
|
|||
group.value += delta * (s.V - group.mean)
|
||||
|
||||
case parser.TOPK:
|
||||
if int64(len(group.heap)) < k || group.heap[0].V < s.V || math.IsNaN(group.heap[0].V) {
|
||||
if int64(len(group.heap)) == k {
|
||||
if k == 1 { // For k==1 we can replace in-situ.
|
||||
group.heap[0] = Sample{
|
||||
Point: Point{V: s.V},
|
||||
Metric: s.Metric,
|
||||
}
|
||||
break
|
||||
}
|
||||
heap.Pop(&group.heap)
|
||||
}
|
||||
// We build a heap of up to k elements, with the smallest element at heap[0].
|
||||
if int64(len(group.heap)) < k {
|
||||
heap.Push(&group.heap, &Sample{
|
||||
Point: Point{V: s.V},
|
||||
Metric: s.Metric,
|
||||
})
|
||||
} else if group.heap[0].V < s.V || (math.IsNaN(group.heap[0].V) && !math.IsNaN(s.V)) {
|
||||
// This new element is bigger than the previous smallest element - overwrite that.
|
||||
group.heap[0] = Sample{
|
||||
Point: Point{V: s.V},
|
||||
Metric: s.Metric,
|
||||
}
|
||||
if k > 1 {
|
||||
heap.Fix(&group.heap, 0) // Maintain the heap invariant.
|
||||
}
|
||||
}
|
||||
|
||||
case parser.BOTTOMK:
|
||||
if int64(len(group.reverseHeap)) < k || group.reverseHeap[0].V > s.V || math.IsNaN(group.reverseHeap[0].V) {
|
||||
if int64(len(group.reverseHeap)) == k {
|
||||
if k == 1 { // For k==1 we can replace in-situ.
|
||||
group.reverseHeap[0] = Sample{
|
||||
Point: Point{V: s.V},
|
||||
Metric: s.Metric,
|
||||
}
|
||||
break
|
||||
}
|
||||
heap.Pop(&group.reverseHeap)
|
||||
}
|
||||
// We build a heap of up to k elements, with the biggest element at heap[0].
|
||||
if int64(len(group.reverseHeap)) < k {
|
||||
heap.Push(&group.reverseHeap, &Sample{
|
||||
Point: Point{V: s.V},
|
||||
Metric: s.Metric,
|
||||
})
|
||||
} else if group.reverseHeap[0].V > s.V || (math.IsNaN(group.reverseHeap[0].V) && !math.IsNaN(s.V)) {
|
||||
// This new element is smaller than the previous biggest element - overwrite that.
|
||||
group.reverseHeap[0] = Sample{
|
||||
Point: Point{V: s.V},
|
||||
Metric: s.Metric,
|
||||
}
|
||||
if k > 1 {
|
||||
heap.Fix(&group.reverseHeap, 0) // Maintain the heap invariant.
|
||||
}
|
||||
}
|
||||
|
||||
case parser.QUANTILE:
|
||||
|
|
Loading…
Reference in New Issue