comparison mercurial/localrepo.py @ 16657:b6081c2c4647

phases: introduce phasecache The original motivation was changectx.phase() had special logic to correctly lookup in repo._phaserev, including invalidating it when necessary. And at other places, repo._phaserev was accessed directly. This led to the discovery that phases state including _phaseroots, _phaserev and _dirtyphase was manipulated in localrepository.py, phases.py, repair.py, etc. phasecache helps encapsulating that. This patch replaces all phase state in localrepo with phasecache and adjust related code except for advance/retractboundary() in phases. These still access to phasecache internals directly. This will be addressed in a followup.
author Patrick Mezard <patrick@mezard.eu>
date Sat, 12 May 2012 00:24:07 +0200
parents a1dcd842ce17
children 525fdb738975
comparison
equal deleted inserted replaced
16656:4ae3ba9e4d7a 16657:b6081c2c4647
39 self.auditor = scmutil.pathauditor(self.root, self._checknested) 39 self.auditor = scmutil.pathauditor(self.root, self._checknested)
40 self.opener = scmutil.opener(self.path) 40 self.opener = scmutil.opener(self.path)
41 self.wopener = scmutil.opener(self.root) 41 self.wopener = scmutil.opener(self.root)
42 self.baseui = baseui 42 self.baseui = baseui
43 self.ui = baseui.copy() 43 self.ui = baseui.copy()
44 self._dirtyphases = False
45 # A list of callback to shape the phase if no data were found. 44 # A list of callback to shape the phase if no data were found.
46 # Callback are in the form: func(repo, roots) --> processed root. 45 # Callback are in the form: func(repo, roots) --> processed root.
47 # This list it to be filled by extension during repo setup 46 # This list it to be filled by extension during repo setup
48 self._phasedefaults = [] 47 self._phasedefaults = []
49 48
180 179
181 def _writebookmarks(self, marks): 180 def _writebookmarks(self, marks):
182 bookmarks.write(self) 181 bookmarks.write(self)
183 182
184 @storecache('phaseroots') 183 @storecache('phaseroots')
185 def _phaseroots(self): 184 def _phasecache(self):
186 phaseroots, self._dirtyphases = phases.readroots( 185 return phases.phasecache(self, self._phasedefaults)
187 self, self._phasedefaults)
188 return phaseroots
189
190 @propertycache
191 def _phaserev(self):
192 cache = [phases.public] * len(self)
193 for phase in phases.trackedphases:
194 roots = map(self.changelog.rev, self._phaseroots[phase])
195 if roots:
196 for rev in roots:
197 cache[rev] = phase
198 for rev in self.changelog.descendants(*roots):
199 cache[rev] = phase
200 return cache
201 186
202 @storecache('00changelog.i') 187 @storecache('00changelog.i')
203 def changelog(self): 188 def changelog(self):
204 c = changelog.changelog(self.sopener) 189 c = changelog.changelog(self.sopener)
205 if 'HG_PENDING' in os.environ: 190 if 'HG_PENDING' in os.environ:
602 repo = (remote and remote.local()) and remote or self 587 repo = (remote and remote.local()) and remote or self
603 return repo[key].branch() 588 return repo[key].branch()
604 589
605 def known(self, nodes): 590 def known(self, nodes):
606 nm = self.changelog.nodemap 591 nm = self.changelog.nodemap
592 pc = self._phasecache
607 result = [] 593 result = []
608 for n in nodes: 594 for n in nodes:
609 r = nm.get(n) 595 r = nm.get(n)
610 resp = not (r is None or self._phaserev[r] >= phases.secret) 596 resp = not (r is None or pc.phase(self, r) >= phases.secret)
611 result.append(resp) 597 result.append(resp)
612 return result 598 return result
613 599
614 def local(self): 600 def local(self):
615 return self 601 return self
861 delattr(self, name) 847 delattr(self, name)
862 except AttributeError: 848 except AttributeError:
863 pass 849 pass
864 850
865 delcache('_tagscache') 851 delcache('_tagscache')
866 delcache('_phaserev')
867 852
868 self._branchcache = None # in UTF-8 853 self._branchcache = None # in UTF-8
869 self._branchcachetip = None 854 self._branchcachetip = None
870 855
871 def invalidatedirstate(self): 856 def invalidatedirstate(self):
929 l.lock() 914 l.lock()
930 return l 915 return l
931 916
932 def unlock(): 917 def unlock():
933 self.store.write() 918 self.store.write()
934 if self._dirtyphases: 919 if '_phasecache' in vars(self):
935 phases.writeroots(self, self._phaseroots) 920 self._phasecache.write()
936 self._dirtyphases = False
937 for k, ce in self._filecache.items(): 921 for k, ce in self._filecache.items():
938 if k == 'dirstate': 922 if k == 'dirstate':
939 continue 923 continue
940 ce.refresh() 924 ce.refresh()
941 925