package attribute
import (
"fmt"
"reflect"
"go.opentelemetry.io/otel/attribute/internal/xxhash"
)
const (
boolID uint64 = 7953749933313450591
int64ID uint64 = 7592915492740740150
float64ID uint64 = 7376742710626956342
stringID uint64 = 6874584755375207263
boolSliceID uint64 = 6875993255270243167
int64SliceID uint64 = 3762322556277578591
float64SliceID uint64 = 7308324551835016539
stringSliceID uint64 = 7453010373645655387
byteSliceID uint64 = 6874028470941080415
sliceID uint64 = 7883494272577650031
emptyID uint64 = 7305809155345288421
)
func hashKVs (kvs []KeyValue ) uint64 {
h := xxhash .New ()
for _ , kv := range kvs {
h = hashKV (h , kv )
}
return h .Sum64 ()
}
func hashKV (h xxhash .Hash , kv KeyValue ) xxhash .Hash {
h = h .String (string (kv .Key ))
return hashValue (h , kv .Value )
}
func hashValue (h xxhash .Hash , v Value ) xxhash .Hash {
switch v .Type () {
case BOOL :
h = h .Uint64 (boolID )
h = h .Uint64 (v .numeric )
case INT64 :
h = h .Uint64 (int64ID )
h = h .Uint64 (v .numeric )
case FLOAT64 :
h = h .Uint64 (float64ID )
h = h .Uint64 (v .numeric )
case STRING :
h = h .Uint64 (stringID )
h = h .String (v .stringly )
case BOOLSLICE :
h = h .Uint64 (boolSliceID )
rv := reflect .ValueOf (v .slice )
for i := 0 ; i < rv .Len (); i ++ {
h = h .Bool (rv .Index (i ).Bool ())
}
case INT64SLICE :
h = h .Uint64 (int64SliceID )
rv := reflect .ValueOf (v .slice )
for i := 0 ; i < rv .Len (); i ++ {
h = h .Int64 (rv .Index (i ).Int ())
}
case FLOAT64SLICE :
h = h .Uint64 (float64SliceID )
rv := reflect .ValueOf (v .slice )
for i := 0 ; i < rv .Len (); i ++ {
h = h .Float64 (rv .Index (i ).Float ())
}
case STRINGSLICE :
h = h .Uint64 (stringSliceID )
rv := reflect .ValueOf (v .slice )
for i := 0 ; i < rv .Len (); i ++ {
h = h .String (rv .Index (i ).String ())
}
case BYTESLICE :
h = h .Uint64 (byteSliceID )
h = h .String (v .stringly )
case SLICE :
h = h .Uint64 (sliceID )
switch vals := v .slice .(type ) {
case [0 ]Value :
case [1 ]Value :
h = hashValueSlice (h , vals [:])
case [2 ]Value :
h = hashValueSlice (h , vals [:])
case [3 ]Value :
h = hashValueSlice (h , vals [:])
case [4 ]Value :
h = hashValueSlice (h , vals [:])
case [5 ]Value :
h = hashValueSlice (h , vals [:])
default :
rv := reflect .ValueOf (v .slice )
for i := 0 ; i < rv .Len (); i ++ {
h = hashValue (h , rv .Index (i ).Interface ().(Value ))
}
}
case EMPTY :
h = h .Uint64 (emptyID )
default :
val := v .AsInterface ()
msg := fmt .Sprintf ("unknown value type: %[1]v (%[1]T)" , val )
panic (msg )
}
return h
}
func hashValueSlice (h xxhash .Hash , vals []Value ) xxhash .Hash {
for _ , v := range vals {
h = hashValue (h , v )
}
return h
}
The pages are generated with Golds v0.8.4 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .