Kaydet (Commit) e6f250ed authored tarafından Antoine Pitrou's avatar Antoine Pitrou

Issue #23266: Much faster implementation of ipaddress.collapse_addresses() when…

Issue #23266: Much faster implementation of ipaddress.collapse_addresses() when there are many non-consecutive addresses.
üst 82e07b92
...@@ -170,16 +170,19 @@ def _find_address_range(addresses): ...@@ -170,16 +170,19 @@ def _find_address_range(addresses):
addresses: a list of IPv#Address objects. addresses: a list of IPv#Address objects.
Returns: Returns:
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] first = last = addresses[0]
i = 1
for ip in addresses[1:]: for ip in addresses[1:]:
if ip._ip == last._ip + 1: if ip._ip == last._ip + 1:
last = ip last = ip
i += 1
else: else:
break break
return (first, last) return (first, last, i)
def _count_righthand_zero_bits(number, bits): def _count_righthand_zero_bits(number, bits):
...@@ -346,12 +349,13 @@ def collapse_addresses(addresses): ...@@ -346,12 +349,13 @@ def collapse_addresses(addresses):
ip, nets[-1])) ip, nets[-1]))
nets.append(ip) nets.append(ip)
# sort and dedup # sort
ips = sorted(set(ips)) ips = sorted(ips)
# find consecutive address ranges in the sorted sequence and summarize them
while i < len(ips): while i < len(ips):
(first, last) = _find_address_range(ips[i:]) (first, last, items) = _find_address_range(ips[i:])
i = ips.index(last) + 1 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)
......
...@@ -766,10 +766,11 @@ class IpaddrUnitTest(unittest.TestCase): ...@@ -766,10 +766,11 @@ class IpaddrUnitTest(unittest.TestCase):
2 ** ipaddress.IPV6LENGTH) 2 ** ipaddress.IPV6LENGTH)
def testInternals(self): def testInternals(self):
first, last = ipaddress._find_address_range([ first, last, nitems = ipaddress._find_address_range([
ipaddress.IPv4Address('10.10.10.10'), ipaddress.IPv4Address('10.10.10.10'),
ipaddress.IPv4Address('10.10.10.12')]) ipaddress.IPv4Address('10.10.10.12')])
self.assertEqual(first, last) self.assertEqual(first, last)
self.assertEqual(nitems, 1)
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))
......
...@@ -203,6 +203,9 @@ Core and Builtins ...@@ -203,6 +203,9 @@ Core and Builtins
Library Library
------- -------
- Issue #23266: Much faster implementation of ipaddress.collapse_addresses()
when there are many non-consecutive addresses.
- Issue #23098: 64-bit dev_t is now supported in the os module. - Issue #23098: 64-bit dev_t is now supported in the os module.
- Issue #21817: When an exception is raised in a task submitted to a - Issue #21817: When an exception is raised in a task submitted to a
......
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