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  }