Mercurial > hg > hg-git
changeset 75:466ebe5a157d
merged awesome changes from chris
author | Scott Chacon <schacon@gmail.com> |
---|---|
date | Fri, 01 May 2009 07:01:27 -0700 |
parents | 7d5fbed25b36 (current diff) 805a42e84605 (diff) |
children | aa2dadf04144 |
files | git_handler.py |
diffstat | 1 files changed, 64 insertions(+), 36 deletions(-) [+] |
line wrap: on
line diff
--- a/git_handler.py +++ b/git_handler.py @@ -359,14 +359,16 @@ def generate_pack_contents(self, want, have): graph_walker = SimpleFetchGraphWalker(want, self.git.get_parents) next = graph_walker.next() - shas = [] + shas = set() while next: if next in have: graph_walker.ack(next) else: - shas.append(next) + shas.add(next) next = graph_walker.next() + seen = [] + # so now i have the shas, need to turn them into a list of # tuples (sha, path) for ALL the objects i'm sending # TODO : don't send blobs or trees they already have @@ -376,11 +378,15 @@ for (mode, name, sha) in tree.entries(): if mode == 57344: # TODO : properly handle submodules continue + if sha in seen: + continue + obj = self.git.get_object(sha) - if isinstance (obj, Blob): + seen.append(sha) + if isinstance(obj, Blob): changes.append((obj, path + name)) elif isinstance(obj, Tree): - changes.extend (get_objects (obj, path + name + '/')) + changes.extend(get_objects (obj, path + name + '/')) return changes objects = [] @@ -603,42 +609,64 @@ self._shas.reverse() return self._shas - def strongly_connected_components(self, graph): - """ Find the strongly connected components in a graph using - Tarjan's algorithm. + def strongly_connected_components(self, G): + """Returns a list of strongly connected components in G. + + Uses Tarjan's algorithm with Nuutila's modifications. + Nonrecursive version of algorithm. - graph should be a dictionary mapping node names to - lists of successor nodes. - """ + References: - result = [ ] - stack = [ ] - low = { } + R. Tarjan (1972). Depth-first search and linear graph algorithms. + SIAM Journal of Computing 1(2):146-160. - def visit(node): - if node in low: return + E. Nuutila and E. Soisalon-Soinen (1994). + On finding the strongly connected components in a directed graph. + Information Processing Letters 49(1): 9-14. - num = len(low) - low[node] = num - stack_pos = len(stack) - stack.append(node) - - for successor in graph[node].parents: - visit(successor) - low[node] = min(low[node], low[successor]) - - if num == low[node]: - component = tuple(stack[stack_pos:]) - del stack[stack_pos:] - result.append(component) - for item in component: - low[item] = len(graph) - - for node in graph: - visit(node) - - return result - + """ + preorder={} + lowlink={} + scc_found={} + scc_queue = [] + scc_list=[] + i=0 # Preorder counter + for source in G: + if source not in scc_found: + queue=[source] + while queue: + v=queue[-1] + if v not in preorder: + i=i+1 + preorder[v]=i + done=1 + v_nbrs=G[v] + for w in v_nbrs: + if w not in preorder: + queue.append(w) + done=0 + break + if done==1: + lowlink[v]=preorder[v] + for w in v_nbrs: + if w not in scc_found: + if preorder[w]>preorder[v]: + lowlink[v]=min([lowlink[v],lowlink[w]]) + else: + lowlink[v]=min([lowlink[v],preorder[w]]) + queue.pop() + if lowlink[v]==preorder[v]: + scc_found[v]=True + scc=[v] + while scc_queue and preorder[scc_queue[-1]]>preorder[v]: + k=scc_queue.pop() + scc_found[k]=True + scc.append(k) + scc_list.append(scc) + else: + scc_queue.append(v) + scc_list.sort(lambda x, y: cmp(len(y),len(x))) + return scc_list def topological_sort(self, graph): count = { }