[PATCH 04 of 10 V2] branchmap: takes filtered revision in account for cache calculation
Pierre-Yves David
pierre-yves.david at ens-lyon.org
Thu Dec 27 18:56:19 CST 2012
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at ens-lyon.org>
# Date 1356655623 -3600
# Node ID 13d786f9f076697469cbfe87becbac340eff17e0
# Parent 43650a9b9e09a53169ddd7e1535b816e470b3e5b
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 distinguish a cache that ignored various revisions below
tiprev.
To detect such difference, we build a hash of all ignored revisions. This hash
is then used when checking the validity of a cache for a repo.
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,
+ filteredhash=None):
super(branchcache, self).__init__(entries)
self.tipnode = tipnode
self.tiprev = tiprev
+ self.filteredhash = filteredhash
+
+ 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.filteredhash == 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.filteredhash = self._hashfiltered(repo)
More information about the Mercurial-devel
mailing list