140 lines
5.3 KiB
Go
140 lines
5.3 KiB
Go
// 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 (
|
|
"container/heap"
|
|
"time"
|
|
|
|
clientmodel "github.com/prometheus/client_golang/model"
|
|
)
|
|
|
|
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}
|
|
)
|
|
|
|
// ViewRequestBuilder represents the summation of all datastore queries that
|
|
// shall be performed to extract values. Call the Get... methods to record the
|
|
// queries. Once done, use HasOp and PopOp to retrieve the resulting
|
|
// operations. The operations are sorted by their fingerprint (and, for equal
|
|
// fingerprints, by the StartsAt timestamp of their operation).
|
|
type ViewRequestBuilder interface {
|
|
// GetMetricAtTime records a query to get, for the given Fingerprint,
|
|
// either the value at that time if there is a match or the one or two
|
|
// values adjacent thereto.
|
|
GetMetricAtTime(fingerprint *clientmodel.Fingerprint, time clientmodel.Timestamp)
|
|
// GetMetricAtInterval records a query to get, for the given
|
|
// Fingerprint, either the value at that interval from From through
|
|
// Through if there is a match or the one or two values adjacent for
|
|
// each point.
|
|
GetMetricAtInterval(fingerprint *clientmodel.Fingerprint, from, through clientmodel.Timestamp, interval time.Duration)
|
|
// GetMetricRange records a query to get, for the given Fingerprint, the
|
|
// values that occur inclusively from From through Through.
|
|
GetMetricRange(fingerprint *clientmodel.Fingerprint, from, through clientmodel.Timestamp)
|
|
// GetMetricRangeAtInterval records a query to get value ranges at
|
|
// intervals for the given Fingerprint:
|
|
//
|
|
// |----| |----| |----| |----|
|
|
// ^ ^ ^ ^ ^ ^
|
|
// | \------------/ \----/ |
|
|
// from interval rangeDuration through
|
|
GetMetricRangeAtInterval(fp *clientmodel.Fingerprint, from, through clientmodel.Timestamp, interval, rangeDuration time.Duration)
|
|
// PopOp emits the next operation in the queue (sorted by
|
|
// fingerprint). If called while HasOps returns false, the
|
|
// behavior is undefined.
|
|
PopOp() op
|
|
// HasOp returns true if there is at least one more operation in the
|
|
// queue.
|
|
HasOp() bool
|
|
}
|
|
|
|
// viewRequestBuilder contains the various requests for data.
|
|
type viewRequestBuilder struct {
|
|
operations ops
|
|
}
|
|
|
|
// NewViewRequestBuilder furnishes a ViewRequestBuilder for remarking what types
|
|
// of queries to perform.
|
|
func NewViewRequestBuilder() *viewRequestBuilder {
|
|
return &viewRequestBuilder{}
|
|
}
|
|
|
|
var getValuesAtTimes = newValueAtTimeList(10 * 1024)
|
|
|
|
// GetMetricAtTime implements ViewRequestBuilder.
|
|
func (v *viewRequestBuilder) GetMetricAtTime(fp *clientmodel.Fingerprint, time clientmodel.Timestamp) {
|
|
heap.Push(&v.operations, getValuesAtTimes.Get(fp, time))
|
|
}
|
|
|
|
var getValuesAtIntervals = newValueAtIntervalList(10 * 1024)
|
|
|
|
// GetMetricAtInterval implements ViewRequestBuilder.
|
|
func (v *viewRequestBuilder) GetMetricAtInterval(fp *clientmodel.Fingerprint, from, through clientmodel.Timestamp, interval time.Duration) {
|
|
heap.Push(&v.operations, getValuesAtIntervals.Get(fp, from, through, interval))
|
|
}
|
|
|
|
var getValuesAlongRanges = newValueAlongRangeList(10 * 1024)
|
|
|
|
// GetMetricRange implements ViewRequestBuilder.
|
|
func (v *viewRequestBuilder) GetMetricRange(fp *clientmodel.Fingerprint, from, through clientmodel.Timestamp) {
|
|
heap.Push(&v.operations, getValuesAlongRanges.Get(fp, from, through))
|
|
}
|
|
|
|
var getValuesAtIntervalAlongRanges = newValueAtIntervalAlongRangeList(10 * 1024)
|
|
|
|
// GetMetricRangeAtInterval implements ViewRequestBuilder.
|
|
func (v *viewRequestBuilder) GetMetricRangeAtInterval(fp *clientmodel.Fingerprint, from, through clientmodel.Timestamp, interval, rangeDuration time.Duration) {
|
|
heap.Push(&v.operations, getValuesAtIntervalAlongRanges.Get(fp, from, through, interval, rangeDuration))
|
|
}
|
|
|
|
// PopOp implements ViewRequestBuilder.
|
|
func (v *viewRequestBuilder) PopOp() op {
|
|
return heap.Pop(&v.operations).(op)
|
|
}
|
|
|
|
// HasOp implements ViewRequestBuilder.
|
|
func (v *viewRequestBuilder) HasOp() bool {
|
|
return v.operations.Len() > 0
|
|
}
|
|
|
|
type view struct {
|
|
*memorySeriesStorage
|
|
}
|
|
|
|
func (v view) appendSamples(fingerprint *clientmodel.Fingerprint, samples Values) {
|
|
v.memorySeriesStorage.appendSamplesWithoutIndexing(fingerprint, samples)
|
|
}
|
|
|
|
func newView() view {
|
|
return view{NewMemorySeriesStorage(MemorySeriesOptions{})}
|
|
}
|
|
|
|
func giveBackOp(op interface{}) bool {
|
|
switch v := op.(type) {
|
|
case *getValuesAtTimeOp:
|
|
return getValuesAtTimes.Give(v)
|
|
case *getValuesAtIntervalOp:
|
|
return getValuesAtIntervals.Give(v)
|
|
case *getValuesAlongRangeOp:
|
|
return getValuesAlongRanges.Give(v)
|
|
case *getValueRangeAtIntervalOp:
|
|
return getValuesAtIntervalAlongRanges.Give(v)
|
|
default:
|
|
panic("unrecognized operation")
|
|
}
|
|
}
|