util/deephash: implement SelfHasher to allow types to hash themselves

Updates: corp#16409
Signed-off-by: Tom DNetto <tom@tailscale.com>
This commit is contained in:
Tom DNetto
2024-01-31 15:33:59 -08:00
committed by Tom
parent b4b2ec7801
commit 2aeef4e610
4 changed files with 62 additions and 2 deletions

View File

@@ -292,6 +292,14 @@ func makeTypeHasher(t reflect.Type) typeHasherFunc {
return hashAddr
}
// Types that implement their own hashing.
if t.Kind() != reflect.Pointer && t.Kind() != reflect.Interface {
// A method can be implemented on either the value receiver or pointer receiver.
if t.Implements(selfHasherType) || reflect.PointerTo(t).Implements(selfHasherType) {
return makeSelfHasherImpl(t)
}
}
// Types that can have their memory representation directly hashed.
if typeIsMemHashable(t) {
return makeMemHasher(t.Size())
@@ -350,6 +358,13 @@ func hashAddr(h *hasher, p pointer) {
}
}
func makeSelfHasherImpl(t reflect.Type) typeHasherFunc {
return func(h *hasher, p pointer) {
e := p.asValue(t)
e.Interface().(SelfHasher).Hash(&h.Block512)
}
}
func hashString(h *hasher, p pointer) {
s := *p.asString()
h.HashUint64(uint64(len(s)))