[VOL-3860] redis client support in voltha-lib-go
redis client support has been added in this patch. There are two
types client `redis` and `redis-sentinel` to connect a redis instance.
redis-sentinel is required to be able to find the master redis
instance from a redis-sentinel process. See redis-sentinel usage
https://redis.io/topics/sentinel and
https://pkg.go.dev/github.com/go-redis/redis/v8#NewFailoverClient
for more information. If there is no need to have any failover
mechanism then the redis client type is the option to choose.
Change-Id: I997ed92115a9d565df632c6dd8184b9bab77b991
diff --git a/vendor/go.opentelemetry.io/otel/label/doc.go b/vendor/go.opentelemetry.io/otel/label/doc.go
new file mode 100644
index 0000000..d631d23
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/label/doc.go
@@ -0,0 +1,16 @@
+// 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.
+
+// Package label provides key and value labels.
+package label // import "go.opentelemetry.io/otel/label"
diff --git a/vendor/go.opentelemetry.io/otel/label/encoder.go b/vendor/go.opentelemetry.io/otel/label/encoder.go
new file mode 100644
index 0000000..6be7a3f
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/label/encoder.go
@@ -0,0 +1,150 @@
+// 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.
+
+package label
+
+import (
+ "bytes"
+ "sync"
+ "sync/atomic"
+)
+
+type (
+ // Encoder is a mechanism for serializing a label set into a
+ // specific string representation that supports caching, to
+ // avoid repeated serialization. An example could be an
+ // exporter encoding the label set into a wire representation.
+ Encoder interface {
+ // Encode returns the serialized encoding of the label
+ // set using its Iterator. This result may be cached
+ // by a label.Set.
+ Encode(iterator Iterator) string
+
+ // ID returns a value that is unique for each class of
+ // label encoder. Label encoders allocate these using
+ // `NewEncoderID`.
+ ID() EncoderID
+ }
+
+ // EncoderID is used to identify distinct Encoder
+ // implementations, for caching encoded results.
+ EncoderID struct {
+ value uint64
+ }
+
+ // defaultLabelEncoder uses a sync.Pool of buffers to reduce
+ // the number of allocations used in encoding labels. This
+ // implementation encodes a comma-separated list of key=value,
+ // with '/'-escaping of '=', ',', and '\'.
+ defaultLabelEncoder struct {
+ // pool is a pool of labelset builders. The buffers in this
+ // pool grow to a size that most label encodings will not
+ // allocate new memory.
+ pool sync.Pool // *bytes.Buffer
+ }
+)
+
+// escapeChar is used to ensure uniqueness of the label encoding where
+// keys or values contain either '=' or ','. Since there is no parser
+// needed for this encoding and its only requirement is to be unique,
+// this choice is arbitrary. Users will see these in some exporters
+// (e.g., stdout), so the backslash ('\') is used as a conventional choice.
+const escapeChar = '\\'
+
+var (
+ _ Encoder = &defaultLabelEncoder{}
+
+ // encoderIDCounter is for generating IDs for other label
+ // encoders.
+ encoderIDCounter uint64
+
+ defaultEncoderOnce sync.Once
+ defaultEncoderID = NewEncoderID()
+ defaultEncoderInstance *defaultLabelEncoder
+)
+
+// NewEncoderID returns a unique label encoder ID. It should be
+// called once per each type of label encoder. Preferably in init() or
+// in var definition.
+func NewEncoderID() EncoderID {
+ return EncoderID{value: atomic.AddUint64(&encoderIDCounter, 1)}
+}
+
+// DefaultEncoder returns a label encoder that encodes labels
+// in such a way that each escaped label's key is followed by an equal
+// sign and then by an escaped label's value. All key-value pairs are
+// separated by a comma.
+//
+// Escaping is done by prepending a backslash before either a
+// backslash, equal sign or a comma.
+func DefaultEncoder() Encoder {
+ defaultEncoderOnce.Do(func() {
+ defaultEncoderInstance = &defaultLabelEncoder{
+ pool: sync.Pool{
+ New: func() interface{} {
+ return &bytes.Buffer{}
+ },
+ },
+ }
+ })
+ return defaultEncoderInstance
+}
+
+// Encode is a part of an implementation of the LabelEncoder
+// interface.
+func (d *defaultLabelEncoder) Encode(iter Iterator) string {
+ buf := d.pool.Get().(*bytes.Buffer)
+ defer d.pool.Put(buf)
+ buf.Reset()
+
+ for iter.Next() {
+ i, keyValue := iter.IndexedLabel()
+ if i > 0 {
+ _, _ = buf.WriteRune(',')
+ }
+ copyAndEscape(buf, string(keyValue.Key))
+
+ _, _ = buf.WriteRune('=')
+
+ if keyValue.Value.Type() == STRING {
+ copyAndEscape(buf, keyValue.Value.AsString())
+ } else {
+ _, _ = buf.WriteString(keyValue.Value.Emit())
+ }
+ }
+ return buf.String()
+}
+
+// ID is a part of an implementation of the LabelEncoder interface.
+func (*defaultLabelEncoder) ID() EncoderID {
+ return defaultEncoderID
+}
+
+// copyAndEscape escapes `=`, `,` and its own escape character (`\`),
+// making the default encoding unique.
+func copyAndEscape(buf *bytes.Buffer, val string) {
+ for _, ch := range val {
+ switch ch {
+ case '=', ',', escapeChar:
+ buf.WriteRune(escapeChar)
+ }
+ buf.WriteRune(ch)
+ }
+}
+
+// Valid returns true if this encoder ID was allocated by
+// `NewEncoderID`. Invalid encoder IDs will not be cached.
+func (id EncoderID) Valid() bool {
+ return id.value != 0
+}
diff --git a/vendor/go.opentelemetry.io/otel/label/iterator.go b/vendor/go.opentelemetry.io/otel/label/iterator.go
new file mode 100644
index 0000000..9e72239
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/label/iterator.go
@@ -0,0 +1,143 @@
+// 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.
+
+package label
+
+// Iterator allows iterating over the set of labels in order,
+// sorted by key.
+type Iterator struct {
+ storage *Set
+ idx int
+}
+
+// MergeIterator supports iterating over two sets of labels while
+// eliminating duplicate values from the combined set. The first
+// iterator value takes precedence.
+type MergeItererator struct {
+ one oneIterator
+ two oneIterator
+ current KeyValue
+}
+
+type oneIterator struct {
+ iter Iterator
+ done bool
+ label KeyValue
+}
+
+// Next moves the iterator to the next position. Returns false if there
+// are no more labels.
+func (i *Iterator) Next() bool {
+ i.idx++
+ return i.idx < i.Len()
+}
+
+// Label returns current KeyValue. Must be called only after Next returns
+// true.
+func (i *Iterator) Label() KeyValue {
+ kv, _ := i.storage.Get(i.idx)
+ return kv
+}
+
+// Attribute is a synonym for Label().
+func (i *Iterator) Attribute() KeyValue {
+ return i.Label()
+}
+
+// IndexedLabel returns current index and label. Must be called only
+// after Next returns true.
+func (i *Iterator) IndexedLabel() (int, KeyValue) {
+ return i.idx, i.Label()
+}
+
+// Len returns a number of labels in the iterator's `*Set`.
+func (i *Iterator) Len() int {
+ return i.storage.Len()
+}
+
+// ToSlice is a convenience function that creates a slice of labels
+// from the passed iterator. The iterator is set up to start from the
+// beginning before creating the slice.
+func (i *Iterator) ToSlice() []KeyValue {
+ l := i.Len()
+ if l == 0 {
+ return nil
+ }
+ i.idx = -1
+ slice := make([]KeyValue, 0, l)
+ for i.Next() {
+ slice = append(slice, i.Label())
+ }
+ return slice
+}
+
+// NewMergeIterator returns a MergeIterator for merging two label sets
+// Duplicates are resolved by taking the value from the first set.
+func NewMergeIterator(s1, s2 *Set) MergeItererator {
+ mi := MergeItererator{
+ one: makeOne(s1.Iter()),
+ two: makeOne(s2.Iter()),
+ }
+ return mi
+}
+
+func makeOne(iter Iterator) oneIterator {
+ oi := oneIterator{
+ iter: iter,
+ }
+ oi.advance()
+ return oi
+}
+
+func (oi *oneIterator) advance() {
+ if oi.done = !oi.iter.Next(); !oi.done {
+ oi.label = oi.iter.Label()
+ }
+}
+
+// Next returns true if there is another label available.
+func (m *MergeItererator) Next() bool {
+ if m.one.done && m.two.done {
+ return false
+ }
+ if m.one.done {
+ m.current = m.two.label
+ m.two.advance()
+ return true
+ }
+ if m.two.done {
+ m.current = m.one.label
+ m.one.advance()
+ return true
+ }
+ if m.one.label.Key == m.two.label.Key {
+ m.current = m.one.label // first iterator label value wins
+ m.one.advance()
+ m.two.advance()
+ return true
+ }
+ if m.one.label.Key < m.two.label.Key {
+ m.current = m.one.label
+ m.one.advance()
+ return true
+ }
+ m.current = m.two.label
+ m.two.advance()
+ return true
+}
+
+// Label returns the current value after Next() returns true.
+func (m *MergeItererator) Label() KeyValue {
+ return m.current
+}
diff --git a/vendor/go.opentelemetry.io/otel/label/key.go b/vendor/go.opentelemetry.io/otel/label/key.go
new file mode 100644
index 0000000..7d72378
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/label/key.go
@@ -0,0 +1,169 @@
+// 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.
+
+package label
+
+// Key represents the key part in key-value pairs. It's a string. The
+// allowed character set in the key depends on the use of the key.
+type Key string
+
+// Bool creates a KeyValue instance with a BOOL Value.
+//
+// If creating both key and a bool value at the same time, then
+// instead of calling Key(name).Bool(value) consider using a
+// convenience function provided by the api/key package -
+// key.Bool(name, value).
+func (k Key) Bool(v bool) KeyValue {
+ return KeyValue{
+ Key: k,
+ Value: BoolValue(v),
+ }
+}
+
+// Int64 creates a KeyValue instance with an INT64 Value.
+//
+// If creating both key and an int64 value at the same time, then
+// instead of calling Key(name).Int64(value) consider using a
+// convenience function provided by the api/key package -
+// key.Int64(name, value).
+func (k Key) Int64(v int64) KeyValue {
+ return KeyValue{
+ Key: k,
+ Value: Int64Value(v),
+ }
+}
+
+// Uint64 creates a KeyValue instance with a UINT64 Value.
+//
+// If creating both key and a uint64 value at the same time, then
+// instead of calling Key(name).Uint64(value) consider using a
+// convenience function provided by the api/key package -
+// key.Uint64(name, value).
+func (k Key) Uint64(v uint64) KeyValue {
+ return KeyValue{
+ Key: k,
+ Value: Uint64Value(v),
+ }
+}
+
+// Float64 creates a KeyValue instance with a FLOAT64 Value.
+//
+// If creating both key and a float64 value at the same time, then
+// instead of calling Key(name).Float64(value) consider using a
+// convenience function provided by the api/key package -
+// key.Float64(name, value).
+func (k Key) Float64(v float64) KeyValue {
+ return KeyValue{
+ Key: k,
+ Value: Float64Value(v),
+ }
+}
+
+// Int32 creates a KeyValue instance with an INT32 Value.
+//
+// If creating both key and an int32 value at the same time, then
+// instead of calling Key(name).Int32(value) consider using a
+// convenience function provided by the api/key package -
+// key.Int32(name, value).
+func (k Key) Int32(v int32) KeyValue {
+ return KeyValue{
+ Key: k,
+ Value: Int32Value(v),
+ }
+}
+
+// Uint32 creates a KeyValue instance with a UINT32 Value.
+//
+// If creating both key and a uint32 value at the same time, then
+// instead of calling Key(name).Uint32(value) consider using a
+// convenience function provided by the api/key package -
+// key.Uint32(name, value).
+func (k Key) Uint32(v uint32) KeyValue {
+ return KeyValue{
+ Key: k,
+ Value: Uint32Value(v),
+ }
+}
+
+// Float32 creates a KeyValue instance with a FLOAT32 Value.
+//
+// If creating both key and a float32 value at the same time, then
+// instead of calling Key(name).Float32(value) consider using a
+// convenience function provided by the api/key package -
+// key.Float32(name, value).
+func (k Key) Float32(v float32) KeyValue {
+ return KeyValue{
+ Key: k,
+ Value: Float32Value(v),
+ }
+}
+
+// String creates a KeyValue instance with a STRING Value.
+//
+// If creating both key and a string value at the same time, then
+// instead of calling Key(name).String(value) consider using a
+// convenience function provided by the api/key package -
+// key.String(name, value).
+func (k Key) String(v string) KeyValue {
+ return KeyValue{
+ Key: k,
+ Value: StringValue(v),
+ }
+}
+
+// Int creates a KeyValue instance with either an INT32 or an INT64
+// Value, depending on whether the int type is 32 or 64 bits wide.
+//
+// If creating both key and an int value at the same time, then
+// instead of calling Key(name).Int(value) consider using a
+// convenience function provided by the api/key package -
+// key.Int(name, value).
+func (k Key) Int(v int) KeyValue {
+ return KeyValue{
+ Key: k,
+ Value: IntValue(v),
+ }
+}
+
+// Uint creates a KeyValue instance with either a UINT32 or a UINT64
+// Value, depending on whether the uint type is 32 or 64 bits wide.
+//
+// If creating both key and a uint value at the same time, then
+// instead of calling Key(name).Uint(value) consider using a
+// convenience function provided by the api/key package -
+// key.Uint(name, value).
+func (k Key) Uint(v uint) KeyValue {
+ return KeyValue{
+ Key: k,
+ Value: UintValue(v),
+ }
+}
+
+// Defined returns true for non-empty keys.
+func (k Key) Defined() bool {
+ return len(k) != 0
+}
+
+// Array creates a KeyValue instance with a ARRAY Value.
+//
+// If creating both key and a array value at the same time, then
+// instead of calling Key(name).String(value) consider using a
+// convenience function provided by the api/key package -
+// key.Array(name, value).
+func (k Key) Array(v interface{}) KeyValue {
+ return KeyValue{
+ Key: k,
+ Value: ArrayValue(v),
+ }
+}
diff --git a/vendor/go.opentelemetry.io/otel/label/kv.go b/vendor/go.opentelemetry.io/otel/label/kv.go
new file mode 100644
index 0000000..3e2764f
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/label/kv.go
@@ -0,0 +1,144 @@
+// 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.
+
+package label
+
+import (
+ "encoding/json"
+ "fmt"
+ "reflect"
+)
+
+// KeyValue holds a key and value pair.
+type KeyValue struct {
+ Key Key
+ Value Value
+}
+
+// Bool creates a new key-value pair with a passed name and a bool
+// value.
+func Bool(k string, v bool) KeyValue {
+ return Key(k).Bool(v)
+}
+
+// Int64 creates a new key-value pair with a passed name and an int64
+// value.
+func Int64(k string, v int64) KeyValue {
+ return Key(k).Int64(v)
+}
+
+// Uint64 creates a new key-value pair with a passed name and a uint64
+// value.
+func Uint64(k string, v uint64) KeyValue {
+ return Key(k).Uint64(v)
+}
+
+// Float64 creates a new key-value pair with a passed name and a float64
+// value.
+func Float64(k string, v float64) KeyValue {
+ return Key(k).Float64(v)
+}
+
+// Int32 creates a new key-value pair with a passed name and an int32
+// value.
+func Int32(k string, v int32) KeyValue {
+ return Key(k).Int32(v)
+}
+
+// Uint32 creates a new key-value pair with a passed name and a uint32
+// value.
+func Uint32(k string, v uint32) KeyValue {
+ return Key(k).Uint32(v)
+}
+
+// Float32 creates a new key-value pair with a passed name and a float32
+// value.
+func Float32(k string, v float32) KeyValue {
+ return Key(k).Float32(v)
+}
+
+// String creates a new key-value pair with a passed name and a string
+// value.
+func String(k, v string) KeyValue {
+ return Key(k).String(v)
+}
+
+// Stringer creates a new key-value pair with a passed name and a string
+// value generated by the passed Stringer interface.
+func Stringer(k string, v fmt.Stringer) KeyValue {
+ return Key(k).String(v.String())
+}
+
+// Int creates a new key-value pair instance with a passed name and
+// either an int32 or an int64 value, depending on whether the int
+// type is 32 or 64 bits wide.
+func Int(k string, v int) KeyValue {
+ return Key(k).Int(v)
+}
+
+// Uint creates a new key-value pair instance with a passed name and
+// either an uint32 or an uint64 value, depending on whether the uint
+// type is 32 or 64 bits wide.
+func Uint(k string, v uint) KeyValue {
+ return Key(k).Uint(v)
+}
+
+// Array creates a new key-value pair with a passed name and a array.
+// Only arrays of primitive type are supported.
+func Array(k string, v interface{}) KeyValue {
+ return Key(k).Array(v)
+}
+
+// Any creates a new key-value pair instance with a passed name and
+// automatic type inference. This is slower, and not type-safe.
+func Any(k string, value interface{}) KeyValue {
+ if value == nil {
+ return String(k, "<nil>")
+ }
+
+ if stringer, ok := value.(fmt.Stringer); ok {
+ return String(k, stringer.String())
+ }
+
+ rv := reflect.ValueOf(value)
+
+ switch rv.Kind() {
+ case reflect.Array, reflect.Slice:
+ return Array(k, value)
+ case reflect.Bool:
+ return Bool(k, rv.Bool())
+ case reflect.Int, reflect.Int8, reflect.Int16:
+ return Int(k, int(rv.Int()))
+ case reflect.Int32:
+ return Int32(k, int32(rv.Int()))
+ case reflect.Int64:
+ return Int64(k, int64(rv.Int()))
+ case reflect.Uint, reflect.Uint8, reflect.Uint16:
+ return Uint(k, uint(rv.Uint()))
+ case reflect.Uint32:
+ return Uint32(k, uint32(rv.Uint()))
+ case reflect.Uint64, reflect.Uintptr:
+ return Uint64(k, rv.Uint())
+ case reflect.Float32:
+ return Float32(k, float32(rv.Float()))
+ case reflect.Float64:
+ return Float64(k, rv.Float())
+ case reflect.String:
+ return String(k, rv.String())
+ }
+ if b, err := json.Marshal(value); value != nil && err == nil {
+ return String(k, string(b))
+ }
+ return String(k, fmt.Sprint(value))
+}
diff --git a/vendor/go.opentelemetry.io/otel/label/set.go b/vendor/go.opentelemetry.io/otel/label/set.go
new file mode 100644
index 0000000..3bd5263
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/label/set.go
@@ -0,0 +1,468 @@
+// 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.
+
+package label
+
+import (
+ "encoding/json"
+ "reflect"
+ "sort"
+ "sync"
+)
+
+type (
+ // Set is the representation for a distinct label set. It
+ // manages an immutable set of labels, with an internal cache
+ // for storing label encodings.
+ //
+ // This type supports the `Equivalent` method of comparison
+ // using values of type `Distinct`.
+ //
+ // This type is used to implement:
+ // 1. Metric labels
+ // 2. Resource sets
+ // 3. Correlation map (TODO)
+ Set struct {
+ equivalent Distinct
+
+ lock sync.Mutex
+ encoders [maxConcurrentEncoders]EncoderID
+ encoded [maxConcurrentEncoders]string
+ }
+
+ // 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 struct {
+ iface interface{}
+ }
+
+ // Filter supports removing certain labels from label sets.
+ // When the filter returns true, the label will be kept in
+ // the filtered label set. When the filter returns false, the
+ // label is excluded from the filtered label set, and the
+ // label instead appears in the `removed` list of excluded labels.
+ Filter func(KeyValue) bool
+
+ // 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 []KeyValue
+)
+
+var (
+ // keyValueType is used in `computeDistinctReflect`.
+ keyValueType = reflect.TypeOf(KeyValue{})
+
+ // emptySet is returned for empty label sets.
+ emptySet = &Set{
+ equivalent: Distinct{
+ iface: [0]KeyValue{},
+ },
+ }
+)
+
+const maxConcurrentEncoders = 3
+
+func EmptySet() *Set {
+ return emptySet
+}
+
+// reflect abbreviates `reflect.ValueOf`.
+func (d Distinct) reflect() reflect.Value {
+ return reflect.ValueOf(d.iface)
+}
+
+// Valid returns true if this value refers to a valid `*Set`.
+func (d Distinct) Valid() bool {
+ return d.iface != nil
+}
+
+// Len returns the number of labels in this set.
+func (l *Set) Len() int {
+ if l == nil || !l.equivalent.Valid() {
+ return 0
+ }
+ return l.equivalent.reflect().Len()
+}
+
+// Get returns the KeyValue at ordered position `idx` in this set.
+func (l *Set) Get(idx int) (KeyValue, bool) {
+ if l == nil {
+ return KeyValue{}, false
+ }
+ value := l.equivalent.reflect()
+
+ if idx >= 0 && idx < value.Len() {
+ // Note: The Go compiler successfully avoids an allocation for
+ // the interface{} conversion here:
+ return value.Index(idx).Interface().(KeyValue), true
+ }
+
+ return KeyValue{}, false
+}
+
+// Value returns the value of a specified key in this set.
+func (l *Set) Value(k Key) (Value, bool) {
+ if l == nil {
+ return Value{}, false
+ }
+ rValue := l.equivalent.reflect()
+ vlen := rValue.Len()
+
+ idx := sort.Search(vlen, func(idx int) bool {
+ return rValue.Index(idx).Interface().(KeyValue).Key >= k
+ })
+ if idx >= vlen {
+ return Value{}, false
+ }
+ keyValue := rValue.Index(idx).Interface().(KeyValue)
+ if k == keyValue.Key {
+ return keyValue.Value, true
+ }
+ return Value{}, false
+}
+
+// HasValue tests whether a key is defined in this set.
+func (l *Set) HasValue(k Key) bool {
+ if l == nil {
+ return false
+ }
+ _, ok := l.Value(k)
+ return ok
+}
+
+// Iter returns an iterator for visiting the labels in this set.
+func (l *Set) Iter() Iterator {
+ return Iterator{
+ storage: l,
+ idx: -1,
+ }
+}
+
+// ToSlice returns the set of labels belonging to this set, sorted,
+// where keys appear no more than once.
+func (l *Set) ToSlice() []KeyValue {
+ iter := l.Iter()
+ return iter.ToSlice()
+}
+
+// Equivalent returns a value that may be used as a map key. The
+// Distinct type guarantees that the result will equal the equivalent
+// Distinct value of any label set with the same elements as this,
+// where sets are made unique by choosing the last value in the input
+// for any given key.
+func (l *Set) Equivalent() Distinct {
+ if l == nil || !l.equivalent.Valid() {
+ return emptySet.equivalent
+ }
+ return l.equivalent
+}
+
+// Equals returns true if the argument set is equivalent to this set.
+func (l *Set) Equals(o *Set) bool {
+ return l.Equivalent() == o.Equivalent()
+}
+
+// Encoded returns the encoded form of this set, according to
+// `encoder`. The result will be cached in this `*Set`.
+func (l *Set) Encoded(encoder Encoder) string {
+ if l == nil || encoder == nil {
+ return ""
+ }
+
+ id := encoder.ID()
+ if !id.Valid() {
+ // Invalid IDs are not cached.
+ return encoder.Encode(l.Iter())
+ }
+
+ var lookup *string
+ l.lock.Lock()
+ for idx := 0; idx < maxConcurrentEncoders; idx++ {
+ if l.encoders[idx] == id {
+ lookup = &l.encoded[idx]
+ break
+ }
+ }
+ l.lock.Unlock()
+
+ if lookup != nil {
+ return *lookup
+ }
+
+ r := encoder.Encode(l.Iter())
+
+ l.lock.Lock()
+ defer l.lock.Unlock()
+
+ for idx := 0; idx < maxConcurrentEncoders; idx++ {
+ if l.encoders[idx] == id {
+ return l.encoded[idx]
+ }
+ if !l.encoders[idx].Valid() {
+ l.encoders[idx] = id
+ l.encoded[idx] = r
+ return r
+ }
+ }
+
+ // TODO: This is a performance cliff. Find a way for this to
+ // generate a warning.
+ return r
+}
+
+func empty() Set {
+ return Set{
+ equivalent: emptySet.equivalent,
+ }
+}
+
+// NewSet returns a new `Set`. See the documentation for
+// `NewSetWithSortableFiltered` for more details.
+//
+// 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()
+ }
+ s, _ := NewSetWithSortableFiltered(kvs, new(Sortable), nil)
+ return s //nolint
+}
+
+// NewSetWithSortable returns a new `Set`. See the documentation for
+// `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)
+ return s //nolint
+}
+
+// NewSetWithFiltered returns a new `Set`. See the documentation for
+// `NewSetWithSortableFiltered` for more details.
+//
+// This call includes a `Filter` to include/exclude label keys from
+// the return value. Excluded keys are returned as a slice of label
+// values.
+func NewSetWithFiltered(kvs []KeyValue, filter Filter) (Set, []KeyValue) {
+ // Check for empty set.
+ if len(kvs) == 0 {
+ return empty(), nil
+ }
+ return NewSetWithSortableFiltered(kvs, new(Sortable), filter)
+}
+
+// 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 labels, by label.EncoderID.
+// This value should not be copied after its first use.
+//
+// The second `[]KeyValue` return value is a list of labels 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
+
+ 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
+ }
+ position--
+ kvs[offset], kvs[position] = kvs[position], kvs[offset]
+ }
+ if filter != nil {
+ return filterSet(kvs[position:], filter)
+ }
+ return Set{
+ equivalent: computeDistinct(kvs[position:]),
+ }, nil
+}
+
+// filterSet reorders `kvs` so that included keys are contiguous at
+// the end of the slice, while excluded keys precede the included keys.
+func filterSet(kvs []KeyValue, filter Filter) (Set, []KeyValue) {
+ var excluded []KeyValue
+
+ // Move labels that do not match the filter so
+ // they're adjacent before calling computeDistinct().
+ distinctPosition := len(kvs)
+
+ // Swap indistinct keys forward and distinct keys toward the
+ // end of the slice.
+ offset := len(kvs) - 1
+ for ; offset >= 0; offset-- {
+ if filter(kvs[offset]) {
+ distinctPosition--
+ kvs[offset], kvs[distinctPosition] = kvs[distinctPosition], kvs[offset]
+ continue
+ }
+ }
+ excluded = kvs[:distinctPosition]
+
+ return Set{
+ equivalent: computeDistinct(kvs[distinctPosition:]),
+ }, excluded
+}
+
+// Filter returns a filtered copy of this `Set`. See the
+// documentation for `NewSetWithSortableFiltered` for more details.
+func (l *Set) Filter(re Filter) (Set, []KeyValue) {
+ if re == nil {
+ return Set{
+ equivalent: l.equivalent,
+ }, nil
+ }
+
+ // Note: This could be refactored to avoid the temporary slice
+ // allocation, if it proves to be expensive.
+ return filterSet(l.ToSlice(), re)
+}
+
+// computeDistinct returns a `Distinct` using either the fixed- or
+// reflect-oriented code path, depending on the size of the input.
+// The input slice is assumed to already be sorted and de-duplicated.
+func computeDistinct(kvs []KeyValue) Distinct {
+ iface := computeDistinctFixed(kvs)
+ if iface == nil {
+ iface = computeDistinctReflect(kvs)
+ }
+ return Distinct{
+ iface: iface,
+ }
+}
+
+// computeDistinctFixed computes a `Distinct` for small slices. It
+// returns nil if the input is too large for this code path.
+func computeDistinctFixed(kvs []KeyValue) interface{} {
+ switch len(kvs) {
+ case 1:
+ ptr := new([1]KeyValue)
+ copy((*ptr)[:], kvs)
+ return *ptr
+ case 2:
+ ptr := new([2]KeyValue)
+ copy((*ptr)[:], kvs)
+ return *ptr
+ case 3:
+ ptr := new([3]KeyValue)
+ copy((*ptr)[:], kvs)
+ return *ptr
+ case 4:
+ ptr := new([4]KeyValue)
+ copy((*ptr)[:], kvs)
+ return *ptr
+ case 5:
+ ptr := new([5]KeyValue)
+ copy((*ptr)[:], kvs)
+ return *ptr
+ case 6:
+ ptr := new([6]KeyValue)
+ copy((*ptr)[:], kvs)
+ return *ptr
+ case 7:
+ ptr := new([7]KeyValue)
+ copy((*ptr)[:], kvs)
+ return *ptr
+ case 8:
+ ptr := new([8]KeyValue)
+ copy((*ptr)[:], kvs)
+ return *ptr
+ case 9:
+ ptr := new([9]KeyValue)
+ copy((*ptr)[:], kvs)
+ return *ptr
+ case 10:
+ ptr := new([10]KeyValue)
+ copy((*ptr)[:], kvs)
+ return *ptr
+ default:
+ return nil
+ }
+}
+
+// computeDistinctReflect computes a `Distinct` using reflection,
+// works for any size input.
+func computeDistinctReflect(kvs []KeyValue) interface{} {
+ at := reflect.New(reflect.ArrayOf(len(kvs), keyValueType)).Elem()
+ for i, keyValue := range kvs {
+ *(at.Index(i).Addr().Interface().(*KeyValue)) = keyValue
+ }
+ return at.Interface()
+}
+
+// MarshalJSON returns the JSON encoding of the `*Set`.
+func (l *Set) MarshalJSON() ([]byte, error) {
+ return json.Marshal(l.equivalent.iface)
+}
+
+// Len implements `sort.Interface`.
+func (l *Sortable) Len() int {
+ return len(*l)
+}
+
+// Swap implements `sort.Interface`.
+func (l *Sortable) Swap(i, j int) {
+ (*l)[i], (*l)[j] = (*l)[j], (*l)[i]
+}
+
+// Less implements `sort.Interface`.
+func (l *Sortable) Less(i, j int) bool {
+ return (*l)[i].Key < (*l)[j].Key
+}
diff --git a/vendor/go.opentelemetry.io/otel/label/type_string.go b/vendor/go.opentelemetry.io/otel/label/type_string.go
new file mode 100644
index 0000000..62afeb6
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/label/type_string.go
@@ -0,0 +1,32 @@
+// Code generated by "stringer -type=Type"; DO NOT EDIT.
+
+package label
+
+import "strconv"
+
+func _() {
+ // An "invalid array index" compiler error signifies that the constant values have changed.
+ // Re-run the stringer command to generate them again.
+ var x [1]struct{}
+ _ = x[INVALID-0]
+ _ = x[BOOL-1]
+ _ = x[INT32-2]
+ _ = x[INT64-3]
+ _ = x[UINT32-4]
+ _ = x[UINT64-5]
+ _ = x[FLOAT32-6]
+ _ = x[FLOAT64-7]
+ _ = x[STRING-8]
+ _ = x[ARRAY-9]
+}
+
+const _Type_name = "INVALIDBOOLINT32INT64UINT32UINT64FLOAT32FLOAT64STRINGARRAY"
+
+var _Type_index = [...]uint8{0, 7, 11, 16, 21, 27, 33, 40, 47, 53, 58}
+
+func (i Type) String() string {
+ if i < 0 || i >= Type(len(_Type_index)-1) {
+ return "Type(" + strconv.FormatInt(int64(i), 10) + ")"
+ }
+ return _Type_name[_Type_index[i]:_Type_index[i+1]]
+}
diff --git a/vendor/go.opentelemetry.io/otel/label/value.go b/vendor/go.opentelemetry.io/otel/label/value.go
new file mode 100644
index 0000000..679009b
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/label/value.go
@@ -0,0 +1,288 @@
+// 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.
+
+package label
+
+import (
+ "encoding/json"
+ "fmt"
+ "reflect"
+ "strconv"
+ "unsafe"
+
+ "go.opentelemetry.io/otel/internal"
+)
+
+//go:generate stringer -type=Type
+
+// Type describes the type of the data Value holds.
+type Type int
+
+// Value represents the value part in key-value pairs.
+type Value struct {
+ vtype Type
+ numeric uint64
+ stringly string
+ // TODO Lazy value type?
+
+ array interface{}
+}
+
+const (
+ INVALID Type = iota // No value.
+ BOOL // Boolean value, use AsBool() to get it.
+ INT32 // 32 bit signed integral value, use AsInt32() to get it.
+ INT64 // 64 bit signed integral value, use AsInt64() to get it.
+ UINT32 // 32 bit unsigned integral value, use AsUint32() to get it.
+ UINT64 // 64 bit unsigned integral value, use AsUint64() to get it.
+ FLOAT32 // 32 bit floating point value, use AsFloat32() to get it.
+ FLOAT64 // 64 bit floating point value, use AsFloat64() to get it.
+ STRING // String value, use AsString() to get it.
+ ARRAY // Array value of arbitrary type, use AsArray() to get it.
+)
+
+// BoolValue creates a BOOL Value.
+func BoolValue(v bool) Value {
+ return Value{
+ vtype: BOOL,
+ numeric: internal.BoolToRaw(v),
+ }
+}
+
+// Int64Value creates an INT64 Value.
+func Int64Value(v int64) Value {
+ return Value{
+ vtype: INT64,
+ numeric: internal.Int64ToRaw(v),
+ }
+}
+
+// Uint64Value creates a UINT64 Value.
+func Uint64Value(v uint64) Value {
+ return Value{
+ vtype: UINT64,
+ numeric: internal.Uint64ToRaw(v),
+ }
+}
+
+// Float64Value creates a FLOAT64 Value.
+func Float64Value(v float64) Value {
+ return Value{
+ vtype: FLOAT64,
+ numeric: internal.Float64ToRaw(v),
+ }
+}
+
+// Int32Value creates an INT32 Value.
+func Int32Value(v int32) Value {
+ return Value{
+ vtype: INT32,
+ numeric: internal.Int32ToRaw(v),
+ }
+}
+
+// Uint32Value creates a UINT32 Value.
+func Uint32Value(v uint32) Value {
+ return Value{
+ vtype: UINT32,
+ numeric: internal.Uint32ToRaw(v),
+ }
+}
+
+// Float32Value creates a FLOAT32 Value.
+func Float32Value(v float32) Value {
+ return Value{
+ vtype: FLOAT32,
+ numeric: internal.Float32ToRaw(v),
+ }
+}
+
+// StringValue creates a STRING Value.
+func StringValue(v string) Value {
+ return Value{
+ vtype: STRING,
+ stringly: v,
+ }
+}
+
+// IntValue creates either an INT32 or an INT64 Value, depending on whether
+// the int type is 32 or 64 bits wide.
+func IntValue(v int) Value {
+ if unsafe.Sizeof(v) == 4 {
+ return Int32Value(int32(v))
+ }
+ return Int64Value(int64(v))
+}
+
+// UintValue creates either a UINT32 or a UINT64 Value, depending on whether
+// the uint type is 32 or 64 bits wide.
+func UintValue(v uint) Value {
+ if unsafe.Sizeof(v) == 4 {
+ return Uint32Value(uint32(v))
+ }
+ return Uint64Value(uint64(v))
+}
+
+// ArrayValue creates an ARRAY value from an array or slice.
+// Only arrays or slices of bool, int, int32, int64, uint, uint32, uint64,
+// float, float32, float64, or string types are allowed. Specifically, arrays
+// and slices can not contain other arrays, slices, structs, or non-standard
+// types. If the passed value is not an array or slice of these types an
+// INVALID value is returned.
+func ArrayValue(v interface{}) Value {
+ switch reflect.TypeOf(v).Kind() {
+ case reflect.Array, reflect.Slice:
+ // get array type regardless of dimensions
+ typ := reflect.TypeOf(v).Elem()
+ kind := typ.Kind()
+ switch kind {
+ case reflect.Bool, reflect.Int, reflect.Int32, reflect.Int64,
+ reflect.Float32, reflect.Float64, reflect.String,
+ reflect.Uint, reflect.Uint32, reflect.Uint64:
+ val := reflect.ValueOf(v)
+ length := val.Len()
+ frozen := reflect.Indirect(reflect.New(reflect.ArrayOf(length, typ)))
+ reflect.Copy(frozen, val)
+ return Value{
+ vtype: ARRAY,
+ array: frozen.Interface(),
+ }
+ default:
+ return Value{vtype: INVALID}
+ }
+ }
+ return Value{vtype: INVALID}
+}
+
+// Type returns a type of the Value.
+func (v Value) Type() Type {
+ return v.vtype
+}
+
+// AsBool returns the bool value. Make sure that the Value's type is
+// BOOL.
+func (v Value) AsBool() bool {
+ return internal.RawToBool(v.numeric)
+}
+
+// AsInt32 returns the int32 value. Make sure that the Value's type is
+// INT32.
+func (v Value) AsInt32() int32 {
+ return internal.RawToInt32(v.numeric)
+}
+
+// AsInt64 returns the int64 value. Make sure that the Value's type is
+// INT64.
+func (v Value) AsInt64() int64 {
+ return internal.RawToInt64(v.numeric)
+}
+
+// AsUint32 returns the uint32 value. Make sure that the Value's type
+// is UINT32.
+func (v Value) AsUint32() uint32 {
+ return internal.RawToUint32(v.numeric)
+}
+
+// AsUint64 returns the uint64 value. Make sure that the Value's type is
+// UINT64.
+func (v Value) AsUint64() uint64 {
+ return internal.RawToUint64(v.numeric)
+}
+
+// AsFloat32 returns the float32 value. Make sure that the Value's
+// type is FLOAT32.
+func (v Value) AsFloat32() float32 {
+ return internal.RawToFloat32(v.numeric)
+}
+
+// AsFloat64 returns the float64 value. Make sure that the Value's
+// type is FLOAT64.
+func (v Value) AsFloat64() float64 {
+ return internal.RawToFloat64(v.numeric)
+}
+
+// AsString returns the string value. Make sure that the Value's type
+// is STRING.
+func (v Value) AsString() string {
+ return v.stringly
+}
+
+// AsArray returns the array Value as an interface{}.
+func (v Value) AsArray() interface{} {
+ return v.array
+}
+
+type unknownValueType struct{}
+
+// AsInterface returns Value's data as interface{}.
+func (v Value) AsInterface() interface{} {
+ switch v.Type() {
+ case ARRAY:
+ return v.AsArray()
+ case BOOL:
+ return v.AsBool()
+ case INT32:
+ return v.AsInt32()
+ case INT64:
+ return v.AsInt64()
+ case UINT32:
+ return v.AsUint32()
+ case UINT64:
+ return v.AsUint64()
+ case FLOAT32:
+ return v.AsFloat32()
+ case FLOAT64:
+ return v.AsFloat64()
+ case STRING:
+ return v.stringly
+ }
+ return unknownValueType{}
+}
+
+// Emit returns a string representation of Value's data.
+func (v Value) Emit() string {
+ switch v.Type() {
+ case ARRAY:
+ return fmt.Sprint(v.array)
+ case BOOL:
+ return strconv.FormatBool(v.AsBool())
+ case INT32:
+ return strconv.FormatInt(int64(v.AsInt32()), 10)
+ case INT64:
+ return strconv.FormatInt(v.AsInt64(), 10)
+ case UINT32:
+ return strconv.FormatUint(uint64(v.AsUint32()), 10)
+ case UINT64:
+ return strconv.FormatUint(v.AsUint64(), 10)
+ case FLOAT32:
+ return fmt.Sprint(v.AsFloat32())
+ case FLOAT64:
+ return fmt.Sprint(v.AsFloat64())
+ case STRING:
+ return v.stringly
+ default:
+ return "unknown"
+ }
+}
+
+// MarshalJSON returns the JSON encoding of the Value.
+func (v Value) MarshalJSON() ([]byte, error) {
+ var jsonVal struct {
+ Type string
+ Value interface{}
+ }
+ jsonVal.Type = v.Type().String()
+ jsonVal.Value = v.AsInterface()
+ return json.Marshal(jsonVal)
+}