summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJosh Bleecher Snyder <josh@tailscale.com>2021-05-10 14:15:31 -0700
committerJosh Bleecher Snyder <josharian@gmail.com>2021-05-11 11:33:17 -0700
commitd4f805339e11d8b15c67b4e9a0da0cb2e2036c81 (patch)
tree0866c656aaf34dfd1edb82e31b396cadd7b99acc
parent752f8c0f2fcdefb83e5a8bcbc53ff444b6fa69e4 (diff)
downloadtailscale-d4f805339e11d8b15c67b4e9a0da0cb2e2036c81.tar.xz
tailscale-d4f805339e11d8b15c67b4e9a0da0cb2e2036c81.zip
internal/deepprint: special-case some common types
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 <josh@tailscale.com>
-rw-r--r--internal/deepprint/deepprint.go75
1 files changed, 75 insertions, 0 deletions
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()))