Mercurial > public > mercurial-scm > hg
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): |