def __default_spt_for_src(g, source): # Adapted from single_source_dijkstra in networkx dist = {} # dictionary of final distances paths = {source: [[source]]} # dictionary of list of paths seen = {source: 0} fringe = [] c = count() # We want to skip comparing node labels heapq.heappush(fringe, (0, next(c), source)) while fringe: (d, _, v) = heapq.heappop(fringe) if v in dist: continue # already searched this node. dist[v] = d for w, edgedata in g[v].iteritems(): if g.is_fake_route(v, w): # Deal with fake edges at a later stage continue vw_dist = d + edgedata.get(METRIC, 1) seen_w = seen.get(w, sys.maxint) if vw_dist < dist.get(w, 0): raise ValueError('Contradictory paths found: ' 'negative metric?') elif vw_dist < seen_w: # vw is better than the old path seen[w] = vw_dist heapq.heappush(fringe, (vw_dist, next(c), w)) paths[w] = list(extend_paths_list(paths[v], w)) elif vw_dist == seen_w: # vw is ECMP paths[w].extend(extend_paths_list(paths[v], w)) # else w is already pushed in the fringe and will pop later return paths, dist
def __update_default_paths(spt, g, dest, added): spt._default_paths[dest] = {dest: [[dest]]} spt._default_dist[dest] = {dest: 0} for n in g.routers: paths = [] cost = sys.maxint for s in added: try: c = spt.default_cost(n, s) + g.metric(s, dest) except KeyError: # No path from n to s, skip continue p = spt.default_path(n, s) if c < cost: # new spt towards s is n-p-s paths = list(extend_paths_list(p, dest)) cost = c elif c == cost: # ecmp paths.extend(extend_paths_list(p, dest)) if paths: log.debug('Adding paths (cost: %s): %s', cost, paths) spt._default_paths[n][dest] = paths spt._default_dist[n][dest] = cost
def __update_default_paths(spt, g, dest, added): spt._default_paths[dest] = {dest: [[dest]]} spt._default_dist[dest] = {dest: 0} for n in g.routers: paths = [] cost = sys.maxint for s in added: try: c = spt.default_cost(n, s) + g.metric(s, dest) except KeyError: # No path from n to s, skip continue p = spt.default_path(n, s) if c < cost: # new spt towards s is n-p-s paths = list(extend_paths_list(p, dest)) cost = c elif c == cost: # ecmp paths.extend(extend_paths_list(p, dest)) if paths: log.debug("Adding paths (cost: %s): %s", cost, paths) spt._default_paths[n][dest] = paths spt._default_dist[n][dest] = cost
def single_source_all_sp(g, source, metric='metric'): """Return the list of all shortest paths originatig from src, and their associated costs. :type g: DiGraph :return: {dst: [[x y z], [a b c], ...]}, {dst: cost} Adapted from single_source_dijkstra in networkx. # Copyright (C) 2004-2010 by # Aric Hagberg <*****@*****.**> # Dan Schult <*****@*****.**> # Pieter Swart <*****@*****.**> # All rights reserved. # BSD license. """ dist = {} # dictionary of final distances paths = {source: [[source]]} # dictionary of list of paths seen = {source: 0} fringe = [] # use heapq with (distance,label) tuples heapq.heappush(fringe, (0, source)) while fringe: (d, v) = heapq.heappop(fringe) if v in dist: continue # already searched this node. dist[v] = d for w, edgedata in g[v].items(): vw_dist = d + edgedata.get(metric, 1) seen_w = seen.get(w, sys.maxint) if vw_dist < dist.get(w, 0): raise ValueError('Contradictory paths found: ' 'negative "%s"?' % metric) elif vw_dist < seen_w: # vw is better than the old path seen[w] = vw_dist heapq.heappush(fringe, (vw_dist, w)) paths[w] = list(extend_paths_list(paths[v], w)) elif vw_dist == seen_w: # vw is ECMP paths[w].extend(extend_paths_list(paths[v], w)) return paths, dist
def __update_default_paths(spt, g, dest, added): for n in g.nodes_iter(): if n == dest: # dest is a path in itspt spt._default_paths[n] = [[n]] spt._default_dist[n] = {n: 0} continue paths = [] cost = sys.maxint for s in added: try: c = spt.default_cost(n, s) + g.metric(s, dest) except KeyError: # No path from n to s, skip continue p = spt.default_path(n, s) if c < cost: # new spt towards s is n-p-s paths = list(extend_paths_list(p, dest)) cost = c elif c == cost: # ecmp paths.extend(extend_paths_list(p, dest)) if paths: log.debug('Adding paths (cost: %s): %s', cost, paths) spt._default_paths[n][dest] = paths spt._default_dist[n][dest] = cost