4
4
package attribute // import "go.opentelemetry.io/otel/attribute"
5
5
6
6
import (
7
+ "cmp"
7
8
"encoding/json"
8
9
"reflect"
10
+ "slices"
9
11
"sort"
10
- "sync"
11
12
)
12
13
13
14
type (
@@ -37,10 +38,11 @@ type (
37
38
iface interface {}
38
39
}
39
40
40
- // Sortable implements sort.Interface, used for sorting KeyValue. This is
41
- // an exported type to support a memory optimization. A pointer to one of
42
- // these is needed for the call to sort.Stable(), which the caller may
43
- // provide in order to avoid an allocation. See NewSetWithSortable().
41
+ // Sortable implements sort.Interface, used for sorting KeyValue.
42
+ //
43
+ // Deprecated: This type is no longer used. It was added as a performance
44
+ // optimization for Go < 1.21 that is no longer needed (Go < 1.21 is no
45
+ // longer supported by the module).
44
46
Sortable []KeyValue
45
47
)
46
48
54
56
iface : [0 ]KeyValue {},
55
57
},
56
58
}
57
-
58
- // sortables is a pool of Sortables used to create Sets with a user does
59
- // not provide one.
60
- sortables = sync.Pool {
61
- New : func () interface {} { return new (Sortable ) },
62
- }
63
59
)
64
60
65
61
// EmptySet returns a reference to a Set with no elements.
@@ -185,26 +181,18 @@ func empty() Set {
185
181
// Except for empty sets, this method adds an additional allocation compared
186
182
// with calls that include a Sortable.
187
183
func NewSet (kvs ... KeyValue ) Set {
188
- // Check for empty set.
189
- if len (kvs ) == 0 {
190
- return empty ()
191
- }
192
- srt := sortables .Get ().(* Sortable )
193
- s , _ := NewSetWithSortableFiltered (kvs , srt , nil )
194
- sortables .Put (srt )
184
+ s , _ := NewSetWithFiltered (kvs , nil )
195
185
return s
196
186
}
197
187
198
188
// NewSetWithSortable returns a new Set. See the documentation for
199
189
// NewSetWithSortableFiltered for more details.
200
190
//
201
191
// This call includes a Sortable option as a memory optimization.
202
- func NewSetWithSortable (kvs []KeyValue , tmp * Sortable ) Set {
203
- // Check for empty set.
204
- if len (kvs ) == 0 {
205
- return empty ()
206
- }
207
- s , _ := NewSetWithSortableFiltered (kvs , tmp , nil )
192
+ //
193
+ // Deprecated: Use [NewSet] instead.
194
+ func NewSetWithSortable (kvs []KeyValue , _ * Sortable ) Set {
195
+ s , _ := NewSetWithFiltered (kvs , nil )
208
196
return s
209
197
}
210
198
@@ -218,48 +206,12 @@ func NewSetWithFiltered(kvs []KeyValue, filter Filter) (Set, []KeyValue) {
218
206
if len (kvs ) == 0 {
219
207
return empty (), nil
220
208
}
221
- srt := sortables .Get ().(* Sortable )
222
- s , filtered := NewSetWithSortableFiltered (kvs , srt , filter )
223
- sortables .Put (srt )
224
- return s , filtered
225
- }
226
-
227
- // NewSetWithSortableFiltered returns a new Set.
228
- //
229
- // Duplicate keys are eliminated by taking the last value. This
230
- // re-orders the input slice so that unique last-values are contiguous
231
- // at the end of the slice.
232
- //
233
- // This ensures the following:
234
- //
235
- // - Last-value-wins semantics
236
- // - Caller sees the reordering, but doesn't lose values
237
- // - Repeated call preserve last-value wins.
238
- //
239
- // Note that methods are defined on Set, although this returns Set. Callers
240
- // can avoid memory allocations by:
241
- //
242
- // - allocating a Sortable for use as a temporary in this method
243
- // - allocating a Set for storing the return value of this constructor.
244
- //
245
- // The result maintains a cache of encoded attributes, by attribute.EncoderID.
246
- // This value should not be copied after its first use.
247
- //
248
- // The second []KeyValue return value is a list of attributes that were
249
- // excluded by the Filter (if non-nil).
250
- func NewSetWithSortableFiltered (kvs []KeyValue , tmp * Sortable , filter Filter ) (Set , []KeyValue ) {
251
- // Check for empty set.
252
- if len (kvs ) == 0 {
253
- return empty (), nil
254
- }
255
-
256
- * tmp = kvs
257
209
258
210
// Stable sort so the following de-duplication can implement
259
211
// last-value-wins semantics.
260
- sort . Stable ( tmp )
261
-
262
- * tmp = nil
212
+ slices . SortStableFunc ( kvs , func ( a , b KeyValue ) int {
213
+ return cmp . Compare ( a . Key , b . Key )
214
+ })
263
215
264
216
position := len (kvs ) - 1
265
217
offset := position - 1
@@ -287,6 +239,35 @@ func NewSetWithSortableFiltered(kvs []KeyValue, tmp *Sortable, filter Filter) (S
287
239
return Set {equivalent : computeDistinct (kvs )}, nil
288
240
}
289
241
242
+ // NewSetWithSortableFiltered returns a new Set.
243
+ //
244
+ // Duplicate keys are eliminated by taking the last value. This
245
+ // re-orders the input slice so that unique last-values are contiguous
246
+ // at the end of the slice.
247
+ //
248
+ // This ensures the following:
249
+ //
250
+ // - Last-value-wins semantics
251
+ // - Caller sees the reordering, but doesn't lose values
252
+ // - Repeated call preserve last-value wins.
253
+ //
254
+ // Note that methods are defined on Set, although this returns Set. Callers
255
+ // can avoid memory allocations by:
256
+ //
257
+ // - allocating a Sortable for use as a temporary in this method
258
+ // - allocating a Set for storing the return value of this constructor.
259
+ //
260
+ // The result maintains a cache of encoded attributes, by attribute.EncoderID.
261
+ // This value should not be copied after its first use.
262
+ //
263
+ // The second []KeyValue return value is a list of attributes that were
264
+ // excluded by the Filter (if non-nil).
265
+ //
266
+ // Deprecated: Use [NewSetWithFiltered] instead.
267
+ func NewSetWithSortableFiltered (kvs []KeyValue , _ * Sortable , filter Filter ) (Set , []KeyValue ) {
268
+ return NewSetWithFiltered (kvs , filter )
269
+ }
270
+
290
271
// filteredToFront filters slice in-place using keep function. All KeyValues that need to
291
272
// be removed are moved to the front. All KeyValues that need to be kept are
292
273
// moved (in-order) to the back. The index for the first KeyValue to be kept is
0 commit comments