diff --git a/storage/interface.go b/storage/interface.go index f5fd19df8..eb2b5975f 100644 --- a/storage/interface.go +++ b/storage/interface.go @@ -180,6 +180,14 @@ type Appender interface { ExemplarAppender } +// GetRef is an extra interface on Appenders used by downstream projects +// (e.g. Cortex) to avoid maintaining a parallel set of references. +type GetRef interface { + // Returns reference number that can be used to pass to Appender.Append(). + // 0 means the appender does not have a reference to this series. + GetRef(lset labels.Labels) uint64 +} + // ExemplarAppender provides an interface for adding samples to exemplar storage, which // within Prometheus is in-memory only. type ExemplarAppender interface { diff --git a/tsdb/db.go b/tsdb/db.go index 8d58f5c58..b8b3c9970 100644 --- a/tsdb/db.go +++ b/tsdb/db.go @@ -795,6 +795,15 @@ type dbAppender struct { db *DB } +var _ storage.GetRef = dbAppender{} + +func (a dbAppender) GetRef(lset labels.Labels) uint64 { + if g, ok := a.Appender.(storage.GetRef); ok { + return g.GetRef(lset) + } + return 0 +} + func (a dbAppender) Commit() error { err := a.Appender.Commit() diff --git a/tsdb/head.go b/tsdb/head.go index cad73e23a..4f4e8d51d 100644 --- a/tsdb/head.go +++ b/tsdb/head.go @@ -1107,6 +1107,15 @@ func (a *initAppender) AppendExemplar(ref uint64, l labels.Labels, e exemplar.Ex return a.app.AppendExemplar(ref, l, e) } +var _ storage.GetRef = &initAppender{} + +func (a *initAppender) GetRef(lset labels.Labels) uint64 { + if g, ok := a.app.(storage.GetRef); ok { + return g.GetRef(lset) + } + return 0 +} + func (a *initAppender) Commit() error { if a.app == nil { return nil @@ -1331,6 +1340,16 @@ func (a *headAppender) AppendExemplar(ref uint64, _ labels.Labels, e exemplar.Ex return s.ref, nil } +var _ storage.GetRef = &headAppender{} + +func (a *headAppender) GetRef(lset labels.Labels) uint64 { + s := a.head.series.getByHash(lset.Hash(), lset) + if s == nil { + return 0 + } + return s.ref +} + func (a *headAppender) log() error { if a.head.wal == nil { return nil