Mercurial > hg
changeset 18013:98c867ac1330
clfilter: add a propertycache that must be unfiltered
Some of the localrepo property caches must be computed unfiltered and
stored globally. Some others must see the filtered version and store data
relative to the current filtering.
This changeset introduces two classes `unfilteredpropertycache`
and `filteredpropertycache` for this purpose. A new function
`hasunfilteredcache` is introduced for unambiguous checking for cached
values on unfiltered repos.
A few tweaks are made to the property cache class to allow overriding
the way the computed value is stored on the object.
Some logic relative to _tagcaches is cleaned up in the process.
author | Pierre-Yves David <pierre-yves.david@logilab.fr> |
---|---|
date | Mon, 08 Oct 2012 20:02:20 +0200 |
parents | 848c428bb5ee |
children | a39fe76c4c65 |
files | mercurial/localrepo.py mercurial/util.py |
diffstat | 2 files changed, 30 insertions(+), 13 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/localrepo.py Mon Oct 08 18:11:56 2012 +0200 +++ b/mercurial/localrepo.py Mon Oct 08 20:02:20 2012 +0200 @@ -23,6 +23,23 @@ def join(self, obj, fname): return obj.sjoin(fname) +class unfilteredpropertycache(propertycache): + """propertycache that apply to unfiltered repo only""" + + def __get__(self, repo, type=None): + return super(unfilteredpropertycache, self).__get__(repo.unfiltered()) + +class filteredpropertycache(propertycache): + """propertycache that must take filtering in account""" + + def cachevalue(self, obj, value): + object.__setattr__(obj, self.name, value) + + +def hasunfilteredcache(repo, name): + """check if an repo and a unfilteredproperty cached value for <name>""" + return name in vars(repo.unfiltered()) + def unfilteredmeth(orig): """decorate method that always need to be run on unfiltered version""" def wrapper(repo, *args, **kwargs): @@ -304,7 +321,7 @@ self.ui.warn(msg % len(list(store))) return store - @propertycache + @unfilteredpropertycache def hiddenrevs(self): """hiddenrevs: revs that should be hidden by command and tools @@ -492,7 +509,7 @@ self.tags() # instantiate the cache self._tag(names, node, message, local, user, date) - @propertycache + @filteredpropertycache def _tagscache(self): '''Returns a tagscache object that contains various tags related caches.''' @@ -879,11 +896,11 @@ return data - @propertycache + @unfilteredpropertycache def _encodefilterpats(self): return self._loadfilter('encode') - @propertycache + @unfilteredpropertycache def _decodefilterpats(self): return self._loadfilter('decode') @@ -1049,13 +1066,10 @@ return 0 def invalidatecaches(self): - def delcache(name): - try: - delattr(self, name) - except AttributeError: - pass - delcache('_tagscache') + if '_tagscache' in vars(self): + # can't use delattr on proxy + del self.__dict__['_tagscache'] self.unfiltered()._branchcache = None # in UTF-8 self.unfiltered()._branchcachetip = None @@ -1070,7 +1084,7 @@ rereads the dirstate. Use dirstate.invalidate() if you want to explicitly read the dirstate again (i.e. restoring it to a previous known good state).''' - if 'dirstate' in self.__dict__: + if hasunfilteredcache(self, 'dirstate'): for k in self.dirstate._filecache: try: delattr(self.dirstate, k) @@ -1127,7 +1141,7 @@ def unlock(): self.store.write() - if '_phasecache' in vars(self): + if hasunfilteredcache(self, '_phasecache'): self._phasecache.write() for k, ce in self._filecache.items(): if k == 'dirstate':
--- a/mercurial/util.py Mon Oct 08 18:11:56 2012 +0200 +++ b/mercurial/util.py Mon Oct 08 20:02:20 2012 +0200 @@ -244,9 +244,12 @@ self.name = func.__name__ def __get__(self, obj, type=None): result = self.func(obj) - setattr(obj, self.name, result) + self.cachevalue(obj, result) return result + def cachevalue(self, obj, value): + setattr(obj, self.name, value) + def pipefilter(s, cmd): '''filter string S through command CMD, returning its output''' p = subprocess.Popen(cmd, shell=True, close_fds=closefds,