[PATCH 7 of 7] discovery: stop using nodemap for membership testing

pierre-yves.david at ens-lyon.org pierre-yves.david at ens-lyon.org
Sun Nov 17 14:31:46 CST 2013


# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at ens-lyon.org>
# Date 1384576123 18000
#      Fri Nov 15 23:28:43 2013 -0500
# Node ID a4229ffd11961fb468d44624be2f680f727c6d78
# Parent  62053df1638dcc0e692a7162de91f196acb5da25
discovery: stop using nodemap for membership testing

Nodemap is not aware of filtering so we need to ask the changelog itself if a
node is known. This is probably a bit slower but such check does not dominated
discovery time. This is necessary if we want to run discovery on filtered repo.

diff --git a/mercurial/discovery.py b/mercurial/discovery.py
--- a/mercurial/discovery.py
+++ b/mercurial/discovery.py
@@ -32,13 +32,13 @@ def findcommonincoming(repo, remote, hea
     if not remote.capable('getbundle'):
         return treediscovery.findcommonincoming(repo, remote, heads, force)
 
     if heads:
         allknown = True
-        nm = repo.changelog.nodemap
+        knownnode = repo.changelog.hasnode # no nodemap until it is filtered
         for h in heads:
-            if nm.get(h) is None:
+            if not knownnode(h):
                 allknown = False
                 break
         if allknown:
             return (heads, False, heads)
 
@@ -170,12 +170,13 @@ def _headssummary(repo, remote, outgoing
     remotebranches = set()
     for branch, heads in remote.branchmap().iteritems():
         remotebranches.add(branch)
         known = []
         unsynced = []
+        knownnode = cl.hasnode # do not use nodemap until it is filtered
         for h in heads:
-            if h in cl.nodemap:
+            if knownnode(h):
                 known.append(h)
             else:
                 unsynced.append(h)
         headssum[branch] = (known, list(known), unsynced)
     # B. add new branch data
@@ -202,15 +203,15 @@ def _headssummary(repo, remote, outgoing
     return headssum
 
 def _oldheadssummary(repo, remoteheads, outgoing, inc=False):
     """Compute branchmapsummary for repo without branchmap support"""
 
-    cl = repo.changelog
     # 1-4b. old servers: Check for new topological heads.
     # Construct {old,new}map with branch = None (topological branch).
     # (code based on update)
-    oldheads = set(h for h in remoteheads if h in cl.nodemap)
+    knownnode = repo.changelog.hasnode # no nodemap until it is filtered
+    oldheads = set(h for h in remoteheads if knownnode(h))
     # all nodes in outgoing.missing are children of either:
     # - an element of oldheads
     # - another element of outgoing.missing
     # - nullrev
     # This explains why the new head are very simple to compute.
diff --git a/mercurial/treediscovery.py b/mercurial/treediscovery.py
--- a/mercurial/treediscovery.py
+++ b/mercurial/treediscovery.py
@@ -17,11 +17,11 @@ def findcommonincoming(repo, remote, hea
     "fetch" is a list of roots of the nodes that would be incoming, to be
       supplied to changegroupsubset.
     "heads" is either the supplied heads, or else the remote's heads.
     """
 
-    m = repo.changelog.nodemap
+    knownnode = repo.changelog.hasnode
     search = []
     fetch = set()
     seen = set()
     seenbranch = set()
     base = set()
@@ -39,11 +39,11 @@ def findcommonincoming(repo, remote, hea
     # and start by examining the heads
     repo.ui.status(_("searching for changes\n"))
 
     unknown = []
     for h in heads:
-        if h not in m:
+        if not knownnode(h):
             unknown.append(h)
         else:
             base.add(h)
 
     if not unknown:
@@ -69,27 +69,27 @@ def findcommonincoming(repo, remote, hea
             if n[0] == nullid: # found the end of the branch
                 pass
             elif n in seenbranch:
                 repo.ui.debug("branch already found\n")
                 continue
-            elif n[1] and n[1] in m: # do we know the base?
+            elif n[1] and knownnode(n[1]): # do we know the base?
                 repo.ui.debug("found incomplete branch %s:%s\n"
                               % (short(n[0]), short(n[1])))
                 search.append(n[0:2]) # schedule branch range for scanning
                 seenbranch.add(n)
             else:
                 if n[1] not in seen and n[1] not in fetch:
-                    if n[2] in m and n[3] in m:
+                    if knownnode(n[2]) and knownnode(n[3]):
                         repo.ui.debug("found new changeset %s\n" %
                                       short(n[1]))
                         fetch.add(n[1]) # earliest unknown
                     for p in n[2:4]:
-                        if p in m:
+                        if knownnode(p):
                             base.add(p) # latest known
 
                 for p in n[2:4]:
-                    if p not in req and p not in m:
+                    if p not in req and not knownnode(p):
                         r.append(p)
                         req.add(p)
             seen.add(n[0])
 
         if r:
@@ -112,11 +112,11 @@ def findcommonincoming(repo, remote, hea
             l.append(n[1])
             p = n[0]
             f = 1
             for i in l:
                 repo.ui.debug("narrowing %d:%d %s\n" % (f, len(l), short(i)))
-                if i in m:
+                if knownnode(i):
                     if f <= 2:
                         repo.ui.debug("found new branch changeset %s\n" %
                                           short(p))
                         fetch.add(p)
                         base.add(i)
@@ -128,11 +128,11 @@ def findcommonincoming(repo, remote, hea
                 p, f = i, f * 2
             search = newsearch
 
     # sanity check our fetch list
     for f in fetch:
-        if f in m:
+        if knownnode(f):
             raise error.RepoError(_("already have changeset ")
                                   + short(f[:4]))
 
     base = list(base)
     if base == [nullid]:


More information about the Mercurial-devel mailing list