github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/pkg/ingester/client/compat.go (about) 1 package client 2 3 import ( 4 "github.com/prometheus/common/model" 5 "github.com/prometheus/prometheus/model/labels" 6 7 "github.com/grafana/loki/pkg/logproto" 8 ) 9 10 const ( 11 // offset64 is an offset require for the FNV (Fowler-Noll-Vo) hash function. 12 offset64 = 14695981039346656037 13 // prime64 is a 64bit prime used by the FNV hash function. 14 prime64 = 1099511628211 15 ) 16 17 // hashNew initializes a new fnv64a hash value. 18 func hashNew() uint64 { 19 return offset64 20 } 21 22 // LabelsToKeyString is used to form a string to be used as 23 // the hashKey. Don't print, use l.String() for printing. 24 func LabelsToKeyString(l labels.Labels) string { 25 // We are allocating 1024, even though most series are less than 600b long. 26 // But this is not an issue as this function is being inlined when called in a loop 27 // and buffer allocated is a static buffer and not a dynamic buffer on the heap. 28 b := make([]byte, 0, 1024) 29 return string(l.Bytes(b)) 30 } 31 32 // FastFingerprint runs the same algorithm as Prometheus labelSetToFastFingerprint() 33 func FastFingerprint(ls []logproto.LabelAdapter) model.Fingerprint { 34 if len(ls) == 0 { 35 return model.Metric(nil).FastFingerprint() 36 } 37 38 var result uint64 39 for _, l := range ls { 40 sum := hashNew() 41 sum = hashAdd(sum, l.Name) 42 sum = hashAddByte(sum, model.SeparatorByte) 43 sum = hashAdd(sum, l.Value) 44 result ^= sum 45 } 46 return model.Fingerprint(result) 47 } 48 49 // Fingerprint runs the same algorithm as Prometheus labelSetToFingerprint() 50 func Fingerprint(labels labels.Labels) model.Fingerprint { 51 sum := hashNew() 52 for _, label := range labels { 53 sum = hashAddString(sum, label.Name) 54 sum = hashAddByte(sum, model.SeparatorByte) 55 sum = hashAddString(sum, label.Value) 56 sum = hashAddByte(sum, model.SeparatorByte) 57 } 58 return model.Fingerprint(sum) 59 }