mirror of
https://github.com/prometheus/prometheus
synced 2025-03-30 23:37:05 +00:00
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)
|
group.value += delta * (s.V - group.mean)
|
||||||
|
|
||||||
case parser.TOPK:
|
case parser.TOPK:
|
||||||
if int64(len(group.heap)) < k || group.heap[0].V < s.V || math.IsNaN(group.heap[0].V) {
|
// We build a heap of up to k elements, with the smallest element at heap[0].
|
||||||
if int64(len(group.heap)) == k {
|
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)
|
|
||||||
}
|
|
||||||
heap.Push(&group.heap, &Sample{
|
heap.Push(&group.heap, &Sample{
|
||||||
Point: Point{V: s.V},
|
Point: Point{V: s.V},
|
||||||
Metric: s.Metric,
|
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.
|
||||||
case parser.BOTTOMK:
|
group.heap[0] = Sample{
|
||||||
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},
|
Point: Point{V: s.V},
|
||||||
Metric: s.Metric,
|
Metric: s.Metric,
|
||||||
}
|
}
|
||||||
break
|
if k > 1 {
|
||||||
|
heap.Fix(&group.heap, 0) // Maintain the heap invariant.
|
||||||
}
|
}
|
||||||
heap.Pop(&group.reverseHeap)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case parser.BOTTOMK:
|
||||||
|
// 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{
|
heap.Push(&group.reverseHeap, &Sample{
|
||||||
Point: Point{V: s.V},
|
Point: Point{V: s.V},
|
||||||
Metric: s.Metric,
|
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:
|
case parser.QUANTILE:
|
||||||
|
Loading…
Reference in New Issue
Block a user