github.com/TeaOSLab/EdgeNode@v1.3.8/internal/metrics/stat.go (about) 1 // Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved. 2 3 package metrics 4 5 import ( 6 "bytes" 7 "encoding/binary" 8 "errors" 9 byteutils "github.com/TeaOSLab/EdgeNode/internal/utils/byte" 10 "github.com/TeaOSLab/EdgeNode/internal/utils/fnv" 11 "strconv" 12 "strings" 13 ) 14 15 type Stat struct { 16 ServerId int64 `json:"serverId"` 17 Keys []string `json:"keys"` 18 Hash string `json:"hash"` 19 Value int64 `json:"value"` 20 Time string `json:"time"` 21 } 22 23 func UniqueKey(serverId int64, keys []string, time string, version int32, itemId int64) string { 24 var keysData = strings.Join(keys, "$EDGE$") 25 return strconv.FormatUint(fnv.HashString(strconv.FormatInt(serverId, 10)+"@"+keysData+"@"+time+"@"+strconv.Itoa(int(version))+"@"+strconv.FormatInt(itemId, 10)), 10) 26 } 27 28 func (this *Stat) UniqueKey(version int32, itemId int64) string { 29 return UniqueKey(this.ServerId, this.Keys, this.Time, version, itemId) 30 } 31 32 func (this *Stat) FullKey(version int32, itemId int64) string { 33 return this.Time + "_" + string(int32ToBigEndian(version)) + this.UniqueKey(version, itemId) 34 } 35 36 func (this *Stat) EncodeValueKey(version int32) string { 37 if this.Value < 0 { 38 this.Value = 0 39 } 40 41 return string(byteutils.Concat([]byte(this.Time), []byte{'_'}, int32ToBigEndian(version), int64ToBigEndian(this.ServerId), int64ToBigEndian(this.Value), []byte(this.Hash))) 42 } 43 44 func (this *Stat) EncodeSumKey(version int32) string { 45 return string(byteutils.Concat([]byte(this.Time), []byte{'_'}, int32ToBigEndian(version), int64ToBigEndian(this.ServerId))) 46 } 47 48 func DecodeValueKey(valueKey string) (serverId int64, timeString string, version int32, value int64, hash string, err error) { 49 var b = []byte(valueKey) 50 var timeIndex = bytes.Index(b, []byte{'_'}) 51 if timeIndex < 0 { 52 return 53 } 54 55 timeString = string(b[:timeIndex]) 56 b = b[timeIndex+1:] 57 58 if len(b) < 20+1 { 59 err = errors.New("invalid value key") 60 return 61 } 62 63 version = int32(binary.BigEndian.Uint32(b[0:4])) 64 serverId = int64(binary.BigEndian.Uint64(b[4:12])) 65 value = int64(binary.BigEndian.Uint64(b[12:20])) 66 hash = string(b[20:]) 67 return 68 } 69 70 func DecodeSumKey(sumKey string) (serverId int64, timeString string, version int32, err error) { 71 var b = []byte(sumKey) 72 var timeIndex = bytes.Index(b, []byte{'_'}) 73 if timeIndex < 0 { 74 return 75 } 76 77 timeString = string(b[:timeIndex]) 78 b = b[timeIndex+1:] 79 80 if len(b) < 12 { 81 err = errors.New("invalid sum key") 82 return 83 } 84 85 version = int32(binary.BigEndian.Uint32(b[:4])) 86 serverId = int64(binary.BigEndian.Uint64(b[4:12])) 87 return 88 } 89 90 func EncodeSumValue(count uint64, total uint64) []byte { 91 var result [16]byte 92 binary.BigEndian.PutUint64(result[:8], count) 93 binary.BigEndian.PutUint64(result[8:], total) 94 return result[:] 95 } 96 97 func DecodeSumValue(data []byte) (count uint64, total uint64) { 98 if len(data) != 16 { 99 return 100 } 101 count = binary.BigEndian.Uint64(data[:8]) 102 total = binary.BigEndian.Uint64(data[8:]) 103 return 104 } 105 106 func int64ToBigEndian(i int64) []byte { 107 if i < 0 { 108 i = 0 109 } 110 var b = make([]byte, 8) 111 binary.BigEndian.PutUint64(b, uint64(i)) 112 return b 113 } 114 115 func int32ToBigEndian(i int32) []byte { 116 if i < 0 { 117 i = 0 118 } 119 var b = make([]byte, 4) 120 binary.BigEndian.PutUint32(b, uint32(i)) 121 return b 122 }