mirror of
https://github.com/prometheus/prometheus.git
synced 2024-12-27 06:29:42 -08:00
Return SamplePair istead of *SamplePair consistently
Formalize ZeroSamplePair as return value for non-existing samples. Change LastSamplePairForFingerprint to return a SamplePair (and not a pointer to it), which saves allocations in a potentially extremely frequent call.
This commit is contained in:
parent
d290340367
commit
1e13f89039
|
@ -194,19 +194,19 @@ func (cd *chunkDesc) maybePopulateLastTime() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// lastSamplePair returns the last sample pair of the underlying chunk, or nil
|
// lastSamplePair returns the last sample pair of the underlying chunk, or
|
||||||
// if the chunk is evicted. For safe concurrent access, this method requires the
|
// ZeroSampleValue if the chunk is evicted. For safe concurrent access, this
|
||||||
// fingerprint of the time series to be locked.
|
// method requires the fingerprint of the time series to be locked.
|
||||||
// TODO(beorn7): Move up into memorySeries.
|
// TODO(beorn7): Move up into memorySeries.
|
||||||
func (cd *chunkDesc) lastSamplePair() *model.SamplePair {
|
func (cd *chunkDesc) lastSamplePair() model.SamplePair {
|
||||||
cd.Lock()
|
cd.Lock()
|
||||||
defer cd.Unlock()
|
defer cd.Unlock()
|
||||||
|
|
||||||
if cd.c == nil {
|
if cd.c == nil {
|
||||||
return nil
|
return ZeroSamplePair
|
||||||
}
|
}
|
||||||
it := cd.c.newIterator()
|
it := cd.c.newIterator()
|
||||||
return &model.SamplePair{
|
return model.SamplePair{
|
||||||
Timestamp: it.lastTimestamp(),
|
Timestamp: it.lastTimestamp(),
|
||||||
Value: it.lastSampleValue(),
|
Value: it.lastSampleValue(),
|
||||||
}
|
}
|
||||||
|
@ -293,8 +293,7 @@ type chunkIterator interface {
|
||||||
lastSampleValue() model.SampleValue
|
lastSampleValue() model.SampleValue
|
||||||
// Gets the value that is closest before the given time. In case a value
|
// Gets the value that is closest before the given time. In case a value
|
||||||
// exist at precisely the given time, that value is returned. If no
|
// exist at precisely the given time, that value is returned. If no
|
||||||
// applicable value exists, a SamplePair with timestamp model.Earliest
|
// applicable value exists, ZeroSamplePair is returned.
|
||||||
// and value 0.0 is returned.
|
|
||||||
valueAtOrBeforeTime(model.Time) model.SamplePair
|
valueAtOrBeforeTime(model.Time) model.SamplePair
|
||||||
// Gets all values contained within a given interval.
|
// Gets all values contained within a given interval.
|
||||||
rangeValues(metric.Interval) []model.SamplePair
|
rangeValues(metric.Interval) []model.SamplePair
|
||||||
|
|
|
@ -307,7 +307,7 @@ func (it *deltaEncodedChunkIterator) valueAtOrBeforeTime(t model.Time) model.Sam
|
||||||
return it.timestampAtIndex(i).After(t)
|
return it.timestampAtIndex(i).After(t)
|
||||||
})
|
})
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
return model.SamplePair{Timestamp: model.Earliest}
|
return ZeroSamplePair
|
||||||
}
|
}
|
||||||
return model.SamplePair{
|
return model.SamplePair{
|
||||||
Timestamp: it.timestampAtIndex(i - 1),
|
Timestamp: it.timestampAtIndex(i - 1),
|
||||||
|
|
|
@ -413,7 +413,7 @@ func (it *doubleDeltaEncodedChunkIterator) valueAtOrBeforeTime(t model.Time) mod
|
||||||
return it.timestampAtIndex(i).After(t)
|
return it.timestampAtIndex(i).After(t)
|
||||||
})
|
})
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
return model.SamplePair{Timestamp: model.Earliest}
|
return ZeroSamplePair
|
||||||
}
|
}
|
||||||
return model.SamplePair{
|
return model.SamplePair{
|
||||||
Timestamp: it.timestampAtIndex(i - 1),
|
Timestamp: it.timestampAtIndex(i - 1),
|
||||||
|
|
|
@ -42,10 +42,12 @@ type Storage interface {
|
||||||
// label matchers. At least one label matcher must be specified that does not
|
// label matchers. At least one label matcher must be specified that does not
|
||||||
// match the empty string.
|
// match the empty string.
|
||||||
MetricsForLabelMatchers(...*metric.LabelMatcher) map[model.Fingerprint]metric.Metric
|
MetricsForLabelMatchers(...*metric.LabelMatcher) map[model.Fingerprint]metric.Metric
|
||||||
// LastSamplePairForFingerprint returns the last sample pair for the
|
// LastSamplePairForFingerprint returns the last sample pair that has
|
||||||
// provided fingerprint. If the respective time series does not exist or
|
// been ingested for the provided fingerprint. If this instance of the
|
||||||
// has an evicted head chunk, nil is returned.
|
// Storage has never ingested a sample for the provided fingerprint (or
|
||||||
LastSamplePairForFingerprint(model.Fingerprint) *model.SamplePair
|
// the last ingestion is so long ago that the series has been archived),
|
||||||
|
// ZeroSamplePair is returned.
|
||||||
|
LastSamplePairForFingerprint(model.Fingerprint) model.SamplePair
|
||||||
// Get all of the label values that are associated with a given label name.
|
// Get all of the label values that are associated with a given label name.
|
||||||
LabelValuesForLabelName(model.LabelName) model.LabelValues
|
LabelValuesForLabelName(model.LabelName) model.LabelValues
|
||||||
// Get the metric associated with the provided fingerprint.
|
// Get the metric associated with the provided fingerprint.
|
||||||
|
@ -73,8 +75,7 @@ type Storage interface {
|
||||||
type SeriesIterator interface {
|
type SeriesIterator interface {
|
||||||
// Gets the value that is closest before the given time. In case a value
|
// Gets the value that is closest before the given time. In case a value
|
||||||
// exist at precisely the given time, that value is returned. If no
|
// exist at precisely the given time, that value is returned. If no
|
||||||
// applicable value exists, a SamplePair with timestamp model.Earliest
|
// applicable value exists, ZeroSamplePair is returned.
|
||||||
// and value 0.0 is returned.
|
|
||||||
ValueAtOrBeforeTime(model.Time) model.SamplePair
|
ValueAtOrBeforeTime(model.Time) model.SamplePair
|
||||||
// Gets the boundary values of an interval: the first and last value
|
// Gets the boundary values of an interval: the first and last value
|
||||||
// within a given interval.
|
// within a given interval.
|
||||||
|
@ -94,3 +95,10 @@ type Preloader interface {
|
||||||
// Close unpins any previously requested series data from memory.
|
// Close unpins any previously requested series data from memory.
|
||||||
Close()
|
Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ZeroSamplePair is the pseudo zero-value of model.SamplePair used by the local
|
||||||
|
// package to signal a non-existing sample. It is a SamplePair with timestamp
|
||||||
|
// model.Earliest and value 0.0. Note that the natural zero value of SamplePair
|
||||||
|
// has a timestamp of 0, which is possible to appear in a real SamplePair and
|
||||||
|
// thus not suitable to signal a non-existing SamplePair.
|
||||||
|
var ZeroSamplePair = model.SamplePair{Timestamp: model.Earliest}
|
||||||
|
|
|
@ -479,7 +479,7 @@ func (it *memorySeriesIterator) ValueAtOrBeforeTime(t model.Time) model.SamplePa
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(it.chunks) == 0 {
|
if len(it.chunks) == 0 {
|
||||||
return model.SamplePair{Timestamp: model.Earliest}
|
return ZeroSamplePair
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the last chunk where firstTime() is before or equal to t.
|
// Find the last chunk where firstTime() is before or equal to t.
|
||||||
|
@ -489,7 +489,7 @@ func (it *memorySeriesIterator) ValueAtOrBeforeTime(t model.Time) model.SamplePa
|
||||||
})
|
})
|
||||||
if i == len(it.chunks) {
|
if i == len(it.chunks) {
|
||||||
// Even the first chunk starts after t.
|
// Even the first chunk starts after t.
|
||||||
return model.SamplePair{Timestamp: model.Earliest}
|
return ZeroSamplePair
|
||||||
}
|
}
|
||||||
it.chunkIt = it.chunkIterator(l - i)
|
it.chunkIt = it.chunkIterator(l - i)
|
||||||
return it.chunkIt.valueAtOrBeforeTime(t)
|
return it.chunkIt.valueAtOrBeforeTime(t)
|
||||||
|
@ -598,7 +598,7 @@ type nopSeriesIterator struct{}
|
||||||
|
|
||||||
// ValueAtTime implements SeriesIterator.
|
// ValueAtTime implements SeriesIterator.
|
||||||
func (i nopSeriesIterator) ValueAtOrBeforeTime(t model.Time) model.SamplePair {
|
func (i nopSeriesIterator) ValueAtOrBeforeTime(t model.Time) model.SamplePair {
|
||||||
return model.SamplePair{Timestamp: model.Earliest}
|
return ZeroSamplePair
|
||||||
}
|
}
|
||||||
|
|
||||||
// BoundaryValues implements SeriesIterator.
|
// BoundaryValues implements SeriesIterator.
|
||||||
|
|
|
@ -346,13 +346,13 @@ func (s *memorySeriesStorage) WaitForIndexing() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// LastSampleForFingerprint implements Storage.
|
// LastSampleForFingerprint implements Storage.
|
||||||
func (s *memorySeriesStorage) LastSamplePairForFingerprint(fp model.Fingerprint) *model.SamplePair {
|
func (s *memorySeriesStorage) LastSamplePairForFingerprint(fp model.Fingerprint) model.SamplePair {
|
||||||
s.fpLocker.Lock(fp)
|
s.fpLocker.Lock(fp)
|
||||||
defer s.fpLocker.Unlock(fp)
|
defer s.fpLocker.Unlock(fp)
|
||||||
|
|
||||||
series, ok := s.fpToSeries.get(fp)
|
series, ok := s.fpToSeries.get(fp)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil
|
return ZeroSamplePair
|
||||||
}
|
}
|
||||||
return series.head().lastSamplePair()
|
return series.head().lastSamplePair()
|
||||||
}
|
}
|
||||||
|
@ -367,7 +367,7 @@ type boundedIterator struct {
|
||||||
// ValueAtOrBeforeTime implements the SeriesIterator interface.
|
// ValueAtOrBeforeTime implements the SeriesIterator interface.
|
||||||
func (bit *boundedIterator) ValueAtOrBeforeTime(ts model.Time) model.SamplePair {
|
func (bit *boundedIterator) ValueAtOrBeforeTime(ts model.Time) model.SamplePair {
|
||||||
if ts < bit.start {
|
if ts < bit.start {
|
||||||
return model.SamplePair{Timestamp: model.Earliest}
|
return ZeroSamplePair
|
||||||
}
|
}
|
||||||
return bit.it.ValueAtOrBeforeTime(ts)
|
return bit.it.ValueAtOrBeforeTime(ts)
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,7 @@ func (h *Handler) federation(w http.ResponseWriter, req *http.Request) {
|
||||||
|
|
||||||
sp := h.storage.LastSamplePairForFingerprint(fp)
|
sp := h.storage.LastSamplePairForFingerprint(fp)
|
||||||
// Discard if sample does not exist or lays before the staleness interval.
|
// Discard if sample does not exist or lays before the staleness interval.
|
||||||
if sp == nil || sp.Timestamp.Before(minTimestamp) {
|
if sp.Timestamp.Before(minTimestamp) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue