Исправлена логика сжатия.

This commit is contained in:
2025-12-05 21:27:00 +10:00
parent 157f334874
commit 4f62c9a051
2 changed files with 42 additions and 14 deletions

View File

@@ -171,12 +171,8 @@ def list_ip(c_list: list = []):
# добавляем IPv4 подсети # добавляем IPv4 подсети
for ip_int, mask in sorted(ipv4_list, key=lambda x: x[0]): for ip_int, mask in sorted(ipv4_list, key=lambda x: x[0]):
Root.insert(net_tree.Net(ip_int, mask, 4)) Root.insert(net_tree.Net(ip_int, mask, 4))
# считаем статистику # сжатие по CIDR, если ключ сжимать, иначе убираем только родителей, покрываемых детьми
Root.finalize() ipv4_list = Root.export_compress('route {addr}/{masklen} blackhole;') if compress else Root.export('route {addr}/{masklen} blackhole;')
# сжатие по CIDR, если ключ сжимать
if compress: Root.collapse()
# получаем результат
ipv4_list = Root.export('route {addr}/{masklen} blackhole;')
else: else:
ipv4_list:bool=False ipv4_list:bool=False
@@ -187,12 +183,8 @@ def list_ip(c_list: list = []):
# добавляем IPv6 подсети # добавляем IPv6 подсети
for ip_int, mask in sorted(ipv6_list, key=lambda x: x[0]): for ip_int, mask in sorted(ipv6_list, key=lambda x: x[0]):
Root.insert(net_tree.Net(ip_int, mask, 6)) Root.insert(net_tree.Net(ip_int, mask, 6))
# считаем статистику # сжатие по CIDR, если ключ сжимать, иначе убираем только родителей, покрываемых детьми
Root.finalize() ipv6_list = Root.export_compress('route {addr}/{masklen} blackhole;') if compress else Root.export('route {addr}/{masklen} blackhole;')
# сжатие по CIDR, если ключ сжимать
if compress: Root.collapse()
# получаем результат
ipv6_list = Root.export('route {addr}/{masklen} blackhole;')
else: else:
ipv6_list:bool=False ipv6_list:bool=False
# возвращаем 2 списка маршрутов # возвращаем 2 списка маршрутов

View File

@@ -238,13 +238,17 @@ class Node:
self.__recalc() self.__recalc()
return delta, fake return delta, fake
def export(self, fmt='{addr}/{masklen}'): def export_compress(self, fmt='{addr}/{masklen}'):
# считаем статистику
self.finalize()
# сжимаем
self.collapse()
result = [] result = []
def walk(node): def walk(node):
if node is None: if node is None:
return return
# если суперсеть реальная дети не нужны # если суперсеть реальная > дети не нужны
if node.is_real: if node.is_real:
result.append(node.net.getAsString(fmt)) result.append(node.net.getAsString(fmt))
return return
@@ -253,3 +257,35 @@ class Node:
walk(self) walk(self)
return "\n".join(result) return "\n".join(result)
def export(self, fmt='{addr}/{masklen}'):
# считаем статистику
self.finalize()
result = []
def walk(node):
if node is None:
return
if node.is_real:
# дети полностью покрывают диапазон родителя?
child_real_vol = 0
for ch in (node.child0, node.child1):
if ch:
child_real_vol += ch.real_volume
# если дети полностью покрывают родителя -> родители не нужны
if child_real_vol >= node.net.volume:
walk(node.child0)
walk(node.child1)
return
# иначе выводим родителя и детей
result.append(node.net.getAsString(fmt))
walk(node.child0)
walk(node.child1)
walk(self)
return "\n".join(result)