util/slicesx: add package for generic slice functions, use

Now that we're using rand.Shuffle in a few locations, create a generic
shuffle function and use it instead. While we're at it, move the
interleaveSlices function to the same package for use.

Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I0b00920e5b3eea846b6cedc30bd34d978a049fd3
This commit is contained in:
Andrew Dunham
2023-03-03 13:15:56 -05:00
parent 88c7d19d54
commit 73fa7dd7af
9 changed files with 121 additions and 46 deletions

View File

@ -24,6 +24,7 @@ import (
"tailscale.com/types/logger"
"tailscale.com/util/cloudenv"
"tailscale.com/util/singleflight"
"tailscale.com/util/slicesx"
)
var zaddr netip.Addr
@ -577,7 +578,7 @@ func (dc *dialCall) raceDial(ctx context.Context, ips []netip.Addr) (net.Conn, e
iv4 = append(iv4, ip)
}
}
ips = interleaveSlices(iv6, iv4)
ips = slicesx.Interleave(iv6, iv4)
go func() {
for i, ip := range ips {
@ -636,21 +637,6 @@ func (dc *dialCall) raceDial(ctx context.Context, ips []netip.Addr) (net.Conn, e
}
}
// interleaveSlices combines two slices of the form [a, b, c] and [x, y, z]
// into a slice with elements interleaved; i.e. [a, x, b, y, c, z].
func interleaveSlices[T any](a, b []T) []T {
var (
i int
ret = make([]T, 0, len(a)+len(b))
)
for i = 0; i < len(a) && i < len(b); i++ {
ret = append(ret, a[i], b[i])
}
ret = append(ret, a[i:]...)
ret = append(ret, b[i:]...)
return ret
}
func v4addrs(aa []netip.Addr) (ret []netip.Addr) {
for _, a := range aa {
a = a.Unmap()