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 (
	
	
	
	
)

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)
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.
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()`.
keyValueType is used in `computeDistinctReflect`.
emptySet is returned for empty label sets.
	emptySet = &Set{
		equivalent: Distinct{
			iface: [0]KeyValue{},
		},
	}
)

const maxConcurrentEncoders = 3

func () *Set {
	return emptySet
}
reflect abbreviates `reflect.ValueOf`.
func ( Distinct) () reflect.Value {
	return reflect.ValueOf(.iface)
}
Valid returns true if this value refers to a valid `*Set`.
func ( Distinct) () bool {
	return .iface != nil
}
Len returns the number of labels in this set.
func ( *Set) () int {
	if  == nil || !.equivalent.Valid() {
		return 0
	}
	return .equivalent.reflect().Len()
}
Get returns the KeyValue at ordered position `idx` in this set.
func ( *Set) ( int) (KeyValue, bool) {
	if  == nil {
		return KeyValue{}, false
	}
	 := .equivalent.reflect()

Note: The Go compiler successfully avoids an allocation for the interface{} conversion here:
		return .Index().Interface().(KeyValue), true
	}

	return KeyValue{}, false
}
Value returns the value of a specified key in this set.
func ( *Set) ( Key) (Value, bool) {
	if  == nil {
		return Value{}, false
	}
	 := .equivalent.reflect()
	 := .Len()

	 := sort.Search(, func( int) bool {
		return .Index().Interface().(KeyValue).Key >= 
	})
	if  >=  {
		return Value{}, false
	}
	 := .Index().Interface().(KeyValue)
	if  == .Key {
		return .Value, true
	}
	return Value{}, false
}
HasValue tests whether a key is defined in this set.
func ( *Set) ( Key) bool {
	if  == nil {
		return false
	}
	,  := .Value()
	return 
}
Iter returns an iterator for visiting the labels in this set.
func ( *Set) () Iterator {
	return Iterator{
		storage: ,
		idx:     -1,
	}
}
ToSlice returns the set of labels belonging to this set, sorted, where keys appear no more than once.
func ( *Set) () []KeyValue {
	 := .Iter()
	return .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 ( *Set) () Distinct {
	if  == nil || !.equivalent.Valid() {
		return emptySet.equivalent
	}
	return .equivalent
}
Equals returns true if the argument set is equivalent to this set.
func ( *Set) ( *Set) bool {
	return .Equivalent() == .Equivalent()
}
Encoded returns the encoded form of this set, according to `encoder`. The result will be cached in this `*Set`.
func ( *Set) ( Encoder) string {
	if  == nil ||  == nil {
		return ""
	}

	 := .ID()
Invalid IDs are not cached.
		return .Encode(.Iter())
	}

	var  *string
	.lock.Lock()
	for  := 0;  < maxConcurrentEncoders; ++ {
		if .encoders[] ==  {
			 = &.encoded[]
			break
		}
	}
	.lock.Unlock()

	if  != nil {
		return *
	}

	 := .Encode(.Iter())

	.lock.Lock()
	defer .lock.Unlock()

	for  := 0;  < maxConcurrentEncoders; ++ {
		if .encoders[] ==  {
			return .encoded[]
		}
		if !.encoders[].Valid() {
			.encoders[] = 
			.encoded[] = 
			return 
		}
	}
TODO: This is a performance cliff. Find a way for this to generate a warning.
	return 
}

func () 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`.
Check for empty set.
	if len() == 0 {
		return empty()
	}
	,  := NewSetWithSortableFiltered(, new(Sortable), nil)
	return  //nolint
}
NewSetWithSortable returns a new `Set`. See the documentation for `NewSetWithSortableFiltered` for more details. This call includes a `*Sortable` option as a memory optimization.
Check for empty set.
	if len() == 0 {
		return empty()
	}
	,  := NewSetWithSortableFiltered(, , nil)
	return  //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.
Check for empty set.
	if len() == 0 {
		return empty(), nil
	}
	return NewSetWithSortableFiltered(, new(Sortable), )
}
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).
Check for empty set.
	if len() == 0 {
		return empty(), nil
	}

	* = 
Stable sort so the following de-duplication can implement last-value-wins semantics.
	sort.Stable()

	* = nil

	 := len() - 1
	 :=  - 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 ;  >= 0; -- {
		if [].Key == [].Key {
			continue
		}
		--
		[], [] = [], []
	}
	if  != nil {
		return filterSet([:], )
	}
	return Set{
		equivalent: computeDistinct([:]),
	}, nil
}
filterSet reorders `kvs` so that included keys are contiguous at the end of the slice, while excluded keys precede the included keys.
func ( []KeyValue,  Filter) (Set, []KeyValue) {
	var  []KeyValue
Move labels that do not match the filter so they're adjacent before calling computeDistinct().
	 := len()
Swap indistinct keys forward and distinct keys toward the end of the slice.
	 := len() - 1
	for ;  >= 0; -- {
		if ([]) {
			--
			[], [] = [], []
			continue
		}
	}
	 = [:]

	return Set{
		equivalent: computeDistinct([:]),
	}, 
}
Filter returns a filtered copy of this `Set`. See the documentation for `NewSetWithSortableFiltered` for more details.
func ( *Set) ( Filter) (Set, []KeyValue) {
	if  == nil {
		return Set{
			equivalent: .equivalent,
		}, nil
	}
Note: This could be refactored to avoid the temporary slice allocation, if it proves to be expensive.
	return filterSet(.ToSlice(), )
}
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 ( []KeyValue) Distinct {
	 := computeDistinctFixed()
	if  == nil {
		 = computeDistinctReflect()
	}
	return Distinct{
		iface: ,
	}
}
computeDistinctFixed computes a `Distinct` for small slices. It returns nil if the input is too large for this code path.
func ( []KeyValue) interface{} {
	switch len() {
	case 1:
		 := new([1]KeyValue)
		copy((*)[:], )
		return *
	case 2:
		 := new([2]KeyValue)
		copy((*)[:], )
		return *
	case 3:
		 := new([3]KeyValue)
		copy((*)[:], )
		return *
	case 4:
		 := new([4]KeyValue)
		copy((*)[:], )
		return *
	case 5:
		 := new([5]KeyValue)
		copy((*)[:], )
		return *
	case 6:
		 := new([6]KeyValue)
		copy((*)[:], )
		return *
	case 7:
		 := new([7]KeyValue)
		copy((*)[:], )
		return *
	case 8:
		 := new([8]KeyValue)
		copy((*)[:], )
		return *
	case 9:
		 := new([9]KeyValue)
		copy((*)[:], )
		return *
	case 10:
		 := new([10]KeyValue)
		copy((*)[:], )
		return *
	default:
		return nil
	}
}
computeDistinctReflect computes a `Distinct` using reflection, works for any size input.
func ( []KeyValue) interface{} {
	 := reflect.New(reflect.ArrayOf(len(), keyValueType)).Elem()
	for ,  := range  {
		*(.Index().Addr().Interface().(*KeyValue)) = 
	}
	return .Interface()
}
MarshalJSON returns the JSON encoding of the `*Set`.
func ( *Set) () ([]byte, error) {
	return json.Marshal(.equivalent.iface)
}
Len implements `sort.Interface`.
func ( *Sortable) () int {
	return len(*)
}
Swap implements `sort.Interface`.
func ( *Sortable) (,  int) {
	(*)[], (*)[] = (*)[], (*)[]
}
Less implements `sort.Interface`.
func ( *Sortable) (,  int) bool {
	return (*)[].Key < (*)[].Key