MCPcopy
hub / github.com/grafana/tempo / combineSearchResults

Function combineSearchResults

pkg/traceql/combine.go:231–293  ·  view source on GitHub ↗

combineSearchResults overlays the incoming search result with the existing result. This is required for the following reason: a trace may be present in multiple blocks, or in partial segments in live traces. The results should reflect elements of all segments.

(existing *tempopb.TraceSearchMetadata, incoming *tempopb.TraceSearchMetadata)

Source from the content-addressed store, hash-verified

229// for the following reason: a trace may be present in multiple blocks, or in partial segments
230// in live traces. The results should reflect elements of all segments.
231func combineSearchResults(existing *tempopb.TraceSearchMetadata, incoming *tempopb.TraceSearchMetadata) {
232 if existing.TraceID == "" {
233 existing.TraceID = incoming.TraceID
234 }
235
236 if existing.RootServiceName == "" {
237 existing.RootServiceName = incoming.RootServiceName
238 }
239
240 if existing.RootTraceName == "" {
241 existing.RootTraceName = incoming.RootTraceName
242 }
243
244 // Earliest start time.
245 if existing.StartTimeUnixNano > incoming.StartTimeUnixNano || existing.StartTimeUnixNano == 0 {
246 existing.StartTimeUnixNano = incoming.StartTimeUnixNano
247 }
248
249 // Longest duration
250 if existing.DurationMs < incoming.DurationMs || existing.DurationMs == 0 {
251 existing.DurationMs = incoming.DurationMs
252 }
253
254 // Combine service stats
255 // It's possible to find multiple trace fragments that satisfy a TraceQL result,
256 // therefore we use max() to merge the ServiceStats.
257 for service, incomingStats := range incoming.ServiceStats {
258 existingStats, ok := existing.ServiceStats[service]
259 if !ok {
260 existingStats = &tempopb.ServiceStats{}
261 if existing.ServiceStats == nil {
262 existing.ServiceStats = make(map[string]*tempopb.ServiceStats)
263 }
264 existing.ServiceStats[service] = existingStats
265 }
266 existingStats.SpanCount = max(existingStats.SpanCount, incomingStats.SpanCount)
267 existingStats.ErrorCount = max(existingStats.ErrorCount, incomingStats.ErrorCount)
268 }
269
270 // make a map of existing Spansets
271 existingSS := make(map[string]*tempopb.SpanSet)
272 for _, ss := range existing.SpanSets {
273 existingSS[spansetID(ss)] = ss
274 }
275
276 // add any new spansets
277 for _, ss := range incoming.SpanSets {
278 id := spansetID(ss)
279 // if not found just add directly
280 if _, ok := existingSS[id]; !ok {
281 existing.SpanSets = append(existing.SpanSets, ss)
282 continue
283 }
284
285 // otherwise combine with existing
286 combineSpansets(existingSS[id], ss)
287 }
288

Callers 3

TestCombineResultsFunction · 0.85
AddMetadataMethod · 0.85
AddMetadataMethod · 0.85

Calls 2

spansetIDFunction · 0.85
combineSpansetsFunction · 0.85

Tested by 1

TestCombineResultsFunction · 0.68