def topology_fiveNode(**kwargs): """Return a scenario based on Five_Node topology. This functions the similar as the GEANT topology but with only 5 nodes All routers are given caches Sources are added on initilization in addition to the main network to all nodes with 2 connections Parameters ---------- seed : int, optional The seed used for random number generation Returns ------- topology : fnss.Topology The topology object """ # 5 nodes topology = fnss.parse_topology_zoo( path.join(TOPOLOGY_RESOURCES_DIR, 'SixNode.graphml')).to_undirected() topology = list(nx.connected_component_subgraphs(topology))[0] deg = nx.degree(topology) receivers = [v for v in topology.nodes() if deg[v] == 1] # 8 nodes # attach sources to topology source_attachments = [v for v in topology.nodes() if deg[v] == 2] # 13 nodes sources = [] for v in source_attachments: u = v + 1000 # node ID of source topology.add_edge(v, u) sources.append(u) routers = [v for v in topology.nodes() if v not in sources + receivers] # Put caches in nodes with top betweenness centralities betw = nx.betweenness_centrality(topology) routers = sorted(routers, key=lambda k: betw[k]) # Select as ICR candidates all routers icr_candidates = routers # add stacks to nodes topology.graph['icr_candidates'] = set(icr_candidates) for v in sources: fnss.add_stack(topology, v, 'source') for v in receivers: fnss.add_stack(topology, v, 'receiver') for v in routers: fnss.add_stack(topology, v, 'router') # set weights and delays on all links fnss.set_weights_constant(topology, 1.0) fnss.set_delays_constant(topology, INTERNAL_LINK_DELAY, 'ms') # label links as internal or external for u, v in topology.edges_iter(): if u in sources or v in sources: topology.edge[u][v]['type'] = 'external' # this prevents sources to be used to route traffic fnss.set_weights_constant(topology, 1000.0, [(u, v)]) fnss.set_delays_constant(topology, EXTERNAL_LINK_DELAY, 'ms', [(u, v)]) else: topology.edge[u][v]['type'] = 'internal' return IcnTopology(topology)
def generate_graph(): graph_distance = fnss.parse_topology_zoo('NSFNET.graphml').to_undirected() fnss.set_weights_constant(graph_distance, 1100.0, [(0, 1)]) fnss.set_weights_constant(graph_distance, 600.0, [(1, 2)]) fnss.set_weights_constant(graph_distance, 1600.0, [(0, 2)]) fnss.set_weights_constant(graph_distance, 1000.0, [(1, 3)]) fnss.set_weights_constant(graph_distance, 2800.0, [(0, 7)]) fnss.set_weights_constant(graph_distance, 600.0, [(3, 4)]) fnss.set_weights_constant(graph_distance, 2000.0, [(2, 5)]) fnss.set_weights_constant(graph_distance, 2400.0, [(3, 10)]) fnss.set_weights_constant(graph_distance, 800.0, [(4, 6)]) fnss.set_weights_constant(graph_distance, 1100.0, [(4, 5)]) fnss.set_weights_constant(graph_distance, 700.0, [(6, 7)]) fnss.set_weights_constant(graph_distance, 2000.0, [(5, 13)]) fnss.set_weights_constant(graph_distance, 1200.0, [(5, 9)]) fnss.set_weights_constant(graph_distance, 900.0, [(9, 8)]) fnss.set_weights_constant(graph_distance, 700.0, [(7, 8)]) fnss.set_weights_constant(graph_distance, 800.0, [(10, 11)]) fnss.set_weights_constant(graph_distance, 800.0, [(10, 12)]) fnss.set_weights_constant(graph_distance, 500.0, [(8, 11)]) fnss.set_weights_constant(graph_distance, 500.0, [(8, 12)]) fnss.set_weights_constant(graph_distance, 300.0, [(11, 13)]) fnss.set_weights_constant(graph_distance, 300.0, [(13, 12)]) return graph_distance
def topology_garr2(**kwargs): """Return a scenario based on GARR topology. Differently from plain GARR, this topology some receivers are appended to routers and only a subset of routers which are actually on the path of some traffic are selected to become ICN routers. These changes make this topology more realistic. Parameters ---------- seed : int, optional The seed used for random number generation Returns ------- topology : fnss.Topology The topology object """ topology = fnss.parse_topology_zoo( path.join(TOPOLOGY_RESOURCES_DIR, 'Garr201201.graphml')).to_undirected() # sources are nodes representing neighbouring AS's sources = [0, 2, 3, 5, 13, 16, 23, 24, 25, 27, 51, 52, 54] # receivers are internal nodes with degree = 1 receivers = [ 1, 7, 8, 9, 11, 12, 19, 26, 28, 30, 32, 33, 41, 42, 43, 47, 48, 50, 53, 57, 60 ] # routers are all remaining nodes --> 27 caches routers = [ n for n in topology.nodes_iter() if n not in receivers + sources ] artificial_receivers = list(range(1000, 1000 + len(routers))) for i in range(len(routers)): topology.add_edge(routers[i], artificial_receivers[i]) receivers += artificial_receivers # Caches to nodes with degree > 3 (after adding artificial receivers) degree = nx.degree(topology) icr_candidates = [n for n in topology.nodes_iter() if degree[n] > 3.5] # set weights and delays on all links fnss.set_weights_constant(topology, 1.0) fnss.set_delays_constant(topology, INTERNAL_LINK_DELAY, 'ms') # Deploy stacks topology.graph['icr_candidates'] = set(icr_candidates) for v in sources: fnss.add_stack(topology, v, 'source') for v in receivers: fnss.add_stack(topology, v, 'receiver') for v in routers: fnss.add_stack(topology, v, 'router') # label links as internal or external for u, v in topology.edges(): if u in sources or v in sources: topology.edge[u][v]['type'] = 'external' # this prevents sources to be used to route traffic fnss.set_weights_constant(topology, 1000.0, [(u, v)]) fnss.set_delays_constant(topology, EXTERNAL_LINK_DELAY, 'ms', [(u, v)]) else: topology.edge[u][v]['type'] = 'internal' return IcnTopology(topology)
def topology_geant2(**kwargs): """Return a scenario based on GEANT topology. Differently from plain GEANT, this topology some receivers are appended to routers and only a subset of routers which are actually on the path of some traffic are selected to become ICN routers. These changes make this topology more realistic. Parameters ---------- seed : int, optional The seed used for random number generation Returns ------- topology : fnss.Topology The topology object """ # 53 nodes topology = fnss.parse_topology_zoo(path.join(TOPOLOGY_RESOURCES_DIR, 'Geant2012.graphml') ).to_undirected() topology = list(nx.connected_component_subgraphs(topology))[0] deg = nx.degree(topology) receivers = [v for v in topology.nodes() if deg[v] == 1] # 8 nodes # attach sources to topology source_attachments = [v for v in topology.nodes() if deg[v] == 2] # 13 nodes sources = [] for v in source_attachments: u = v + 1000 # node ID of source topology.add_edge(v, u) sources.append(u) routers = [v for v in topology.nodes() if v not in sources + receivers] # Put caches in nodes with top betweenness centralities betw = nx.betweenness_centrality(topology) routers = sorted(routers, key=lambda k: betw[k]) # Select as ICR candidates the top 50% routers for betweenness centrality icr_candidates = routers[len(routers) // 2:] # add stacks to nodes topology.graph['icr_candidates'] = set(icr_candidates) for v in sources: fnss.add_stack(topology, v, 'source') for v in receivers: fnss.add_stack(topology, v, 'receiver') for v in routers: fnss.add_stack(topology, v, 'router') # set weights and delays on all links fnss.set_weights_constant(topology, 1.0) fnss.set_delays_constant(topology, INTERNAL_LINK_DELAY, 'ms') # label links as internal or external for u, v in topology.edges_iter(): if u in sources or v in sources: topology.edge[u][v]['type'] = 'external' # this prevents sources to be used to route traffic fnss.set_weights_constant(topology, 1000.0, [(u, v)]) fnss.set_delays_constant(topology, EXTERNAL_LINK_DELAY, 'ms', [(u, v)]) else: topology.edge[u][v]['type'] = 'internal' return IcnTopology(topology)
def topology_geant2(**kwargs): """Return a scenario based on GEANT topology. Differently from plain GEANT, this topology some receivers are appended to routers and only a subset of routers which are actually on the path of some traffic are selected to become ICN routers. These changes make this topology more realistic. Parameters ---------- seed : int, optional The seed used for random number generation Returns ------- topology : fnss.Topology The topology object """ # 53 nodes topology = fnss.parse_topology_zoo(path.join(TOPOLOGY_RESOURCES_DIR, 'Geant2012.graphml') ).to_undirected() topology = list(nx.connected_component_subgraphs(topology))[0] deg = nx.degree(topology) receivers = [v for v in topology.nodes() if deg[v] == 1] # 8 nodes # attach sources to topology source_attachments = [v for v in topology.nodes() if deg[v] == 2] # 13 nodes sources = [] for v in source_attachments: u = v + 1000 # node ID of source topology.add_edge(v, u) sources.append(u) routers = [v for v in topology.nodes() if v not in sources + receivers] # Put caches in nodes with top betweenness centralities betw = nx.betweenness_centrality(topology) routers = sorted(routers, key=lambda k: betw[k]) # Select as ICR candidates the top 50% routers for betweenness centrality icr_candidates = routers[len(routers)//2:] # add stacks to nodes topology.graph['icr_candidates'] = set(icr_candidates) for v in sources: fnss.add_stack(topology, v, 'source') for v in receivers: fnss.add_stack(topology, v, 'receiver') for v in routers: fnss.add_stack(topology, v, 'router') # set weights and delays on all links fnss.set_weights_constant(topology, 1.0) fnss.set_delays_constant(topology, INTERNAL_LINK_DELAY, 'ms') # label links as internal or external for u, v in topology.edges_iter(): if u in sources or v in sources: topology.edge[u][v]['type'] = 'external' # this prevents sources to be used to route traffic fnss.set_weights_constant(topology, 1000.0, [(u, v)]) fnss.set_delays_constant(topology, EXTERNAL_LINK_DELAY, 'ms', [(u, v)]) else: topology.edge[u][v]['type'] = 'internal' return IcnTopology(topology)
def topology_fiveNode(**kwargs): """Return a scenario based on Five_Node topology. This functions the similar as the GEANT topology but with only 5 nodes All routers are given caches Sources are added on initilization in addition to the main network to all nodes with 2 connections Parameters ---------- seed : int, optional The seed used for random number generation Returns ------- topology : fnss.Topology The topology object """ # 5 nodes topology = fnss.parse_topology_zoo(path.join(TOPOLOGY_RESOURCES_DIR, 'SixNode.graphml') ).to_undirected() topology = list(nx.connected_component_subgraphs(topology))[0] deg = nx.degree(topology) receivers = [v for v in topology.nodes() if deg[v] == 1] # 8 nodes # attach sources to topology source_attachments = [v for v in topology.nodes() if deg[v] == 2] # 13 nodes sources = [] for v in source_attachments: u = v + 1000 # node ID of source topology.add_edge(v, u) sources.append(u) routers = [v for v in topology.nodes() if v not in sources + receivers] # Put caches in nodes with top betweenness centralities betw = nx.betweenness_centrality(topology) routers = sorted(routers, key=lambda k: betw[k]) # Select as ICR candidates all routers icr_candidates = routers # add stacks to nodes topology.graph['icr_candidates'] = set(icr_candidates) for v in sources: fnss.add_stack(topology, v, 'source') for v in receivers: fnss.add_stack(topology, v, 'receiver') for v in routers: fnss.add_stack(topology, v, 'router') # set weights and delays on all links fnss.set_weights_constant(topology, 1.0) fnss.set_delays_constant(topology, INTERNAL_LINK_DELAY, 'ms') # label links as internal or external for u, v in topology.edges_iter(): if u in sources or v in sources: topology.edge[u][v]['type'] = 'external' # this prevents sources to be used to route traffic fnss.set_weights_constant(topology, 1000.0, [(u, v)]) fnss.set_delays_constant(topology, EXTERNAL_LINK_DELAY, 'ms', [(u, v)]) else: topology.edge[u][v]['type'] = 'internal' return IcnTopology(topology)
def topology_wide(network_cache=0.05, n_contents=100000, seed=None): """ Return a scenario based on GARR topology Parameters ---------- network_cache : float Size of network cache (sum of all caches) normalized by size of content population n_contents : int Size of content population seed : int, optional The seed used for random number generation Returns ------- topology : fnss.Topology The topology object """ topology = fnss.parse_topology_zoo( path.join(TOPOLOGY_RESOURCES_DIR, 'WideJpn.graphml')).to_undirected() # sources are nodes representing neighbouring AS's sources = [9, 8, 11, 13, 12, 15, 14, 17, 16, 19, 18] # receivers are internal nodes with degree = 1 receivers = [27, 28, 3, 5, 4, 7] # caches are all remaining nodes --> 27 caches caches = [n for n in topology.nodes() if n not in receivers + sources] # set weights and delays on all links fnss.set_weights_constant(topology, 1.0) fnss.set_delays_constant(topology, INTERNAL_LINK_DELAY, 'ms') # randomly allocate contents to sources content_placement = uniform_content_placement(topology, range(1, n_contents + 1), sources, seed=seed) for v in sources: fnss.add_stack(topology, v, 'source', {'contents': content_placement[v]}) for v in receivers: fnss.add_stack(topology, v, 'receiver', {}) # label links as internal or external for u, v in topology.edges(): if u in sources or v in sources: topology.edge[u][v]['type'] = 'external' # this prevents sources to be used to route traffic fnss.set_weights_constant(topology, 1000.0, [(u, v)]) fnss.set_delays_constant(topology, EXTERNAL_LINK_DELAY, 'ms', [(u, v)]) else: topology.edge[u][v]['type'] = 'internal' cache_placement = uniform_cache_placement(topology, network_cache * n_contents, caches) for node, size in cache_placement.iteritems(): fnss.add_stack(topology, node, 'cache', {'size': size}) return topology
def topology_garr2(**kwargs): """Return a scenario based on GARR topology. Differently from plain GARR, this topology some receivers are appended to routers and only a subset of routers which are actually on the path of some traffic are selected to become ICN routers. These changes make this topology more realistic. Parameters ---------- seed : int, optional The seed used for random number generation Returns ------- topology : fnss.Topology The topology object """ topology = fnss.parse_topology_zoo(path.join(TOPOLOGY_RESOURCES_DIR, 'Garr201201.graphml')).to_undirected() # sources are nodes representing neighbouring AS's sources = [0, 2, 3, 5, 13, 16, 23, 24, 25, 27, 51, 52, 54] # receivers are internal nodes with degree = 1 receivers = [1, 7, 8, 9, 11, 12, 19, 26, 28, 30, 32, 33, 41, 42, 43, 47, 48, 50, 53, 57, 60] # routers are all remaining nodes --> 27 caches routers = [n for n in topology.nodes_iter() if n not in receivers + sources] artificial_receivers = list(range(1000, 1000 + len(routers))) for i in range(len(routers)): topology.add_edge(routers[i], artificial_receivers[i]) receivers += artificial_receivers # Caches to nodes with degree > 3 (after adding artificial receivers) degree = nx.degree(topology) icr_candidates = [n for n in topology.nodes_iter() if degree[n] > 3.5] # set weights and delays on all links fnss.set_weights_constant(topology, 1.0) fnss.set_delays_constant(topology, INTERNAL_LINK_DELAY, 'ms') # Deploy stacks topology.graph['icr_candidates'] = set(icr_candidates) for v in sources: fnss.add_stack(topology, v, 'source') for v in receivers: fnss.add_stack(topology, v, 'receiver') for v in routers: fnss.add_stack(topology, v, 'router') # label links as internal or external for u, v in topology.edges(): if u in sources or v in sources: topology.edge[u][v]['type'] = 'external' # this prevents sources to be used to route traffic fnss.set_weights_constant(topology, 1000.0, [(u, v)]) fnss.set_delays_constant(topology, EXTERNAL_LINK_DELAY, 'ms',[(u, v)]) else: topology.edge[u][v]['type'] = 'internal' return IcnTopology(topology)
def test_parse_topology_zoo(self): topozoo_file = path.join(RES_DIR, 'topozoo-arnes.graphml') topology = fnss.parse_topology_zoo(topozoo_file) self.assertEqual(type(topology), fnss.Topology) self.assertFalse(topology.is_multigraph()) self.assertEqual(34, topology.number_of_nodes()) self.assertEqual(46, topology.number_of_edges()) self.assertEqual(1000000000.0, topology.adj[4][15]['capacity']) self.assertEquals('bps', topology.graph['capacity_unit']) self.assertTrue(all(topology.adj[u][v]['length'] >= 0 for u, v in topology.edges() if 'length' in topology.adj[u][v]))
def test_parse_topology_zoo(self): topozoo_file = path.join(RES_DIR,'topozoo-arnes.graphml') topology = fnss.parse_topology_zoo(topozoo_file) self.assertEqual(type(topology), fnss.Topology) self.assertFalse(topology.is_multigraph()) self.assertEqual(34, topology.number_of_nodes()) self.assertEqual(46, topology.number_of_edges()) self.assertEqual(1000000000.0, topology.edge[4][15]['capacity']) self.assertEquals('bps', topology.graph['capacity_unit']) self.assertTrue(all(topology.edge[u][v]['length'] >= 0 for u,v in topology.edges_iter() if 'length' in topology.edge[u][v]))
def topology_geant(**kwargs): """Return a scenario based on GEANT topology Parameters ---------- seed : int, optional The seed used for random number generation Returns ------- topology : fnss.Topology The topology object """ # 240 nodes in the main component topology = fnss.parse_topology_zoo( path.join(TOPOLOGY_RESOURCES_DIR, 'Geant2012.graphml')).to_undirected() topology = list(nx.connected_component_subgraphs(topology))[0] deg = nx.degree(topology) receivers = [v for v in topology.nodes() if deg[v] == 1] # 8 nodes icr_candidates = [v for v in topology.nodes() if deg[v] > 2] # 19 nodes # attach sources to topology source_attachments = [v for v in topology.nodes() if deg[v] == 2] # 13 nodes sources = [] for v in source_attachments: u = v + 1000 # node ID of source topology.add_edge(v, u) sources.append(u) routers = [v for v in topology.nodes() if v not in sources + receivers] # add stacks to nodes topology.graph['icr_candidates'] = set(icr_candidates) for v in sources: fnss.add_stack(topology, v, 'source') for v in receivers: fnss.add_stack(topology, v, 'receiver') for v in routers: fnss.add_stack(topology, v, 'router') # set weights and delays on all links fnss.set_weights_constant(topology, 1.0) fnss.set_delays_constant(topology, INTERNAL_LINK_DELAY, 'ms') # label links as internal or external for u, v in topology.edges_iter(): if u in sources or v in sources: topology.edge[u][v]['type'] = 'external' # this prevents sources to be used to route traffic fnss.set_weights_constant(topology, 1000.0, [(u, v)]) fnss.set_delays_constant(topology, EXTERNAL_LINK_DELAY, 'ms', [(u, v)]) else: topology.edge[u][v]['type'] = 'internal' return IcnTopology(topology)
def topology_garr(network_cache=0.05, n_contents=100000, seed=None): """ Return a scenario based on GARR topology Parameters ---------- network_cache : float Size of network cache (sum of all caches) normalized by size of content population n_contents : int Size of content population seed : int, optional The seed used for random number generation Returns ------- topology : fnss.Topology The topology object """ topology = fnss.parse_topology_zoo(path.join(TOPOLOGY_RESOURCES_DIR, 'Garr201201.graphml')).to_undirected() # sources are nodes representing neighbouring AS's sources = [0, 2, 3, 5, 13, 16, 23, 24, 25, 27, 51, 52, 54] # receivers are internal nodes with degree = 1 receivers = [1, 7, 8, 9, 11, 12, 19, 26, 28, 30, 32, 33, 41, 42, 43, 47, 48, 50, 53, 57, 60] # caches are all remaining nodes --> 27 caches caches = [n for n in topology.nodes() if n not in receivers + sources] # set weights and delays on all links fnss.set_weights_constant(topology, 1.0) fnss.set_delays_constant(topology, INTERNAL_LINK_DELAY, 'ms') # randomly allocate contents to sources content_placement = uniform_content_placement(topology, range(1, n_contents+1), sources, seed=seed) for v in sources: fnss.add_stack(topology, v, 'source', {'contents': content_placement[v]}) for v in receivers: fnss.add_stack(topology, v, 'receiver', {}) # label links as internal or external for u, v in topology.edges(): if u in sources or v in sources: topology.edge[u][v]['type'] = 'external' # this prevents sources to be used to route traffic fnss.set_weights_constant(topology, 1000.0, [(u, v)]) fnss.set_delays_constant(topology, EXTERNAL_LINK_DELAY, 'ms',[(u, v)]) else: topology.edge[u][v]['type'] = 'internal' cache_placement = uniform_cache_placement(topology, network_cache*n_contents, caches) for node, size in cache_placement.iteritems(): fnss.add_stack(topology, node, 'cache', {'size': size}) return topology
def topology_geant(**kwargs): """Return a scenario based on GEANT topology Parameters ---------- seed : int, optional The seed used for random number generation Returns ------- topology : fnss.Topology The topology object """ # 240 nodes in the main component topology = fnss.parse_topology_zoo(path.join(TOPOLOGY_RESOURCES_DIR, 'Geant2012.graphml') ).to_undirected() topology = list(nx.connected_component_subgraphs(topology))[0] deg = nx.degree(topology) receivers = [v for v in topology.nodes() if deg[v] == 1] # 8 nodes icr_candidates = [v for v in topology.nodes() if deg[v] > 2] # 19 nodes # attach sources to topology source_attachments = [v for v in topology.nodes() if deg[v] == 2] # 13 nodes sources = [] for v in source_attachments: u = v + 1000 # node ID of source topology.add_edge(v, u) sources.append(u) routers = [v for v in topology.nodes() if v not in sources + receivers] # add stacks to nodes topology.graph['icr_candidates'] = set(icr_candidates) for v in sources: fnss.add_stack(topology, v, 'source') for v in receivers: fnss.add_stack(topology, v, 'receiver') for v in routers: fnss.add_stack(topology, v, 'router') # set weights and delays on all links fnss.set_weights_constant(topology, 1.0) fnss.set_delays_constant(topology, INTERNAL_LINK_DELAY, 'ms') # label links as internal or external for u, v in topology.edges_iter(): if u in sources or v in sources: topology.edge[u][v]['type'] = 'external' # this prevents sources to be used to route traffic fnss.set_weights_constant(topology, 1000.0, [(u, v)]) fnss.set_delays_constant(topology, EXTERNAL_LINK_DELAY, 'ms', [(u, v)]) else: topology.edge[u][v]['type'] = 'internal' return IcnTopology(topology)
def topology_garr(**kwargs): """Return a scenario based on GARR topology Parameters ---------- seed : int, optional The seed used for random number generation Returns ------- topology : fnss.Topology The topology object """ topology = fnss.parse_topology_zoo( path.join(TOPOLOGY_RESOURCES_DIR, 'Garr201201.graphml')).to_undirected() # sources are nodes representing neighbouring AS's sources = [0, 2, 3, 5, 13, 16, 23, 24, 25, 27, 51, 52, 54] # receivers are internal nodes with degree = 1 receivers = [ 1, 7, 8, 9, 11, 12, 19, 26, 28, 30, 32, 33, 41, 42, 43, 47, 48, 50, 53, 57, 60 ] # caches are all remaining nodes --> 27 caches routers = [n for n in topology.nodes() if n not in receivers + sources] icr_candidates = routers # set weights and delays on all links fnss.set_weights_constant(topology, 1.0) fnss.set_delays_constant(topology, INTERNAL_LINK_DELAY, 'ms') # Deploy stacks topology.graph['icr_candidates'] = set(icr_candidates) for v in sources: fnss.add_stack(topology, v, 'source') for v in receivers: fnss.add_stack(topology, v, 'receiver') for v in routers: fnss.add_stack(topology, v, 'router') # label links as internal or external for u, v in topology.edges(): if u in sources or v in sources: topology.edge[u][v]['type'] = 'external' # this prevents sources to be used to route traffic fnss.set_weights_constant(topology, 1000.0, [(u, v)]) fnss.set_delays_constant(topology, EXTERNAL_LINK_DELAY, 'ms', [(u, v)]) else: topology.edge[u][v]['type'] = 'internal' return IcnTopology(topology)
def parse(topo_path, xml_path, delay, buffer_type): topology = fnss.parse_topology_zoo(topo_path) topology = topology.to_undirected() fnss.set_capacities_edge_betweenness(topology, [200, 500, 1000], 'Mbps') # TODO: hardcode now fnss.set_weights_constant(topology, 1) fnss.set_delays_constant(topology, delay, 'ms') if buffer_type == 'bdp': fnss.set_buffer_sizes_bw_delay_prod(topology, 'packet', 1500) elif buffer_type == 'bw': fnss.set_buffer_sizes_link_bandwidth(topology, buffer_unit='packet') else: fnss.set_buffer_sizes_constant(topology, 1500, 'packet') fnss.write_topology(topology, xml_path)
def test_parse_topology_zoo_multigraph(self): topozoo_file = path.join(RES_DIR, 'topozoo-garr.graphml') topology = fnss.parse_topology_zoo(topozoo_file) self.assertEqual(type(topology), fnss.Topology) self.assertFalse(topology.is_multigraph()) self.assertEqual(61, topology.number_of_nodes()) self.assertEqual(75, topology.number_of_edges()) self.assertEquals('bps', topology.graph['capacity_unit']) self.assertEquals(2000000000, topology.edge[37][58]['capacity']) bundled_links = [(43, 18), (49, 32), (41, 18), (4, 7), (6, 55), (9, 58), (58, 37), (10, 55), (14, 57), (14, 35), (18, 41), (18, 43), (31, 33), (31, 34), (32, 49), (37, 58)] for u, v in topology.edges(): print(u, v) self.assertEquals((u, v) in bundled_links, topology.edge[u][v]['bundle'])
def test_parse_topology_zoo_multigraph(self): topozoo_file = path.join(RES_DIR,'topozoo-garr.graphml') topology = fnss.parse_topology_zoo(topozoo_file) self.assertEqual(type(topology), fnss.Topology) self.assertFalse(topology.is_multigraph()) self.assertEqual(61, topology.number_of_nodes()) self.assertEqual(75, topology.number_of_edges()) self.assertEquals('bps', topology.graph['capacity_unit']) self.assertEquals(2000000000, topology.edge[37][58]['capacity']) bundled_links = [(43, 18), (49, 32), (41, 18), (4, 7), (6, 55), (9, 58), (58, 37), (10, 55), (14, 57), (14, 35), (18, 41), (18, 43), (31, 33), (31, 34), (32, 49), (37, 58)] for u, v in topology.edges(): print(u, v) self.assertEquals((u, v) in bundled_links, topology.edge[u][v]['bundle'])
def topology_wide(**kwargs): """Return a scenario based on GARR topology Parameters ---------- seed : int, optional The seed used for random number generation Returns ------- topology : fnss.Topology The topology object """ topology = fnss.parse_topology_zoo( path.join(TOPOLOGY_RESOURCES_DIR, 'WideJpn.graphml')).to_undirected() # sources are nodes representing neighbouring AS's sources = [9, 8, 11, 13, 12, 15, 14, 17, 16, 19, 18] # receivers are internal nodes with degree = 1 receivers = [27, 28, 3, 5, 4, 7] # caches are all remaining nodes --> 27 caches routers = [n for n in topology.nodes() if n not in receivers + sources] # All routers can be upgraded to ICN functionalities icr_candidates = routers # set weights and delays on all links fnss.set_weights_constant(topology, 1.0) fnss.set_delays_constant(topology, INTERNAL_LINK_DELAY, 'ms') # Deploy stacks topology.graph['icr_candidates'] = set(icr_candidates) for v in sources: fnss.add_stack(topology, v, 'source') for v in receivers: fnss.add_stack(topology, v, 'receiver') for v in routers: fnss.add_stack(topology, v, 'router') # label links as internal or external for u, v in topology.edges(): if u in sources or v in sources: topology.adj[u][v]['type'] = 'external' # this prevents sources to be used to route traffic fnss.set_weights_constant(topology, 1000.0, [(u, v)]) fnss.set_delays_constant(topology, EXTERNAL_LINK_DELAY, 'ms', [(u, v)]) else: topology.adj[u][v]['type'] = 'internal' return IcnTopology(topology)
def topology_garr(**kwargs): """Return a scenario based on GARR topology Parameters ---------- seed : int, optional The seed used for random number generation Returns ------- topology : fnss.Topology The topology object """ topology = fnss.parse_topology_zoo(path.join(TOPOLOGY_RESOURCES_DIR, 'Garr201201.graphml')).to_undirected() # sources are nodes representing neighbouring AS's sources = [0, 2, 3, 5, 13, 16, 23, 24, 25, 27, 51, 52, 54] # receivers are internal nodes with degree = 1 receivers = [1, 7, 8, 9, 11, 12, 19, 26, 28, 30, 32, 33, 41, 42, 43, 47, 48, 50, 53, 57, 60] # caches are all remaining nodes --> 27 caches routers = [n for n in topology.nodes() if n not in receivers + sources] icr_candidates = routers # set weights and delays on all links fnss.set_weights_constant(topology, 1.0) fnss.set_delays_constant(topology, INTERNAL_LINK_DELAY, 'ms') # Deploy stacks topology.graph['icr_candidates'] = set(icr_candidates) for v in sources: fnss.add_stack(topology, v, 'source') for v in receivers: fnss.add_stack(topology, v, 'receiver') for v in routers: fnss.add_stack(topology, v, 'router') # label links as internal or external for u, v in topology.edges(): if u in sources or v in sources: topology.edge[u][v]['type'] = 'external' # this prevents sources to be used to route traffic fnss.set_weights_constant(topology, 1000.0, [(u, v)]) fnss.set_delays_constant(topology, EXTERNAL_LINK_DELAY, 'ms',[(u, v)]) else: topology.edge[u][v]['type'] = 'internal' return IcnTopology(topology)
def topology_wide(**kwargs): """Return a scenario based on WIDE topology Parameters ---------- seed : int, optional The seed used for random number generation Returns ------- topology : fnss.Topology The topology object """ topology = fnss.parse_topology_zoo(path.join(TOPOLOGY_RESOURCES_DIR, 'WideJpn.graphml')).to_undirected() # sources are nodes representing neighbouring AS's sources = [9, 8, 11, 13, 12, 15, 14, 17, 16, 19, 18] # receivers are internal nodes with degree = 1 receivers = [27, 28, 3, 5, 4, 7] # caches are all remaining nodes --> 27 caches routers = [n for n in topology.nodes() if n not in receivers + sources] # All routers can be upgraded to ICN functionalitirs icr_candidates = routers # set weights and delays on all links fnss.set_weights_constant(topology, 1.0) fnss.set_delays_constant(topology, INTERNAL_LINK_DELAY, 'ms') # Deploy stacks topology.graph['icr_candidates'] = set(icr_candidates) for v in sources: fnss.add_stack(topology, v, 'source') for v in receivers: fnss.add_stack(topology, v, 'receiver') for v in routers: fnss.add_stack(topology, v, 'router') # label links as internal or external for u, v in topology.edges(): if u in sources or v in sources: topology.edge[u][v]['type'] = 'external' # this prevents sources to be used to route traffic fnss.set_weights_constant(topology, 1000.0, [(u, v)]) fnss.set_delays_constant(topology, EXTERNAL_LINK_DELAY, 'ms',[(u, v)]) else: topology.edge[u][v]['type'] = 'internal' return IcnTopology(topology)
def scenario_garr(net_cache=[0.01, 0.05], n_contents=100000, alpha=[0.6, 0.8, 1.0]): """ Return a scenario based on GARR topology Parameters ---------- scenario_id : str String identifying the scenario (will be in the filename) net_cache : float Size of network cache (sum of all caches) normalized by size of content population n_contents : int Size of content population alpha : float List of alpha of Zipf content distribution """ rate = 12.0 warmup = 9000 duration = 36000 T = 'GARR' # name of the topology topology = fnss.parse_topology_zoo( path.join(scenarios_dir, 'resources/Garr201201.graphml')).to_undirected() # sources are nodes representing neighbouring AS's sources = [0, 2, 3, 5, 13, 16, 23, 24, 25, 27, 51, 52, 54] # receivers are internal nodes with degree = 1 receivers = [ 1, 7, 8, 9, 11, 12, 19, 26, 28, 30, 32, 33, 41, 42, 43, 47, 48, 50, 53, 57, 60 ] # caches are all remaining nodes --> 27 caches caches = [n for n in topology.nodes() if n not in receivers + sources] # set weights and delays on all links fnss.set_weights_constant(topology, 1.0) fnss.set_delays_constant(topology, internal_link_delay, 'ms') # randomly allocate contents to sources contents = dict([(v, []) for v in sources]) for c in range(1, n_contents + 1): s = choice(sources) contents[s].append(c) for v in sources: fnss.add_stack(topology, v, 'source', {'contents': contents[v]}) for v in receivers: fnss.add_stack(topology, v, 'receiver', {}) # label links as internal or external for u, v in topology.edges(): if u in sources or v in sources: topology.edge[u][v]['type'] = 'external' # this prevents sources to be used to route traffic fnss.set_weights_constant(topology, 1000.0, [(u, v)]) fnss.set_delays_constant(topology, external_link_delay, 'ms', [(u, v)]) else: topology.edge[u][v]['type'] = 'internal' for nc in net_cache: size = (float(nc) * n_contents) / len(caches) # size of a single cache C = str(nc) for v in caches: fnss.add_stack(topology, v, 'cache', {'size': size}) fnss.write_topology( topology, path.join(scenarios_dir, topo_prefix + 'T=%s@C=%s' % (T, C) + '.xml')) print('[WROTE TOPOLOGY] T: %s, C: %s' % (T, C)) for a in alpha: event_schedule = gen_req_schedule(receivers, rate, warmup, duration, n_contents, a) fnss.write_event_schedule( event_schedule, path.join(scenarios_dir, es_prefix + 'T=%s@A=%s' % (T, str(a)) + '.xml')) print('[WROTE SCHEDULE] T: %s, Alpha: %s, Events: %d' % (T, str(a), len(event_schedule)))
def scenario_geant(net_cache=[0.05], n_contents=100000, alpha=[0.6, 0.8, 1.0]): """ Return a scenario based on GARR topology Parameters ---------- scenario_id : str String identifying the scenario (will be in the filename) net_cache : float Size of network cache (sum of all caches) normalized by size of content population n_contents : int Size of content population alpha : float List of alpha of Zipf content distribution """ rate = 12.0 warmup = 9000 duration = 36000 T = 'GEANT' # name of the topology # 240 nodes in the main component topology = fnss.parse_topology_zoo(path.join(scenarios_dir, 'resources/Geant2012.graphml')).to_undirected() topology = nx.connected_component_subgraphs(topology)[0] deg = nx.degree(topology) receivers = [v for v in topology.nodes() if deg[v] == 1] # 8 nodes caches = [v for v in topology.nodes() if deg[v] > 2] # 19 nodes # attach sources to topology source_attachments = [v for v in topology.nodes() if deg[v] == 2] # 13 nodes sources = [] for v in source_attachments: u = v + 1000 # node ID of source topology.add_edge(v, u) sources.append(u) routers = [v for v in topology.nodes() if v not in caches + sources + receivers] # randomly allocate contents to sources contents = dict([(v, []) for v in sources]) for c in range(1, n_contents + 1): s = choice(sources) contents[s].append(c) for v in sources: fnss.add_stack(topology, v, 'source', {'contents': contents[v]}) for v in receivers: fnss.add_stack(topology, v, 'receiver', {}) for v in routers: fnss.add_stack(topology, v, 'router', {}) # set weights and delays on all links fnss.set_weights_constant(topology, 1.0) fnss.set_delays_constant(topology, internal_link_delay, 'ms') # label links as internal or external for u, v in topology.edges(): if u in sources or v in sources: topology.edge[u][v]['type'] = 'external' # this prevents sources to be used to route traffic fnss.set_weights_constant(topology, 1000.0, [(u, v)]) fnss.set_delays_constant(topology, external_link_delay, 'ms', [(u, v)]) else: topology.edge[u][v]['type'] = 'internal' for nc in net_cache: size = (float(nc)*n_contents)/len(caches) # size of a single cache C = str(nc) for v in caches: fnss.add_stack(topology, v, 'cache', {'size': size}) fnss.write_topology(topology, path.join(scenarios_dir, topo_prefix + 'T=%s@C=%s' % (T, C) + '.xml')) print('[WROTE TOPOLOGY] T: %s, C: %s' % (T, C)) for a in alpha: event_schedule = gen_req_schedule(receivers, rate, warmup, duration, n_contents, a) fnss.write_event_schedule(event_schedule, path.join(scenarios_dir, es_prefix + 'T=%s@A=%s' % (T, str(a)) + '.xml')) print('[WROTE SCHEDULE] T: %s, Alpha: %s, Events: %d' % (T, str(a), len(event_schedule)))
def scenario_garr(net_cache=[0.01, 0.05], n_contents=100000, alpha=[0.6, 0.8, 1.0]): """ Return a scenario based on GARR topology Parameters ---------- scenario_id : str String identifying the scenario (will be in the filename) net_cache : float Size of network cache (sum of all caches) normalized by size of content population n_contents : int Size of content population alpha : float List of alpha of Zipf content distribution """ rate = 12.0 warmup = 9000 duration = 36000 T = 'GARR' # name of the topology topology = fnss.parse_topology_zoo(path.join(scenarios_dir, 'resources/Garr201201.graphml')).to_undirected() # sources are nodes representing neighbouring AS's sources = [0, 2, 3, 5, 13, 16, 23, 24, 25, 27, 51, 52, 54] # receivers are internal nodes with degree = 1 receivers = [1, 7, 8, 9, 11, 12, 19, 26, 28, 30, 32, 33, 41, 42, 43, 47, 48, 50, 53, 57, 60] # caches are all remaining nodes --> 27 caches caches = [n for n in topology.nodes() if n not in receivers + sources] # set weights and delays on all links fnss.set_weights_constant(topology, 1.0) fnss.set_delays_constant(topology, internal_link_delay, 'ms') # randomly allocate contents to sources contents = dict([(v, []) for v in sources]) for c in range(1, n_contents + 1): s = choice(sources) contents[s].append(c) for v in sources: fnss.add_stack(topology, v, 'source', {'contents': contents[v]}) for v in receivers: fnss.add_stack(topology, v, 'receiver', {}) # label links as internal or external for u, v in topology.edges(): if u in sources or v in sources: topology.edge[u][v]['type'] = 'external' # this prevents sources to be used to route traffic fnss.set_weights_constant(topology, 1000.0, [(u, v)]) fnss.set_delays_constant(topology, external_link_delay, 'ms',[(u, v)]) else: topology.edge[u][v]['type'] = 'internal' for nc in net_cache: size = (float(nc)*n_contents)/len(caches) # size of a single cache C = str(nc) for v in caches: fnss.add_stack(topology, v, 'cache', {'size': size}) fnss.write_topology(topology, path.join(scenarios_dir, topo_prefix + 'T=%s@C=%s' % (T, C) + '.xml')) print('[WROTE TOPOLOGY] T: %s, C: %s' % (T, C)) for a in alpha: event_schedule = gen_req_schedule(receivers, rate, warmup, duration, n_contents, a) fnss.write_event_schedule(event_schedule, path.join(scenarios_dir, es_prefix + 'T=%s@A=%s' % (T, str(a)) + '.xml')) print('[WROTE SCHEDULE] T: %s, Alpha: %s, Events: %d' % (T, str(a), len(event_schedule)))
def test_parse_topology_zoo_multigraph_directed_topology(self): topozoo_file = path.join(RES_DIR, 'topozoo-kdl.graphml') topology = fnss.parse_topology_zoo(topozoo_file) self.assertEqual(type(topology), fnss.DirectedTopology) self.assertFalse(topology.is_multigraph()) self.assertTrue(topology.graph['link_bundling'])
def scenario_geant(net_cache=[0.05], n_contents=100000, alpha=[0.6, 0.8, 1.0]): """ Return a scenario based on GARR topology Parameters ---------- scenario_id : str String identifying the scenario (will be in the filename) net_cache : float Size of network cache (sum of all caches) normalized by size of content population n_contents : int Size of content population alpha : float List of alpha of Zipf content distribution """ rate = 12.0 warmup = 9000 duration = 36000 T = 'GEANT' # name of the topology # 240 nodes in the main component topology = fnss.parse_topology_zoo( path.join(scenarios_dir, 'resources/Geant2012.graphml')).to_undirected() topology = list(nx.connected_component_subgraphs(topology))[0] deg = nx.degree(topology) receivers = [v for v in topology.nodes() if deg[v] == 1] # 8 nodes caches = [v for v in topology.nodes() if deg[v] > 2] # 19 nodes # attach sources to topology source_attachments = [v for v in topology.nodes() if deg[v] == 2] # 13 nodes sources = [] for v in source_attachments: u = v + 1000 # node ID of source topology.add_edge(v, u) sources.append(u) routers = [ v for v in topology.nodes() if v not in caches + sources + receivers ] # randomly allocate contents to sources contents = dict([(v, []) for v in sources]) for c in range(1, n_contents + 1): s = choice(sources) contents[s].append(c) for v in sources: fnss.add_stack(topology, v, 'source', {'contents': contents[v]}) for v in receivers: fnss.add_stack(topology, v, 'receiver', {}) for v in routers: fnss.add_stack(topology, v, 'router', {}) # set weights and delays on all links fnss.set_weights_constant(topology, 1.0) fnss.set_delays_constant(topology, internal_link_delay, 'ms') # label links as internal or external for u, v in topology.edges(): if u in sources or v in sources: topology.edge[u][v]['type'] = 'external' # this prevents sources to be used to route traffic fnss.set_weights_constant(topology, 1000.0, [(u, v)]) fnss.set_delays_constant(topology, external_link_delay, 'ms', [(u, v)]) else: topology.edge[u][v]['type'] = 'internal' for nc in net_cache: size = (float(nc) * n_contents) / len(caches) # size of a single cache C = str(nc) for v in caches: fnss.add_stack(topology, v, 'cache', {'size': size}) fnss.write_topology( topology, path.join(scenarios_dir, topo_prefix + 'T=%s@C=%s' % (T, C) + '.xml')) print('[WROTE TOPOLOGY] T: %s, C: %s' % (T, C)) for a in alpha: event_schedule = gen_req_schedule(receivers, rate, warmup, duration, n_contents, a) fnss.write_event_schedule( event_schedule, path.join(scenarios_dir, es_prefix + 'T=%s@A=%s' % (T, str(a)) + '.xml')) print('[WROTE SCHEDULE] T: %s, Alpha: %s, Events: %d' % (T, str(a), len(event_schedule)))
def topology_geant(network_cache=0.05, n_contents=100000, seed=None): """ Return a scenario based on GEANT topology Parameters ---------- network_cache : float Size of network cache (sum of all caches) normalized by size of content population n_contents : int Size of content population seed : int, optional The seed used for random number generation Returns ------- topology : fnss.Topology The topology object """ # 240 nodes in the main component topology = fnss.parse_topology_zoo(path.join(TOPOLOGY_RESOURCES_DIR, 'Geant2012.graphml') ).to_undirected() topology = nx.connected_component_subgraphs(topology)[0] deg = nx.degree(topology) receivers = [v for v in topology.nodes() if deg[v] == 1] # 8 nodes caches = [v for v in topology.nodes() if deg[v] > 2] # 19 nodes # attach sources to topology source_attachments = [v for v in topology.nodes() if deg[v] == 2] # 13 nodes sources = [] for v in source_attachments: u = v + 1000 # node ID of source topology.add_edge(v, u) sources.append(u) routers = [v for v in topology.nodes() if v not in caches + sources + receivers] # randomly allocate contents to sources content_placement = uniform_content_placement(topology, range(1, n_contents+1), sources, seed=seed) # add stacks to nodes for v in sources: fnss.add_stack(topology, v, 'source', {'contents': content_placement[v]}) for v in receivers: fnss.add_stack(topology, v, 'receiver', {}) for v in routers: fnss.add_stack(topology, v, 'router', {}) # set weights and delays on all links fnss.set_weights_constant(topology, 1.0) fnss.set_delays_constant(topology, INTERNAL_LINK_DELAY, 'ms') # label links as internal or external for u, v in topology.edges_iter(): if u in sources or v in sources: topology.edge[u][v]['type'] = 'external' # this prevents sources to be used to route traffic fnss.set_weights_constant(topology, 1000.0, [(u, v)]) fnss.set_delays_constant(topology, EXTERNAL_LINK_DELAY, 'ms', [(u, v)]) else: topology.edge[u][v]['type'] = 'internal' # place caches cache_placement = uniform_cache_placement(topology, network_cache*n_contents, caches) for node, size in cache_placement.iteritems(): fnss.add_stack(topology, node, 'cache', {'size': size}) return topology
def topology(): fnss_topology = fnss.parse_topology_zoo('AttMpls.gml') #fnss.two_tier_topology(1, 2, 2) "Create a network with some docker containers acting as hosts." # Set link attributes # https://fnss.github.io/doc/core/apidoc/fnss.functions.html #fnss.set_capacities_constant(fnss_topology, 10, 'Mbps') #fnss.set_delays_constant(fnss_topology, 2, 'ms') #fnss.set_buffer_sizes_constant(fnss_topology, 50, 'packets') fnss.set_delays_geo_distance(fnss_topology, specific_delay=fnss.PROPAGATION_DELAY_FIBER) mn_topo = fnss.to_mininet(fnss_topology, relabel_nodes=True) for node in mn_topo.hosts(): mn_topo.setNodeInfo( node, { "dcmd": ["/bin/bash", "/ndn-entrypoint.sh"], "dimage": "ndnrepo_ndn:latest", "privileged": True, "cls": Docker }) #mn_topo.setNodeInfo(node, "privileged", True ) #mn_topo.setNodeInfo(node, "dimage", "ndnrepo_ndn:latest" ) #node.dcmd=["/bin/bash", "/ndn-entrypoint.sh"] # = Docker('{0}'.format(node), ip='10.0.0.{0}'.format(node), , privileged=True, dimage="ndnrepo_ndn:latest") #node.type='host' #print node #nodes.append(node) net = NDNContainernet(topo=mn_topo, link=TCLink, controller=Controller) dumpNodeConnections(net.hosts) dumpNodeConnections(net.switches) fnss_topology.edges() info('*** Starting network\n') net.start() embed() #TODO Add NDN Links for all #fnss_topology.edges() #[(0, 1), (0, 2), (1, 3), (1, 4), (2, 5), (2, 6)] #addNDNRoute(d1, d2) #net = Containernet(controller=Controller) info('*** Adding controller\n') #net.addController('c0') info('*** Adding docker containers\n') #d1 = net.addDocker('d1', ip='10.0.0.251', dcmd=["/bin/bash", "/ndn-entrypoint.sh"], privileged=True, dimage="ndnrepo_ndn:latest") #d2 = net.addDocker('d2', ip='10.0.0.250', dcmd=["/bin/bash", "/ndn-entrypoint.sh"], privileged=True, dimage="ndnrepo_ndn:latest") #s1 = net.addSwitch('s1') info('*** Creating links\n') #net.addLink(d1, s1) #net.addLink(s1, d2) time.sleep(5) print addNDNRoute(d1, d2) #TODO create file when inserting is done while not (checkRepoNGInitDone(d1) and checkRepoNGInitDone(d2)): time.sleep(5) print listFilesInRepo(d1) print listFilesInRepo(d2) info('*** Running CLI\n') dumpNodeConnections(net.hosts) CLI(net) info('*** Stopping network') net.stop()
def topology_geant_custom(network_cache=0.05, n_contents=100000, seed=None): """ Return a scenario based on GEANT topology Parameters ---------- network_cache : float Size of network cache (sum of all caches) normalized by size of content population n_contents : int Size of content population seed : int, optional The seed used for random number generation Returns ------- topology : fnss.Topology The topology object """ topology = fnss.parse_topology_zoo( path.join(TOPOLOGY_RESOURCES_DIR, "Geant2012.graphml")).to_undirected() topology = list(nx.connected_component_subgraphs(topology))[0] deg = nx.degree(topology) caches = [v for v in topology.nodes()] # 38 nodes cache_catogory = [ 1, 4, 2, 1, 3, 3, 3, 1, 4, 3, 2, 1, 1, 2, 1, 4, 2, 3, 1, 3, 3, 2, 3, 4, 4, 2, 3, 1, 3, 1, 3, 1, 3, 1, 1, 3, 1, 1, 4, 1 ] count = 0 for node in caches: fnss.add_stack(topology, node, 'receiver', {}) count += 1 # attach sources to topology source_attachments = [v for v in topology.nodes() if deg[v] == 2] # 13 nodes sources = [] for v in source_attachments: u = v + 1000 # node ID of source topology.add_edge(v, u) sources.append(u) # randomly allocate contents to sources content_placement = uniform_content_placement(topology, range(1, n_contents + 1), sources, seed=seed) # add stacks to nodes for v in sources: fnss.add_stack(topology, v, 'source', {'contents': content_placement[v]}) # set weights and delays on all links fnss.set_weights_constant(topology, 1.0) fnss.set_delays_constant(topology, INTERNAL_LINK_DELAY, 'ms') # label links as internal or external for u, v in topology.edges_iter(): if u in sources or v in sources: topology.edge[u][v]['type'] = 'external' # this prevents sources to be used to route traffic fnss.set_weights_constant(topology, 1000.0, [(u, v)]) fnss.set_delays_constant(topology, EXTERNAL_LINK_DELAY, 'ms', [(u, v)]) else: topology.edge[u][v]['type'] = 'internal' # place caches cache_placement = uniform_cache_placement(topology, network_cache * n_contents, caches) for node, size in cache_placement.iteritems(): fnss.add_stack(topology, node, 'cache', {'size': size}) return topology