Depointerize Matrix/Vector types as well as time.Time arguments.

This commit is contained in:
Julius Volz 2013-03-28 17:05:06 +01:00
parent b912f75d11
commit ec413459fa
8 changed files with 65 additions and 65 deletions

View file

@ -95,7 +95,7 @@ func main() {
case ruleResult := <-ruleResults:
for _, sample := range ruleResult.Samples {
ts.AppendSample(*sample)
ts.AppendSample(sample)
}
}
}

View file

@ -27,8 +27,8 @@ import (
// ----------------------------------------------------------------------------
// Raw data value types.
type Vector []*model.Sample
type Matrix []*model.SampleSet
type Vector model.Samples
type Matrix []model.SampleSet
type groupedAggregation struct {
labels model.Metric
@ -97,23 +97,23 @@ type Node interface {
// interface represents the type returned to the parent node.
type ScalarNode interface {
Node
Eval(timestamp *time.Time, view *viewAdapter) model.SampleValue
Eval(timestamp time.Time, view *viewAdapter) model.SampleValue
}
type VectorNode interface {
Node
Eval(timestamp *time.Time, view *viewAdapter) Vector
Eval(timestamp time.Time, view *viewAdapter) Vector
}
type MatrixNode interface {
Node
Eval(timestamp *time.Time, view *viewAdapter) Matrix
EvalBoundaries(timestamp *time.Time, view *viewAdapter) Matrix
Eval(timestamp time.Time, view *viewAdapter) Matrix
EvalBoundaries(timestamp time.Time, view *viewAdapter) Matrix
}
type StringNode interface {
Node
Eval(timestamp *time.Time, view *viewAdapter) string
Eval(timestamp time.Time, view *viewAdapter) string
}
// ----------------------------------------------------------------------------
@ -227,17 +227,17 @@ func (node MatrixLiteral) Children() []Node { return []Node{} }
func (node StringLiteral) Children() []Node { return []Node{} }
func (node StringFunctionCall) Children() []Node { return node.args }
func (node *ScalarLiteral) Eval(timestamp *time.Time, view *viewAdapter) model.SampleValue {
func (node *ScalarLiteral) Eval(timestamp time.Time, view *viewAdapter) model.SampleValue {
return node.value
}
func (node *ScalarArithExpr) Eval(timestamp *time.Time, view *viewAdapter) model.SampleValue {
func (node *ScalarArithExpr) Eval(timestamp time.Time, view *viewAdapter) model.SampleValue {
lhs := node.lhs.Eval(timestamp, view)
rhs := node.rhs.Eval(timestamp, view)
return evalScalarBinop(node.opType, lhs, rhs)
}
func (node *ScalarFunctionCall) Eval(timestamp *time.Time, view *viewAdapter) model.SampleValue {
func (node *ScalarFunctionCall) Eval(timestamp time.Time, view *viewAdapter) model.SampleValue {
return node.function.callFn(timestamp, view, node.args).(model.SampleValue)
}
@ -263,7 +263,7 @@ func EvalVectorInstant(node VectorNode, timestamp time.Time) (vector Vector) {
if err != nil {
return
}
return node.Eval(&timestamp, viewAdapter)
return node.Eval(timestamp, viewAdapter)
}
func EvalVectorRange(node VectorNode, start time.Time, end time.Time, interval time.Duration) (matrix Matrix, err error) {
@ -278,7 +278,7 @@ func EvalVectorRange(node VectorNode, start time.Time, end time.Time, interval t
// TODO implement watchdog timer for long-running queries.
sampleSets := map[string]*model.SampleSet{}
for t := start; t.Before(end); t = t.Add(interval) {
vector := node.Eval(&t, viewAdapter)
vector := node.Eval(t, viewAdapter)
for _, sample := range vector {
samplePair := model.SamplePair{
Value: sample.Value,
@ -297,7 +297,7 @@ func EvalVectorRange(node VectorNode, start time.Time, end time.Time, interval t
}
for _, sampleSet := range sampleSets {
matrix = append(matrix, sampleSet)
matrix = append(matrix, *sampleSet)
}
return
}
@ -312,23 +312,23 @@ func labelIntersection(metric1, metric2 model.Metric) model.Metric {
return intersection
}
func (node *VectorAggregation) groupedAggregationsToVector(aggregations map[string]*groupedAggregation, timestamp *time.Time) Vector {
func (node *VectorAggregation) groupedAggregationsToVector(aggregations map[string]*groupedAggregation, timestamp time.Time) Vector {
vector := Vector{}
for _, aggregation := range aggregations {
if node.aggrType == AVG {
aggregation.value = aggregation.value / model.SampleValue(aggregation.groupCount)
}
sample := &model.Sample{
sample := model.Sample{
Metric: aggregation.labels,
Value: aggregation.value,
Timestamp: *timestamp,
Timestamp: timestamp,
}
vector = append(vector, sample)
}
return vector
}
func (node *VectorAggregation) Eval(timestamp *time.Time, view *viewAdapter) Vector {
func (node *VectorAggregation) Eval(timestamp time.Time, view *viewAdapter) Vector {
vector := node.vector.Eval(timestamp, view)
result := map[string]*groupedAggregation{}
for _, sample := range vector {
@ -361,7 +361,7 @@ func (node *VectorAggregation) Eval(timestamp *time.Time, view *viewAdapter) Vec
return node.groupedAggregationsToVector(result, timestamp)
}
func (node *VectorLiteral) Eval(timestamp *time.Time, view *viewAdapter) Vector {
func (node *VectorLiteral) Eval(timestamp time.Time, view *viewAdapter) Vector {
values, err := view.GetValueAtTime(node.fingerprints, timestamp)
if err != nil {
log.Printf("Unable to get vector values")
@ -370,7 +370,7 @@ func (node *VectorLiteral) Eval(timestamp *time.Time, view *viewAdapter) Vector
return values
}
func (node *VectorFunctionCall) Eval(timestamp *time.Time, view *viewAdapter) Vector {
func (node *VectorFunctionCall) Eval(timestamp time.Time, view *viewAdapter) Vector {
return node.function.callFn(timestamp, view, node.args).(Vector)
}
@ -514,7 +514,7 @@ func labelsEqual(labels1, labels2 model.Metric) bool {
return true
}
func (node *VectorArithExpr) Eval(timestamp *time.Time, view *viewAdapter) Vector {
func (node *VectorArithExpr) Eval(timestamp time.Time, view *viewAdapter) Vector {
lhs := node.lhs.Eval(timestamp, view)
result := Vector{}
if node.rhs.Type() == SCALAR {
@ -545,10 +545,10 @@ func (node *VectorArithExpr) Eval(timestamp *time.Time, view *viewAdapter) Vecto
panic("Invalid vector arithmetic expression operands")
}
func (node *MatrixLiteral) Eval(timestamp *time.Time, view *viewAdapter) Matrix {
func (node *MatrixLiteral) Eval(timestamp time.Time, view *viewAdapter) Matrix {
interval := &model.Interval{
OldestInclusive: timestamp.Add(-node.interval),
NewestInclusive: *timestamp,
NewestInclusive: timestamp,
}
values, err := view.GetRangeValues(node.fingerprints, interval)
if err != nil {
@ -558,10 +558,10 @@ func (node *MatrixLiteral) Eval(timestamp *time.Time, view *viewAdapter) Matrix
return values
}
func (node *MatrixLiteral) EvalBoundaries(timestamp *time.Time, view *viewAdapter) Matrix {
func (node *MatrixLiteral) EvalBoundaries(timestamp time.Time, view *viewAdapter) Matrix {
interval := &model.Interval{
OldestInclusive: timestamp.Add(-node.interval),
NewestInclusive: *timestamp,
NewestInclusive: timestamp,
}
values, err := view.GetBoundaryValues(node.fingerprints, interval)
if err != nil {
@ -583,11 +583,11 @@ func (matrix Matrix) Swap(i, j int) {
matrix[i], matrix[j] = matrix[j], matrix[i]
}
func (node *StringLiteral) Eval(timestamp *time.Time, view *viewAdapter) string {
func (node *StringLiteral) Eval(timestamp time.Time, view *viewAdapter) string {
return node.str
}
func (node *StringFunctionCall) Eval(timestamp *time.Time, view *viewAdapter) string {
func (node *StringFunctionCall) Eval(timestamp time.Time, view *viewAdapter) string {
return node.function.callFn(timestamp, view, node.args).(string)
}

View file

@ -24,7 +24,7 @@ type Function struct {
name string
argTypes []ExprType
returnType ExprType
callFn func(timestamp *time.Time, view *viewAdapter, args []Node) interface{}
callFn func(timestamp time.Time, view *viewAdapter, args []Node) interface{}
}
func (function *Function) CheckArgTypes(args []Node) error {
@ -63,17 +63,17 @@ func (function *Function) CheckArgTypes(args []Node) error {
}
// === time() ===
func timeImpl(timestamp *time.Time, view *viewAdapter, args []Node) interface{} {
func timeImpl(timestamp time.Time, view *viewAdapter, args []Node) interface{} {
return model.SampleValue(time.Now().Unix())
}
// === count(vector VectorNode) ===
func countImpl(timestamp *time.Time, view *viewAdapter, args []Node) interface{} {
func countImpl(timestamp time.Time, view *viewAdapter, args []Node) interface{} {
return model.SampleValue(len(args[0].(VectorNode).Eval(timestamp, view)))
}
// === delta(matrix MatrixNode, isCounter ScalarNode) ===
func deltaImpl(timestamp *time.Time, view *viewAdapter, args []Node) interface{} {
func deltaImpl(timestamp time.Time, view *viewAdapter, args []Node) interface{} {
matrixNode := args[0].(MatrixNode)
isCounter := int(args[1].(ScalarNode).Eval(timestamp, view))
resultVector := Vector{}
@ -98,10 +98,10 @@ func deltaImpl(timestamp *time.Time, view *viewAdapter, args []Node) interface{}
lastValue = currentValue
}
resultValue := lastValue - samples.Values[0].Value + counterCorrection
resultSample := &model.Sample{
resultSample := model.Sample{
Metric: samples.Metric,
Value: resultValue,
Timestamp: *timestamp,
Timestamp: timestamp,
}
resultVector = append(resultVector, resultSample)
}
@ -109,7 +109,7 @@ func deltaImpl(timestamp *time.Time, view *viewAdapter, args []Node) interface{}
}
// === rate(node *MatrixNode) ===
func rateImpl(timestamp *time.Time, view *viewAdapter, args []Node) interface{} {
func rateImpl(timestamp time.Time, view *viewAdapter, args []Node) interface{} {
args = append(args, &ScalarLiteral{value: 1})
vector := deltaImpl(timestamp, view, args).(Vector)
@ -124,36 +124,36 @@ func rateImpl(timestamp *time.Time, view *viewAdapter, args []Node) interface{}
}
// === sampleVectorImpl() ===
func sampleVectorImpl(timestamp *time.Time, view *viewAdapter, args []Node) interface{} {
func sampleVectorImpl(timestamp time.Time, view *viewAdapter, args []Node) interface{} {
return Vector{
&model.Sample{
model.Sample{
Metric: model.Metric{
model.MetricNameLabel: "http_requests",
"job": "api-server",
"instance": "0",
},
Value: 10,
Timestamp: *timestamp,
Timestamp: timestamp,
},
&model.Sample{
model.Sample{
Metric: model.Metric{
model.MetricNameLabel: "http_requests",
"job": "api-server",
"instance": "1",
},
Value: 20,
Timestamp: *timestamp,
Timestamp: timestamp,
},
&model.Sample{
model.Sample{
Metric: model.Metric{
model.MetricNameLabel: "http_requests",
"job": "api-server",
"instance": "2",
},
Value: 30,
Timestamp: *timestamp,
Timestamp: timestamp,
},
&model.Sample{
model.Sample{
Metric: model.Metric{
model.MetricNameLabel: "http_requests",
"job": "api-server",
@ -161,9 +161,9 @@ func sampleVectorImpl(timestamp *time.Time, view *viewAdapter, args []Node) inte
"group": "canary",
},
Value: 40,
Timestamp: *timestamp,
Timestamp: timestamp,
},
&model.Sample{
model.Sample{
Metric: model.Metric{
model.MetricNameLabel: "http_requests",
"job": "api-server",
@ -171,9 +171,9 @@ func sampleVectorImpl(timestamp *time.Time, view *viewAdapter, args []Node) inte
"group": "canary",
},
Value: 40,
Timestamp: *timestamp,
Timestamp: timestamp,
},
&model.Sample{
model.Sample{
Metric: model.Metric{
model.MetricNameLabel: "http_requests",
"job": "api-server",
@ -181,9 +181,9 @@ func sampleVectorImpl(timestamp *time.Time, view *viewAdapter, args []Node) inte
"group": "mytest",
},
Value: 40,
Timestamp: *timestamp,
Timestamp: timestamp,
},
&model.Sample{
model.Sample{
Metric: model.Metric{
model.MetricNameLabel: "http_requests",
"job": "api-server",
@ -191,7 +191,7 @@ func sampleVectorImpl(timestamp *time.Time, view *viewAdapter, args []Node) inte
"group": "mytest",
},
Value: 40,
Timestamp: *timestamp,
Timestamp: timestamp,
},
}
}

View file

@ -50,11 +50,11 @@ func interpolateSamples(first, second *model.SamplePair, timestamp time.Time) *m
// 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) {
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)
delta := candidate.Timestamp.Sub(timestamp)
// Samples before target time.
if delta < 0 {
// Ignore samples outside of staleness policy window.
@ -86,7 +86,7 @@ func (v *viewAdapter) chooseClosestSample(samples []model.SamplePair, timestamp
switch {
case closestBefore != nil && closestAfter != nil:
sample = interpolateSamples(closestBefore, closestAfter, *timestamp)
sample = interpolateSamples(closestBefore, closestAfter, timestamp)
case closestBefore != nil:
sample = closestBefore
default:
@ -96,26 +96,26 @@ func (v *viewAdapter) chooseClosestSample(samples []model.SamplePair, timestamp
return
}
func (v *viewAdapter) GetValueAtTime(fingerprints model.Fingerprints, timestamp *time.Time) (samples []*model.Sample, err error) {
func (v *viewAdapter) GetValueAtTime(fingerprints model.Fingerprints, timestamp time.Time) (samples Vector, err error) {
for _, fingerprint := range fingerprints {
sampleCandidates := v.view.GetValueAtTime(fingerprint, *timestamp)
sampleCandidates := v.view.GetValueAtTime(fingerprint, timestamp)
samplePair := v.chooseClosestSample(sampleCandidates, timestamp)
m, err := queryStorage.GetMetricForFingerprint(fingerprint)
if err != nil {
continue
}
if samplePair != nil {
samples = append(samples, &model.Sample{
samples = append(samples, model.Sample{
Metric: *m,
Value: samplePair.Value,
Timestamp: *timestamp,
Timestamp: timestamp,
})
}
}
return
}
func (v *viewAdapter) GetBoundaryValues(fingerprints model.Fingerprints, interval *model.Interval) (sampleSets []*model.SampleSet, err error) {
func (v *viewAdapter) GetBoundaryValues(fingerprints model.Fingerprints, interval *model.Interval) (sampleSets []model.SampleSet, err error) {
for _, fingerprint := range fingerprints {
// TODO: change to GetBoundaryValues() once it has the right return type.
samplePairs := v.view.GetRangeValues(fingerprint, *interval)
@ -129,7 +129,7 @@ func (v *viewAdapter) GetBoundaryValues(fingerprints model.Fingerprints, interva
continue
}
sampleSet := &model.SampleSet{
sampleSet := model.SampleSet{
Metric: *m,
Values: samplePairs,
}
@ -138,7 +138,7 @@ func (v *viewAdapter) GetBoundaryValues(fingerprints model.Fingerprints, interva
return sampleSets, nil
}
func (v *viewAdapter) GetRangeValues(fingerprints model.Fingerprints, interval *model.Interval) (sampleSets []*model.SampleSet, err error) {
func (v *viewAdapter) GetRangeValues(fingerprints model.Fingerprints, interval *model.Interval) (sampleSets []model.SampleSet, err error) {
for _, fingerprint := range fingerprints {
samplePairs := v.view.GetRangeValues(fingerprint, *interval)
if samplePairs == nil {
@ -151,7 +151,7 @@ func (v *viewAdapter) GetRangeValues(fingerprints model.Fingerprints, interval *
continue
}
sampleSet := &model.SampleSet{
sampleSet := model.SampleSet{
Metric: *m,
Values: samplePairs,
}

View file

@ -152,8 +152,8 @@ func TypedValueToJSON(data interface{}, typeStr string) string {
return string(dataJSON)
}
func EvalToString(node Node, timestamp *time.Time, format OutputFormat) string {
viewAdapter, err := viewAdapterForInstantQuery(node, *timestamp)
func EvalToString(node Node, timestamp time.Time, format OutputFormat) string {
viewAdapter, err := viewAdapterForInstantQuery(node, timestamp)
if err != nil {
panic(err)
}

View file

@ -241,7 +241,7 @@ func TestExpressions(t *testing.T) {
t.Errorf("Test should fail, but didn't")
}
failed := false
resultStr := ast.EvalToString(testExpr, &testEvalTime, ast.TEXT)
resultStr := ast.EvalToString(testExpr, testEvalTime, ast.TEXT)
resultLines := strings.Split(resultStr, "\n")
if len(exprTest.output) != len(resultLines) {

View file

@ -42,7 +42,7 @@ func getTestVectorFromTestMatrix(matrix ast.Matrix) ast.Vector {
vector := ast.Vector{}
for _, sampleSet := range matrix {
lastSample := sampleSet.Values[len(sampleSet.Values)-1]
vector = append(vector, &model.Sample{
vector = append(vector, model.Sample{
Metric: sampleSet.Metric,
Value: lastSample.Value,
Timestamp: lastSample.Timestamp,

View file

@ -44,7 +44,7 @@ func (serv MetricsService) Query(expr string, formatJson string) (result string)
rb.SetContentType(gorest.Text_Plain)
}
return ast.EvalToString(exprNode, &timestamp, format)
return ast.EvalToString(exprNode, timestamp, format)
}
func (serv MetricsService) QueryRange(expr string, end int64, duration int64, step int64) string {