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

@@ -7,11 +7,25 @@ import (
"net/netip"
"reflect"
"time"
"tailscale.com/util/hashx"
)
// SelfHasher is the interface implemented by types that can compute their own hash
// by writing values through the given parameter.
//
// Implementations of Hash MUST NOT call `Reset` or `Sum` on the provided argument.
//
// This interface should not be considered stable and is likely to change in the
// future.
type SelfHasher interface {
Hash(*hashx.Block512)
}
var (
timeTimeType = reflect.TypeOf((*time.Time)(nil)).Elem()
netipAddrType = reflect.TypeOf((*netip.Addr)(nil)).Elem()
timeTimeType = reflect.TypeOf((*time.Time)(nil)).Elem()
netipAddrType = reflect.TypeOf((*netip.Addr)(nil)).Elem()
selfHasherType = reflect.TypeOf((*SelfHasher)(nil)).Elem()
)
// typeIsSpecialized reports whether this type has specialized hashing.
@@ -21,6 +35,11 @@ func typeIsSpecialized(t reflect.Type) bool {
case timeTimeType, netipAddrType:
return true
default:
if t.Kind() != reflect.Pointer && t.Kind() != reflect.Interface {
if t.Implements(selfHasherType) || reflect.PointerTo(t).Implements(selfHasherType) {
return true
}
}
return false
}
}