mirror of
https://github.com/prometheus/prometheus.git
synced 2025-01-12 14:27:27 -08:00
Implement sample interpolation in query layer.
This commit is contained in:
parent
c59f3fc538
commit
676845afaf
|
@ -28,32 +28,71 @@ var queryStorage metric.Storage = nil
|
||||||
|
|
||||||
type viewAdapter struct {
|
type viewAdapter struct {
|
||||||
view metric.View
|
view metric.View
|
||||||
// TODO: use this.
|
|
||||||
stalenessPolicy *metric.StalenessPolicy
|
stalenessPolicy *metric.StalenessPolicy
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *viewAdapter) chooseClosestSample(samples []model.SamplePair, timestamp *time.Time) (sample *model.SamplePair) {
|
// interpolateSamples interpolates a value at a target time between two
|
||||||
var minDelta time.Duration
|
// provided sample pairs.
|
||||||
for _, candidate := range samples {
|
func interpolateSamples(first, second *model.SamplePair, timestamp time.Time) *model.SamplePair {
|
||||||
// Ignore samples outside of staleness policy window.
|
dv := second.Value - first.Value
|
||||||
delta := candidate.Timestamp.Sub(*timestamp)
|
dt := second.Timestamp.Sub(first.Timestamp)
|
||||||
if delta < 0 {
|
|
||||||
delta = -delta
|
dDt := dv / model.SampleValue(dt)
|
||||||
|
offset := model.SampleValue(timestamp.Sub(first.Timestamp))
|
||||||
|
|
||||||
|
return &model.SamplePair{
|
||||||
|
Value: first.Value + (offset * dDt),
|
||||||
|
Timestamp: timestamp,
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// chooseClosestSample chooses the closest sample of a list of samples
|
||||||
|
// surrounding a given target time. If samples are found both before and after
|
||||||
|
// the target time, the sample value is interpolated between these. Otherwise,
|
||||||
|
// the single closest sample is returned verbatim.
|
||||||
|
func (v *viewAdapter) chooseClosestSample(samples []model.SamplePair, timestamp *time.Time) (sample *model.SamplePair) {
|
||||||
|
var closestBefore *model.SamplePair
|
||||||
|
var closestAfter *model.SamplePair
|
||||||
|
for _, candidate := range samples {
|
||||||
|
delta := candidate.Timestamp.Sub(*timestamp)
|
||||||
|
// Samples before target time.
|
||||||
|
if delta < 0 {
|
||||||
|
// Ignore samples outside of staleness policy window.
|
||||||
|
if -delta > v.stalenessPolicy.DeltaAllowance {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// Ignore samples that are farther away than what we've seen before.
|
||||||
|
if closestBefore != nil && candidate.Timestamp.Before(closestBefore.Timestamp) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
sample := candidate
|
||||||
|
closestBefore = &sample
|
||||||
|
}
|
||||||
|
|
||||||
|
// Samples after target time.
|
||||||
|
if delta >= 0 {
|
||||||
|
// Ignore samples outside of staleness policy window.
|
||||||
if delta > v.stalenessPolicy.DeltaAllowance {
|
if delta > v.stalenessPolicy.DeltaAllowance {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
// Ignore samples that are farther away than samples we've seen before.
|
||||||
// Skip sample if we've seen a closer one before this.
|
if closestAfter != nil && candidate.Timestamp.After(closestAfter.Timestamp) {
|
||||||
if sample != nil {
|
|
||||||
if delta > minDelta {
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
sample := candidate
|
||||||
|
closestAfter = &sample
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sample = &candidate
|
switch {
|
||||||
minDelta = delta
|
case closestBefore != nil && closestAfter != nil:
|
||||||
|
sample = interpolateSamples(closestBefore, closestAfter, *timestamp)
|
||||||
|
case closestBefore != nil:
|
||||||
|
sample = closestBefore
|
||||||
|
default:
|
||||||
|
sample = closestAfter
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue