back out changes to intern.go in case anyone else is importing that
Some checks failed
CI / Go tests (push) Has been cancelled
CI / More Go tests (push) Has been cancelled
CI / Go tests with previous Go version (push) Has been cancelled
CI / UI tests (push) Has been cancelled
CI / Go tests on Windows (push) Has been cancelled
CI / Mixins tests (push) Has been cancelled
CI / Build Prometheus for common architectures (0) (push) Has been cancelled
CI / Build Prometheus for common architectures (1) (push) Has been cancelled
CI / Build Prometheus for common architectures (2) (push) Has been cancelled
CI / Build Prometheus for all architectures (0) (push) Has been cancelled
CI / Build Prometheus for all architectures (1) (push) Has been cancelled
CI / Build Prometheus for all architectures (10) (push) Has been cancelled
CI / Build Prometheus for all architectures (11) (push) Has been cancelled
CI / Build Prometheus for all architectures (2) (push) Has been cancelled
CI / Build Prometheus for all architectures (3) (push) Has been cancelled
CI / Build Prometheus for all architectures (4) (push) Has been cancelled
CI / Build Prometheus for all architectures (5) (push) Has been cancelled
CI / Build Prometheus for all architectures (6) (push) Has been cancelled
CI / Build Prometheus for all architectures (7) (push) Has been cancelled
CI / Build Prometheus for all architectures (8) (push) Has been cancelled
CI / Build Prometheus for all architectures (9) (push) Has been cancelled
CI / Check generated parser (push) Has been cancelled
CI / golangci-lint (push) Has been cancelled
CI / fuzzing (push) Has been cancelled
CI / codeql (push) Has been cancelled
CI / Report status of build Prometheus for all architectures (push) Has been cancelled
CI / Publish main branch artifacts (push) Has been cancelled
CI / Publish release artefacts (push) Has been cancelled
CI / Publish UI on npm Registry (push) Has been cancelled

package

Signed-off-by: Callum Styan <callumstyan@gmail.com>
This commit is contained in:
Callum Styan 2024-08-28 13:08:12 -07:00
parent d8db139a36
commit 9f3d25f959
2 changed files with 56 additions and 81 deletions

View file

@ -23,8 +23,6 @@ import (
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/client_golang/prometheus/promauto"
"github.com/prometheus/prometheus/model/labels"
"github.com/prometheus/prometheus/tsdb/chunks"
"go.uber.org/atomic" "go.uber.org/atomic"
) )
@ -36,33 +34,53 @@ var noReferenceReleases = promauto.NewCounter(prometheus.CounterOpts{
}) })
type pool struct { type pool struct {
mtx sync.RWMutex mtx sync.RWMutex
pool map[chunks.HeadSeriesRef]*entry pool map[string]*entry
shouldIntern bool
} }
type entry struct { type entry struct {
refs atomic.Int64 refs atomic.Int64
lset labels.Labels
s string
} }
func newEntry(lset labels.Labels) *entry { func newEntry(s string) *entry {
return &entry{lset: lset} return &entry{s: s}
} }
func newPool(shouldIntern bool) *pool { func newPool() *pool {
return &pool{ return &pool{
pool: map[chunks.HeadSeriesRef]*entry{}, pool: map[string]*entry{},
shouldIntern: shouldIntern,
} }
} }
func (p *pool) release(ref chunks.HeadSeriesRef) { func (p *pool) intern(s string) string {
if !p.shouldIntern { if s == "" {
return return ""
} }
p.mtx.RLock() p.mtx.RLock()
interned, ok := p.pool[ref] interned, ok := p.pool[s]
p.mtx.RUnlock()
if ok {
interned.refs.Inc()
return interned.s
}
p.mtx.Lock()
defer p.mtx.Unlock()
if interned, ok := p.pool[s]; ok {
interned.refs.Inc()
return interned.s
}
p.pool[s] = newEntry(s)
p.pool[s].refs.Store(1)
return s
}
func (p *pool) release(s string) {
p.mtx.RLock()
interned, ok := p.pool[s]
p.mtx.RUnlock() p.mtx.RUnlock()
if !ok { if !ok {
@ -80,33 +98,5 @@ func (p *pool) release(ref chunks.HeadSeriesRef) {
if interned.refs.Load() != 0 { if interned.refs.Load() != 0 {
return return
} }
delete(p.pool, ref) delete(p.pool, s)
}
func (p *pool) intern(ref chunks.HeadSeriesRef, lset labels.Labels) labels.Labels {
if !p.shouldIntern {
return lset
}
p.mtx.RLock()
interned, ok := p.pool[ref]
p.mtx.RUnlock()
if ok {
interned.refs.Inc()
return interned.lset
}
p.mtx.Lock()
defer p.mtx.Unlock()
if interned, ok := p.pool[ref]; ok {
interned.refs.Inc()
return interned.lset
}
if lset.Len() == 0 {
return labels.EmptyLabels()
}
p.pool[ref] = newEntry(lset)
p.pool[ref].refs.Store(1)
return p.pool[ref].lset
} }

View file

@ -24,82 +24,67 @@ import (
"time" "time"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/prometheus/prometheus/model/labels"
"github.com/prometheus/prometheus/tsdb/chunks"
) )
func TestIntern(t *testing.T) { func TestIntern(t *testing.T) {
interner := newPool(true) interner := newPool()
testString := "TestIntern_DeleteRef" testString := "TestIntern"
ref := chunks.HeadSeriesRef(1234) interner.intern(testString)
interned, ok := interner.pool[testString]
lset := labels.FromStrings("name", testString)
interner.intern(ref, lset)
interned, ok := interner.pool[ref]
require.True(t, ok) require.True(t, ok)
require.Equal(t, lset, interned.lset)
require.Equal(t, int64(1), interned.refs.Load(), fmt.Sprintf("expected refs to be 1 but it was %d", interned.refs.Load())) require.Equal(t, int64(1), interned.refs.Load(), fmt.Sprintf("expected refs to be 1 but it was %d", interned.refs.Load()))
} }
func TestIntern_MultiRef(t *testing.T) { func TestIntern_MultiRef(t *testing.T) {
interner := newPool(true) interner := newPool()
testString := "TestIntern_DeleteRef" testString := "TestIntern_MultiRef"
ref := chunks.HeadSeriesRef(1234)
lset := labels.FromStrings("name", testString) interner.intern(testString)
interner.intern(ref, lset) interned, ok := interner.pool[testString]
interned, ok := interner.pool[ref]
require.True(t, ok) require.True(t, ok)
require.Equal(t, lset, interned.lset)
require.Equal(t, int64(1), interned.refs.Load(), fmt.Sprintf("expected refs to be 1 but it was %d", interned.refs.Load())) require.Equal(t, int64(1), interned.refs.Load(), fmt.Sprintf("expected refs to be 1 but it was %d", interned.refs.Load()))
interner.intern(ref, lset) interner.intern(testString)
interned, ok = interner.pool[ref] interned, ok = interner.pool[testString]
require.True(t, ok) require.True(t, ok)
require.NotNil(t, interned)
require.Equal(t, int64(2), interned.refs.Load(), fmt.Sprintf("expected refs to be 2 but it was %d", interned.refs.Load())) require.Equal(t, int64(2), interned.refs.Load(), fmt.Sprintf("expected refs to be 2 but it was %d", interned.refs.Load()))
} }
func TestIntern_DeleteRef(t *testing.T) { func TestIntern_DeleteRef(t *testing.T) {
interner := newPool(true) interner := newPool()
testString := "TestIntern_DeleteRef" testString := "TestIntern_DeleteRef"
ref := chunks.HeadSeriesRef(1234)
interner.intern(ref, labels.FromStrings("name", testString))
interned, ok := interner.pool[ref]
require.NotNil(t, interned) interner.intern(testString)
interned, ok := interner.pool[testString]
require.True(t, ok) require.True(t, ok)
require.Equal(t, int64(1), interned.refs.Load(), fmt.Sprintf("expected refs to be 1 but it was %d", interned.refs.Load())) require.Equal(t, int64(1), interned.refs.Load(), fmt.Sprintf("expected refs to be 1 but it was %d", interned.refs.Load()))
interner.release(ref) interner.release(testString)
_, ok = interner.pool[ref] _, ok = interner.pool[testString]
require.False(t, ok) require.False(t, ok)
} }
func TestIntern_MultiRef_Concurrent(t *testing.T) { func TestIntern_MultiRef_Concurrent(t *testing.T) {
interner := newPool(true) interner := newPool()
testString := "TestIntern_MultiRef_Concurrent" testString := "TestIntern_MultiRef_Concurrent"
ref := chunks.HeadSeriesRef(1234)
interner.intern(ref, labels.FromStrings("name", testString)) interner.intern(testString)
interned, ok := interner.pool[ref] interned, ok := interner.pool[testString]
require.NotNil(t, interned)
require.True(t, ok) require.True(t, ok)
require.Equal(t, int64(1), interned.refs.Load(), fmt.Sprintf("expected refs to be 1 but it was %d", interned.refs.Load())) require.Equal(t, int64(1), interned.refs.Load(), fmt.Sprintf("expected refs to be 1 but it was %d", interned.refs.Load()))
go interner.release(ref) go interner.release(testString)
interner.intern(ref, labels.FromStrings("name", testString)) interner.intern(testString)
time.Sleep(time.Millisecond) time.Sleep(time.Millisecond)
interner.mtx.RLock() interner.mtx.RLock()
interned, ok = interner.pool[ref] interned, ok = interner.pool[testString]
interner.mtx.RUnlock() interner.mtx.RUnlock()
require.True(t, ok) require.True(t, ok)
require.Equal(t, int64(1), interned.refs.Load(), fmt.Sprintf("expected refs to be 1 but it was %d", interned.refs.Load())) require.Equal(t, int64(1), interned.refs.Load(), fmt.Sprintf("expected refs to be 1 but it was %d", interned.refs.Load()))