Skip to content

Commit e291c99

Browse files
committed
Implement recursive cumulative dedup in table view
1 parent ca267f0 commit e291c99

File tree

1 file changed

+29
-6
lines changed

1 file changed

+29
-6
lines changed

pkg/query/table.go

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,10 @@ func generateTableArrowRecord(
135135

136136
for sampleRow := 0; sampleRow < int(r.Record.NumRows()); sampleRow++ {
137137
previousTableRow := -1
138+
// Track which table rows have been counted for this sample to avoid
139+
// double-counting cumulative values for recursive functions.
140+
seenInSample := make(map[int]struct{})
141+
138142
lOffsetStart, lOffsetEnd := r.Locations.ValueOffsets(sampleRow)
139143
for locationRow := int(lOffsetStart); locationRow < int(lOffsetEnd); locationRow++ {
140144
if r.Locations.ListValues().IsNull(locationRow) {
@@ -164,10 +168,17 @@ func generateTableArrowRecord(
164168
} else {
165169
tb.addresses[string(buildID)][addr] = tableRow
166170
}
171+
seenInSample[tableRow] = struct{}{}
167172
previousTableRow = tableRow
168173
tableRow++
169174
} else {
170-
tb.mergeRow(r, cr, sampleRow, locationRow, -1, tb.addresses[unsafeString(buildID)][addr], previousTableRow, isLeaf)
175+
// Only add to cumulative if this is the first occurrence in this sample
176+
_, alreadySeen := seenInSample[cr]
177+
addCumulative := !alreadySeen
178+
if addCumulative {
179+
seenInSample[cr] = struct{}{}
180+
}
181+
tb.mergeRow(r, cr, sampleRow, locationRow, -1, tb.addresses[unsafeString(buildID)][addr], previousTableRow, isLeaf, addCumulative)
171182
previousTableRow = tb.addresses[unsafeString(buildID)][addr]
172183
}
173184
} else {
@@ -184,10 +195,17 @@ func generateTableArrowRecord(
184195
return nil, 0, err
185196
}
186197
tb.functions[string(fn)] = tableRow
198+
seenInSample[tableRow] = struct{}{}
187199
previousTableRow = tableRow
188200
tableRow++
189201
} else {
190-
tb.mergeRow(r, cr, sampleRow, locationRow, lineRow, tb.functions[unsafeString(fn)], previousTableRow, isLeaf)
202+
// Only add to cumulative if this is the first occurrence in this sample
203+
_, alreadySeen := seenInSample[cr]
204+
addCumulative := !alreadySeen
205+
if addCumulative {
206+
seenInSample[cr] = struct{}{}
207+
}
208+
tb.mergeRow(r, cr, sampleRow, locationRow, lineRow, tb.functions[unsafeString(fn)], previousTableRow, isLeaf, addCumulative)
191209
previousTableRow = tb.functions[unsafeString(fn)]
192210
}
193211
}
@@ -432,10 +450,15 @@ func (tb *tableBuilder) appendRow(
432450
return nil
433451
}
434452

435-
func (tb *tableBuilder) mergeRow(r *profile.RecordReader, mergeRow, sampleRow, _, lineRow, currentTableRow, previousTableRow int, isLeaf bool) {
436-
tb.builderCumulative.Add(mergeRow, r.Value.Value(sampleRow))
437-
if r.Diff.Value(sampleRow) != 0 {
438-
tb.builderCumulativeDiff.Add(mergeRow, r.Diff.Value(sampleRow))
453+
// mergeRow merges sample data into an existing table row.
454+
// If addCumulative is false, only caller/callee relationships and flat values (if leaf) are updated.
455+
// This is used to avoid double-counting cumulative values for recursive functions.
456+
func (tb *tableBuilder) mergeRow(r *profile.RecordReader, mergeRow, sampleRow, _, lineRow, currentTableRow, previousTableRow int, isLeaf, addCumulative bool) {
457+
if addCumulative {
458+
tb.builderCumulative.Add(mergeRow, r.Value.Value(sampleRow))
459+
if r.Diff.Value(sampleRow) != 0 {
460+
tb.builderCumulativeDiff.Add(mergeRow, r.Diff.Value(sampleRow))
461+
}
439462
}
440463

441464
if isLeaf {

0 commit comments

Comments
 (0)