def get_prefix_nodes_info(root_node) -> None: """ Calculate number of nodes which were allocated without regarding the allocation policy. Final result will be printed to the standard output :param root_node: pointer to the root node in trie structure, which represents address sapce :return: None. Just print final result """ helper = Helper() if not root_node: return node_path = list() node_path.append(root_node) prefixes_test = list() while node_path: node = node_path.pop() if node.prefix_flag: prefixes_test.append(node) if node.right_child: node_path.append(node.right_child) if node.left_child: node_path.append(node.left_child) incorrect_nodes = {0: 0, 1: 0, 2: 0, 3: 0, 4: 0} for prefix_node in prefixes_test: full_prefix_path = AbstractTrie.get_just_prefix_path(prefix_node)[1:] org_level = helper.get_organisation_level_by_depth(prefix_node.depth) if len(full_prefix_path) == 0: incorrect_nodes[org_level] += 1 continue if org_level != 4: converted_to_org_level = [ helper.get_organisation_level_by_depth(n.depth) for n in full_prefix_path if org_level - helper.get_organisation_level_by_depth(n.depth) == 1 ] else: converted_to_org_level = [ helper.get_organisation_level_by_depth(n.depth) for n in full_prefix_path if org_level - helper.get_organisation_level_by_depth(n.depth) == 1 or org_level - helper.get_organisation_level_by_depth(n.depth == 2) ] if not converted_to_org_level: incorrect_nodes[org_level] += 1 print(f"Number of nodes were allocated incorrectly: {incorrect_nodes}")
def start_generating(self) -> List[str]: """Start generating process. :return: list with generated prefixes """ # Generate new RIR nodes and add them to binary trie if Helper.distribution_random_plan: if self.stats: print( "[RANDOM GENERATING]: Start generating prefixes randomly") Randomizer = RandomGenerator( self._binary_trie, self.Help, distribution_plan=Helper.distribution_random_plan, stats=self.stats) Randomizer.random_generate() if self.stats: print( "[RANDOM GENERATING]: Random generating phase successfully done" ) else: if self.stats: print( "[RANDOM GENERATING]: Random generating phase is skipped. Only RIR prefixes that have " "a length in interval 12 - 31 could be generated randomly" ) if self.stats: print( "[TRIE TRAVERSING GENERATING]: Start generating prefixes using constructed trie" ) self._binary_trie.generate_prefixes() if self.stats: print( "[TRIE TRAVERSING GENERATING]: Traversing trie generating phase successfully done" ) new_prefixes = set( AbstractTrie.get_prefix_nodes(self._binary_trie.root_node)) output_converter = Converter(new_prefixes) converted_prefixes = output_converter.convert_prefixes() return converted_prefixes
def start_generating(self): if self.rgr != 1: self._binary_trie.trie_traversal("generate") # second phase of generating - random generating if self.rgr != 0: # Generate prefixes that couldn't be added to trie by generating process self._random_generate(self.Help.distribution_random_plan) if self.Help.distribution_plan: self._random_generate(self.Help.distribution_plan, True) new_prefixes = set(AbstractTrie.get_prefix_nodes(self._binary_trie.root_node)) output_converter = Converter(new_prefixes) converted_prefixes = output_converter.convert_prefixes() return converted_prefixes
def create_stats(output_prefixes: List[str], name: str, root_node) -> None: """ This method used for creating statistic information about dataset and run the same tests as __main__ :param output_prefixes: prefix dataset which will be tested :param name: path to the output folder which will be used for saving graphs :param root_node: pointer to the root node :return: None """ depth_distribution = {key: 0 for key in range(65)} # get_prefix_nodes_info(root_node) for single_prefix in output_prefixes: prefix_len = int(single_prefix.split('/')[1]) depth_distribution[prefix_len] += 1 depth_distribution_graph(depth_distribution, name) level_distribution_stats = AbstractTrie.level_stats(root_node) level_distribution(level_distribution_stats, name)
def add_node(self, node_value: str, parent_node: Optional[Node] = None, creating_phase: bool = True) -> Node: """Add new node to binary trie. :raises PrefixAlreadyExists in case if new node already exists in binary trie. Method isn't called in creating phase :raises MaximumLevelException in case if after adding a new node to binary trie level changes and greater than max possible value :param node_value: string; string representation of node :param parent_node None or Node; node object which represent the parent for added node :param creating_phase boolean; signalize phase of generator when node is added while binary trie is initializing :return: constructed node object """ if not parent_node: current_node = self.root_node else: current_node = parent_node if not creating_phase and AbstractTrie.is_exist( current_node, node_value): raise PrefixAlreadyExists for curr_len, bit in enumerate(node_value, 1): if bit == '0': if not current_node.left_child: current_node.left_child = Node(bit, current_node.depth + 1) current_node.left_child.path = current_node current_node = current_node.left_child else: if not current_node.right_child: current_node.right_child = Node(bit, current_node.depth + 1) current_node.right_child.path = current_node current_node = current_node.right_child try: self.calculate_level(current_node) except MaximumLevelException: if not current_node.right_child and not current_node.left_child: AbstractTrie.delete_node_from_trie(current_node) raise current_node.prefix_flag = True self._prefix_nodes[current_node.depth] += 1 if not creating_phase: current_node.allow_generate = False if current_node.depth > self._trie_depth: self._trie_depth = current_node.depth return current_node
plt.xlabel('Počet adres') plt.ylabel('Spotřebovaný čas [s]') plt.legend() plt.savefig(f"statistics/time.png", format='png', dpi=850) if __name__ == '__main__': prefix_sets = ['dataset2007', 'dataset2019'] for current_set in prefix_sets: path = f"formated_datasets/{current_set}" prefixes = InputArgumentsValidator.read_seed_file(path) print( f"Number of uniq prefixes which could be generated or used for generating process {len(prefixes)}" ) binary_trie = Trie() depth_distribution_stats = {key: 0 for key in range(65)} for prefix in prefixes: depth_distribution_stats[len(prefix)] += 1 binary_trie.add_node(prefix) depth_distribution_graph(depth_distribution_stats, current_set) level_distribution_stats = AbstractTrie.level_stats( binary_trie.root_node) level_distribution(level_distribution_stats, current_set)