]> granicus.if.org Git - python/commitdiff
Issue #23266: Much faster implementation of ipaddress.collapse_addresses() when there...
authorAntoine Pitrou <solipsis@pitrou.net>
Sun, 18 Jan 2015 15:22:47 +0000 (16:22 +0100)
committerAntoine Pitrou <solipsis@pitrou.net>
Sun, 18 Jan 2015 15:22:47 +0000 (16:22 +0100)
Lib/ipaddress.py
Lib/test/test_ipaddress.py
Misc/NEWS

index b32a7e1dac2f8b7bc08525ad63cc2774870f7ef5..8d369e3986f7f3ac678a8ca8970977b93992b525 100644 (file)
@@ -170,16 +170,19 @@ def _find_address_range(addresses):
         addresses: a list of IPv#Address objects.
 
     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]
+    i = 1
     for ip in addresses[1:]:
         if ip._ip == last._ip + 1:
             last = ip
+            i += 1
         else:
             break
-    return (first, last)
+    return (first, last, i)
 
 
 def _count_righthand_zero_bits(number, bits):
@@ -346,12 +349,13 @@ def collapse_addresses(addresses):
                                  ip, nets[-1]))
             nets.append(ip)
 
-    # sort and dedup
-    ips = sorted(set(ips))
+    # sort
+    ips = sorted(ips)
 
+    # find consecutive address ranges in the sorted sequence and summarize them
     while i < len(ips):
-        (first, last) = _find_address_range(ips[i:])
-        i = ips.index(last) + 1
+        (first, last, items) = _find_address_range(ips[i:])
+        i = items + i
         addrs.extend(summarize_address_range(first, last))
 
     return _collapse_addresses_internal(addrs + nets)
index c45e142f92039971559c693a824d66525086bbdd..1fbd2d5323f8c903bd47144c808c07c1bd73546c 100644 (file)
@@ -766,10 +766,11 @@ class IpaddrUnitTest(unittest.TestCase):
                           2 ** ipaddress.IPV6LENGTH)
 
     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.12')])
         self.assertEqual(first, last)
+        self.assertEqual(nitems, 1)
         self.assertEqual(128, ipaddress._count_righthand_zero_bits(0, 128))
         self.assertEqual("IPv4Network('1.2.3.0/24')", repr(self.ipv4_network))
 
index 1c1bbb05396d3bfa962fae0280268d18ae383847..c3b84eb6063f2b9c428c4eb2f2aedeb5d82496ff 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -203,6 +203,9 @@ Core and Builtins
 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 #21817: When an exception is raised in a task submitted to a