internal/godebug
< internal/intern;
- internal/bytealg, internal/intern, internal/itoa, math/bits, sort, strconv
+ internal/bytealg, internal/itoa, math/bits, sort, strconv, unique
< net/netip;
# net is unavoidable when doing any networking,
package netip
-import "internal/intern"
+import "unique"
var (
Z0 = z0
type Uint128 = uint128
+type AddrDetail = addrDetail
+
func Mk128(hi, lo uint64) Uint128 {
return uint128{hi, lo}
}
-func MkAddr(u Uint128, z *intern.Value) Addr {
+func MkAddr(u Uint128, z unique.Handle[AddrDetail]) Addr {
return Addr{u, z}
}
"errors"
"math"
"strconv"
+ "unique"
"internal/bytealg"
- "internal/intern"
"internal/itoa"
)
// bytewise processing.
addr uint128
- // z is a combination of the address family and the IPv6 zone.
- //
- // nil means invalid IP address (for a zero Addr).
- // z4 means an IPv4 address.
- // z6noz means an IPv6 address without a zone.
- //
- // Otherwise it's the interned zone name string.
- z *intern.Value
+ // Details about the address, wrapped up together and canonicalized.
+ z unique.Handle[addrDetail]
+}
+
+// addrDetail represents the details of an Addr, like address family and IPv6 zone.
+type addrDetail struct {
+ IsV6 bool // IPv4 is false, IPv6 is true.
+ ZoneV6 string // != nil only if IsV6 is true.
}
// z0, z4, and z6noz are sentinel Addr.z values.
// See the Addr type's field docs.
var (
- z0 = (*intern.Value)(nil)
- z4 = new(intern.Value)
- z6noz = new(intern.Value)
+ z0 unique.Handle[addrDetail]
+ z4 = unique.Make(addrDetail{})
+ z6noz = unique.Make(addrDetail{IsV6: true})
)
// IPv6LinkLocalAllNodes returns the IPv6 link-local all nodes multicast
// Zone returns ip's IPv6 scoped addressing zone, if any.
func (ip Addr) Zone() string {
- if ip.z == nil {
+ if ip.z == z0 {
return ""
}
- zone, _ := ip.z.Get().(string)
- return zone
+ return ip.z.Value().ZoneV6
}
// Compare returns an integer comparing two IPs.
ip.z = z6noz
return ip
}
- ip.z = intern.GetByString(zone)
+ ip.z = unique.Make(addrDetail{IsV6: true, ZoneV6: zone})
return ip
}
"encoding/json"
"flag"
"fmt"
- "internal/intern"
"internal/testenv"
"net"
. "net/netip"
"sort"
"strings"
"testing"
+ "unique"
)
var long = flag.Bool("long", false, "run long tests")
// IPv6 with a zone specifier.
{
in: "fd7a:115c:a1e0:ab12:4843:cd96:626b:430b%eth0",
- ip: MkAddr(Mk128(0xfd7a115ca1e0ab12, 0x4843cd96626b430b), intern.Get("eth0")),
+ ip: MkAddr(Mk128(0xfd7a115ca1e0ab12, 0x4843cd96626b430b), unique.Make(AddrDetail{IsV6: true, ZoneV6: "eth0"})),
},
// IPv6 with dotted decimal and zone specifier.
{
in: "1:2::ffff:192.168.140.255%eth1",
- ip: MkAddr(Mk128(0x0001000200000000, 0x0000ffffc0a88cff), intern.Get("eth1")),
+ ip: MkAddr(Mk128(0x0001000200000000, 0x0000ffffc0a88cff), unique.Make(AddrDetail{IsV6: true, ZoneV6: "eth1"})),
str: "1:2::ffff:c0a8:8cff%eth1",
},
// 4-in-6 with zone
{
in: "::ffff:192.168.140.255%eth1",
- ip: MkAddr(Mk128(0, 0x0000ffffc0a88cff), intern.Get("eth1")),
+ ip: MkAddr(Mk128(0, 0x0000ffffc0a88cff), unique.Make(AddrDetail{IsV6: true, ZoneV6: "eth1"})),
str: "::ffff:192.168.140.255%eth1",
},
// IPv6 with capital letters.
}
func BenchmarkParseAddr(b *testing.B) {
- sinkInternValue = intern.Get("eth1") // Pin to not benchmark the intern package
+ sinkInternValue = unique.Make(AddrDetail{IsV6: true, ZoneV6: "eth1"}) // Pin to not benchmark the intern package
for _, test := range parseBenchInputs {
b.Run(test.name, func(b *testing.B) {
b.ReportAllocs()
sinkAddrPort AddrPort
sinkPrefix Prefix
sinkPrefixSlice []Prefix
- sinkInternValue *intern.Value
+ sinkInternValue unique.Handle[AddrDetail]
sinkIP16 [16]byte
sinkIP4 [4]byte
sinkBool bool