Description
In our code, we've ended up writing ad-hoc ordering functions for netip.Prefix a whole bunch of times, for use with sort.Slice and the new slices.SortFunc. Writing those ordering functions is repetitive, and just tricky enough that it's easy to write comparators that don't conform to the contracts that sort and slices specify.
I propose adding Prefix.Less
and Prefix.Compare
to net/netip, so that people don't have to write their own ordering functions for prefixes. Less
is a trivial wrapper around Compare
. Compare
orders two prefixes as follows:
- By address family (e.g. IPv4 before IPv6)
- Then by ascending pfx.Bits(),
- Then by pfx.Addr().
An example ordering:
0.0.0.0/0
10.0.0.0/8
11.0.0.0/8
10.0.0.0/24
::/0
Back when we first wrote net/netip, we hesitated to add Less
and Compare
to prefix, because there didn't seem to be an obvious order we could impose: Prefixes organize themselves naturally into a binary tree rather than a flat list. So, Contains
has an obvious definition, as does Overlaps
, but Less
and Compare
would require us to come up with some arbitrary flattening of the tree to make sense.
Now that we have a bit more experience with using net/netip in the wild, I have two arguments for implementing Less
and Compare
as defined above:
- Empirically, there does exist a generally accepted ordering for prefixes: it's the ordering from
ip route show
, and virtually all other network-oriented software. That order is the one specified above, where smaller prefixes appear first, and so the list reads from most general to most specific. This is also the order you get when implementing a binary tree as an array, or when you place prefixes into a tree and traverse it breadth-first. - A lot of prefix sorting happens in test code, where the caller just wants any reproducible ordering, and mainly doesn't want to have to implement the mildly fiddly Compare themselves.
While we're in there, AddrPort also lacks comparators, so we could add those as well. The above discussion doesn't apply to AddrPort, in that there is an obvious ordering available (order by Addr first, then Port). Looking back, I believe we simply forgot to make AddrPort's API consistent with Addr.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
Status