mirror of
https://github.com/prometheus/prometheus.git
synced 2024-12-26 06:04:05 -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
|
||||
// if the chunk is evicted. For safe concurrent access, this method requires the
|
||||
// fingerprint of the time series to be locked.
|
||||
// lastSamplePair returns the last sample pair of the underlying chunk, or
|
||||
// ZeroSampleValue if the chunk is evicted. For safe concurrent access, this
|
||||
// method requires the fingerprint of the time series to be locked.
|
||||
// TODO(beorn7): Move up into memorySeries.
|
||||
func (cd *chunkDesc) lastSamplePair() *model.SamplePair {
|
||||
func (cd *chunkDesc) lastSamplePair() model.SamplePair {
|
||||
cd.Lock()
|
||||
defer cd.Unlock()
|
||||
|
||||
if cd.c == nil {
|
||||
return nil
|
||||
return ZeroSamplePair
|
||||
}
|
||||
it := cd.c.newIterator()
|
||||
return &model.SamplePair{
|
||||
return model.SamplePair{
|
||||
Timestamp: it.lastTimestamp(),
|
||||
Value: it.lastSampleValue(),
|
||||
}
|
||||
|
@ -293,8 +293,7 @@ type chunkIterator interface {
|
|||
lastSampleValue() model.SampleValue
|
||||
// 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
|
||||
// applicable value exists, a SamplePair with timestamp model.Earliest
|
||||
// and value 0.0 is returned.
|
||||
// applicable value exists, ZeroSamplePair is returned.
|
||||
valueAtOrBeforeTime(model.Time) model.SamplePair
|
||||
// Gets all values contained within a given interval.
|
||||
rangeValues(metric.Interval) []model.SamplePair
|
||||
|
|
|
@ -307,7 +307,7 @@ func (it *deltaEncodedChunkIterator) valueAtOrBeforeTime(t model.Time) model.Sam
|
|||
return it.timestampAtIndex(i).After(t)
|
||||
})
|
||||
if i == 0 {
|
||||
return model.SamplePair{Timestamp: model.Earliest}
|
||||
return ZeroSamplePair
|
||||
}
|
||||
return model.SamplePair{
|
||||
Timestamp: it.timestampAtIndex(i - 1),
|
||||
|
|
|
@ -413,7 +413,7 @@ func (it *doubleDeltaEncodedChunkIterator) valueAtOrBeforeTime(t model.Time) mod
|
|||
return it.timestampAtIndex(i).After(t)
|
||||
})
|
||||
if i == 0 {
|
||||
return model.SamplePair{Timestamp: model.Earliest}
|
||||
return ZeroSamplePair
|
||||
}
|
||||
return model.SamplePair{
|
||||
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
|
||||
// match the empty string.
|
||||
MetricsForLabelMatchers(...*metric.LabelMatcher) map[model.Fingerprint]metric.Metric
|
||||
// LastSamplePairForFingerprint returns the last sample pair for the
|
||||
// provided fingerprint. If the respective time series does not exist or
|
||||
// has an evicted head chunk, nil is returned.
|
||||
LastSamplePairForFingerprint(model.Fingerprint) *model.SamplePair
|
||||
// LastSamplePairForFingerprint returns the last sample pair that has
|
||||
// been ingested for the provided fingerprint. If this instance of the
|
||||
// Storage has never ingested a sample for the provided fingerprint (or
|
||||
// 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.
|
||||
LabelValuesForLabelName(model.LabelName) model.LabelValues
|
||||
// Get the metric associated with the provided fingerprint.
|
||||
|
@ -73,8 +75,7 @@ type Storage interface {
|
|||
type SeriesIterator interface {
|
||||
// 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
|
||||
// applicable value exists, a SamplePair with timestamp model.Earliest
|
||||
// and value 0.0 is returned.
|
||||
// applicable value exists, ZeroSamplePair is returned.
|
||||
ValueAtOrBeforeTime(model.Time) model.SamplePair
|
||||
// Gets the boundary values of an interval: the first and last value
|
||||
// within a given interval.
|
||||
|
@ -94,3 +95,10 @@ type Preloader interface {
|
|||
// Close unpins any previously requested series data from memory.
|
||||
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 {
|
||||
return model.SamplePair{Timestamp: model.Earliest}
|
||||
return ZeroSamplePair
|
||||
}
|
||||
|
||||
// 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) {
|
||||
// Even the first chunk starts after t.
|
||||
return model.SamplePair{Timestamp: model.Earliest}
|
||||
return ZeroSamplePair
|
||||
}
|
||||
it.chunkIt = it.chunkIterator(l - i)
|
||||
return it.chunkIt.valueAtOrBeforeTime(t)
|
||||
|
@ -598,7 +598,7 @@ type nopSeriesIterator struct{}
|
|||
|
||||
// ValueAtTime implements SeriesIterator.
|
||||
func (i nopSeriesIterator) ValueAtOrBeforeTime(t model.Time) model.SamplePair {
|
||||
return model.SamplePair{Timestamp: model.Earliest}
|
||||
return ZeroSamplePair
|
||||
}
|
||||
|
||||
// BoundaryValues implements SeriesIterator.
|
||||
|
|
|
@ -346,13 +346,13 @@ func (s *memorySeriesStorage) WaitForIndexing() {
|
|||
}
|
||||
|
||||
// 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)
|
||||
defer s.fpLocker.Unlock(fp)
|
||||
|
||||
series, ok := s.fpToSeries.get(fp)
|
||||
if !ok {
|
||||
return nil
|
||||
return ZeroSamplePair
|
||||
}
|
||||
return series.head().lastSamplePair()
|
||||
}
|
||||
|
@ -367,7 +367,7 @@ type boundedIterator struct {
|
|||
// ValueAtOrBeforeTime implements the SeriesIterator interface.
|
||||
func (bit *boundedIterator) ValueAtOrBeforeTime(ts model.Time) model.SamplePair {
|
||||
if ts < bit.start {
|
||||
return model.SamplePair{Timestamp: model.Earliest}
|
||||
return ZeroSamplePair
|
||||
}
|
||||
return bit.it.ValueAtOrBeforeTime(ts)
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@ func (h *Handler) federation(w http.ResponseWriter, req *http.Request) {
|
|||
|
||||
sp := h.storage.LastSamplePairForFingerprint(fp)
|
||||
// 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
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue