comparison mercurial/context.py @ 7368:595ba2537d4f

context: use descriptors to speed up lazy attributes
author Dirkjan Ochtman <dirkjan@ochtman.nl>
date Fri, 14 Nov 2008 12:44:26 +0100
parents ad0eb8762458
children a8376f2aa3b1
comparison
equal deleted inserted replaced
7367:ad0eb8762458 7368:595ba2537d4f
6 # of the GNU General Public License, incorporated herein by reference. 6 # of the GNU General Public License, incorporated herein by reference.
7 7
8 from node import nullid, nullrev, short, hex 8 from node import nullid, nullrev, short, hex
9 from i18n import _ 9 from i18n import _
10 import ancestor, bdiff, revlog, util, os, errno 10 import ancestor, bdiff, revlog, util, os, errno
11
12 class propertycache(object):
13 def __init__(self, func):
14 self.func = func
15 self.name = func.__name__
16 def __get__(self, obj, type=None):
17 result = self.func(obj)
18 setattr(obj, self.name, result)
19 return result
11 20
12 class changectx(object): 21 class changectx(object):
13 """A changecontext object makes access to data related to a particular 22 """A changecontext object makes access to data related to a particular
14 changeset convenient.""" 23 changeset convenient."""
15 def __init__(self, repo, changeid=''): 24 def __init__(self, repo, changeid=''):
49 return not (self == other) 58 return not (self == other)
50 59
51 def __nonzero__(self): 60 def __nonzero__(self):
52 return self._rev != nullrev 61 return self._rev != nullrev
53 62
54 def __getattr__(self, name): 63 def _changeset(self):
55 if name == '_changeset': 64 return self._repo.changelog.read(self.node())
56 self._changeset = self._repo.changelog.read(self.node()) 65 _changeset = propertycache(_changeset)
57 return self._changeset 66
58 elif name == '_manifest': 67 def _manifest(self):
59 self._manifest = self._repo.manifest.read(self._changeset[0]) 68 return self._repo.manifest.read(self._changeset[0])
60 return self._manifest 69 _manifest = propertycache(_manifest)
61 elif name == '_manifestdelta': 70
62 md = self._repo.manifest.readdelta(self._changeset[0]) 71 def _manifestdelta(self):
63 self._manifestdelta = md 72 return self._repo.manifest.readdelta(self._changeset[0])
64 return self._manifestdelta 73 _manifestdelta = propertycache(_manifestdelta)
65 elif name == '_parents': 74
66 p = self._repo.changelog.parentrevs(self._rev) 75 def _parents(self):
67 if p[1] == nullrev: 76 p = self._repo.changelog.parentrevs(self._rev)
68 p = p[:-1] 77 if p[1] == nullrev:
69 self._parents = [changectx(self._repo, x) for x in p] 78 p = p[:-1]
70 return self._parents 79 return [changectx(self._repo, x) for x in p]
71 else: 80 _parents = propertycache(_parents)
72 raise AttributeError(name)
73 81
74 def __contains__(self, key): 82 def __contains__(self, key):
75 return key in self._manifest 83 return key in self._manifest
76 84
77 def __getitem__(self, key): 85 def __getitem__(self, key):
191 if changectx is not None: 199 if changectx is not None:
192 self._changectx = changectx 200 self._changectx = changectx
193 if fileid is not None: 201 if fileid is not None:
194 self._fileid = fileid 202 self._fileid = fileid
195 203
196 def __getattr__(self, name): 204 def _changectx(self):
197 if name == '_changectx': 205 return changectx(self._repo, self._changeid)
198 self._changectx = changectx(self._repo, self._changeid) 206 _changectx = propertycache(_changectx)
199 return self._changectx 207
200 elif name == '_filelog': 208 def _filelog(self):
201 self._filelog = self._repo.file(self._path) 209 return self._repo.file(self._path)
202 return self._filelog 210 _filelog = propertycache(_filelog)
203 elif name == '_changeid': 211
204 if '_changectx' in self.__dict__: 212 def _changeid(self):
205 self._changeid = self._changectx.rev() 213 if '_changectx' in self.__dict__:
206 else: 214 return self._changectx.rev()
207 self._changeid = self._filelog.linkrev(self._filerev)
208 return self._changeid
209 elif name == '_filenode':
210 if '_fileid' in self.__dict__:
211 self._filenode = self._filelog.lookup(self._fileid)
212 else:
213 self._filenode = self._changectx.filenode(self._path)
214 return self._filenode
215 elif name == '_filerev':
216 self._filerev = self._filelog.rev(self._filenode)
217 return self._filerev
218 elif name == '_repopath':
219 self._repopath = self._path
220 return self._repopath
221 else: 215 else:
222 raise AttributeError(name) 216 return self._filelog.linkrev(self._filerev)
217 _changeid = propertycache(_changeid)
218
219 def _filenode(self):
220 if '_fileid' in self.__dict__:
221 return self._filelog.lookup(self._fileid)
222 else:
223 return self._changectx.filenode(self._path)
224 _filenode = propertycache(_filenode)
225
226 def _filerev(self):
227 return self._filelog.rev(self._filenode)
228 _filerev = propertycache(_filerev)
229
230 def _repopath(self):
231 return self._path
232 _repopath = propertycache(_repopath)
223 233
224 def __nonzero__(self): 234 def __nonzero__(self):
225 try: 235 try:
226 n = self._filenode 236 n = self._filenode
227 return True 237 return True
503 return True 513 return True
504 514
505 def __contains__(self, key): 515 def __contains__(self, key):
506 return self._dirstate[key] not in "?r" 516 return self._dirstate[key] not in "?r"
507 517
508 def __getattr__(self, name): 518 def _manifest(self):
509 if name == '_status':
510 self._status = self._repo.status(unknown=True)
511 return self._status
512 elif name == '_user':
513 self._user = self._repo.ui.username()
514 return self._user
515 elif name == '_date':
516 self._date = util.makedate()
517 return self._date
518 if name == '_manifest':
519 self._buildmanifest()
520 return self._manifest
521 elif name == '_parents':
522 p = self._repo.dirstate.parents()
523 if p[1] == nullid:
524 p = p[:-1]
525 self._parents = [changectx(self._repo, x) for x in p]
526 return self._parents
527 else:
528 raise AttributeError(name)
529
530 def _buildmanifest(self):
531 """generate a manifest corresponding to the working directory""" 519 """generate a manifest corresponding to the working directory"""
532 520
533 man = self._parents[0].manifest().copy() 521 man = self._parents[0].manifest().copy()
534 copied = self._repo.dirstate.copies() 522 copied = self._repo.dirstate.copies()
535 cf = lambda x: man.flags(copied.get(x, x)) 523 cf = lambda x: man.flags(copied.get(x, x))
545 533
546 for f in deleted + removed: 534 for f in deleted + removed:
547 if f in man: 535 if f in man:
548 del man[f] 536 del man[f]
549 537
550 self._manifest = man 538 return man
539 _manifest = propertycache(_manifest)
540
541 def _status(self):
542 return self._repo.status(unknown=True)
543 _status = propertycache(_status)
544
545 def _user(self):
546 return self._repo.ui.username()
547 _user = propertycache(_user)
548
549 def _date(self):
550 return util.makedate()
551 _date = propertycache(_date)
552
553 def _parents(self):
554 p = self._repo.dirstate.parents()
555 if p[1] == nullid:
556 p = p[:-1]
557 self._parents = [changectx(self._repo, x) for x in p]
558 return self._parents
559 _parents = propertycache(_parents)
551 560
552 def manifest(self): return self._manifest 561 def manifest(self): return self._manifest
553 562
554 def user(self): return self._user or self._repo.ui.username() 563 def user(self): return self._user or self._repo.ui.username()
555 def date(self): return self._date 564 def date(self): return self._date
620 if filelog: 629 if filelog:
621 self._filelog = filelog 630 self._filelog = filelog
622 if workingctx: 631 if workingctx:
623 self._changectx = workingctx 632 self._changectx = workingctx
624 633
625 def __getattr__(self, name): 634 def _changectx(self):
626 if name == '_changectx': 635 return workingctx(self._repo)
627 self._changectx = workingctx(self._repo) 636 _changectx = propertycache(_changectx)
628 return self._changectx 637
629 elif name == '_repopath': 638 def _repopath(self):
630 self._repopath = (self._repo.dirstate.copied(self._path) 639 return self._repo.dirstate.copied(self._path) or self._path
631 or self._path) 640 _repopath = propertycache(_repopath)
632 return self._repopath 641
633 elif name == '_filelog': 642 def _filelog(self):
634 self._filelog = self._repo.file(self._repopath) 643 return self._repo.file(self._repopath)
635 return self._filelog 644 _filelog = propertycache(_filelog)
636 else:
637 raise AttributeError(name)
638 645
639 def __nonzero__(self): 646 def __nonzero__(self):
640 return True 647 return True
641 648
642 def __str__(self): 649 def __str__(self):