github.com/kiali/kiali@v1.84.0/tracing/jaeger/model/keyvalue.go (about)

     1  // Copyright (c) 2019 The Jaeger Authors.
     2  // Copyright (c) 2017 Uber Technologies, Inc.
     3  //
     4  // Licensed under the Apache License, Version 2.0 (the "License");
     5  // you may not use this file except in compliance with the License.
     6  // You may obtain a copy of the License at
     7  //
     8  // http://www.apache.org/licenses/LICENSE-2.0
     9  //
    10  // Unless required by applicable law or agreed to in writing, software
    11  // distributed under the License is distributed on an "AS IS" BASIS,
    12  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  // See the License for the specific language governing permissions and
    14  // limitations under the License.
    15  
    16  // Cloned from github.com/jaegertracing/jaeger/
    17  
    18  //nolint
    19  package model
    20  
    21  import (
    22  	"bytes"
    23  	"encoding/binary"
    24  	"encoding/hex"
    25  	"fmt"
    26  	"io"
    27  	"sort"
    28  	"strconv"
    29  )
    30  
    31  // These constants are kept mostly for backwards compatibility.
    32  const (
    33  	// StringType indicates the value is a unicode string
    34  	StringType = ValueType_STRING
    35  	// BoolType indicates the value is a Boolean encoded as int64 number 0 or 1
    36  	BoolType = ValueType_BOOL
    37  	// Int64Type indicates the value is an int64 number
    38  	Int64Type = ValueType_INT64
    39  	// Float64Type indicates the value is a float64 number stored as int64
    40  	Float64Type = ValueType_FLOAT64
    41  	// BinaryType indicates the value is binary blob stored as a byte array
    42  	BinaryType = ValueType_BINARY
    43  )
    44  
    45  // KeyValues is a type alias that exposes convenience functions like Sort, FindByKey.
    46  type KeyValues []*KeyValue
    47  
    48  // String creates a String-typed KeyValue
    49  func String(key string, value string) KeyValue {
    50  	return KeyValue{Key: key, VType: StringType, VStr: value}
    51  }
    52  
    53  // Bool creates a Bool-typed KeyValue
    54  func Bool(key string, value bool) KeyValue {
    55  	return KeyValue{Key: key, VType: BoolType, VBool: value}
    56  }
    57  
    58  // Int64 creates a Int64-typed KeyValue
    59  func Int64(key string, value int64) KeyValue {
    60  	return KeyValue{Key: key, VType: Int64Type, VInt64: value}
    61  }
    62  
    63  // Float64 creates a Float64-typed KeyValue
    64  func Float64(key string, value float64) KeyValue {
    65  	return KeyValue{Key: key, VType: Float64Type, VFloat64: value}
    66  }
    67  
    68  // Binary creates a Binary-typed KeyValue
    69  func Binary(key string, value []byte) KeyValue {
    70  	return KeyValue{Key: key, VType: BinaryType, VBinary: value}
    71  }
    72  
    73  // Bool returns the Boolean value stored in this KeyValue or false if it stores a different type.
    74  // The caller must check VType before using this method.
    75  func (kv *KeyValue) Bool() bool {
    76  	if kv.VType == BoolType {
    77  		return kv.VBool
    78  	}
    79  	return false
    80  }
    81  
    82  // Int64 returns the Int64 value stored in this KeyValue or 0 if it stores a different type.
    83  // The caller must check VType before using this method.
    84  func (kv *KeyValue) Int64() int64 {
    85  	if kv.VType == Int64Type {
    86  		return kv.VInt64
    87  	}
    88  	return 0
    89  }
    90  
    91  // Float64 returns the Float64 value stored in this KeyValue or 0 if it stores a different type.
    92  // The caller must check VType before using this method.
    93  func (kv *KeyValue) Float64() float64 {
    94  	if kv.VType == Float64Type {
    95  		return kv.VFloat64
    96  	}
    97  	return 0
    98  }
    99  
   100  // Binary returns the blob ([]byte) value stored in this KeyValue or nil if it stores a different type.
   101  // The caller must check VType before using this method.
   102  func (kv *KeyValue) Binary() []byte {
   103  	if kv.VType == BinaryType {
   104  		return kv.VBinary
   105  	}
   106  	return nil
   107  }
   108  
   109  // Value returns typed values stored in KeyValue as interface{}.
   110  func (kv *KeyValue) Value() interface{} {
   111  	switch kv.VType {
   112  	case StringType:
   113  		return kv.VStr
   114  	case BoolType:
   115  		return kv.VBool
   116  	case Int64Type:
   117  		return kv.VInt64
   118  	case Float64Type:
   119  		return kv.VFloat64
   120  	case BinaryType:
   121  		return kv.VBinary
   122  	default:
   123  		return fmt.Errorf("unknown type %d", kv.VType)
   124  	}
   125  }
   126  
   127  // AsStringLossy returns a potentially lossy string representation of the value.
   128  func (kv *KeyValue) AsStringLossy() string {
   129  	return kv.asString(true)
   130  }
   131  
   132  // AsString returns a string representation of the value.
   133  func (kv *KeyValue) AsString() string {
   134  	return kv.asString(false)
   135  }
   136  
   137  func (kv *KeyValue) asString(truncate bool) string {
   138  	switch kv.VType {
   139  	case StringType:
   140  		return kv.VStr
   141  	case BoolType:
   142  		if kv.Bool() {
   143  			return "true"
   144  		}
   145  		return "false"
   146  	case Int64Type:
   147  		return strconv.FormatInt(kv.Int64(), 10)
   148  	case Float64Type:
   149  		return strconv.FormatFloat(kv.Float64(), 'g', 10, 64)
   150  	case BinaryType:
   151  		if truncate && len(kv.VBinary) > 256 {
   152  			return hex.EncodeToString(kv.VBinary[0:256]) + "..."
   153  		}
   154  		return hex.EncodeToString(kv.VBinary)
   155  	default:
   156  		return fmt.Sprintf("unknown type %d", kv.VType)
   157  	}
   158  }
   159  
   160  // IsLess compares KeyValue object with another KeyValue.
   161  // The order is based first on the keys, then on type, and finally on the value.
   162  func (kv *KeyValue) IsLess(two *KeyValue) bool {
   163  	return KeyValueCompare(kv, two) < 0
   164  }
   165  
   166  func (kvs KeyValues) Len() int      { return len(kvs) }
   167  func (kvs KeyValues) Swap(i, j int) { kvs[i], kvs[j] = kvs[j], kvs[i] }
   168  func (kvs KeyValues) Less(i, j int) bool {
   169  	return kvs[i].IsLess(kvs[j])
   170  }
   171  
   172  // Sort does in-place sorting of KeyValues, then by value type, then by value.
   173  func (kvs KeyValues) Sort() {
   174  	sort.Sort(kvs)
   175  }
   176  
   177  // FindByKey scans the list of key-values searching for the first one with the given key.
   178  // Returns found tag and a boolean flag indicating if the search was successful.
   179  func (kvs KeyValues) FindByKey(key string) (*KeyValue, bool) {
   180  	for _, kv := range kvs {
   181  		if kv.Key == key {
   182  			return kv, true
   183  		}
   184  	}
   185  	return &KeyValue{}, false
   186  }
   187  
   188  // Equal compares KeyValues with another list. Both lists must be already sorted.
   189  func (kvs KeyValues) Equal(other KeyValues) bool {
   190  	l1, l2 := len(kvs), len(other)
   191  	if l1 != l2 {
   192  		return false
   193  	}
   194  	for i := 0; i < l1; i++ {
   195  		if !kvs[i].Equal(&other[i]) {
   196  			return false
   197  		}
   198  	}
   199  	return true
   200  }
   201  
   202  // Hash implements Hash from Hashable.
   203  func (kvs KeyValues) Hash(w io.Writer) error {
   204  	for i := range kvs {
   205  		if err := kvs[i].Hash(w); err != nil {
   206  			return err
   207  		}
   208  	}
   209  	return nil
   210  }
   211  
   212  // Hash implements Hash from Hashable.
   213  func (kv KeyValue) Hash(w io.Writer) error {
   214  	if _, err := w.Write([]byte(kv.Key)); err != nil {
   215  		return err
   216  	}
   217  	if err := binary.Write(w, binary.BigEndian, uint16(kv.VType)); err != nil {
   218  		return err
   219  	}
   220  	var err error
   221  	switch kv.VType {
   222  	case StringType:
   223  		_, err = w.Write([]byte(kv.VStr))
   224  	case BoolType:
   225  		err = binary.Write(w, binary.BigEndian, kv.VBool)
   226  	case Int64Type:
   227  		err = binary.Write(w, binary.BigEndian, kv.VInt64)
   228  	case Float64Type:
   229  		err = binary.Write(w, binary.BigEndian, kv.VFloat64)
   230  	case BinaryType:
   231  		_, err = w.Write(kv.VBinary)
   232  	default:
   233  		err = fmt.Errorf("unknown type %d", kv.VType)
   234  	}
   235  	return err
   236  }
   237  
   238  func KeyValueCompare(this *KeyValue, that interface{}) int {
   239  	if that == nil {
   240  		if this == nil {
   241  			return 0
   242  		}
   243  		return 1
   244  	}
   245  
   246  	that1, ok := that.(*KeyValue)
   247  	if !ok {
   248  		that2, ok := that.(KeyValue)
   249  		if ok {
   250  			that1 = &that2
   251  		} else {
   252  			return 1
   253  		}
   254  	}
   255  	if that1 == nil {
   256  		if this == nil {
   257  			return 0
   258  		}
   259  		return 1
   260  	} else if this == nil {
   261  		return -1
   262  	}
   263  	if this.Key != that1.Key {
   264  		if this.Key < that1.Key {
   265  			return -1
   266  		}
   267  		return 1
   268  	}
   269  	if this.VType != that1.VType {
   270  		if this.VType < that1.VType {
   271  			return -1
   272  		}
   273  		return 1
   274  	}
   275  	if this.VStr != that1.VStr {
   276  		if this.VStr < that1.VStr {
   277  			return -1
   278  		}
   279  		return 1
   280  	}
   281  	if this.VBool != that1.VBool {
   282  		if !this.VBool {
   283  			return -1
   284  		}
   285  		return 1
   286  	}
   287  	if this.VInt64 != that1.VInt64 {
   288  		if this.VInt64 < that1.VInt64 {
   289  			return -1
   290  		}
   291  		return 1
   292  	}
   293  	if this.VFloat64 != that1.VFloat64 {
   294  		if this.VFloat64 < that1.VFloat64 {
   295  			return -1
   296  		}
   297  		return 1
   298  	}
   299  	if c := bytes.Compare(this.VBinary, that1.VBinary); c != 0 {
   300  		return c
   301  	}
   302  	return 0
   303  }
   304  func (this *KeyValue) Equal(that interface{}) bool {
   305  	if that == nil {
   306  		return this == nil
   307  	}
   308  
   309  	that1, ok := that.(*KeyValue)
   310  	if !ok {
   311  		that2, ok := that.(KeyValue)
   312  		if ok {
   313  			that1 = &that2
   314  		} else {
   315  			return false
   316  		}
   317  	}
   318  	if that1 == nil {
   319  		return this == nil
   320  	} else if this == nil {
   321  		return false
   322  	}
   323  	if this.Key != that1.Key {
   324  		return false
   325  	}
   326  	if this.VType != that1.VType {
   327  		return false
   328  	}
   329  	if this.VStr != that1.VStr {
   330  		return false
   331  	}
   332  	if this.VBool != that1.VBool {
   333  		return false
   334  	}
   335  	if this.VInt64 != that1.VInt64 {
   336  		return false
   337  	}
   338  	if this.VFloat64 != that1.VFloat64 {
   339  		return false
   340  	}
   341  	if !bytes.Equal(this.VBinary, that1.VBinary) {
   342  		return false
   343  	}
   344  	return true
   345  }