Kaydet (Commit) b53f0fbf authored tarafından Serhiy Storchaka's avatar Serhiy Storchaka

Issue #23266: Restore the performance of ipaddress.collapse_addresses() whith

duplicated addresses and simplify the code.
üst 1202a473
...@@ -164,25 +164,23 @@ def _split_optional_netmask(address): ...@@ -164,25 +164,23 @@ def _split_optional_netmask(address):
def _find_address_range(addresses): def _find_address_range(addresses):
"""Find a sequence of IPv#Address. """Find a sequence of sorted deduplicated IPv#Address.
Args: Args:
addresses: a list of IPv#Address objects. addresses: a list of IPv#Address objects.
Returns: Yields:
A tuple containing the first and last IP addresses in the sequence, A tuple containing the first and last IP addresses in the sequence.
and the number of distinct IP addresses in the sequence.
""" """
first = last = addresses[0] it = iter(addresses)
i = 1 first = last = next(it)
for ip in addresses[1:]: for ip in it:
if ip._ip == last._ip + 1: if ip._ip != last._ip + 1:
last = ip yield first, last
i += 1 first = ip
else: last = ip
break yield first, last
return (first, last, i)
def _count_righthand_zero_bits(number, bits): def _count_righthand_zero_bits(number, bits):
...@@ -323,7 +321,6 @@ def collapse_addresses(addresses): ...@@ -323,7 +321,6 @@ def collapse_addresses(addresses):
TypeError: If passed a list of mixed version objects. TypeError: If passed a list of mixed version objects.
""" """
i = 0
addrs = [] addrs = []
ips = [] ips = []
nets = [] nets = []
...@@ -349,14 +346,13 @@ def collapse_addresses(addresses): ...@@ -349,14 +346,13 @@ def collapse_addresses(addresses):
ip, nets[-1])) ip, nets[-1]))
nets.append(ip) nets.append(ip)
# sort # sort and dedup
ips = sorted(ips) ips = sorted(set(ips))
# find consecutive address ranges in the sorted sequence and summarize them # find consecutive address ranges in the sorted sequence and summarize them
while i < len(ips): if ips:
(first, last, items) = _find_address_range(ips[i:]) for first, last in _find_address_range(ips):
i = items + i addrs.extend(summarize_address_range(first, last))
addrs.extend(summarize_address_range(first, last))
return _collapse_addresses_internal(addrs + nets) return _collapse_addresses_internal(addrs + nets)
......
...@@ -790,11 +790,15 @@ class IpaddrUnitTest(unittest.TestCase): ...@@ -790,11 +790,15 @@ class IpaddrUnitTest(unittest.TestCase):
2 ** ipaddress.IPV6LENGTH) 2 ** ipaddress.IPV6LENGTH)
def testInternals(self): def testInternals(self):
first, last, nitems = ipaddress._find_address_range([ ip1 = ipaddress.IPv4Address('10.10.10.10')
ipaddress.IPv4Address('10.10.10.10'), ip2 = ipaddress.IPv4Address('10.10.10.11')
ipaddress.IPv4Address('10.10.10.12')]) ip3 = ipaddress.IPv4Address('10.10.10.12')
self.assertEqual(first, last) self.assertEqual(list(ipaddress._find_address_range([ip1])),
self.assertEqual(nitems, 1) [(ip1, ip1)])
self.assertEqual(list(ipaddress._find_address_range([ip1, ip3])),
[(ip1, ip1), (ip3, ip3)])
self.assertEqual(list(ipaddress._find_address_range([ip1, ip2, ip3])),
[(ip1, ip3)])
self.assertEqual(128, ipaddress._count_righthand_zero_bits(0, 128)) self.assertEqual(128, ipaddress._count_righthand_zero_bits(0, 128))
self.assertEqual("IPv4Network('1.2.3.0/24')", repr(self.ipv4_network)) self.assertEqual("IPv4Network('1.2.3.0/24')", repr(self.ipv4_network))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment