Patchwork D7492: localrepo: also fastpath access to working copy parents when possible

login
register
mail settings
Submitter phabricator
Date Nov. 24, 2019, 11:27 a.m.
Message ID <21c42d9c418f28c0c7c357d725ef287e@localhost.localdomain>
Download mbox | patch
Permalink /patch/43514/
State Not Applicable
Headers show

Comments

phabricator - Nov. 24, 2019, 11:27 a.m.
marmoute updated this revision to Diff 18382.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7492?vs=18365&id=18382

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7492/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7492

AFFECTED FILES
  mercurial/context.py
  mercurial/localrepo.py
  mercurial/scmutil.py
  tests/test-repo-filters-tiptoe.t

CHANGE DETAILS




To: marmoute, #hg-reviewers
Cc: mercurial-devel

Patch

diff --git a/tests/test-repo-filters-tiptoe.t b/tests/test-repo-filters-tiptoe.t
--- a/tests/test-repo-filters-tiptoe.t
+++ b/tests/test-repo-filters-tiptoe.t
@@ -62,7 +62,6 @@ 
 Getting status of working copy
 
   $ hg status
-  debug.filters: computing revision filter for "visible"
   M c
   A d
   R a
@@ -78,7 +77,6 @@ 
 Getting working copy diff
 
   $ hg diff
-  debug.filters: computing revision filter for "visible"
   diff -r c2932ca7786be30b67154d541a8764fae5532261 a
   --- a/a	Thu Jan 01 00:00:00 1970 +0000
   +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py
--- a/mercurial/scmutil.py
+++ b/mercurial/scmutil.py
@@ -1463,6 +1463,7 @@ 
         if src not in newctx or dst in newctx or ds[dst] != b'a':
             src = None
         ds.copy(src, dst)
+    repo._quick_access_changeid_invalidate()
 
 
 def writerequires(opener, requirements):
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -1514,18 +1514,51 @@ 
         narrowspec.save(self, newincludes, newexcludes)
         self.invalidate(clearfilecache=True)
 
-    @util.propertycache
+    @unfilteredpropertycache
+    def _quick_access_changeid_null(self):
+        return {
+            b'null': (nullrev, nullid),
+            nullrev: (nullrev, nullid),
+            nullid: (nullrev, nullid),
+        }
+
+    @unfilteredpropertycache
+    def _quick_access_changeid_wc(self):
+        # also fast path access to the working copy parents
+        # however, only do it for filter that ensure wc is visible.
+        quick = {}
+        cl = self.unfiltered().changelog
+        for node in self.dirstate.parents():
+            if node == nullid:
+                continue
+            rev = cl.index.get_rev(node)
+            if rev is None:
+                # unknown working copy parent case:
+                #
+                #   skip the fast path and let higher code deal with it
+                continue
+            pair = (rev, node)
+            quick[rev] = pair
+            quick[node] = pair
+        return quick
+
+    @unfilteredmethod
+    def _quick_access_changeid_invalidate(self):
+        if '_quick_access_changeid_wc' in vars(self):
+            del self.__dict__['_quick_access_changeid_wc']
+
+    @property
     def _quick_access_changeid(self):
         """an helper dictionnary for __getitem__ calls
 
         This contains a list of symbol we can recognise right away without
         further processing.
         """
-        return {
-            b'null': (nullrev, nullid),
-            nullrev: (nullrev, nullid),
-            nullid: (nullrev, nullid),
-        }
+        mapping = self._quick_access_changeid_null
+        if self.filtername in repoview.filter_has_wc:
+            mapping = mapping.copy()
+            mapping.update(self._quick_access_changeid_wc)
+        return mapping
 
     def __getitem__(self, changeid):
         # dealing with special cases
@@ -1897,6 +1930,7 @@ 
                 for f, s in sorted(self.dirstate.copies().items()):
                     if f not in pctx and s not in pctx:
                         self.dirstate.copy(None, f)
+            self._quick_access_changeid_invalidate()
 
     def filectx(self, path, changeid=None, fileid=None, changectx=None):
         """changeid must be a changeset revision, if specified.
@@ -2494,6 +2528,7 @@ 
     def invalidatevolatilesets(self):
         self.filteredrevcache.clear()
         obsolete.clearobscaches(self)
+        self._quick_access_changeid_invalidate()
 
     def invalidatedirstate(self):
         '''Invalidates the dirstate, causing the next call to dirstate
diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -1966,6 +1966,7 @@ 
             for f in self.removed():
                 self._repo.dirstate.drop(f)
             self._repo.dirstate.setparents(node)
+            self._repo._quick_access_changeid_invalidate()
 
         # write changes out explicitly, because nesting wlock at
         # runtime may prevent 'wlock.release()' in 'repo.commit()'