Skip to content

Instantly share code, notes, and snippets.

@carl-mastrangelo
Last active January 27, 2023 21:25
Show Gist options
  • Save carl-mastrangelo/8e0c64e8b4588669857808f37aebcdac to your computer and use it in GitHub Desktop.
Save carl-mastrangelo/8e0c64e8b4588669857808f37aebcdac to your computer and use it in GitHub Desktop.
Golang hash function
// https://play.golang.org/p/auAxrJQ1b1
package main
import (
"fmt"
"reflect"
"unsafe"
)
type rtype struct {
size uintptr
ptrdata uintptr // number of bytes in the type that can contain pointers
hash uint32 // hash of type; avoids computation in hash tables
tflag uint8 // extra type information flags
align uint8 // alignment of variable with this type
fieldAlign uint8 // alignment of struct field with this type
kind uint8 // enumeration for C
alg *typeAlg // algorithm table
gcdata *byte // garbage collection data
str int32 // string form
ptrToThis int32 // type for pointer to this type, may be zero
}
// a copy of runtime.typeAlg
type typeAlg struct {
hash func(unsafe.Pointer, uintptr) uintptr
equal func(unsafe.Pointer, unsafe.Pointer) bool
}
type iface struct {
tab uintptr
data unsafe.Pointer
}
func getalgs(example interface{}, seed uintptr) (hash func(in interface{}) uintptr, equal func(a, b interface{}) bool) {
typ := reflect.ValueOf(reflect.TypeOf(example))
rt := *(*rtype)(unsafe.Pointer(typ.Pointer()))
alg := rt.alg
origiface := *(*iface)(unsafe.Pointer(&example))
origitab := origiface.tab
hash = func(in interface{}) uintptr {
is := *(*iface)(unsafe.Pointer(uintptr(unsafe.Pointer(&in))))
if is.tab != origitab {
panic("wrong type")
}
return alg.hash(is.data, seed)
}
equal = func(a, b interface{}) bool {
leftiface := *(*iface)(unsafe.Pointer(&a))
rightiface := *(*iface)(unsafe.Pointer(&a))
if leftiface.tab != origitab || rightiface.tab != origitab {
panic("wrong type")
}
return alg.equal(leftiface.data, rightiface.data)
}
return
}
func main() {
hash, equal := getalgs(2, 0)
fmt.Println(hash(4))
hash(1)
fmt.Println(equal(*new(int), *new(int)))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment