Cidr4 merge algorithm #5

Merged
PavelPatsey merged 91 commits from CIDR4_merge_algorithm into main 2025-01-27 22:05:39 +03:00
2 changed files with 42 additions and 7 deletions
Showing only changes of commit 735a3c0216 - Show all commits
+27 -2
View File
@@ -4,6 +4,7 @@ from vpn_manager.cidr4_merge.cidr4_merger import (
Cidr4MergerError, Cidr4MergerError,
calc_dip, calc_dip,
cidr4_to_node, cidr4_to_node,
find_neighbors,
find_parent, find_parent,
make_cidr4, make_cidr4,
merge_nodes, merge_nodes,
@@ -94,6 +95,31 @@ def test_merge_two_nodes():
assert merge_two_nodes((0, 32), (6, 31)) == ((0, 29), 5) 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(): def test_merge_nodes():
assert merge_nodes( assert merge_nodes(
[ [
@@ -104,7 +130,6 @@ def test_merge_nodes():
2, 2,
) == ([(0, 30), (4, 32)], 2) ) == ([(0, 30), (4, 32)], 2)
# т.е. сейчас алгоритм работает так, что он может оставить соседей
assert merge_nodes( assert merge_nodes(
[ [
(0, 32), (0, 32),
@@ -113,7 +138,7 @@ def test_merge_nodes():
(7, 32), (7, 32),
], ],
2, 2,
) == ([(0, 30), (4, 30)], 4) ) == ([(0, 29)], 4)
assert merge_nodes( assert merge_nodes(
[ [
+15 -5
View File
@@ -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 :] nodes = nodes[:idx] + [parent_node] + nodes[idx + 2 :]
sum_dip += dip sum_dip += dip
# for i, (a, b) in enumerate(zip(nodes, nodes[1:])): while neighbors := find_neighbors(nodes):
# parent_node, dip = merge_two_nodes(a, b) idx, a, b = neighbors[0]
# assert parent_node != a parent_node, dip = merge_two_nodes(a, b)
# assert parent_node != b nodes = nodes[:idx] + [parent_node] + nodes[idx + 2 :]
sum_dip += dip
return nodes, sum_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(): def main():
required_len = 20 required_len = 20
data = get_data() data = get_data()
nodes = sorted(map(cidr4_to_node, data)) nodes = sorted(map(cidr4_to_node, data))
merged_nodes, sum_dip = merge_nodes(nodes, required_len) merged_nodes, sum_dip = merge_nodes(nodes, required_len)
cidr4s = [make_cidr4(ip, mask_len) for ip, mask_len in merged_nodes] 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__": if __name__ == "__main__":