net/ipset: skip the loop over Prefixes when there's only one

For pprof cosmetic/confusion reasons more than performance, but it
might have tiny speed benefit.

Updates #12486

Change-Id: I40e03714f3afa3a7e7f5e1fa99b81c7e889b91b6
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick 2024-06-16 20:33:43 -07:00 committed by Brad Fitzpatrick
parent 20a5f939ba
commit 1f6645b19f
2 changed files with 14 additions and 11 deletions

View File

@ -70,7 +70,15 @@ func NewContainsIPFunc(addrs views.Slice[netip.Prefix]) func(ip netip.Addr) bool
// If any addr is a prefix with more than a single IP, then do either a
// linear scan or a bart table, depending on the number of addrs.
if addrs.ContainsFunc(func(p netip.Prefix) bool { return !p.IsSingleIP() }) {
if addrs.Len() > 6 {
if addrs.Len() == 1 {
pathForTest("one-prefix")
return addrs.At(0).Contains
}
if addrs.Len() <= 6 {
// Small enough to do a linear search.
pathForTest("linear-contains")
return prefixContainsLoop(addrs.AsSlice())
}
pathForTest("bart")
// Built a bart table.
t := &bart.Table[struct{}]{}
@ -78,11 +86,6 @@ func NewContainsIPFunc(addrs views.Slice[netip.Prefix]) func(ip netip.Addr) bool
t.Insert(addrs.At(i), struct{}{})
}
return bartLookup(t)
} else {
pathForTest("linear-contains")
// Small enough to do a linear search.
return prefixContainsLoop(addrs.AsSlice())
}
}
// Fast paths for 1 and 2 IPs:
if addrs.Len() == 1 {

View File

@ -41,7 +41,7 @@ var newContainsIPFuncTests = []struct {
{
name: "cidr-list-1",
pfx: pp("10.0.0.0/8"),
want: "linear-contains",
want: "one-prefix",
wantIn: aa("10.0.0.1", "10.2.3.4"),
wantOut: aa("8.8.8.8"),
},