summaryrefslogtreecommitdiff
path: root/vendor/go.opentelemetry.io/otel/attribute/set.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/go.opentelemetry.io/otel/attribute/set.go')
-rw-r--r--vendor/go.opentelemetry.io/otel/attribute/set.go139
1 files changed, 59 insertions, 80 deletions
diff --git a/vendor/go.opentelemetry.io/otel/attribute/set.go b/vendor/go.opentelemetry.io/otel/attribute/set.go
index fb6da5145..bff9c7fdb 100644
--- a/vendor/go.opentelemetry.io/otel/attribute/set.go
+++ b/vendor/go.opentelemetry.io/otel/attribute/set.go
@@ -1,24 +1,14 @@
// Copyright The OpenTelemetry Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
package attribute // import "go.opentelemetry.io/otel/attribute"
import (
+ "cmp"
"encoding/json"
"reflect"
+ "slices"
"sort"
- "sync"
)
type (
@@ -26,23 +16,33 @@ type (
// immutable set of attributes, with an internal cache for storing
// attribute encodings.
//
- // This type supports the Equivalent method of comparison using values of
- // type Distinct.
+ // This type will remain comparable for backwards compatibility. The
+ // equivalence of Sets across versions is not guaranteed to be stable.
+ // Prior versions may find two Sets to be equal or not when compared
+ // directly (i.e. ==), but subsequent versions may not. Users should use
+ // the Equals method to ensure stable equivalence checking.
+ //
+ // Users should also use the Distinct returned from Equivalent as a map key
+ // instead of a Set directly. In addition to that type providing guarantees
+ // on stable equivalence, it may also provide performance improvements.
Set struct {
equivalent Distinct
}
- // Distinct wraps a variable-size array of KeyValue, constructed with keys
- // in sorted order. This can be used as a map key or for equality checking
- // between Sets.
+ // Distinct is a unique identifier of a Set.
+ //
+ // Distinct is designed to be ensures equivalence stability: comparisons
+ // will return the save value across versions. For this reason, Distinct
+ // should always be used as a map key instead of a Set.
Distinct struct {
iface interface{}
}
- // Sortable implements sort.Interface, used for sorting KeyValue. This is
- // an exported type to support a memory optimization. A pointer to one of
- // these is needed for the call to sort.Stable(), which the caller may
- // provide in order to avoid an allocation. See NewSetWithSortable().
+ // Sortable implements sort.Interface, used for sorting KeyValue.
+ //
+ // Deprecated: This type is no longer used. It was added as a performance
+ // optimization for Go < 1.21 that is no longer needed (Go < 1.21 is no
+ // longer supported by the module).
Sortable []KeyValue
)
@@ -56,12 +56,6 @@ var (
iface: [0]KeyValue{},
},
}
-
- // sortables is a pool of Sortables used to create Sets with a user does
- // not provide one.
- sortables = sync.Pool{
- New: func() interface{} { return new(Sortable) },
- }
)
// EmptySet returns a reference to a Set with no elements.
@@ -187,13 +181,7 @@ func empty() Set {
// Except for empty sets, this method adds an additional allocation compared
// with calls that include a Sortable.
func NewSet(kvs ...KeyValue) Set {
- // Check for empty set.
- if len(kvs) == 0 {
- return empty()
- }
- srt := sortables.Get().(*Sortable)
- s, _ := NewSetWithSortableFiltered(kvs, srt, nil)
- sortables.Put(srt)
+ s, _ := NewSetWithFiltered(kvs, nil)
return s
}
@@ -201,12 +189,10 @@ func NewSet(kvs ...KeyValue) Set {
// NewSetWithSortableFiltered for more details.
//
// This call includes a Sortable option as a memory optimization.
-func NewSetWithSortable(kvs []KeyValue, tmp *Sortable) Set {
- // Check for empty set.
- if len(kvs) == 0 {
- return empty()
- }
- s, _ := NewSetWithSortableFiltered(kvs, tmp, nil)
+//
+// Deprecated: Use [NewSet] instead.
+func NewSetWithSortable(kvs []KeyValue, _ *Sortable) Set {
+ s, _ := NewSetWithFiltered(kvs, nil)
return s
}
@@ -220,48 +206,12 @@ func NewSetWithFiltered(kvs []KeyValue, filter Filter) (Set, []KeyValue) {
if len(kvs) == 0 {
return empty(), nil
}
- srt := sortables.Get().(*Sortable)
- s, filtered := NewSetWithSortableFiltered(kvs, srt, filter)
- sortables.Put(srt)
- return s, filtered
-}
-
-// NewSetWithSortableFiltered returns a new Set.
-//
-// Duplicate keys are eliminated by taking the last value. This
-// re-orders the input slice so that unique last-values are contiguous
-// at the end of the slice.
-//
-// This ensures the following:
-//
-// - Last-value-wins semantics
-// - Caller sees the reordering, but doesn't lose values
-// - Repeated call preserve last-value wins.
-//
-// Note that methods are defined on Set, although this returns Set. Callers
-// can avoid memory allocations by:
-//
-// - allocating a Sortable for use as a temporary in this method
-// - allocating a Set for storing the return value of this constructor.
-//
-// The result maintains a cache of encoded attributes, by attribute.EncoderID.
-// This value should not be copied after its first use.
-//
-// 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 {
- return empty(), nil
- }
-
- *tmp = kvs
// Stable sort so the following de-duplication can implement
// last-value-wins semantics.
- sort.Stable(tmp)
-
- *tmp = nil
+ slices.SortStableFunc(kvs, func(a, b KeyValue) int {
+ return cmp.Compare(a.Key, b.Key)
+ })
position := len(kvs) - 1
offset := position - 1
@@ -289,6 +239,35 @@ func NewSetWithSortableFiltered(kvs []KeyValue, tmp *Sortable, filter Filter) (S
return Set{equivalent: computeDistinct(kvs)}, nil
}
+// NewSetWithSortableFiltered returns a new Set.
+//
+// Duplicate keys are eliminated by taking the last value. This
+// re-orders the input slice so that unique last-values are contiguous
+// at the end of the slice.
+//
+// This ensures the following:
+//
+// - Last-value-wins semantics
+// - Caller sees the reordering, but doesn't lose values
+// - Repeated call preserve last-value wins.
+//
+// Note that methods are defined on Set, although this returns Set. Callers
+// can avoid memory allocations by:
+//
+// - allocating a Sortable for use as a temporary in this method
+// - allocating a Set for storing the return value of this constructor.
+//
+// The result maintains a cache of encoded attributes, by attribute.EncoderID.
+// This value should not be copied after its first use.
+//
+// The second []KeyValue return value is a list of attributes that were
+// excluded by the Filter (if non-nil).
+//
+// Deprecated: Use [NewSetWithFiltered] instead.
+func NewSetWithSortableFiltered(kvs []KeyValue, _ *Sortable, filter Filter) (Set, []KeyValue) {
+ return NewSetWithFiltered(kvs, filter)
+}
+
// filteredToFront filters slice in-place using keep function. All KeyValues that need to
// be removed are moved to the front. All KeyValues that need to be kept are
// moved (in-order) to the back. The index for the first KeyValue to be kept is