Mercurial > public > mercurial-scm > hg
comparison mercurial/localrepo.py @ 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 | 67c874d14c2c |
children | a39fe76c4c65 |
comparison
equal
deleted
inserted
replaced
18012:848c428bb5ee | 18013:98c867ac1330 |
---|---|
20 | 20 |
21 class storecache(filecache): | 21 class storecache(filecache): |
22 """filecache for files in the store""" | 22 """filecache for files in the store""" |
23 def join(self, obj, fname): | 23 def join(self, obj, fname): |
24 return obj.sjoin(fname) | 24 return obj.sjoin(fname) |
25 | |
26 class unfilteredpropertycache(propertycache): | |
27 """propertycache that apply to unfiltered repo only""" | |
28 | |
29 def __get__(self, repo, type=None): | |
30 return super(unfilteredpropertycache, self).__get__(repo.unfiltered()) | |
31 | |
32 class filteredpropertycache(propertycache): | |
33 """propertycache that must take filtering in account""" | |
34 | |
35 def cachevalue(self, obj, value): | |
36 object.__setattr__(obj, self.name, value) | |
37 | |
38 | |
39 def hasunfilteredcache(repo, name): | |
40 """check if an repo and a unfilteredproperty cached value for <name>""" | |
41 return name in vars(repo.unfiltered()) | |
25 | 42 |
26 def unfilteredmeth(orig): | 43 def unfilteredmeth(orig): |
27 """decorate method that always need to be run on unfiltered version""" | 44 """decorate method that always need to be run on unfiltered version""" |
28 def wrapper(repo, *args, **kwargs): | 45 def wrapper(repo, *args, **kwargs): |
29 return orig(repo.unfiltered(), *args, **kwargs) | 46 return orig(repo.unfiltered(), *args, **kwargs) |
302 # message is rare enough to not be translated | 319 # message is rare enough to not be translated |
303 msg = 'obsolete feature not enabled but %i markers found!\n' | 320 msg = 'obsolete feature not enabled but %i markers found!\n' |
304 self.ui.warn(msg % len(list(store))) | 321 self.ui.warn(msg % len(list(store))) |
305 return store | 322 return store |
306 | 323 |
307 @propertycache | 324 @unfilteredpropertycache |
308 def hiddenrevs(self): | 325 def hiddenrevs(self): |
309 """hiddenrevs: revs that should be hidden by command and tools | 326 """hiddenrevs: revs that should be hidden by command and tools |
310 | 327 |
311 This set is carried on the repo to ease initialization and lazy | 328 This set is carried on the repo to ease initialization and lazy |
312 loading; it'll probably move back to changelog for efficiency and | 329 loading; it'll probably move back to changelog for efficiency and |
490 '(please commit .hgtags manually)')) | 507 '(please commit .hgtags manually)')) |
491 | 508 |
492 self.tags() # instantiate the cache | 509 self.tags() # instantiate the cache |
493 self._tag(names, node, message, local, user, date) | 510 self._tag(names, node, message, local, user, date) |
494 | 511 |
495 @propertycache | 512 @filteredpropertycache |
496 def _tagscache(self): | 513 def _tagscache(self): |
497 '''Returns a tagscache object that contains various tags related | 514 '''Returns a tagscache object that contains various tags related |
498 caches.''' | 515 caches.''' |
499 | 516 |
500 # This simplifies its cache management by having one decorated | 517 # This simplifies its cache management by having one decorated |
877 data = fn(data, cmd, ui=self.ui, repo=self, filename=filename) | 894 data = fn(data, cmd, ui=self.ui, repo=self, filename=filename) |
878 break | 895 break |
879 | 896 |
880 return data | 897 return data |
881 | 898 |
882 @propertycache | 899 @unfilteredpropertycache |
883 def _encodefilterpats(self): | 900 def _encodefilterpats(self): |
884 return self._loadfilter('encode') | 901 return self._loadfilter('encode') |
885 | 902 |
886 @propertycache | 903 @unfilteredpropertycache |
887 def _decodefilterpats(self): | 904 def _decodefilterpats(self): |
888 return self._loadfilter('decode') | 905 return self._loadfilter('decode') |
889 | 906 |
890 def adddatafilter(self, name, filter): | 907 def adddatafilter(self, name, filter): |
891 self._datafilters[name] = filter | 908 self._datafilters[name] = filter |
1047 # invalidated. | 1064 # invalidated. |
1048 self.destroyed() | 1065 self.destroyed() |
1049 return 0 | 1066 return 0 |
1050 | 1067 |
1051 def invalidatecaches(self): | 1068 def invalidatecaches(self): |
1052 def delcache(name): | 1069 |
1053 try: | 1070 if '_tagscache' in vars(self): |
1054 delattr(self, name) | 1071 # can't use delattr on proxy |
1055 except AttributeError: | 1072 del self.__dict__['_tagscache'] |
1056 pass | |
1057 | |
1058 delcache('_tagscache') | |
1059 | 1073 |
1060 self.unfiltered()._branchcache = None # in UTF-8 | 1074 self.unfiltered()._branchcache = None # in UTF-8 |
1061 self.unfiltered()._branchcachetip = None | 1075 self.unfiltered()._branchcachetip = None |
1062 obsolete.clearobscaches(self) | 1076 obsolete.clearobscaches(self) |
1063 | 1077 |
1068 | 1082 |
1069 This is different to dirstate.invalidate() that it doesn't always | 1083 This is different to dirstate.invalidate() that it doesn't always |
1070 rereads the dirstate. Use dirstate.invalidate() if you want to | 1084 rereads the dirstate. Use dirstate.invalidate() if you want to |
1071 explicitly read the dirstate again (i.e. restoring it to a previous | 1085 explicitly read the dirstate again (i.e. restoring it to a previous |
1072 known good state).''' | 1086 known good state).''' |
1073 if 'dirstate' in self.__dict__: | 1087 if hasunfilteredcache(self, 'dirstate'): |
1074 for k in self.dirstate._filecache: | 1088 for k in self.dirstate._filecache: |
1075 try: | 1089 try: |
1076 delattr(self.dirstate, k) | 1090 delattr(self.dirstate, k) |
1077 except AttributeError: | 1091 except AttributeError: |
1078 pass | 1092 pass |
1125 l.lock() | 1139 l.lock() |
1126 return l | 1140 return l |
1127 | 1141 |
1128 def unlock(): | 1142 def unlock(): |
1129 self.store.write() | 1143 self.store.write() |
1130 if '_phasecache' in vars(self): | 1144 if hasunfilteredcache(self, '_phasecache'): |
1131 self._phasecache.write() | 1145 self._phasecache.write() |
1132 for k, ce in self._filecache.items(): | 1146 for k, ce in self._filecache.items(): |
1133 if k == 'dirstate': | 1147 if k == 'dirstate': |
1134 continue | 1148 continue |
1135 ce.refresh() | 1149 ce.refresh() |