Patchwork [2,of,3] repoview: move function for computing filtered hash

login
register
mail settings
Submitter Gregory Szorc
Date April 14, 2015, 6:19 p.m.
Message ID <3ff6f1a639e2633af1ee.1429035585@gps-mbp.local>
Download mbox | patch
Permalink /patch/8656/
State Accepted
Headers show

Comments

Gregory Szorc - April 14, 2015, 6:19 p.m.
# HG changeset patch
# User Gregory Szorc <gregory.szorc@gmail.com>
# Date 1427939009 25200
#      Wed Apr 01 18:43:29 2015 -0700
# Node ID 3ff6f1a639e2633af1ee8be2c354ebd2fb023bf2
# Parent  3e3ba5bfa939902f994227b3bcb321b5b251a398
repoview: move function for computing filtered hash

An upcoming patch will establish per-filter tags caches. We'll want
to use the same cache validation logic as the branch cache. Prepare
for that by moving the logic for computing a filtered view hash
to somewhere central.
Pierre-Yves David - April 14, 2015, 6:50 p.m.
On 04/14/2015 02:19 PM, Gregory Szorc wrote:
> # HG changeset patch
> # User Gregory Szorc <gregory.szorc@gmail.com>
> # Date 1427939009 25200
> #      Wed Apr 01 18:43:29 2015 -0700
> # Node ID 3ff6f1a639e2633af1ee8be2c354ebd2fb023bf2
> # Parent  3e3ba5bfa939902f994227b3bcb321b5b251a398
> repoview: move function for computing filtered hash
>
> An upcoming patch will establish per-filter tags caches. We'll want
> to use the same cache validation logic as the branch cache. Prepare
> for that by moving the logic for computing a filtered view hash
> to somewhere central.

The first two patches are queued.

Patch

diff --git a/mercurial/branchmap.py b/mercurial/branchmap.py
--- a/mercurial/branchmap.py
+++ b/mercurial/branchmap.py
@@ -6,8 +6,9 @@ 
 # GNU General Public License version 2 or any later version.
 
 from node import bin, hex, nullid, nullrev
 import encoding
+import scmutil
 import util
 import time
 from array import array
 from struct import calcsize, pack, unpack
@@ -135,37 +136,17 @@  class branchcache(dict):
             self._closednodes = set()
         else:
             self._closednodes = closednodes
 
-    def _hashfiltered(self, repo):
-        """build hash of revision filtered in the current cache
-
-        Tracking tipnode and tiprev is not enough to ensure validity of the
-        cache as they do not help to distinct cache that ignored various
-        revision bellow tiprev.
-
-        To detect such difference, we build a cache of all ignored revisions.
-        """
-        cl = repo.changelog
-        if not cl.filteredrevs:
-            return None
-        key = None
-        revs = sorted(r for r in cl.filteredrevs if r <= self.tiprev)
-        if revs:
-            s = util.sha1()
-            for rev in revs:
-                s.update('%s;' % rev)
-            key = s.digest()
-        return key
-
     def validfor(self, repo):
         """Is the cache content valid regarding a repo
 
         - False when cached tipnode is unknown or if we detect a strip.
         - True when cache is up to date or a subset of current repo."""
         try:
             return ((self.tipnode == repo.changelog.node(self.tiprev))
-                    and (self.filteredhash == self._hashfiltered(repo)))
+                    and (self.filteredhash == \
+                         scmutil.filteredhash(repo, self.tiprev)))
         except IndexError:
             return False
 
     def _branchtip(self, heads):
@@ -282,9 +263,9 @@  class branchcache(dict):
                 tiprev = max(cl.rev(node) for node in heads)
                 if tiprev > self.tiprev:
                     self.tipnode = cl.node(tiprev)
                     self.tiprev = tiprev
-        self.filteredhash = self._hashfiltered(repo)
+        self.filteredhash = scmutil.filteredhash(repo, self.tiprev)
 
         duration = time.time() - starttime
         repo.ui.log('branchcache', 'updated %s branch cache in %.4f seconds\n',
                     repo.filtername, duration)
diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py
--- a/mercurial/scmutil.py
+++ b/mercurial/scmutil.py
@@ -171,8 +171,32 @@  class casecollisionauditor(object):
             self._ui.warn(_("warning: %s\n") % msg)
         self._loweredfiles.add(fl)
         self._newfiles.add(f)
 
+def filteredhash(repo, maxrev):
+    """build hash of filtered revisions in the current repoview.
+
+    Multiple caches perform up-to-date validation by checking that the
+    tiprev and tipnode stored in the cache file match the current repository.
+    However, this is not sufficient for validating repoviews because the set
+    of revisions in the view may change without the repository tiprev and
+    tipnode changing.
+
+    This function hashes all the revs filtered from the view and returns
+    that SHA-1 digest.
+    """
+    cl = repo.changelog
+    if not cl.filteredrevs:
+        return None
+    key = None
+    revs = sorted(r for r in cl.filteredrevs if r <= maxrev)
+    if revs:
+        s = util.sha1()
+        for rev in revs:
+            s.update('%s;' % rev)
+        key = s.digest()
+    return key
+
 class abstractvfs(object):
     """Abstract base class; cannot be instantiated"""
 
     def __init__(self, *args, **kwargs):