Patchwork [4,of,9,sparse] sparse: move config signature logic into core

login
register
mail settings
Submitter Gregory Szorc
Date July 6, 2017, 9:54 p.m.
Message ID <b9d7f9e9fd096f795314.1499378060@ubuntu-vm-main>
Download mbox | patch
Permalink /patch/22056/
State Accepted
Headers show

Comments

Gregory Szorc - July 6, 2017, 9:54 p.m.
# HG changeset patch
# User Gregory Szorc <gregory.szorc@gmail.com>
# Date 1499377725 25200
#      Thu Jul 06 14:48:45 2017 -0700
# Node ID b9d7f9e9fd096f795314ad9ccaea85139df47997
# Parent  7bd81df5813100a0a28ac2373722cd6405b5c505
sparse: move config signature logic into core

The implementation changed slightly. Before, 0 was being used as
the default value and we cast the int to a string. We also
handled I/O exceptions manually. The new code uses vfs.tryread()
so we always feed data into the hasher. The empty string does hash
and this should result in identical behavior in terms of the
result being suitable for a cache key. We just avoid the
I/O exceptions and type coercion. This made the code simple enough
that the separate checksum function could be inlined.
via Mercurial-devel - July 6, 2017, 10:35 p.m.
On Thu, Jul 6, 2017 at 2:54 PM, Gregory Szorc <gregory.szorc@gmail.com> wrote:
> # HG changeset patch
> # User Gregory Szorc <gregory.szorc@gmail.com>
> # Date 1499377725 25200
> #      Thu Jul 06 14:48:45 2017 -0700
> # Node ID b9d7f9e9fd096f795314ad9ccaea85139df47997
> # Parent  7bd81df5813100a0a28ac2373722cd6405b5c505
> sparse: move config signature logic into core
>
> The implementation changed slightly. Before, 0 was being used as
> the default value and we cast the int to a string. We also
> handled I/O exceptions manually. The new code uses vfs.tryread()
> so we always feed data into the hasher. The empty string does hash
> and this should result in identical behavior in terms of the
> result being suitable for a cache key. We just avoid the
> I/O exceptions and type coercion. This made the code simple enough
> that the separate checksum function could be inlined.

Queued patches 1-3. As I mentioned on IRC, this one got a little large
with both move and refactoring in one to follow (both versions don't
even fit on one page of my terminal, so comparing gets hard). Please
split up move and refactoring (I don't really care whether you move or
refactor first).

Patch

diff --git a/hgext/sparse.py b/hgext/sparse.py
--- a/hgext/sparse.py
+++ b/hgext/sparse.py
@@ -413,38 +413,6 @@  def _setupdirstate(ui):
 
 def _wraprepo(ui, repo):
     class SparseRepo(repo.__class__):
-        def _sparsechecksum(self, path):
-            data = self.vfs.read(path)
-            return hashlib.sha1(data).hexdigest()
-
-        def _sparsesignature(self, includetemp=True):
-            """Returns the signature string representing the contents of the
-            current project sparse configuration. This can be used to cache the
-            sparse matcher for a given set of revs."""
-            signaturecache = self._sparsesignaturecache
-            signature = signaturecache.get('signature')
-            if includetemp:
-                tempsignature = signaturecache.get('tempsignature')
-            else:
-                tempsignature = 0
-
-            if signature is None or (includetemp and tempsignature is None):
-                signature = 0
-                try:
-                    signature = self._sparsechecksum('sparse')
-                except (OSError, IOError):
-                    pass
-                signaturecache['signature'] = signature
-
-                tempsignature = 0
-                if includetemp:
-                    try:
-                        tempsignature = self._sparsechecksum('tempsparse')
-                    except (OSError, IOError):
-                        pass
-                    signaturecache['tempsignature'] = tempsignature
-            return '%s %s' % (str(signature), str(tempsignature))
-
         def sparsematch(self, *revs, **kwargs):
             """Returns the sparse match function for the given revs.
 
@@ -459,7 +427,7 @@  def _wraprepo(ui, repo):
                     self.dirstate.parents() if node != nullid]
 
             includetemp = kwargs.get('includetemp', True)
-            signature = self._sparsesignature(includetemp=includetemp)
+            signature = sparse.configsignature(self, includetemp=includetemp)
 
             key = '%s %s' % (str(signature), ' '.join([str(r) for r in revs]))
 
diff --git a/mercurial/sparse.py b/mercurial/sparse.py
--- a/mercurial/sparse.py
+++ b/mercurial/sparse.py
@@ -7,6 +7,8 @@ 
 
 from __future__ import absolute_import
 
+import hashlib
+
 from .i18n import _
 from .node import nullid
 from . import (
@@ -130,6 +132,31 @@  def activeprofiles(repo):
 def invalidatesignaturecache(repo):
     repo._sparsesignaturecache.clear()
 
+def configsignature(repo, includetemp=True):
+    """Obtain the signature string for the current sparse configuration.
+
+    This is used to construct a cache key for matchers.
+    """
+    cache = repo._sparsesignaturecache
+
+    signature = cache.get('signature')
+
+    if includetemp:
+        tempsignature = cache.get('tempsignature')
+    else:
+        tempsignature = '0'
+
+    if signature is None or (includetemp and tempsignature is None):
+        signature = hashlib.sha1(repo.vfs.tryread('sparse')).hexdigest()
+        cache['signature'] = signature
+
+        if includetemp:
+            raw = repo.vfs.tryread('tempsparse')
+            tempsignature = hashlib.sha1(raw).hexdigest()
+            cache['tempsignature'] = tempsignature
+
+    return '%s %s' % (signature, tempsignature)
+
 def writeconfig(repo, includes, excludes, profiles):
     """Write the sparse config file given a sparse configuration."""
     with repo.vfs('sparse', 'wb') as fh: