[PATCH 3 of 6 V5] revset: remove grandparent by using reachableroots
Pierre-Yves David
pierre-yves.david at ens-lyon.org
Fri Aug 7 21:06:52 UTC 2015
# HG changeset patch
# User Laurent Charignon <lcharignon at fb.com>
# Date 1434770932 25200
# Fri Jun 19 20:28:52 2015 -0700
# Node ID 9965ba0c40447c09e998d84024c23444b2ee5d95
# Parent 5f55544d6c5187bbf31ab4cc851f094867421430
revset: remove grandparent by using reachableroots
This patch is part of a series of patches to speed up the computation of
revset.reachableroots by introducing a C implementation. The main motivation
is to speed up smartlog on big repositories. At the end of the series, on our
big repositories the computation of reachableroots is 10-50x faster and
smartlog on is 2x-5x faster.
Before this patch, we had a custom computation for grandparent that was very
close to the idea of reacheablerooots. This patch expresses grandparent with
reachableroots to reduce the amount of code.
diff --git a/mercurial/graphmod.py b/mercurial/graphmod.py
--- a/mercurial/graphmod.py
+++ b/mercurial/graphmod.py
@@ -17,10 +17,11 @@ context of the graph returned. Type is a
Data depends on type.
"""
from mercurial.node import nullrev
import util
+import revset
import heapq
CHANGESET = 'C'
@@ -231,12 +232,10 @@ def dagwalker(repo, revs):
returned.
"""
if not revs:
return
- cl = repo.changelog
- lowestrev = revs.min()
gpcache = {}
if repo.ui.configbool('experimental', 'graph-group-branches', False):
firstbranch = ()
firstbranchrevset = repo.ui.config(
@@ -254,11 +253,11 @@ def dagwalker(repo, revs):
p.rev() != nullrev and p.rev() not in parents]
for mpar in mpars:
gp = gpcache.get(mpar)
if gp is None:
- gp = gpcache[mpar] = grandparent(cl, lowestrev, revs, mpar)
+ gp = gpcache[mpar] = revset.reachableroots(repo, revs, [mpar])
if not gp:
parents.append(mpar)
else:
parents.extend(g for g in gp if g not in parents)
@@ -352,28 +351,10 @@ def colored(dag, repo):
# Yield and move on
yield (cur, type, data, (col, color), edges)
seen = next
-def grandparent(cl, lowestrev, roots, head):
- """Return all ancestors of head in roots which revision is
- greater or equal to lowestrev.
- """
- pending = set([head])
- seen = set()
- kept = set()
- llowestrev = max(nullrev, lowestrev)
- while pending:
- r = pending.pop()
- if r >= llowestrev and r not in seen:
- if r in roots:
- kept.add(r)
- else:
- pending.update([p for p in cl.parentrevs(r)])
- seen.add(r)
- return sorted(kept)
-
def asciiedges(type, char, lines, seen, rev, parents):
"""adds edge info to changelog DAG walk suitable for ascii()"""
if rev not in seen:
seen.append(rev)
nodeidx = seen.index(rev)
More information about the Mercurial-devel
mailing list