Patchwork [3,of,9] branchmap: takes filtered revision in account for cache calculation

login
register
mail settings
Submitter Pierre-Yves David
Date Dec. 26, 2012, 8:32 p.m.
Message ID <4b098d0339f9e8b1805c.1356553979@yamac.local>
Download mbox | patch
Permalink /patch/299/
State Superseded, archived
Commit c351759ab0a07dcd92d6312ab0a02e5bfaafde4a
Headers show

Comments

Pierre-Yves David - Dec. 26, 2012, 8:32 p.m.
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at ens-lyon.org>
# Date 1356276302 -3600
# Node ID 4b098d0339f9e8b1805c4f6ef1d8bcf59f5a6349
# Parent  fbf90f3d261f274c1e690026c1a95fd787d3facc
branchmap: takes filtered revision in account for cache calculation

Tracking tipnode and tiprev is not enough to ensure validaty 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 revision ignored. This hash
is then used when checking validity of a cache for a repo.
Kevin Bullock - Dec. 27, 2012, 4:49 p.m.
On Dec 26, 2012, at 2:32 PM, Pierre-Yves David wrote:

> # HG changeset patch
> # User Pierre-Yves David <pierre-yves.david at ens-lyon.org>
> # Date 1356276302 -3600
> # Node ID 4b098d0339f9e8b1805c4f6ef1d8bcf59f5a6349
> # Parent  fbf90f3d261f274c1e690026c1a95fd787d3facc
> branchmap: takes filtered revision in account for cache calculation
> 
> Tracking tipnode and tiprev is not enough to ensure validaty of the cache as
> they do not help to distinct cache that ignored various revision bellow tip rev.
              help distinguish a cache that               revisions below
> 
> To detect such difference, we build a cache of all revision ignored. This hash
                                        hash?        ignored revisions.
> is then used when checking validity of a cache for a repo.
                    checking the validity of

> diff --git a/mercurial/branchmap.py b/mercurial/branchmap.py
> --- a/mercurial/branchmap.py
> +++ b/mercurial/branchmap.py
> @@ -5,10 +5,11 @@
> # This software may be used and distributed according to the terms of the
> # GNU General Public License version 2 or any later version.
> 
> from node import bin, hex, nullid, nullrev
> import encoding
> +import util
> 
> def read(repo):
>     try:
>         f = repo.opener("cache/branchheads")
>         lines = f.read().split('\n')
> @@ -67,22 +68,45 @@ def updatecache(repo):
>     repo._branchcache = partial
> 
> class branchcache(dict):
>     """A dict like object that hold branches heads cache"""
> 
> -    def __init__(self, entries=(), tipnode=nullid, tiprev=nullrev):
> +    def __init__(self, entries=(), tipnode=nullid, tiprev=nullrev,
> +                 filtered=None):
>         super(branchcache, self).__init__(entries)
>         self.tipnode = tipnode
>         self.tiprev = tiprev
> +        self.filtered = filtered

Name of this property should indicate that it's a hash, not a list.

pacem in terris / ??? / ?????? / ????????? / ??
Kevin R. Bullock
Pierre-Yves David - Dec. 28, 2012, 12:37 a.m.
On 27 d?c. 2012, at 17:49, Kevin Bullock wrote:

> On Dec 26, 2012, at 2:32 PM, Pierre-Yves David wrote:
> 
>> # HG changeset patch
>> # User Pierre-Yves David <pierre-yves.david at ens-lyon.org>
>> # Date 1356276302 -3600
>> # Node ID 4b098d0339f9e8b1805c4f6ef1d8bcf59f5a6349
>> # Parent  fbf90f3d261f274c1e690026c1a95fd787d3facc
>> branchmap: takes filtered revision in account for cache calculation
>> 
>> Tracking tipnode and tiprev is not enough to ensure validaty of the cache as
>> they do not help to distinct cache that ignored various revision bellow tip rev.
>              help distinguish a cache that               revisions below
>> 
>> To detect such difference, we build a cache of all revision ignored. This hash
>                                        hash?        ignored revisions.
>> is then used when checking validity of a cache for a repo.
>                    checking the validity of
> 
>> diff --git a/mercurial/branchmap.py b/mercurial/branchmap.py
>> --- a/mercurial/branchmap.py
>> +++ b/mercurial/branchmap.py
>> @@ -5,10 +5,11 @@
>> # This software may be used and distributed according to the terms of the
>> # GNU General Public License version 2 or any later version.
>> 
>> from node import bin, hex, nullid, nullrev
>> import encoding
>> +import util
>> 
>> def read(repo):
>>    try:
>>        f = repo.opener("cache/branchheads")
>>        lines = f.read().split('\n')
>> @@ -67,22 +68,45 @@ def updatecache(repo):
>>    repo._branchcache = partial
>> 
>> class branchcache(dict):
>>    """A dict like object that hold branches heads cache"""
>> 
>> -    def __init__(self, entries=(), tipnode=nullid, tiprev=nullrev):
>> +    def __init__(self, entries=(), tipnode=nullid, tiprev=nullrev,
>> +                 filtered=None):
>>        super(branchcache, self).__init__(entries)
>>        self.tipnode = tipnode
>>        self.tiprev = tiprev
>> +        self.filtered = filtered
> 
> Name of this property should indicate that it's a hash, not a list.

Should I name that `hashfiltered` or `filteredhash` ?

Patch

diff --git a/mercurial/branchmap.py b/mercurial/branchmap.py
--- a/mercurial/branchmap.py
+++ b/mercurial/branchmap.py
@@ -5,10 +5,11 @@ 
 # This software may be used and distributed according to the terms of the
 # GNU General Public License version 2 or any later version.
 
 from node import bin, hex, nullid, nullrev
 import encoding
+import util
 
 def read(repo):
     try:
         f = repo.opener("cache/branchheads")
         lines = f.read().split('\n')
@@ -67,22 +68,45 @@  def updatecache(repo):
     repo._branchcache = partial
 
 class branchcache(dict):
     """A dict like object that hold branches heads cache"""
 
-    def __init__(self, entries=(), tipnode=nullid, tiprev=nullrev):
+    def __init__(self, entries=(), tipnode=nullid, tiprev=nullrev,
+                 filtered=None):
         super(branchcache, self).__init__(entries)
         self.tipnode = tipnode
         self.tiprev = tiprev
+        self.filtered = filtered
+
+    def _hashfiltered(self, repo):
+        """build hash of revision filtered in the current cache
+
+        Tracking tipnode and tiprev is not enough to ensure validaty 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 revision ignored."""
+        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 valide regarding a repo
 
         - False when cached tipnode are 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)
+            return ((self.tipnode == repo.changelog.node(self.tiprev))
+                    and (self.filtered == self._hashfiltered(repo)))
         except IndexError:
             return False
 
 
     def write(self, repo):
@@ -170,5 +194,6 @@  class branchcache(dict):
             for heads in self.values():
                 tiprev = max(cl.rev(node) for node in heads)
                 if tiprev > self.tiprev:
                     self.tipnode = cl.node(tiprev)
                     self.tiprev = tiprev
+        self.filtered = self._hashfiltered(repo)