v8.run/go/exp@v0.0.26-0.20230226010534-afcdbd3f782d/hash/hashutil/hasher.go (about) 1 package hashutil 2 3 import ( 4 "reflect" 5 "unsafe" 6 7 "v8.run/go/exp/hash/wyhash" 8 ) 9 10 func Hasher[T comparable](seed uint64) func(T) uint64 { 11 var v T 12 t := reflect.TypeOf(v) 13 14 // Mix Seed 15 wyhash.WYRAND(&seed) 16 wyhash.WYRAND(&seed) 17 18 switch t.Kind() { 19 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, 20 reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, 21 reflect.Float32, reflect.Float64, reflect.Bool, 22 reflect.Complex64, reflect.Complex128, 23 reflect.Pointer, reflect.UnsafePointer, reflect.Uintptr: 24 return func(v T) uint64 { 25 return wyhash.WYHASH_RAW( 26 unsafe.Pointer(&v), 27 unsafe.Sizeof(v), 28 seed, 29 ) 30 } 31 case reflect.String: 32 return func(v T) uint64 { 33 return wyhash.HashString(*(*string)(unsafe.Pointer(&v)), seed) 34 } 35 case reflect.Slice: 36 switch t.Elem().Kind() { 37 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, 38 reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, 39 reflect.Float32, reflect.Float64, reflect.Bool, 40 reflect.Complex64, reflect.Complex128, 41 reflect.Pointer, reflect.UnsafePointer, reflect.Uintptr: 42 return func(v T) uint64 { 43 sh := (*reflect.SliceHeader)(unsafe.Pointer(&v)) 44 return wyhash.WYHASH_RAW( 45 unsafe.Pointer(sh.Data), 46 unsafe.Sizeof(v)*uintptr(sh.Len), 47 seed, 48 ) 49 } 50 } 51 } 52 53 return nil 54 }