lib/connections: Fix and optimize registry (#7996)

Registry.Get used a full sort to get the minimum of a list, and the sort
was broken because util.AddressUnspecifiedLess assumed it could find out
whether an address is IPv4 or IPv6 from its Network method. However,
net.(TCP|UDP)Addr.Network always returns "tcp"/"udp".
This commit is contained in:
greatroar
2021-10-06 10:52:51 +02:00
committed by GitHub
parent c94b797f00
commit 7c292cc812
8 changed files with 76 additions and 106 deletions
+38 -13
View File
@@ -7,13 +7,18 @@
package registry
import (
"net"
"testing"
)
func TestRegistry(t *testing.T) {
r := New()
if res := r.Get("int", intLess); res != nil {
want := func(i int) func(interface{}) bool {
return func(x interface{}) bool { return x.(int) == i }
}
if res := r.Get("int", want(1)); res != nil {
t.Error("unexpected")
}
@@ -24,30 +29,28 @@ func TestRegistry(t *testing.T) {
r.Register("int6", 6)
r.Register("int6", 66)
if res := r.Get("int", intLess).(int); res != 1 {
if res := r.Get("int", want(1)).(int); res != 1 {
t.Error("unexpected", res)
}
// int is prefix of int4, so returns 1
if res := r.Get("int4", intLess).(int); res != 1 {
if res := r.Get("int4", want(1)).(int); res != 1 {
t.Error("unexpected", res)
}
r.Unregister("int", 1)
// Check that falls through to 11
if res := r.Get("int", intLess).(int); res != 11 {
if res := r.Get("int", want(1)).(int); res == 1 {
t.Error("unexpected", res)
}
// 6 is smaller than 11 available in int.
if res := r.Get("int6", intLess).(int); res != 6 {
if res := r.Get("int6", want(6)).(int); res != 6 {
t.Error("unexpected", res)
}
// Unregister 11, int should be impossible to find
r.Unregister("int", 11)
if res := r.Get("int", intLess); res != nil {
if res := r.Get("int", want(11)); res != nil {
t.Error("unexpected")
}
@@ -59,13 +62,35 @@ func TestRegistry(t *testing.T) {
r.Register("int", 1)
r.Unregister("int", 1)
if res := r.Get("int4", intLess).(int); res != 1 {
if res := r.Get("int4", want(1)).(int); res != 1 {
t.Error("unexpected", res)
}
}
func intLess(i, j interface{}) bool {
iInt := i.(int)
jInt := j.(int)
return iInt < jInt
func TestShortSchemeFirst(t *testing.T) {
r := New()
r.Register("foo", 0)
r.Register("foobar", 1)
// If we don't care about the value, we should get the one with "foo".
res := r.Get("foo", func(interface{}) bool { return false })
if res != 0 {
t.Error("unexpected", res)
}
}
func BenchmarkGet(b *testing.B) {
r := New()
for _, addr := range []string{"192.168.1.1", "172.1.1.1", "10.1.1.1"} {
r.Register("tcp", &net.TCPAddr{IP: net.ParseIP(addr)})
}
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
r.Get("tcp", func(x interface{}) bool {
return x.(*net.TCPAddr).IP.IsUnspecified()
})
}
}