Cidr4 merge algorithm #5
@@ -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(
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -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__":
|
||||||
|
|||||||
Reference in New Issue
Block a user