2013-02-08 17:03:26 +00:00
|
|
|
// Copyright 2013 Prometheus Team
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
package metric
|
|
|
|
|
|
|
|
import (
|
|
|
|
"sort"
|
|
|
|
"time"
|
2013-06-19 13:00:00 +00:00
|
|
|
|
2013-06-25 12:02:27 +00:00
|
|
|
clientmodel "github.com/prometheus/client_golang/model"
|
2013-02-08 17:03:26 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
// firstSupertime is the smallest valid supertime that may be seeked to.
|
|
|
|
firstSupertime = []byte{0, 0, 0, 0, 0, 0, 0, 0}
|
|
|
|
// lastSupertime is the largest valid supertime that may be seeked to.
|
|
|
|
lastSupertime = []byte{127, 255, 255, 255, 255, 255, 255, 255}
|
|
|
|
)
|
|
|
|
|
|
|
|
// Represents the summation of all datastore queries that shall be performed to
|
|
|
|
// extract values. Each operation mutates the state of the builder.
|
|
|
|
type ViewRequestBuilder interface {
|
2013-06-25 12:02:27 +00:00
|
|
|
GetMetricAtTime(fingerprint *clientmodel.Fingerprint, time time.Time)
|
|
|
|
GetMetricAtInterval(fingerprint *clientmodel.Fingerprint, from, through time.Time, interval time.Duration)
|
|
|
|
GetMetricRange(fingerprint *clientmodel.Fingerprint, from, through time.Time)
|
2013-02-08 17:03:26 +00:00
|
|
|
ScanJobs() scanJobs
|
|
|
|
}
|
|
|
|
|
|
|
|
// Contains the various unoptimized requests for data.
|
|
|
|
type viewRequestBuilder struct {
|
2013-06-25 12:02:27 +00:00
|
|
|
operations map[clientmodel.Fingerprint]ops
|
2013-02-08 17:03:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Furnishes a ViewRequestBuilder for remarking what types of queries to perform.
|
2013-05-07 12:25:01 +00:00
|
|
|
func NewViewRequestBuilder() *viewRequestBuilder {
|
|
|
|
return &viewRequestBuilder{
|
2013-06-25 12:02:27 +00:00
|
|
|
operations: make(map[clientmodel.Fingerprint]ops),
|
2013-02-08 17:03:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Gets for the given Fingerprint either the value at that time if there is an
|
|
|
|
// match or the one or two values adjacent thereto.
|
2013-05-07 12:25:01 +00:00
|
|
|
func (v *viewRequestBuilder) GetMetricAtTime(fingerprint *clientmodel.Fingerprint, time time.Time) {
|
2013-06-25 12:02:27 +00:00
|
|
|
ops := v.operations[*fingerprint]
|
2013-03-13 21:05:58 +00:00
|
|
|
ops = append(ops, &getValuesAtTimeOp{
|
2013-02-08 17:03:26 +00:00
|
|
|
time: time,
|
|
|
|
})
|
2013-06-25 12:02:27 +00:00
|
|
|
v.operations[*fingerprint] = ops
|
2013-02-08 17:03:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Gets for the given Fingerprint either the value at that interval from From
|
|
|
|
// through Through if there is an match or the one or two values adjacent
|
|
|
|
// for each point.
|
2013-05-07 12:25:01 +00:00
|
|
|
func (v *viewRequestBuilder) GetMetricAtInterval(fingerprint *clientmodel.Fingerprint, from, through time.Time, interval time.Duration) {
|
2013-06-25 12:02:27 +00:00
|
|
|
ops := v.operations[*fingerprint]
|
2013-03-13 21:05:58 +00:00
|
|
|
ops = append(ops, &getValuesAtIntervalOp{
|
2013-02-08 17:03:26 +00:00
|
|
|
from: from,
|
|
|
|
through: through,
|
|
|
|
interval: interval,
|
|
|
|
})
|
2013-06-25 12:02:27 +00:00
|
|
|
v.operations[*fingerprint] = ops
|
2013-02-08 17:03:26 +00:00
|
|
|
}
|
|
|
|
|
2013-05-07 12:25:01 +00:00
|
|
|
// Gets for the given Fingerprint the values that occur inclusively from From
|
|
|
|
// through Through.
|
|
|
|
func (v *viewRequestBuilder) GetMetricRange(fingerprint *clientmodel.Fingerprint, from, through time.Time) {
|
2013-06-25 12:02:27 +00:00
|
|
|
ops := v.operations[*fingerprint]
|
2013-03-13 21:05:58 +00:00
|
|
|
ops = append(ops, &getValuesAlongRangeOp{
|
2013-02-08 17:03:26 +00:00
|
|
|
from: from,
|
|
|
|
through: through,
|
|
|
|
})
|
2013-06-25 12:02:27 +00:00
|
|
|
v.operations[*fingerprint] = ops
|
2013-02-08 17:03:26 +00:00
|
|
|
}
|
|
|
|
|
2013-05-07 12:25:01 +00:00
|
|
|
// Gets value ranges at intervals for the given Fingerprint:
|
|
|
|
//
|
|
|
|
// |----| |----| |----| |----|
|
|
|
|
// ^ ^ ^ ^ ^ ^
|
|
|
|
// | \------------/ \----/ |
|
|
|
|
// from interval rangeDuration through
|
|
|
|
func (v *viewRequestBuilder) GetMetricRangeAtInterval(fingerprint *clientmodel.Fingerprint, from, through time.Time, interval, rangeDuration time.Duration) {
|
|
|
|
ops := v.operations[*fingerprint]
|
|
|
|
ops = append(ops, &getValueRangeAtIntervalOp{
|
|
|
|
rangeFrom: from,
|
|
|
|
rangeThrough: from.Add(rangeDuration),
|
|
|
|
rangeDuration: rangeDuration,
|
|
|
|
interval: interval,
|
|
|
|
through: through,
|
|
|
|
})
|
|
|
|
v.operations[*fingerprint] = ops
|
|
|
|
}
|
|
|
|
|
2013-02-08 17:03:26 +00:00
|
|
|
// Emits the optimized scans that will occur in the data store. This
|
|
|
|
// effectively resets the ViewRequestBuilder back to a pristine state.
|
2013-05-07 12:25:01 +00:00
|
|
|
func (v *viewRequestBuilder) ScanJobs() (j scanJobs) {
|
2013-02-08 17:03:26 +00:00
|
|
|
for fingerprint, operations := range v.operations {
|
2013-03-15 20:05:51 +00:00
|
|
|
sort.Sort(startsAtSort{operations})
|
2013-02-08 17:03:26 +00:00
|
|
|
|
2013-05-17 10:58:15 +00:00
|
|
|
fpCopy := fingerprint
|
2013-02-08 17:03:26 +00:00
|
|
|
j = append(j, scanJob{
|
2013-05-17 10:58:15 +00:00
|
|
|
fingerprint: &fpCopy,
|
2013-05-07 12:25:01 +00:00
|
|
|
// BUG: Evaluate whether we need to implement an optimize() working also
|
|
|
|
// for getValueRangeAtIntervalOp and use it here instead of just passing
|
|
|
|
// through the list of ops as-is.
|
|
|
|
operations: operations,
|
2013-02-08 17:03:26 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
delete(v.operations, fingerprint)
|
|
|
|
}
|
|
|
|
|
|
|
|
sort.Sort(j)
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
2013-03-07 01:16:39 +00:00
|
|
|
|
|
|
|
type view struct {
|
2013-05-16 14:02:07 +00:00
|
|
|
*memorySeriesStorage
|
2013-03-07 01:16:39 +00:00
|
|
|
}
|
|
|
|
|
2013-06-25 12:02:27 +00:00
|
|
|
func (v view) appendSamples(fingerprint *clientmodel.Fingerprint, samples Values) {
|
2013-05-28 12:36:03 +00:00
|
|
|
v.memorySeriesStorage.appendSamplesWithoutIndexing(fingerprint, samples)
|
2013-03-07 01:16:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func newView() view {
|
2013-06-06 16:16:22 +00:00
|
|
|
return view{NewMemorySeriesStorage(MemorySeriesOptions{})}
|
2013-03-07 01:16:39 +00:00
|
|
|
}
|