Repository: prometheus/prometheus
File: promql/engine.go (Go)

Code before:
		}
		return vec
	}
	return v
}

// mergeSeriesWithSameLabelset merges series in a matrix that have the same labelset
// after __name__ label removal. This happens when delayed name removal is enabled and
// operations like OR combine series that originally had different names but end up
// with the same labelset after dropping the name. If series with the same labelset
// have overlapping timestamps, an error is returned.
func (ev *evaluator) mergeSeriesWithSameLabelset(mat Matrix) Matrix {
	if len(mat) <= 1 {
		return mat
	}

	// Group series by their labelset hash.
	seriesByHash := make(map[uint64][]int)
	for i := range mat {
		hash := mat[i].Metric.Hash()
		seriesByHash[hash] = append(seriesByHash[hash], i)
	}

	// Check if any merging is needed.
	needsMerge := false
	for _, indices := range seriesByHash {
		if len(indices) > 1 {
			needsMerge = true
			break
		}
	}

	if !needsMerge {
		return mat
	}

	// Merge series with the same labelset.
	merged := make(Matrix, 0, len(seriesByHash))
	for _, indices := range seriesByHash {
		base := mat[indices[0]]

		if len(indices) == 1 {
			// No collision, add as-is.
			merged = append(merged, base)
			continue
		}

		// Multiple series with the same labelset - check for overlaps and merge.
		// Build a set of timestamps to detect overlaps.
		timestamps := make(map[int64]struct{}, len(base.Floats)+len(base.Histograms))
		for _, p := range base.Floats {

Review comment (bug):
This whole grouping step (same as I had in my variant) was the main thing I was a bit unsure about, since it introduces extra memory overhead for everyone (even if small), even though it's only necessary for handling some very uncommon edge cases.

So I wonder if we should have a more efficient happy path without extra allocations, like the existing `ContainsSameLabelset()`, and only falling back to this merge algorithm if that is true?

Code after:
		}
		return vec
	}
	return v
}

// mergeSeriesWithSameLabelset merges series in a matrix that have the same labelset
// after __name__ label removal. This happens when delayed name removal is enabled and
// operations like OR combine series that originally had different names but end up
// with the same labelset after dropping the name. If series with the same labelset
// have overlapping timestamps, an error is returned.
func (ev *evaluator) mergeSeriesWithSameLabelset(mat Matrix) Matrix {
	if len(mat) <= 1 {
		return mat
	}

	// Fast path: check if there are any duplicate labelsets without allocating.
	// This is the common case and we want to avoid allocations.
	if !mat.ContainsSameLabelset() {
		return mat
	}

	// Slow path: there are duplicates, so we need to merge series with non-overlapping timestamps.
	// Group series by their labelset hash.
	seriesByHash := make(map[uint64][]int)
	for i := range mat {
		hash := mat[i].Metric.Hash()
		seriesByHash[hash] = append(seriesByHash[hash], i)
	}

	// Merge series with the same labelset.
	merged := make(Matrix, 0, len(seriesByHash))
	for _, indices := range seriesByHash {
		if len(indices) == 1 {
			// No collision, add as-is.
			merged = append(merged, mat[indices[0]])
			continue
		}

		// Multiple series with the same labelset - merge all samples.
		base := mat[indices[0]]
		for _, idx := range indices[1:] {
			base.Floats = append(base.Floats, mat[idx].Floats...)
			base.Histograms = append(base.Histograms, mat[idx].Histograms...)
		}

		// Sort merged samples by timestamp.
		sort.Slice(base.Floats, func(i, j int) bool {
			return base.Floats[i].T < base.Floats[j].T
		})
		sort.Slice(base.Histograms, func(i, j int) bool {