mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-12-24 19:30:06 +01:00
284 lines
8.8 KiB
Go
284 lines
8.8 KiB
Go
// Copyright The OpenTelemetry Authors
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package pcommon // import "go.opentelemetry.io/collector/pdata/pcommon"
|
|
|
|
import (
|
|
"go.uber.org/multierr"
|
|
|
|
"go.opentelemetry.io/collector/pdata/internal"
|
|
otlpcommon "go.opentelemetry.io/collector/pdata/internal/data/protogen/common/v1"
|
|
)
|
|
|
|
// Map stores a map of string keys to elements of Value type.
|
|
//
|
|
// Must use NewMap function to create new instances.
|
|
// Important: zero-initialized instance is not valid for use.
|
|
type Map internal.Map
|
|
|
|
// NewMap creates a Map with 0 elements.
|
|
func NewMap() Map {
|
|
orig := []otlpcommon.KeyValue(nil)
|
|
state := internal.StateMutable
|
|
return Map(internal.NewMap(&orig, &state))
|
|
}
|
|
|
|
func (m Map) getOrig() *[]otlpcommon.KeyValue {
|
|
return internal.GetOrigMap(internal.Map(m))
|
|
}
|
|
|
|
func (m Map) getState() *internal.State {
|
|
return internal.GetMapState(internal.Map(m))
|
|
}
|
|
|
|
func newMap(orig *[]otlpcommon.KeyValue, state *internal.State) Map {
|
|
return Map(internal.NewMap(orig, state))
|
|
}
|
|
|
|
// Clear erases any existing entries in this Map instance.
|
|
func (m Map) Clear() {
|
|
m.getState().AssertMutable()
|
|
*m.getOrig() = nil
|
|
}
|
|
|
|
// EnsureCapacity increases the capacity of this Map instance, if necessary,
|
|
// to ensure that it can hold at least the number of elements specified by the capacity argument.
|
|
func (m Map) EnsureCapacity(capacity int) {
|
|
m.getState().AssertMutable()
|
|
oldOrig := *m.getOrig()
|
|
if capacity <= cap(oldOrig) {
|
|
return
|
|
}
|
|
*m.getOrig() = make([]otlpcommon.KeyValue, len(oldOrig), capacity)
|
|
copy(*m.getOrig(), oldOrig)
|
|
}
|
|
|
|
// Get returns the Value associated with the key and true. Returned
|
|
// Value is not a copy, it is a reference to the value stored in this map.
|
|
// It is allowed to modify the returned value using Value.Set* functions.
|
|
// Such modification will be applied to the value stored in this map.
|
|
//
|
|
// If the key does not exist returns a zero-initialized KeyValue and false.
|
|
// Calling any functions on the returned invalid instance may cause a panic.
|
|
func (m Map) Get(key string) (Value, bool) {
|
|
for i := range *m.getOrig() {
|
|
akv := &(*m.getOrig())[i]
|
|
if akv.Key == key {
|
|
return newValue(&akv.Value, m.getState()), true
|
|
}
|
|
}
|
|
return newValue(nil, m.getState()), false
|
|
}
|
|
|
|
// Remove removes the entry associated with the key and returns true if the key
|
|
// was present in the map, otherwise returns false.
|
|
func (m Map) Remove(key string) bool {
|
|
m.getState().AssertMutable()
|
|
for i := range *m.getOrig() {
|
|
akv := &(*m.getOrig())[i]
|
|
if akv.Key == key {
|
|
*akv = (*m.getOrig())[len(*m.getOrig())-1]
|
|
*m.getOrig() = (*m.getOrig())[:len(*m.getOrig())-1]
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// RemoveIf removes the entries for which the function in question returns true
|
|
func (m Map) RemoveIf(f func(string, Value) bool) {
|
|
m.getState().AssertMutable()
|
|
newLen := 0
|
|
for i := 0; i < len(*m.getOrig()); i++ {
|
|
akv := &(*m.getOrig())[i]
|
|
if f(akv.Key, newValue(&akv.Value, m.getState())) {
|
|
continue
|
|
}
|
|
if newLen == i {
|
|
// Nothing to move, element is at the right place.
|
|
newLen++
|
|
continue
|
|
}
|
|
(*m.getOrig())[newLen] = (*m.getOrig())[i]
|
|
newLen++
|
|
}
|
|
*m.getOrig() = (*m.getOrig())[:newLen]
|
|
}
|
|
|
|
// PutEmpty inserts or updates an empty value to the map under given key
|
|
// and return the updated/inserted value.
|
|
func (m Map) PutEmpty(k string) Value {
|
|
m.getState().AssertMutable()
|
|
if av, existing := m.Get(k); existing {
|
|
av.getOrig().Value = nil
|
|
return newValue(av.getOrig(), m.getState())
|
|
}
|
|
*m.getOrig() = append(*m.getOrig(), otlpcommon.KeyValue{Key: k})
|
|
return newValue(&(*m.getOrig())[len(*m.getOrig())-1].Value, m.getState())
|
|
}
|
|
|
|
// PutStr performs the Insert or Update action. The Value is
|
|
// inserted to the map that did not originally have the key. The key/value is
|
|
// updated to the map where the key already existed.
|
|
func (m Map) PutStr(k string, v string) {
|
|
m.getState().AssertMutable()
|
|
if av, existing := m.Get(k); existing {
|
|
av.SetStr(v)
|
|
} else {
|
|
*m.getOrig() = append(*m.getOrig(), newKeyValueString(k, v))
|
|
}
|
|
}
|
|
|
|
// PutInt performs the Insert or Update action. The int Value is
|
|
// inserted to the map that did not originally have the key. The key/value is
|
|
// updated to the map where the key already existed.
|
|
func (m Map) PutInt(k string, v int64) {
|
|
m.getState().AssertMutable()
|
|
if av, existing := m.Get(k); existing {
|
|
av.SetInt(v)
|
|
} else {
|
|
*m.getOrig() = append(*m.getOrig(), newKeyValueInt(k, v))
|
|
}
|
|
}
|
|
|
|
// PutDouble performs the Insert or Update action. The double Value is
|
|
// inserted to the map that did not originally have the key. The key/value is
|
|
// updated to the map where the key already existed.
|
|
func (m Map) PutDouble(k string, v float64) {
|
|
m.getState().AssertMutable()
|
|
if av, existing := m.Get(k); existing {
|
|
av.SetDouble(v)
|
|
} else {
|
|
*m.getOrig() = append(*m.getOrig(), newKeyValueDouble(k, v))
|
|
}
|
|
}
|
|
|
|
// PutBool performs the Insert or Update action. The bool Value is
|
|
// inserted to the map that did not originally have the key. The key/value is
|
|
// updated to the map where the key already existed.
|
|
func (m Map) PutBool(k string, v bool) {
|
|
m.getState().AssertMutable()
|
|
if av, existing := m.Get(k); existing {
|
|
av.SetBool(v)
|
|
} else {
|
|
*m.getOrig() = append(*m.getOrig(), newKeyValueBool(k, v))
|
|
}
|
|
}
|
|
|
|
// PutEmptyBytes inserts or updates an empty byte slice under given key and returns it.
|
|
func (m Map) PutEmptyBytes(k string) ByteSlice {
|
|
m.getState().AssertMutable()
|
|
bv := otlpcommon.AnyValue_BytesValue{}
|
|
if av, existing := m.Get(k); existing {
|
|
av.getOrig().Value = &bv
|
|
} else {
|
|
*m.getOrig() = append(*m.getOrig(), otlpcommon.KeyValue{Key: k, Value: otlpcommon.AnyValue{Value: &bv}})
|
|
}
|
|
return ByteSlice(internal.NewByteSlice(&bv.BytesValue, m.getState()))
|
|
}
|
|
|
|
// PutEmptyMap inserts or updates an empty map under given key and returns it.
|
|
func (m Map) PutEmptyMap(k string) Map {
|
|
m.getState().AssertMutable()
|
|
kvl := otlpcommon.AnyValue_KvlistValue{KvlistValue: &otlpcommon.KeyValueList{Values: []otlpcommon.KeyValue(nil)}}
|
|
if av, existing := m.Get(k); existing {
|
|
av.getOrig().Value = &kvl
|
|
} else {
|
|
*m.getOrig() = append(*m.getOrig(), otlpcommon.KeyValue{Key: k, Value: otlpcommon.AnyValue{Value: &kvl}})
|
|
}
|
|
return Map(internal.NewMap(&kvl.KvlistValue.Values, m.getState()))
|
|
}
|
|
|
|
// PutEmptySlice inserts or updates an empty slice under given key and returns it.
|
|
func (m Map) PutEmptySlice(k string) Slice {
|
|
m.getState().AssertMutable()
|
|
vl := otlpcommon.AnyValue_ArrayValue{ArrayValue: &otlpcommon.ArrayValue{Values: []otlpcommon.AnyValue(nil)}}
|
|
if av, existing := m.Get(k); existing {
|
|
av.getOrig().Value = &vl
|
|
} else {
|
|
*m.getOrig() = append(*m.getOrig(), otlpcommon.KeyValue{Key: k, Value: otlpcommon.AnyValue{Value: &vl}})
|
|
}
|
|
return Slice(internal.NewSlice(&vl.ArrayValue.Values, m.getState()))
|
|
}
|
|
|
|
// Len returns the length of this map.
|
|
//
|
|
// Because the Map is represented internally by a slice of pointers, and the data are comping from the wire,
|
|
// it is possible that when iterating using "Range" to get access to fewer elements because nil elements are skipped.
|
|
func (m Map) Len() int {
|
|
return len(*m.getOrig())
|
|
}
|
|
|
|
// Range calls f sequentially for each key and value present in the map. If f returns false, range stops the iteration.
|
|
//
|
|
// Example:
|
|
//
|
|
// sm.Range(func(k string, v Value) bool {
|
|
// ...
|
|
// })
|
|
func (m Map) Range(f func(k string, v Value) bool) {
|
|
for i := range *m.getOrig() {
|
|
kv := &(*m.getOrig())[i]
|
|
if !f(kv.Key, Value(internal.NewValue(&kv.Value, m.getState()))) {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
// CopyTo copies all elements from the current map overriding the destination.
|
|
func (m Map) CopyTo(dest Map) {
|
|
dest.getState().AssertMutable()
|
|
newLen := len(*m.getOrig())
|
|
oldCap := cap(*dest.getOrig())
|
|
if newLen <= oldCap {
|
|
// New slice fits in existing slice, no need to reallocate.
|
|
*dest.getOrig() = (*dest.getOrig())[:newLen:oldCap]
|
|
for i := range *m.getOrig() {
|
|
akv := &(*m.getOrig())[i]
|
|
destAkv := &(*dest.getOrig())[i]
|
|
destAkv.Key = akv.Key
|
|
newValue(&akv.Value, m.getState()).CopyTo(newValue(&destAkv.Value, dest.getState()))
|
|
}
|
|
return
|
|
}
|
|
|
|
// New slice is bigger than exist slice. Allocate new space.
|
|
origs := make([]otlpcommon.KeyValue, len(*m.getOrig()))
|
|
for i := range *m.getOrig() {
|
|
akv := &(*m.getOrig())[i]
|
|
origs[i].Key = akv.Key
|
|
newValue(&akv.Value, m.getState()).CopyTo(newValue(&origs[i].Value, dest.getState()))
|
|
}
|
|
*dest.getOrig() = origs
|
|
}
|
|
|
|
// AsRaw returns a standard go map representation of this Map.
|
|
func (m Map) AsRaw() map[string]any {
|
|
rawMap := make(map[string]any)
|
|
m.Range(func(k string, v Value) bool {
|
|
rawMap[k] = v.AsRaw()
|
|
return true
|
|
})
|
|
return rawMap
|
|
}
|
|
|
|
// FromRaw overrides this Map instance from a standard go map.
|
|
func (m Map) FromRaw(rawMap map[string]any) error {
|
|
m.getState().AssertMutable()
|
|
if len(rawMap) == 0 {
|
|
*m.getOrig() = nil
|
|
return nil
|
|
}
|
|
|
|
var errs error
|
|
origs := make([]otlpcommon.KeyValue, len(rawMap))
|
|
ix := 0
|
|
for k, iv := range rawMap {
|
|
origs[ix].Key = k
|
|
errs = multierr.Append(errs, newValue(&origs[ix].Value, m.getState()).FromRaw(iv))
|
|
ix++
|
|
}
|
|
*m.getOrig() = origs
|
|
return errs
|
|
}
|