From d4f805339e11d8b15c67b4e9a0da0cb2e2036c81 Mon Sep 17 00:00:00 2001 From: Josh Bleecher Snyder Date: Mon, 10 May 2021 14:15:31 -0700 Subject: [PATCH] internal/deepprint: special-case some common types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These show up a lot in our data structures. name old time/op new time/op delta Hash-8 11.5µs ± 1% 7.8µs ± 1% -32.17% (p=0.000 n=10+10) name old alloc/op new alloc/op delta Hash-8 1.98kB ± 0% 1.67kB ± 0% -15.73% (p=0.000 n=10+10) name old allocs/op new allocs/op delta Hash-8 82.0 ± 0% 53.0 ± 0% -35.37% (p=0.000 n=10+10) Signed-off-by: Josh Bleecher Snyder --- internal/deepprint/deepprint.go | 75 +++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/internal/deepprint/deepprint.go b/internal/deepprint/deepprint.go index 580b85237..f0e93980c 100644 --- a/internal/deepprint/deepprint.go +++ b/internal/deepprint/deepprint.go @@ -16,6 +16,10 @@ import ( "crypto/sha256" "fmt" "reflect" + + "inet.af/netaddr" + "tailscale.com/tailcfg" + "tailscale.com/types/wgkey" ) func Hash(v ...interface{}) string { @@ -41,10 +45,81 @@ func Print(w *bufio.Writer, v ...interface{}) { print(w, reflect.ValueOf(v), make(map[uintptr]bool)) } +var ( + netaddrIPType = reflect.TypeOf(netaddr.IP{}) + netaddrIPPrefix = reflect.TypeOf(netaddr.IPPrefix{}) + wgkeyKeyType = reflect.TypeOf(wgkey.Key{}) + wgkeyPrivateType = reflect.TypeOf(wgkey.Private{}) + tailcfgDiscoKeyType = reflect.TypeOf(tailcfg.DiscoKey{}) +) + func print(w *bufio.Writer, v reflect.Value, visited map[uintptr]bool) { if !v.IsValid() { return } + + // Special case some common types. + if v.CanInterface() { + switch v.Type() { + case netaddrIPType: + var b []byte + var err error + if v.CanAddr() { + x := v.Addr().Interface().(*netaddr.IP) + b, err = x.MarshalText() + } else { + x := v.Interface().(netaddr.IP) + b, err = x.MarshalText() + } + if err == nil { + w.Write(b) + return + } + case netaddrIPPrefix: + var b []byte + var err error + if v.CanAddr() { + x := v.Addr().Interface().(*netaddr.IPPrefix) + b, err = x.MarshalText() + } else { + x := v.Interface().(netaddr.IPPrefix) + b, err = x.MarshalText() + } + if err == nil { + w.Write(b) + return + } + case wgkeyKeyType: + if v.CanAddr() { + x := v.Addr().Interface().(*wgkey.Key) + w.Write(x[:]) + } else { + x := v.Interface().(wgkey.Key) + w.Write(x[:]) + } + return + case wgkeyPrivateType: + if v.CanAddr() { + x := v.Addr().Interface().(*wgkey.Private) + w.Write(x[:]) + } else { + x := v.Interface().(wgkey.Private) + w.Write(x[:]) + } + return + case tailcfgDiscoKeyType: + if v.CanAddr() { + x := v.Addr().Interface().(*tailcfg.DiscoKey) + w.Write(x[:]) + } else { + x := v.Interface().(tailcfg.DiscoKey) + w.Write(x[:]) + } + return + } + } + + // Generic handling. switch v.Kind() { default: panic(fmt.Sprintf("unhandled kind %v for type %v", v.Kind(), v.Type()))