mirror of
https://github.com/prometheus/prometheus.git
synced 2025-03-05 20:59:13 -08:00
perf(nhcb): reuse calculated metric name and hash if possible
We advance the embedded parser one series at a time. Before we advance, we clear any calculated name and hash. During processing we remember if we already calculated the name or hash. Signed-off-by: György Krajcsovits <gyorgy.krajcsovits@grafana.com>
This commit is contained in:
parent
bcb1213010
commit
bb5746c3e4
|
@ -36,6 +36,15 @@ const (
|
|||
stateEmitting
|
||||
)
|
||||
|
||||
// Keep track of what information we have already loaded about the next series.
|
||||
type histogramInfoPreloaded struct {
|
||||
hasName bool // The metricName and suffix is loaded.
|
||||
hasHash bool // The hash was calculated.
|
||||
metricName string // Without magic suffixes.
|
||||
suffixType convertnhcb.SuffixType
|
||||
hash uint64
|
||||
}
|
||||
|
||||
// The NHCBParser wraps a Parser and converts classic histograms to native
|
||||
// histograms with custom buckets.
|
||||
//
|
||||
|
@ -59,6 +68,9 @@ type NHCBParser struct {
|
|||
// State of the parser.
|
||||
state collectionState
|
||||
|
||||
// Preloaded information about classic histogram series.
|
||||
preload histogramInfoPreloaded
|
||||
|
||||
// Caches the values from the underlying parser.
|
||||
// For Series and Histogram.
|
||||
bytes []byte
|
||||
|
@ -190,6 +202,11 @@ func (p *NHCBParser) Next() (Entry, error) {
|
|||
return p.entry, p.err
|
||||
}
|
||||
|
||||
// We are advancing the embedded parser, whatever we knew preloaded
|
||||
// about the previous series is now invalid.
|
||||
p.preload.hasName = false
|
||||
p.preload.hasHash = false
|
||||
|
||||
p.entry, p.err = p.parser.Next()
|
||||
if p.err != nil {
|
||||
if errors.Is(p.err, io.EOF) && p.processNHCB() {
|
||||
|
@ -237,6 +254,7 @@ func (p *NHCBParser) Next() (Entry, error) {
|
|||
}
|
||||
|
||||
// Return true if labels have changed and we should emit the NHCB.
|
||||
// Also store the calculated metric name and hash if possible for future use.
|
||||
func (p *NHCBParser) compareLabels() bool {
|
||||
if p.state != stateCollecting {
|
||||
return false
|
||||
|
@ -245,26 +263,38 @@ func (p *NHCBParser) compareLabels() bool {
|
|||
// Different metric type.
|
||||
return true
|
||||
}
|
||||
_, name := convertnhcb.GetHistogramMetricBaseName(p.lset.Get(labels.MetricName))
|
||||
if p.lastHistogramName != name {
|
||||
p.preload.hasName = true
|
||||
p.preload.suffixType, p.preload.metricName = convertnhcb.GetHistogramMetricBaseName(p.lset.Get(labels.MetricName))
|
||||
if p.lastHistogramName != p.preload.metricName {
|
||||
// Different metric name.
|
||||
return true
|
||||
}
|
||||
nextHash, _ := p.lset.HashWithoutLabels(p.hBuffer, labels.BucketLabel)
|
||||
p.preload.hasHash = true
|
||||
p.preload.hash, _ = p.lset.HashWithoutLabels(p.hBuffer, labels.BucketLabel)
|
||||
// Different label values.
|
||||
return p.lastHistogramLabelsHash != nextHash
|
||||
return p.lastHistogramLabelsHash != p.preload.hash
|
||||
}
|
||||
|
||||
// Save the label set of the classic histogram without suffix and bucket `le` label.
|
||||
func (p *NHCBParser) storeClassicLabels(name string) {
|
||||
p.lastHistogramName = name
|
||||
p.lastHistogramLabelsHash, _ = p.lset.HashWithoutLabels(p.hBuffer, labels.BucketLabel)
|
||||
if p.preload.hasHash {
|
||||
p.lastHistogramLabelsHash = p.preload.hash
|
||||
} else {
|
||||
p.lastHistogramLabelsHash, _ = p.lset.HashWithoutLabels(p.hBuffer, labels.BucketLabel)
|
||||
}
|
||||
p.lastHistogramExponential = false
|
||||
}
|
||||
|
||||
func (p *NHCBParser) storeExponentialLabels() {
|
||||
p.lastHistogramName = p.lset.Get(labels.MetricName)
|
||||
p.lastHistogramLabelsHash, _ = p.lset.HashWithoutLabels(p.hBuffer)
|
||||
if p.preload.hasHash {
|
||||
p.lastHistogramLabelsHash = p.preload.hash
|
||||
} else {
|
||||
// In the current model and client_golang, "le" label is not allowed
|
||||
// for histogram so ignoring "le" here is ok.
|
||||
p.lastHistogramLabelsHash, _ = p.lset.HashWithoutLabels(p.hBuffer, labels.BucketLabel)
|
||||
}
|
||||
p.lastHistogramExponential = true
|
||||
}
|
||||
|
||||
|
@ -276,9 +306,16 @@ func (p *NHCBParser) handleClassicHistogramSeries(lset labels.Labels) bool {
|
|||
if p.typ != model.MetricTypeHistogram {
|
||||
return false
|
||||
}
|
||||
mName := lset.Get(labels.MetricName)
|
||||
|
||||
var name string
|
||||
var suffixType convertnhcb.SuffixType
|
||||
if p.preload.hasName {
|
||||
suffixType, name = p.preload.suffixType, p.preload.metricName
|
||||
} else {
|
||||
suffixType, name = convertnhcb.GetHistogramMetricBaseName(lset.Get(labels.MetricName))
|
||||
}
|
||||
|
||||
// Sanity check to ensure that the TYPE metadata entry name is the same as the base name.
|
||||
suffixType, name := convertnhcb.GetHistogramMetricBaseName(mName)
|
||||
if name != string(p.bName) {
|
||||
return false
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue