Mercurial > hg
changeset 6429:532ca442b903
symmetricdifference: move back to copies
It's too tightly dependent on known revlog ordering to fit well in ancestors
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Sat, 29 Mar 2008 12:39:47 -0500 |
parents | cbdefda439b6 |
children | a6a66e812c34 |
files | mercurial/ancestor.py mercurial/copies.py |
diffstat | 2 files changed, 39 insertions(+), 42 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/ancestor.py Sat Mar 29 12:39:47 2008 -0500 +++ b/mercurial/ancestor.py Sat Mar 29 12:39:47 2008 -0500 @@ -81,43 +81,3 @@ gx = x.next() except StopIteration: return None - -def symmetricdifference(a, b, pfunc): - """symmetric difference of the sets of ancestors of a and b - - I.e. revisions that are ancestors of a or b, but not both. - """ - # basic idea: - # - mark a and b with different sides - # - if a parent's children are all on the same side, the parent is - # on that side, otherwise it is on no side - # - walk the graph in topological order with the help of a heap; - # - add unseen parents to side map - # - clear side of any parent that has children on different sides - # - track number of unvisited nodes that might still be on a side - # - quit when interesting nodes is zero - if a == b: - return [a] - - side = {a: -1, b: 1} - visit = [-a, -b] - heapq.heapify(visit) - interesting = len(visit) - - while interesting: - r = -heapq.heappop(visit) - if side[r]: - interesting -= 1 - for p in pfunc(r): - if p not in side: - # first time we see p; add it to visit - side[p] = side[r] - if side[p]: - interesting += 1 - heapq.heappush(visit, -p) - elif side[p] and side[p] != side[r]: - # p was interesting but now we know better - side[p] = 0 - interesting -= 1 - - return [r for r in side if side[r]]
--- a/mercurial/copies.py Sat Mar 29 12:39:47 2008 -0500 +++ b/mercurial/copies.py Sat Mar 29 12:39:47 2008 -0500 @@ -7,7 +7,7 @@ from node import nullid, nullrev from i18n import _ -import util, ancestor +import util, heapq def _nonoverlap(d1, d2, d3): "Return list of elements in d1 not in d2 or d3" @@ -53,6 +53,43 @@ old.sort() return [o[1] for o in old] +def _symmetricdifference(a, b, pfunc): + """find revisions that are ancestors of a or b, but not both""" + # basic idea: + # - mark a and b with different sides + # - if a parent's children are all on the same side, the parent is + # on that side, otherwise it is on no side + # - walk the graph in topological order with the help of a heap; + # - add unseen parents to side map + # - clear side of any parent that has children on different sides + # - track number of unvisited nodes that might still be on a side + # - quit when interesting nodes is zero + if a == b: + return [a] + + side = {a: -1, b: 1} + visit = [-a, -b] + heapq.heapify(visit) + interesting = len(visit) + + while interesting: + r = -heapq.heappop(visit) + if side[r]: + interesting -= 1 + for p in pfunc(r): + if p not in side: + # first time we see p; add it to visit + side[p] = side[r] + if side[p]: + interesting += 1 + heapq.heappush(visit, -p) + elif side[p] and side[p] != side[r]: + # p was interesting but now we know better + side[p] = 0 + interesting -= 1 + + return [r for r in side if side[r]] + def copies(repo, c1, c2, ca, checkdirs=False): """ Find moves and copies between context c1 and c2 @@ -69,7 +106,7 @@ pr = repo.changelog.parentrevs def parents(rev): return [p for p in pr(rev) if p != nullrev] - limit = min(ancestor.symmetricdifference(rev1, rev2, parents)) + limit = min(_symmetricdifference(rev1, rev2, parents)) m1 = c1.manifest() m2 = c2.manifest() ma = ca.manifest()