From 06cd1558bb0ead3b03591b111c54011c02314a9f Mon Sep 17 00:00:00 2001 From: Tyler Yahn Date: Tue, 2 Jan 2024 13:34:13 -0800 Subject: [PATCH] Use filteredToFront to unique --- attribute/set.go | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/attribute/set.go b/attribute/set.go index f9df5eb12b74..f9bbdea0590c 100644 --- a/attribute/set.go +++ b/attribute/set.go @@ -250,8 +250,8 @@ func NewSetWithFiltered(kvs []KeyValue, filter Filter) (Set, []KeyValue) { // The second []KeyValue return value is a list of attributes that were // excluded by the Filter (if non-nil). func NewSetWithSortableFiltered(kvs []KeyValue, tmp *Sortable, filter Filter) (Set, []KeyValue) { - // Check for empty set. - if len(kvs) == 0 { + n := len(kvs) + if n == 0 { return empty(), nil } @@ -263,28 +263,24 @@ func NewSetWithSortableFiltered(kvs []KeyValue, tmp *Sortable, filter Filter) (S *tmp = nil - position := len(kvs) - 1 - offset := position - 1 - - // The requirements stated above require that the stable - // result be placed in the end of the input slice, while - // overwritten values are swapped to the beginning. - // - // De-duplicate with last-value-wins semantics. Preserve - // duplicate values at the beginning of the input slice. - for ; offset >= 0; offset-- { - if kvs[offset].Key == kvs[position].Key { - continue + // Use filteredToFront here for last-value-wins semantics. + prev := kvs[n-1].Key + uniq := filteredToFront(kvs[:n-1], func(kv KeyValue) bool { + if kv.Key == prev { + return false } - position-- - kvs[offset], kvs[position] = kvs[position], kvs[offset] - } + prev = kv.Key + return true + }) + kvs = kvs[uniq:] + if filter != nil { - return filterSet(kvs[position:], filter) + // TODO (MrAlias): there is a potential optimization here where the + // filtering and uniquing are all done in the same step. For example: + // https://github.com/open-telemetry/opentelemetry-go/blob/228cc878a0f5de19290e8b2035dc4d0019f2a249/attribute/set.go#L266-L300 + return filterSet(kvs, filter) } - return Set{ - equivalent: computeDistinct(kvs[position:]), - }, nil + return Set{equivalent: computeDistinct(kvs)}, nil } // filterSet reorders kvs so that included keys are contiguous at the end of