mirror of
https://github.com/prometheus/prometheus.git
synced 2025-03-05 20:59:13 -08:00
Export members of EvalNodeHelper to facilitate usage in external functions (#7860)
Signed-off-by: Vijay Samuel <vjsamuel@ebay.com>
This commit is contained in:
parent
c806262206
commit
00ee73ef91
|
@ -792,13 +792,13 @@ func (ev *evaluator) Eval(expr parser.Expr) (v parser.Value, ws storage.Warnings
|
|||
// EvalNodeHelper stores extra information and caches for evaluating a single node across steps.
|
||||
type EvalNodeHelper struct {
|
||||
// Evaluation timestamp.
|
||||
ts int64
|
||||
Ts int64
|
||||
// Vector that can be used for output.
|
||||
out Vector
|
||||
Out Vector
|
||||
|
||||
// Caches.
|
||||
// dropMetricName and label_*.
|
||||
dmn map[uint64]labels.Labels
|
||||
// DropMetricName and label_*.
|
||||
Dmn map[uint64]labels.Labels
|
||||
// signatureFunc.
|
||||
sigf map[string]string
|
||||
// funcHistogramQuantile.
|
||||
|
@ -816,24 +816,24 @@ type EvalNodeHelper struct {
|
|||
resultMetric map[string]labels.Labels
|
||||
}
|
||||
|
||||
// dropMetricName is a cached version of dropMetricName.
|
||||
func (enh *EvalNodeHelper) dropMetricName(l labels.Labels) labels.Labels {
|
||||
if enh.dmn == nil {
|
||||
enh.dmn = make(map[uint64]labels.Labels, len(enh.out))
|
||||
// DropMetricName is a cached version of DropMetricName.
|
||||
func (enh *EvalNodeHelper) DropMetricName(l labels.Labels) labels.Labels {
|
||||
if enh.Dmn == nil {
|
||||
enh.Dmn = make(map[uint64]labels.Labels, len(enh.Out))
|
||||
}
|
||||
h := l.Hash()
|
||||
ret, ok := enh.dmn[h]
|
||||
ret, ok := enh.Dmn[h]
|
||||
if ok {
|
||||
return ret
|
||||
}
|
||||
ret = dropMetricName(l)
|
||||
enh.dmn[h] = ret
|
||||
enh.Dmn[h] = ret
|
||||
return ret
|
||||
}
|
||||
|
||||
func (enh *EvalNodeHelper) signatureFunc(on bool, names ...string) func(labels.Labels) string {
|
||||
if enh.sigf == nil {
|
||||
enh.sigf = make(map[string]string, len(enh.out))
|
||||
enh.sigf = make(map[string]string, len(enh.Out))
|
||||
}
|
||||
f := signatureFunc(on, enh.lblBuf, names...)
|
||||
return func(l labels.Labels) string {
|
||||
|
@ -885,7 +885,7 @@ func (ev *evaluator) rangeEval(f func([]parser.Value, *EvalNodeHelper) (Vector,
|
|||
biggestLen = len(matrixes[i])
|
||||
}
|
||||
}
|
||||
enh := &EvalNodeHelper{out: make(Vector, 0, biggestLen)}
|
||||
enh := &EvalNodeHelper{Out: make(Vector, 0, biggestLen)}
|
||||
seriess := make(map[uint64]Series, biggestLen) // Output series by series hash.
|
||||
tempNumSamples := ev.currentSamples
|
||||
for ts := ev.startTimestamp; ts <= ev.endTimestamp; ts += ev.interval {
|
||||
|
@ -916,12 +916,12 @@ func (ev *evaluator) rangeEval(f func([]parser.Value, *EvalNodeHelper) (Vector,
|
|||
args[i] = vectors[i]
|
||||
}
|
||||
// Make the function call.
|
||||
enh.ts = ts
|
||||
enh.Ts = ts
|
||||
result, ws := f(args, enh)
|
||||
if result.ContainsSameLabelset() {
|
||||
ev.errorf("vector cannot contain metrics with the same labelset")
|
||||
}
|
||||
enh.out = result[:0] // Reuse result vector.
|
||||
enh.Out = result[:0] // Reuse result vector.
|
||||
warnings = append(warnings, ws...)
|
||||
|
||||
ev.currentSamples += len(result)
|
||||
|
@ -1030,7 +1030,7 @@ func (ev *evaluator) eval(expr parser.Expr) (parser.Value, storage.Warnings) {
|
|||
vs, ok := e.Args[0].(*parser.VectorSelector)
|
||||
if ok {
|
||||
return ev.rangeEval(func(v []parser.Value, enh *EvalNodeHelper) (Vector, storage.Warnings) {
|
||||
val, ws := ev.vectorSelector(vs, enh.ts)
|
||||
val, ws := ev.vectorSelector(vs, enh.Ts)
|
||||
return call([]parser.Value{val}, e.Args, enh), ws
|
||||
})
|
||||
}
|
||||
|
@ -1101,7 +1101,7 @@ func (ev *evaluator) eval(expr parser.Expr) (parser.Value, storage.Warnings) {
|
|||
points := getPointSlice(16)
|
||||
inMatrix := make(Matrix, 1)
|
||||
inArgs[matrixArgIndex] = inMatrix
|
||||
enh := &EvalNodeHelper{out: make(Vector, 0, 1)}
|
||||
enh := &EvalNodeHelper{Out: make(Vector, 0, 1)}
|
||||
// Process all the calls for one time series at a time.
|
||||
it := storage.NewBuffer(selRange)
|
||||
for i, s := range selVS.Series {
|
||||
|
@ -1134,10 +1134,10 @@ func (ev *evaluator) eval(expr parser.Expr) (parser.Value, storage.Warnings) {
|
|||
continue
|
||||
}
|
||||
inMatrix[0].Points = points
|
||||
enh.ts = ts
|
||||
enh.Ts = ts
|
||||
// Make the function call.
|
||||
outVec := call(inArgs, e.Args, enh)
|
||||
enh.out = outVec[:0]
|
||||
enh.Out = outVec[:0]
|
||||
if len(outVec) > 0 {
|
||||
ss.Points = append(ss.Points, Point{V: outVec[0].Point.V, T: ts})
|
||||
}
|
||||
|
@ -1227,7 +1227,7 @@ func (ev *evaluator) eval(expr parser.Expr) (parser.Value, storage.Warnings) {
|
|||
case lt == parser.ValueTypeScalar && rt == parser.ValueTypeScalar:
|
||||
return ev.rangeEval(func(v []parser.Value, enh *EvalNodeHelper) (Vector, storage.Warnings) {
|
||||
val := scalarBinop(e.Op, v[0].(Vector)[0].Point.V, v[1].(Vector)[0].Point.V)
|
||||
return append(enh.out, Sample{Point: Point{V: val}}), nil
|
||||
return append(enh.Out, Sample{Point: Point{V: val}}), nil
|
||||
}, e.LHS, e.RHS)
|
||||
case lt == parser.ValueTypeVector && rt == parser.ValueTypeVector:
|
||||
switch e.Op {
|
||||
|
@ -1262,7 +1262,7 @@ func (ev *evaluator) eval(expr parser.Expr) (parser.Value, storage.Warnings) {
|
|||
|
||||
case *parser.NumberLiteral:
|
||||
return ev.rangeEval(func(v []parser.Value, enh *EvalNodeHelper) (Vector, storage.Warnings) {
|
||||
return append(enh.out, Sample{Point: Point{V: e.Val}}), nil
|
||||
return append(enh.Out, Sample{Point: Point{V: e.Val}}), nil
|
||||
})
|
||||
|
||||
case *parser.VectorSelector:
|
||||
|
@ -1530,10 +1530,10 @@ func (ev *evaluator) VectorAnd(lhs, rhs Vector, matching *parser.VectorMatching,
|
|||
for _, ls := range lhs {
|
||||
// If there's a matching entry in the right-hand side Vector, add the sample.
|
||||
if _, ok := rightSigs[sigf(ls.Metric)]; ok {
|
||||
enh.out = append(enh.out, ls)
|
||||
enh.Out = append(enh.Out, ls)
|
||||
}
|
||||
}
|
||||
return enh.out
|
||||
return enh.Out
|
||||
}
|
||||
|
||||
func (ev *evaluator) VectorOr(lhs, rhs Vector, matching *parser.VectorMatching, enh *EvalNodeHelper) Vector {
|
||||
|
@ -1546,15 +1546,15 @@ func (ev *evaluator) VectorOr(lhs, rhs Vector, matching *parser.VectorMatching,
|
|||
// Add everything from the left-hand-side Vector.
|
||||
for _, ls := range lhs {
|
||||
leftSigs[sigf(ls.Metric)] = struct{}{}
|
||||
enh.out = append(enh.out, ls)
|
||||
enh.Out = append(enh.Out, ls)
|
||||
}
|
||||
// Add all right-hand side elements which have not been added from the left-hand side.
|
||||
for _, rs := range rhs {
|
||||
if _, ok := leftSigs[sigf(rs.Metric)]; !ok {
|
||||
enh.out = append(enh.out, rs)
|
||||
enh.Out = append(enh.Out, rs)
|
||||
}
|
||||
}
|
||||
return enh.out
|
||||
return enh.Out
|
||||
}
|
||||
|
||||
func (ev *evaluator) VectorUnless(lhs, rhs Vector, matching *parser.VectorMatching, enh *EvalNodeHelper) Vector {
|
||||
|
@ -1570,10 +1570,10 @@ func (ev *evaluator) VectorUnless(lhs, rhs Vector, matching *parser.VectorMatchi
|
|||
|
||||
for _, ls := range lhs {
|
||||
if _, ok := rightSigs[sigf(ls.Metric)]; !ok {
|
||||
enh.out = append(enh.out, ls)
|
||||
enh.Out = append(enh.Out, ls)
|
||||
}
|
||||
}
|
||||
return enh.out
|
||||
return enh.Out
|
||||
}
|
||||
|
||||
// VectorBinop evaluates a binary operation between two Vectors, excluding set operators.
|
||||
|
@ -1592,7 +1592,7 @@ func (ev *evaluator) VectorBinop(op parser.ItemType, lhs, rhs Vector, matching *
|
|||
|
||||
// All samples from the rhs hashed by the matching label/values.
|
||||
if enh.rightSigs == nil {
|
||||
enh.rightSigs = make(map[string]Sample, len(enh.out))
|
||||
enh.rightSigs = make(map[string]Sample, len(enh.Out))
|
||||
} else {
|
||||
for k := range enh.rightSigs {
|
||||
delete(enh.rightSigs, k)
|
||||
|
@ -1657,7 +1657,7 @@ func (ev *evaluator) VectorBinop(op parser.ItemType, lhs, rhs Vector, matching *
|
|||
}
|
||||
metric := resultMetric(ls.Metric, rs.Metric, op, matching, enh)
|
||||
if returnBool {
|
||||
metric = enh.dropMetricName(metric)
|
||||
metric = enh.DropMetricName(metric)
|
||||
}
|
||||
insertedSigs, exists := matchedSigs[sig]
|
||||
if matching.Card == parser.CardOneToOne {
|
||||
|
@ -1680,12 +1680,12 @@ func (ev *evaluator) VectorBinop(op parser.ItemType, lhs, rhs Vector, matching *
|
|||
insertedSigs[insertSig] = struct{}{}
|
||||
}
|
||||
|
||||
enh.out = append(enh.out, Sample{
|
||||
enh.Out = append(enh.Out, Sample{
|
||||
Metric: metric,
|
||||
Point: Point{V: value},
|
||||
})
|
||||
}
|
||||
return enh.out
|
||||
return enh.Out
|
||||
}
|
||||
|
||||
func signatureFunc(on bool, b []byte, names ...string) func(labels.Labels) string {
|
||||
|
@ -1704,7 +1704,7 @@ func signatureFunc(on bool, b []byte, names ...string) func(labels.Labels) strin
|
|||
// binary operation and the matching options.
|
||||
func resultMetric(lhs, rhs labels.Labels, op parser.ItemType, matching *parser.VectorMatching, enh *EvalNodeHelper) labels.Labels {
|
||||
if enh.resultMetric == nil {
|
||||
enh.resultMetric = make(map[string]labels.Labels, len(enh.out))
|
||||
enh.resultMetric = make(map[string]labels.Labels, len(enh.Out))
|
||||
}
|
||||
|
||||
if enh.lb == nil {
|
||||
|
@ -1784,12 +1784,12 @@ func (ev *evaluator) VectorscalarBinop(op parser.ItemType, lhs Vector, rhs Scala
|
|||
if keep {
|
||||
lhsSample.V = value
|
||||
if shouldDropMetricName(op) || returnBool {
|
||||
lhsSample.Metric = enh.dropMetricName(lhsSample.Metric)
|
||||
lhsSample.Metric = enh.DropMetricName(lhsSample.Metric)
|
||||
}
|
||||
enh.out = append(enh.out, lhsSample)
|
||||
enh.Out = append(enh.Out, lhsSample)
|
||||
}
|
||||
}
|
||||
return enh.out
|
||||
return enh.Out
|
||||
}
|
||||
|
||||
func dropMetricName(l labels.Labels) labels.Labels {
|
||||
|
@ -2069,7 +2069,7 @@ func (ev *evaluator) aggregation(op parser.ItemType, grouping []string, without
|
|||
// The heap keeps the lowest value on top, so reverse it.
|
||||
sort.Sort(sort.Reverse(aggr.heap))
|
||||
for _, v := range aggr.heap {
|
||||
enh.out = append(enh.out, Sample{
|
||||
enh.Out = append(enh.Out, Sample{
|
||||
Metric: v.Metric,
|
||||
Point: Point{V: v.V},
|
||||
})
|
||||
|
@ -2080,7 +2080,7 @@ func (ev *evaluator) aggregation(op parser.ItemType, grouping []string, without
|
|||
// The heap keeps the lowest value on top, so reverse it.
|
||||
sort.Sort(sort.Reverse(aggr.reverseHeap))
|
||||
for _, v := range aggr.reverseHeap {
|
||||
enh.out = append(enh.out, Sample{
|
||||
enh.Out = append(enh.Out, Sample{
|
||||
Metric: v.Metric,
|
||||
Point: Point{V: v.V},
|
||||
})
|
||||
|
@ -2094,12 +2094,12 @@ func (ev *evaluator) aggregation(op parser.ItemType, grouping []string, without
|
|||
// For other aggregations, we already have the right value.
|
||||
}
|
||||
|
||||
enh.out = append(enh.out, Sample{
|
||||
enh.Out = append(enh.Out, Sample{
|
||||
Metric: aggr.labels,
|
||||
Point: Point{V: aggr.value},
|
||||
})
|
||||
}
|
||||
return enh.out
|
||||
return enh.Out
|
||||
}
|
||||
|
||||
// btos returns 1 if b is true, 0 otherwise.
|
||||
|
|
|
@ -36,7 +36,7 @@ import (
|
|||
// value,and nil for strings.
|
||||
// args are the original arguments to the function, where you can access
|
||||
// matrixSelectors, vectorSelectors, and StringLiterals.
|
||||
// enh.out is a pre-allocated empty vector that you may use to accumulate
|
||||
// enh.Out is a pre-allocated empty vector that you may use to accumulate
|
||||
// output before returning it. The vectors in vals should not be returned.a
|
||||
// Range vector functions need only return a vector with the right value,
|
||||
// the metric and timestamp are not needed.
|
||||
|
@ -48,7 +48,7 @@ type FunctionCall func(vals []parser.Value, args parser.Expressions, enh *EvalNo
|
|||
// === time() float64 ===
|
||||
func funcTime(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) Vector {
|
||||
return Vector{Sample{Point: Point{
|
||||
V: float64(enh.ts) / 1000,
|
||||
V: float64(enh.Ts) / 1000,
|
||||
}}}
|
||||
}
|
||||
|
||||
|
@ -62,14 +62,14 @@ func extrapolatedRate(vals []parser.Value, args parser.Expressions, enh *EvalNod
|
|||
|
||||
var (
|
||||
samples = vals[0].(Matrix)[0]
|
||||
rangeStart = enh.ts - durationMilliseconds(ms.Range+vs.Offset)
|
||||
rangeEnd = enh.ts - durationMilliseconds(vs.Offset)
|
||||
rangeStart = enh.Ts - durationMilliseconds(ms.Range+vs.Offset)
|
||||
rangeEnd = enh.Ts - durationMilliseconds(vs.Offset)
|
||||
)
|
||||
|
||||
// No sense in trying to compute a rate without at least two points. Drop
|
||||
// this Vector element.
|
||||
if len(samples.Points) < 2 {
|
||||
return enh.out
|
||||
return enh.Out
|
||||
}
|
||||
var (
|
||||
counterCorrection float64
|
||||
|
@ -126,7 +126,7 @@ func extrapolatedRate(vals []parser.Value, args parser.Expressions, enh *EvalNod
|
|||
resultValue = resultValue / ms.Range.Seconds()
|
||||
}
|
||||
|
||||
return append(enh.out, Sample{
|
||||
return append(enh.Out, Sample{
|
||||
Point: Point{V: resultValue},
|
||||
})
|
||||
}
|
||||
|
@ -148,12 +148,12 @@ func funcIncrease(vals []parser.Value, args parser.Expressions, enh *EvalNodeHel
|
|||
|
||||
// === irate(node parser.ValueTypeMatrix) Vector ===
|
||||
func funcIrate(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) Vector {
|
||||
return instantValue(vals, enh.out, true)
|
||||
return instantValue(vals, enh.Out, true)
|
||||
}
|
||||
|
||||
// === idelta(node model.ValMatrix) Vector ===
|
||||
func funcIdelta(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) Vector {
|
||||
return instantValue(vals, enh.out, false)
|
||||
return instantValue(vals, enh.Out, false)
|
||||
}
|
||||
|
||||
func instantValue(vals []parser.Value, out Vector, isRate bool) Vector {
|
||||
|
@ -234,7 +234,7 @@ func funcHoltWinters(vals []parser.Value, args parser.Expressions, enh *EvalNode
|
|||
|
||||
// Can't do the smoothing operation with less than two points.
|
||||
if l < 2 {
|
||||
return enh.out
|
||||
return enh.Out
|
||||
}
|
||||
|
||||
var s0, s1, b float64
|
||||
|
@ -256,7 +256,7 @@ func funcHoltWinters(vals []parser.Value, args parser.Expressions, enh *EvalNode
|
|||
s0, s1 = s1, x+y
|
||||
}
|
||||
|
||||
return append(enh.out, Sample{
|
||||
return append(enh.Out, Sample{
|
||||
Point: Point{V: s1},
|
||||
})
|
||||
}
|
||||
|
@ -284,12 +284,12 @@ func funcClampMax(vals []parser.Value, args parser.Expressions, enh *EvalNodeHel
|
|||
vec := vals[0].(Vector)
|
||||
max := vals[1].(Vector)[0].Point.V
|
||||
for _, el := range vec {
|
||||
enh.out = append(enh.out, Sample{
|
||||
Metric: enh.dropMetricName(el.Metric),
|
||||
enh.Out = append(enh.Out, Sample{
|
||||
Metric: enh.DropMetricName(el.Metric),
|
||||
Point: Point{V: math.Min(max, el.V)},
|
||||
})
|
||||
}
|
||||
return enh.out
|
||||
return enh.Out
|
||||
}
|
||||
|
||||
// === clamp_min(Vector parser.ValueTypeVector, min Scalar) Vector ===
|
||||
|
@ -297,12 +297,12 @@ func funcClampMin(vals []parser.Value, args parser.Expressions, enh *EvalNodeHel
|
|||
vec := vals[0].(Vector)
|
||||
min := vals[1].(Vector)[0].Point.V
|
||||
for _, el := range vec {
|
||||
enh.out = append(enh.out, Sample{
|
||||
Metric: enh.dropMetricName(el.Metric),
|
||||
enh.Out = append(enh.Out, Sample{
|
||||
Metric: enh.DropMetricName(el.Metric),
|
||||
Point: Point{V: math.Max(min, el.V)},
|
||||
})
|
||||
}
|
||||
return enh.out
|
||||
return enh.Out
|
||||
}
|
||||
|
||||
// === round(Vector parser.ValueTypeVector, toNearest=1 Scalar) Vector ===
|
||||
|
@ -319,23 +319,23 @@ func funcRound(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper
|
|||
|
||||
for _, el := range vec {
|
||||
v := math.Floor(el.V*toNearestInverse+0.5) / toNearestInverse
|
||||
enh.out = append(enh.out, Sample{
|
||||
Metric: enh.dropMetricName(el.Metric),
|
||||
enh.Out = append(enh.Out, Sample{
|
||||
Metric: enh.DropMetricName(el.Metric),
|
||||
Point: Point{V: v},
|
||||
})
|
||||
}
|
||||
return enh.out
|
||||
return enh.Out
|
||||
}
|
||||
|
||||
// === Scalar(node parser.ValueTypeVector) Scalar ===
|
||||
func funcScalar(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) Vector {
|
||||
v := vals[0].(Vector)
|
||||
if len(v) != 1 {
|
||||
return append(enh.out, Sample{
|
||||
return append(enh.Out, Sample{
|
||||
Point: Point{V: math.NaN()},
|
||||
})
|
||||
}
|
||||
return append(enh.out, Sample{
|
||||
return append(enh.Out, Sample{
|
||||
Point: Point{V: v[0].V},
|
||||
})
|
||||
}
|
||||
|
@ -343,7 +343,7 @@ func funcScalar(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelpe
|
|||
func aggrOverTime(vals []parser.Value, enh *EvalNodeHelper, aggrFn func([]Point) float64) Vector {
|
||||
el := vals[0].(Matrix)[0]
|
||||
|
||||
return append(enh.out, Sample{
|
||||
return append(enh.Out, Sample{
|
||||
Point: Point{V: aggrFn(el.Points)},
|
||||
})
|
||||
}
|
||||
|
@ -431,7 +431,7 @@ func funcQuantileOverTime(vals []parser.Value, args parser.Expressions, enh *Eva
|
|||
for _, v := range el.Points {
|
||||
values = append(values, Sample{Point: Point{V: v.V}})
|
||||
}
|
||||
return append(enh.out, Sample{
|
||||
return append(enh.Out, Sample{
|
||||
Point: Point{V: quantile(q, values)},
|
||||
})
|
||||
}
|
||||
|
@ -467,9 +467,9 @@ func funcStdvarOverTime(vals []parser.Value, args parser.Expressions, enh *EvalN
|
|||
// === absent(Vector parser.ValueTypeVector) Vector ===
|
||||
func funcAbsent(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) Vector {
|
||||
if len(vals[0].(Vector)) > 0 {
|
||||
return enh.out
|
||||
return enh.Out
|
||||
}
|
||||
return append(enh.out,
|
||||
return append(enh.Out,
|
||||
Sample{
|
||||
Metric: createLabelsForAbsentFunction(args[0]),
|
||||
Point: Point{V: 1},
|
||||
|
@ -482,7 +482,7 @@ func funcAbsent(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelpe
|
|||
// Due to engine optimization, this function is only called when this condition is true.
|
||||
// Then, the engine post-processes the results to get the expected output.
|
||||
func funcAbsentOverTime(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) Vector {
|
||||
return append(enh.out,
|
||||
return append(enh.Out,
|
||||
Sample{
|
||||
Point: Point{V: 1},
|
||||
})
|
||||
|
@ -490,12 +490,12 @@ func funcAbsentOverTime(vals []parser.Value, args parser.Expressions, enh *EvalN
|
|||
|
||||
func simpleFunc(vals []parser.Value, enh *EvalNodeHelper, f func(float64) float64) Vector {
|
||||
for _, el := range vals[0].(Vector) {
|
||||
enh.out = append(enh.out, Sample{
|
||||
Metric: enh.dropMetricName(el.Metric),
|
||||
enh.Out = append(enh.Out, Sample{
|
||||
Metric: enh.DropMetricName(el.Metric),
|
||||
Point: Point{V: f(el.V)},
|
||||
})
|
||||
}
|
||||
return enh.out
|
||||
return enh.Out
|
||||
}
|
||||
|
||||
// === abs(Vector parser.ValueTypeVector) Vector ===
|
||||
|
@ -542,12 +542,12 @@ func funcLog10(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper
|
|||
func funcTimestamp(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) Vector {
|
||||
vec := vals[0].(Vector)
|
||||
for _, el := range vec {
|
||||
enh.out = append(enh.out, Sample{
|
||||
Metric: enh.dropMetricName(el.Metric),
|
||||
enh.Out = append(enh.Out, Sample{
|
||||
Metric: enh.DropMetricName(el.Metric),
|
||||
Point: Point{V: float64(el.T) / 1000},
|
||||
})
|
||||
}
|
||||
return enh.out
|
||||
return enh.Out
|
||||
}
|
||||
|
||||
// linearRegression performs a least-square linear regression analysis on the
|
||||
|
@ -582,14 +582,14 @@ func funcDeriv(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper
|
|||
// No sense in trying to compute a derivative without at least two points.
|
||||
// Drop this Vector element.
|
||||
if len(samples.Points) < 2 {
|
||||
return enh.out
|
||||
return enh.Out
|
||||
}
|
||||
|
||||
// We pass in an arbitrary timestamp that is near the values in use
|
||||
// to avoid floating point accuracy issues, see
|
||||
// https://github.com/prometheus/prometheus/issues/2674
|
||||
slope, _ := linearRegression(samples.Points, samples.Points[0].T)
|
||||
return append(enh.out, Sample{
|
||||
return append(enh.Out, Sample{
|
||||
Point: Point{V: slope},
|
||||
})
|
||||
}
|
||||
|
@ -602,11 +602,11 @@ func funcPredictLinear(vals []parser.Value, args parser.Expressions, enh *EvalNo
|
|||
// No sense in trying to predict anything without at least two points.
|
||||
// Drop this Vector element.
|
||||
if len(samples.Points) < 2 {
|
||||
return enh.out
|
||||
return enh.Out
|
||||
}
|
||||
slope, intercept := linearRegression(samples.Points, enh.ts)
|
||||
slope, intercept := linearRegression(samples.Points, enh.Ts)
|
||||
|
||||
return append(enh.out, Sample{
|
||||
return append(enh.Out, Sample{
|
||||
Point: Point{V: slope*duration + intercept},
|
||||
})
|
||||
}
|
||||
|
@ -649,14 +649,14 @@ func funcHistogramQuantile(vals []parser.Value, args parser.Expressions, enh *Ev
|
|||
|
||||
for _, mb := range enh.signatureToMetricWithBuckets {
|
||||
if len(mb.buckets) > 0 {
|
||||
enh.out = append(enh.out, Sample{
|
||||
enh.Out = append(enh.Out, Sample{
|
||||
Metric: mb.metric,
|
||||
Point: Point{V: bucketQuantile(q, mb.buckets)},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return enh.out
|
||||
return enh.Out
|
||||
}
|
||||
|
||||
// === resets(Matrix parser.ValueTypeMatrix) Vector ===
|
||||
|
@ -673,7 +673,7 @@ func funcResets(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelpe
|
|||
prev = current
|
||||
}
|
||||
|
||||
return append(enh.out, Sample{
|
||||
return append(enh.Out, Sample{
|
||||
Point: Point{V: float64(resets)},
|
||||
})
|
||||
}
|
||||
|
@ -692,7 +692,7 @@ func funcChanges(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelp
|
|||
prev = current
|
||||
}
|
||||
|
||||
return append(enh.out, Sample{
|
||||
return append(enh.Out, Sample{
|
||||
Point: Point{V: float64(changes)},
|
||||
})
|
||||
}
|
||||
|
@ -716,13 +716,13 @@ func funcLabelReplace(vals []parser.Value, args parser.Expressions, enh *EvalNod
|
|||
if !model.LabelNameRE.MatchString(dst) {
|
||||
panic(errors.Errorf("invalid destination label name in label_replace(): %s", dst))
|
||||
}
|
||||
enh.dmn = make(map[uint64]labels.Labels, len(enh.out))
|
||||
enh.Dmn = make(map[uint64]labels.Labels, len(enh.Out))
|
||||
}
|
||||
|
||||
for _, el := range vector {
|
||||
h := el.Metric.Hash()
|
||||
var outMetric labels.Labels
|
||||
if l, ok := enh.dmn[h]; ok {
|
||||
if l, ok := enh.Dmn[h]; ok {
|
||||
outMetric = l
|
||||
} else {
|
||||
srcVal := el.Metric.Get(src)
|
||||
|
@ -730,7 +730,7 @@ func funcLabelReplace(vals []parser.Value, args parser.Expressions, enh *EvalNod
|
|||
if indexes == nil {
|
||||
// If there is no match, no replacement should take place.
|
||||
outMetric = el.Metric
|
||||
enh.dmn[h] = outMetric
|
||||
enh.Dmn[h] = outMetric
|
||||
} else {
|
||||
res := enh.regex.ExpandString([]byte{}, repl, srcVal, indexes)
|
||||
|
||||
|
@ -739,21 +739,21 @@ func funcLabelReplace(vals []parser.Value, args parser.Expressions, enh *EvalNod
|
|||
lb.Set(dst, string(res))
|
||||
}
|
||||
outMetric = lb.Labels()
|
||||
enh.dmn[h] = outMetric
|
||||
enh.Dmn[h] = outMetric
|
||||
}
|
||||
}
|
||||
|
||||
enh.out = append(enh.out, Sample{
|
||||
enh.Out = append(enh.Out, Sample{
|
||||
Metric: outMetric,
|
||||
Point: Point{V: el.Point.V},
|
||||
})
|
||||
}
|
||||
return enh.out
|
||||
return enh.Out
|
||||
}
|
||||
|
||||
// === Vector(s Scalar) Vector ===
|
||||
func funcVector(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) Vector {
|
||||
return append(enh.out,
|
||||
return append(enh.Out,
|
||||
Sample{
|
||||
Metric: labels.Labels{},
|
||||
Point: Point{V: vals[0].(Vector)[0].V},
|
||||
|
@ -769,8 +769,8 @@ func funcLabelJoin(vals []parser.Value, args parser.Expressions, enh *EvalNodeHe
|
|||
srcLabels = make([]string, len(args)-3)
|
||||
)
|
||||
|
||||
if enh.dmn == nil {
|
||||
enh.dmn = make(map[uint64]labels.Labels, len(enh.out))
|
||||
if enh.Dmn == nil {
|
||||
enh.Dmn = make(map[uint64]labels.Labels, len(enh.Out))
|
||||
}
|
||||
|
||||
for i := 3; i < len(args); i++ {
|
||||
|
@ -789,7 +789,7 @@ func funcLabelJoin(vals []parser.Value, args parser.Expressions, enh *EvalNodeHe
|
|||
for _, el := range vector {
|
||||
h := el.Metric.Hash()
|
||||
var outMetric labels.Labels
|
||||
if l, ok := enh.dmn[h]; ok {
|
||||
if l, ok := enh.Dmn[h]; ok {
|
||||
outMetric = l
|
||||
} else {
|
||||
|
||||
|
@ -807,35 +807,35 @@ func funcLabelJoin(vals []parser.Value, args parser.Expressions, enh *EvalNodeHe
|
|||
}
|
||||
|
||||
outMetric = lb.Labels()
|
||||
enh.dmn[h] = outMetric
|
||||
enh.Dmn[h] = outMetric
|
||||
}
|
||||
|
||||
enh.out = append(enh.out, Sample{
|
||||
enh.Out = append(enh.Out, Sample{
|
||||
Metric: outMetric,
|
||||
Point: Point{V: el.Point.V},
|
||||
})
|
||||
}
|
||||
return enh.out
|
||||
return enh.Out
|
||||
}
|
||||
|
||||
// Common code for date related functions.
|
||||
func dateWrapper(vals []parser.Value, enh *EvalNodeHelper, f func(time.Time) float64) Vector {
|
||||
if len(vals) == 0 {
|
||||
return append(enh.out,
|
||||
return append(enh.Out,
|
||||
Sample{
|
||||
Metric: labels.Labels{},
|
||||
Point: Point{V: f(time.Unix(enh.ts/1000, 0).UTC())},
|
||||
Point: Point{V: f(time.Unix(enh.Ts/1000, 0).UTC())},
|
||||
})
|
||||
}
|
||||
|
||||
for _, el := range vals[0].(Vector) {
|
||||
t := time.Unix(int64(el.V), 0).UTC()
|
||||
enh.out = append(enh.out, Sample{
|
||||
Metric: enh.dropMetricName(el.Metric),
|
||||
enh.Out = append(enh.Out, Sample{
|
||||
Metric: enh.DropMetricName(el.Metric),
|
||||
Point: Point{V: f(t)},
|
||||
})
|
||||
}
|
||||
return enh.out
|
||||
return enh.Out
|
||||
}
|
||||
|
||||
// === days_in_month(v Vector) Scalar ===
|
||||
|
|
Loading…
Reference in a new issue