Browse Source

internal/deephash: remove netaddr special cases

All netaddr types that we are concerned with now implement AppendTo.
Use the AppendTo method if available, and remove all references to netaddr.

This is slower but cleaner, and more readily re-usable by others.

name              old time/op    new time/op    delta
Hash-8              12.6µs ± 0%    14.8µs ± 1%  +18.05%  (p=0.000 n=8+10)
HashMapAcyclic-8    21.4µs ± 1%    21.9µs ± 1%   +2.39%  (p=0.000 n=10+9)

name              old alloc/op   new alloc/op   delta
Hash-8                408B ± 0%      408B ± 0%     ~     (p=1.000 n=10+10)
HashMapAcyclic-8     1.00B ± 0%     1.00B ± 0%     ~     (all equal)

name              old allocs/op  new allocs/op  delta
Hash-8                6.00 ± 0%      6.00 ± 0%     ~     (all equal)
HashMapAcyclic-8      0.00           0.00          ~     (all equal)

Signed-off-by: Josh Bleecher Snyder <[email protected]>
Josh Bleecher Snyder 4 years ago
parent
commit
15a7ff83de
1 changed files with 12 additions and 37 deletions
  1. 12 37
      internal/deephash/deephash.go

+ 12 - 37
internal/deephash/deephash.go

@@ -16,7 +16,6 @@ import (
 	"strconv"
 	"sync"
 
-	"inet.af/netaddr"
 	"tailscale.com/tailcfg"
 	"tailscale.com/types/wgkey"
 )
@@ -47,14 +46,16 @@ func printTo(w *bufio.Writer, v interface{}, scratch []byte) {
 }
 
 var (
-	netaddrIPType       = reflect.TypeOf(netaddr.IP{})
-	netaddrIPPrefix     = reflect.TypeOf(netaddr.IPPrefix{})
-	netaddrIPPort       = reflect.TypeOf(netaddr.IPPort{})
 	wgkeyKeyType        = reflect.TypeOf(wgkey.Key{})
 	wgkeyPrivateType    = reflect.TypeOf(wgkey.Private{})
 	tailcfgDiscoKeyType = reflect.TypeOf(tailcfg.DiscoKey{})
+	appenderToType      = reflect.TypeOf((*appenderTo)(nil)).Elem()
 )
 
+type appenderTo interface {
+	AppendTo([]byte) []byte
+}
+
 // print hashes v into w.
 // It reports whether it was able to do so without hitting a cycle.
 func print(w *bufio.Writer, v reflect.Value, visited map[uintptr]bool, scratch []byte) (acyclic bool) {
@@ -62,42 +63,16 @@ func print(w *bufio.Writer, v reflect.Value, visited map[uintptr]bool, scratch [
 		return true
 	}
 
-	// Special case some common types.
 	if v.CanInterface() {
-		switch v.Type() {
-		case netaddrIPType:
-			scratch = scratch[:0]
-			if v.CanAddr() {
-				x := v.Addr().Interface().(*netaddr.IP)
-				scratch = x.AppendTo(scratch)
-			} else {
-				x := v.Interface().(netaddr.IP)
-				scratch = x.AppendTo(scratch)
-			}
-			w.Write(scratch)
-			return true
-		case netaddrIPPrefix:
-			scratch = scratch[:0]
-			if v.CanAddr() {
-				x := v.Addr().Interface().(*netaddr.IPPrefix)
-				scratch = x.AppendTo(scratch)
-			} else {
-				x := v.Interface().(netaddr.IPPrefix)
-				scratch = x.AppendTo(scratch)
-			}
-			w.Write(scratch)
-			return true
-		case netaddrIPPort:
-			scratch = scratch[:0]
-			if v.CanAddr() {
-				x := v.Addr().Interface().(*netaddr.IPPort)
-				scratch = x.AppendTo(scratch)
-			} else {
-				x := v.Interface().(netaddr.IPPort)
-				scratch = x.AppendTo(scratch)
-			}
+		// Use AppendTo methods, if available and cheap.
+		if v.CanAddr() && v.Type().Implements(appenderToType) {
+			a := v.Addr().Interface().(appenderTo)
+			scratch = a.AppendTo(scratch[:0])
 			w.Write(scratch)
 			return true
+		}
+		// Special case some common types.
+		switch v.Type() {
 		case wgkeyKeyType:
 			if v.CanAddr() {
 				x := v.Addr().Interface().(*wgkey.Key)