Advertisement
999ms

Untitled

Jul 15th, 2020
1,217
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.11 KB | None | 0 0
  1. from random import randint
  2. import time
  3.  
  4.  
  5. ## Trie part
  6.  
  7. class Trie:
  8.     class Node:
  9.         def __init__(self, data):
  10.             self.data = data
  11.             self.next_nodes = dict()
  12.             self.routing_prefixes = set()
  13.             self.isTerminal = False
  14.  
  15.     def __init__(self):
  16.         self.root_node = Trie.Node(0)
  17.  
  18.     def add_address(self, address):
  19.         # address = str('132.123.123.123/231')
  20.         if '/' in address:
  21.             address, routing_prefix = address.split('/')
  22.         else:
  23.             address, routing_prefix = address, None
  24.  
  25.         address = address.split('.')
  26.  
  27.         current_node = self.root_node
  28.         for value in address:
  29.             if value not in current_node.next_nodes:
  30.                 current_node.next_nodes[value] = Trie.Node(value)
  31.             current_node = current_node.next_nodes[value]
  32.  
  33.         if routing_prefix is None:
  34.             current_node.isTerminal = True
  35.         else:
  36.             current_node.routing_prefixes.add(routing_prefix)
  37.  
  38.     def __contains__(self, address):
  39.         if '/' in address:
  40.             address, routing_prefix = address.split('/')
  41.         else:
  42.             address, routing_prefix = address, None
  43.  
  44.         address = address.split('.')
  45.         if len(address) != 4:
  46.             return False
  47.  
  48.         try:
  49.             address = list(map(int, address))
  50.         except ValueError:
  51.             return False
  52.  
  53.         current_node = self.root_node
  54.         for value in address:
  55.             if value not in current_node.next_nodes:
  56.                 return False
  57.             current_node = current_node.next_nodes[value]
  58.  
  59.         if routing_prefix is None:
  60.             return current_node.isTerminal
  61.         else:
  62.             return routing_prefix in current_node.routing_prefixes
  63.  
  64.     def __dfs__(self, node, prefix, result):
  65.         if node.isTerminal:
  66.             result.append(prefix)
  67.         for routing_prefix in node.routing_prefixes:
  68.             result.append(prefix + '/' + routing_prefix)
  69.  
  70.         if len(prefix):
  71.             prefix += '.'
  72.         for index in node.next_nodes:
  73.             self.__dfs__(node.next_nodes[index], prefix + str(index), result)
  74.  
  75.     def get_all_addresses(self):
  76.         result = []
  77.         self.__dfs__(self.root_node, '', result)
  78.         return result
  79.  
  80.     def __dfs_size__(self, node):
  81.         ans = node.next_nodes.__sizeof__()
  82.         ans += node.routing_prefixes.__sizeof__()
  83.         ans += node.data.__sizeof__()
  84.  
  85.         for index in node.next_nodes:
  86.             ans += self.__dfs_size__(node.next_nodes[index])
  87.         return ans
  88.  
  89.     def __sizeof__(self):
  90.         return self.__dfs_size__(self.root_node)
  91.  
  92.  
  93. ## Dict part
  94.  
  95. def add_address(address):
  96.     if '/' in address:
  97.         address, routing_prefix = address.split('/')
  98.     else:
  99.         routing_prefix = None
  100.     addresses_dict.setdefault(address, set()).add(routing_prefix)
  101.  
  102.  
  103. def contains(address):
  104.     if '/' in address:
  105.         address, routing_prefix = address.split('/')
  106.     else:
  107.         routing_prefix = None
  108.     if address not in addresses_dict:
  109.         return False
  110.     return routing_prefix in addresses_dict[address]
  111.  
  112.  
  113. ## Make tests
  114. def get_rand_address(N):
  115.     mask = [str(randint(1, 255)) + '.' + str(randint(1, 255)) + '.' + str(randint(1, 255)) + '.' + str(randint(1, 255))
  116.             for i in range(N)]
  117.     submask = [mask[i] + '/' + str(j) for i in range(N) for j in range(32)]
  118.     return submask
  119.  
  120.  
  121. def test_add(N):
  122.     addresses = get_rand_address(N)
  123.  
  124.     start = time.time()
  125.     for address in addresses:
  126.         trie.add_address(address)
  127.     time_trie = time.time() - start
  128.  
  129.     start = time.time()
  130.     for address in addresses:
  131.         add_address(address)
  132.     time_dict = time.time() - start
  133.  
  134.     start = time.time()
  135.     for address in addresses:
  136.         addresses_set.add(address)
  137.     time_set = time.time() - start
  138.  
  139.     return [time_trie, time_dict, time_set]
  140.  
  141.  
  142. def test_contains(N):
  143.     addresses = get_rand_address(N)
  144.     start = time.time()
  145.     for address in addresses:
  146.         check = trie.__contains__(address)
  147.     time_trie = time.time() - start
  148.     start = time.time()
  149.     for address in addresses:
  150.         check = contains(address)
  151.     time_dict = time.time() - start
  152.     start = time.time()
  153.     for address in addresses:
  154.         check = address in addresses_set
  155.     time_set = time.time() - start
  156.     return [time_trie, time_dict, time_set]
  157.  
  158.  
  159. ###########
  160.  
  161. trie = Trie()
  162. addresses_dict = dict()
  163. addresses_set = set()
  164.  
  165. N = 30000
  166. time_add = test_add(N)
  167. print(N)
  168. print('Add to trie: ', 'time = ', time_add[0] * 1000, 'ms')
  169. print('Add to dict: ', 'time = ', time_add[1] * 1000, 'ms')
  170. print('Add to set: ', 'time = ', time_add[2] * 1000, 'ms')
  171.  
  172. time_contains = test_contains(N)
  173. print('Contains in trie: ', 'time = ', time_contains[0] * 1000, 'ms')
  174. print('Contains in dict: ', 'time = ', time_contains[1] * 1000, 'ms')
  175. print('Contains in set: ', 'time = ', time_contains[2] * 1000, 'ms')
  176.  
  177. print('Trie size in bytes', trie.__sizeof__())
  178. print('Dict size in bytes', addresses_dict.__sizeof__())
  179. print('Set size in bytes', addresses_set.__sizeof__())
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement