compareCidrv6(): -1 | 0 | 1
Compares two IPv6 CIDR blocks for sorting.
Orders by address ascending, then by prefix length ascending — so where
two blocks share a start address, the shorter prefix (the larger block,
the supernet) sorts first. This is the order PostgreSQL's cidr type
uses, and the order every containing block needs to precede the blocks
it contains, which is what cidrv6Merge relies on internally.
The block is ordered as written: the address field is compared as
stored, without applying the network mask first. A block carrying host
bits therefore sorts by the address stringifyCidrv6 will print
for it, and 2001:db8::5/64 does not compare equal to 2001:db8::/64
even though they cover the same addresses. Normalize with
cidrv6FirstAddress first if that is the order you want.
Both dialects are compared by mask, so 2001:db8::/32 and
2001:db8::/ffff:ffff:: are equal, and the order is the same as by
prefix length: /32 is ffff:ffff::, /33 is ffff:ffff:8000::.
Comparing masks rather than prefix lengths is what keeps a comparator
total, since a mask always exists and a prefix length does not
(ADR 0006).
Sort a list of allocations
Sort a list of allocations
import { assertEquals } from "@std/assert"; import { compareCidrv6, parseCidrv6, stringifyCidrv6 } from "@hertzg/ip/cidrv6"; const blocks = ["2001:db8:1::/48", "2001:db8::/48", "2001:db8::/32"].map(parseCidrv6); assertEquals(blocks.toSorted(compareCidrv6).map(stringifyCidrv6), [ "2001:db8::/32", "2001:db8::/48", "2001:db8:1::/48", ]);
A supernet sorts before its subnets
A supernet sorts before its subnets
import { assertEquals } from "@std/assert"; import { compareCidrv6, parseCidrv6 } from "@hertzg/ip/cidrv6"; assertEquals(compareCidrv6(parseCidrv6("2001:db8::/32"), parseCidrv6("2001:db8::/48")), -1); assertEquals(compareCidrv6(parseCidrv6("2001:db8::/48"), parseCidrv6("2001:db8::/32")), 1); assertEquals(compareCidrv6(parseCidrv6("2001:db8::/32"), parseCidrv6("2001:db8::/32")), 0);
The dialect does not affect the order
The dialect does not affect the order
import { assertEquals } from "@std/assert"; import { compareCidrv6, parseCidrv6 } from "@hertzg/ip/cidrv6"; const prefixed = parseCidrv6("2001:db8::/32"); const masked = { address: prefixed.address, mask: 0xFFFFFFFF000000000000000000000000n }; assertEquals(compareCidrv6(prefixed, masked), 0); assertEquals(compareCidrv6(masked, parseCidrv6("2001:db8::/48")), -1);