mirror of
https://github.com/prometheus-community/windows_exporter.git
synced 2026-10-17 10:09:05 +02:00
pdh: reuse the row maps between samples (#2654)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
025359921e
commit
3e013fe22b
@@ -429,6 +429,12 @@ type collectState struct {
|
||||
valid []bool
|
||||
|
||||
names instanceNameCache
|
||||
|
||||
// index, occurrences and seen back the maps of rowSet. They are cleared
|
||||
// for every sample, so their buckets are not allocated again.
|
||||
index map[instanceKey]int
|
||||
occurrences map[string]int
|
||||
seen map[string]int
|
||||
}
|
||||
|
||||
// collect replaces the content of dst with one sample.
|
||||
@@ -581,13 +587,24 @@ type rowSet[T any] struct {
|
||||
func newRowSet[T any](c *Collector[T], dst *[]T, state *collectState) rowSet[T] {
|
||||
state.names.startSample()
|
||||
|
||||
if state.index == nil {
|
||||
state.index = map[instanceKey]int{}
|
||||
state.occurrences = map[string]int{}
|
||||
state.seen = map[string]int{}
|
||||
} else {
|
||||
// A failed sample can leave entries behind.
|
||||
clear(state.index)
|
||||
clear(state.occurrences)
|
||||
clear(state.seen)
|
||||
}
|
||||
|
||||
return rowSet[T]{
|
||||
c: c,
|
||||
dst: dst,
|
||||
index: map[instanceKey]int{},
|
||||
index: state.index,
|
||||
nameCache: &state.names,
|
||||
occurrences: map[string]int{},
|
||||
seen: map[string]int{},
|
||||
occurrences: state.occurrences,
|
||||
seen: state.seen,
|
||||
valid: state.valid[:0],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -482,3 +482,34 @@ func TestInstanceNameCache(t *testing.T) {
|
||||
require.Len(t, cache.names, 1, "name of a vanished instance kept")
|
||||
require.Contains(t, cache.names, "a\x00", "keyed by the UTF-16LE content")
|
||||
}
|
||||
|
||||
// TestRowSetReusesState checks that a sample does not see the instances of an
|
||||
// earlier sample that shared its state, even if that sample did not finish.
|
||||
func TestRowSetReusesState(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
c := newRowSetTestCollector(false)
|
||||
c.counters[1].FieldIndexSecondValue = -1
|
||||
state := &collectState{}
|
||||
|
||||
var dst []rowSetValues
|
||||
|
||||
// A sample that fails after its first counter array.
|
||||
rows := newRowSet(c, &dst, state)
|
||||
addDuplicateTestItems(&rows, CounterTypeRaw, 0, []string{"a", "a", "b"}, []float64{1, 2, 3})
|
||||
|
||||
for range 2 {
|
||||
dst = nil
|
||||
rows = newRowSet(c, &dst, state)
|
||||
addDuplicateTestItems(&rows, CounterTypeRaw, 0, []string{"b", "c"}, []float64{4, 5})
|
||||
addDuplicateTestItems(&rows, CounterTypeRaw, 1, []string{"b", "c"}, []float64{6, 7})
|
||||
rows.finish()
|
||||
|
||||
state.valid = rows.valid
|
||||
|
||||
require.Equal(t, []rowSetValues{
|
||||
{Name: "b", A: 4, B: 6},
|
||||
{Name: "c", A: 5, B: 7},
|
||||
}, dst)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user