Don't reallocate label set if still known

If the storage deprecates a ref, we have to re-insert with the full
label set. Typically that doesn't correlate with a new series being
created.
We can still use the allocated label set from before.
This commit is contained in:
Fabian Reinartz 2017-06-26 08:56:40 +02:00
parent 2368d2c45b
commit 9ea748e745

View file

@ -428,8 +428,9 @@ type loop interface {
}
type lsetCacheEntry struct {
lset labels.Labels
hash uint64
metric string
lset labels.Labels
hash uint64
}
type refEntry struct {
@ -507,7 +508,10 @@ func (c *scrapeCache) getRef(met string) (string, bool) {
return e.ref, true
}
func (c *scrapeCache) addRef(met, ref string, lset labels.Labels) {
func (c *scrapeCache) addRef(met, ref string, lset labels.Labels, hash uint64) {
if ref == "" {
return
}
// Clean up the label set cache before overwriting the ref for a previously seen
// metric representation. It won't be caught by the cleanup in iterDone otherwise.
if e, ok := c.refs[met]; ok {
@ -517,12 +521,11 @@ func (c *scrapeCache) addRef(met, ref string, lset labels.Labels) {
// met is the raw string the metric was ingested as. The label set is not ordered
// and thus it's not suitable to uniquely identify cache entries.
// We store a hash over the label set instead.
c.lsets[ref] = &lsetCacheEntry{lset: lset, hash: lset.Hash()}
c.lsets[ref] = &lsetCacheEntry{metric: met, lset: lset, hash: hash}
}
func (c *scrapeCache) trackStaleness(ref string) {
e := c.lsets[ref]
c.seriesCur[e.hash] = e.lset
func (c *scrapeCache) trackStaleness(hash uint64, lset labels.Labels) {
c.seriesCur[hash] = lset
}
func (c *scrapeCache) forEachStale(f func(labels.Labels) bool) {
@ -742,7 +745,8 @@ loop:
switch err = app.AddFast(ref, t, v); err {
case nil:
if tp == nil {
sl.cache.trackStaleness(ref)
e := sl.cache.lsets[ref]
sl.cache.trackStaleness(e.hash, e.lset)
}
case storage.ErrNotFound:
ok = false
@ -768,8 +772,19 @@ loop:
}
}
if !ok {
var lset labels.Labels
mets := p.Metric(&lset)
var (
lset labels.Labels
mets string
hash uint64
)
if e, ok := sl.cache.lsets[ref]; ok {
mets = e.metric
lset = e.lset
hash = e.hash
} else {
mets = p.Metric(&lset)
hash = lset.Hash()
}
var ref string
ref, err = app.Add(lset, t, v)
@ -796,13 +811,11 @@ loop:
default:
break loop
}
sl.cache.addRef(mets, ref, lset)
if tp == nil {
// Bypass staleness logic if there is an explicit timestamp.
sl.cache.trackStaleness(ref)
sl.cache.trackStaleness(hash, lset)
}
sl.cache.addRef(mets, ref, lset, hash)
}
added++
}
@ -933,7 +946,7 @@ func (sl *scrapeLoop) addReportSample(app storage.Appender, s string, t int64, v
ref, err := app.Add(met, t, v)
switch err {
case nil:
sl.cache.addRef(s2, ref, met)
sl.cache.addRef(s2, ref, met, met.Hash())
return nil
case storage.ErrOutOfOrderSample, storage.ErrDuplicateSampleForTimestamp:
return nil