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:
Jan-Otto Kröpke
2026-10-10 16:59:55 +02:00
committed by GitHub
co-authored by Claude Opus 5.5
parent 025359921e
commit 3e013fe22b
2 changed files with 51 additions and 3 deletions
+20 -3
View File
@@ -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],
}
}
+31
View File
@@ -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)
}
}