def share_edge(s1, s2): """Determine whether two slices share a physical edge.""" # This is only correct if we have a guarantee that the topologies are sane, # and only give us real internal edges. s1_ls = set(map_edges(edges_of_topo(s1.l_topo), s1.node_map, s1.port_map)) s2_ls = set(map_edges(edges_of_topo(s2.l_topo), s2.node_map, s2.port_map)) return not s1_ls.isdisjoint(s2_ls)
def edge_in(edge, slic, memo=None): """Determine whether a slice uses a given physical edge""" if memo is not None: if slic not in memo: memo[slic] = set(map_edges(edges_of_topo(slic.l_topo), slic.node_map, slic.port_map)) return edge in memo[slic] else: return edge in set(map_edges(edges_of_topo(slic.l_topo), slic.node_map, slic.port_map))
def edge_optimal(topo, slices, verbose=False): """Return the minimum per-slice-per-edge vlan assignment. verbose: print a '.' every 1000 edges processed RETURNS: {edge: {slice: tag}}. Note that while this is inconvenient to work with from slices, it's much more convenient to generate. If you want {slice: {edge: tag}}, there's a converter in edge_compile.py """ if verbose: import sys count = 0 edges = edges_of_topo(topo, undirected=True) edge_slices = {} slice_edges = {} for edge in edges: edge_slices[edge] = set() for slic in slices: if edge_in(edge, slic, memo=slice_edges): edge_slices[edge].add(slic) if verbose: count +=1 if count % 1000 == 0: print '.', sys.stdout.flush() edge_vlans = {} for (edge, slics) in edge_slices.items(): edge_vlans[edge] = dict(zip(slics, range(1, len(slics) + 1))) return edge_vlans