diff --git a/tests/cidr4_merge/test_cidr4_merger.py b/tests/cidr4_merge/test_cidr4_merger.py index 10c372e..f4a9652 100644 --- a/tests/cidr4_merge/test_cidr4_merger.py +++ b/tests/cidr4_merge/test_cidr4_merger.py @@ -4,6 +4,7 @@ from vpn_manager.cidr4_merge.cidr4_merger import ( Cidr4MergerError, calc_dip, cidr4_to_node, + find_neighbors, find_parent, make_cidr4, merge_nodes, @@ -94,6 +95,31 @@ def test_merge_two_nodes(): assert merge_two_nodes((0, 32), (6, 31)) == ((0, 29), 5) +def test_find_neighbors(): + assert find_neighbors([(0, 32), (2, 32), (4, 32), (6, 32)]) == [] + assert find_neighbors([(0, 32), (1, 32)]) == [(0, (0, 32), (1, 32))] + assert find_neighbors( + [ + (0, 32), + (1, 32), + (6, 32), + (7, 32), + ] + ) == [ + (0, (0, 32), (1, 32)), + (2, (6, 32), (7, 32)), + ] + assert find_neighbors( + [ + (0, 32), + (1, 32), + (6, 32), + ] + ) == [ + (0, (0, 32), (1, 32)), + ] + + def test_merge_nodes(): assert merge_nodes( [ @@ -104,7 +130,6 @@ def test_merge_nodes(): 2, ) == ([(0, 30), (4, 32)], 2) - # т.е. сейчас алгоритм работает так, что он может оставить соседей assert merge_nodes( [ (0, 32), @@ -113,7 +138,7 @@ def test_merge_nodes(): (7, 32), ], 2, - ) == ([(0, 30), (4, 30)], 4) + ) == ([(0, 29)], 4) assert merge_nodes( [ diff --git a/vpn_manager/cidr4_merge/cidr4_merger.py b/vpn_manager/cidr4_merge/cidr4_merger.py index e250f17..2a5ede9 100644 --- a/vpn_manager/cidr4_merge/cidr4_merger.py +++ b/vpn_manager/cidr4_merge/cidr4_merger.py @@ -55,21 +55,31 @@ def merge_nodes(nodes: list[Node], required_len: int) -> tuple[list[Node], int]: nodes = nodes[:idx] + [parent_node] + nodes[idx + 2 :] sum_dip += dip - # for i, (a, b) in enumerate(zip(nodes, nodes[1:])): - # parent_node, dip = merge_two_nodes(a, b) - # assert parent_node != a - # assert parent_node != b + while neighbors := find_neighbors(nodes): + idx, a, b = neighbors[0] + parent_node, dip = merge_two_nodes(a, b) + nodes = nodes[:idx] + [parent_node] + nodes[idx + 2 :] + sum_dip += dip return nodes, sum_dip +def find_neighbors(nodes: list[Node]) -> list[tuple[int, Node, Node]]: + neighbors = [] + for i, (a, b) in enumerate(zip(nodes, nodes[1:])): + parent_node, dip = merge_two_nodes(a, b) + if parent_node[1] + 1 == a[1] == b[1]: + neighbors.append((i, a, b)) + return neighbors + + def main(): required_len = 20 data = get_data() nodes = sorted(map(cidr4_to_node, data)) merged_nodes, sum_dip = merge_nodes(nodes, required_len) cidr4s = [make_cidr4(ip, mask_len) for ip, mask_len in merged_nodes] - print(sorted(cidr4s), sum_dip, sep="\n") + print(cidr4s, sum_dip, sep="\n") if __name__ == "__main__":