Patchwork [02,of,10,lazy-changelog-parse] context: use changelogrevision

login
register
mail settings
Submitter Gregory Szorc
Date March 6, 2016, 11:58 p.m.
Message ID <45c41cbfe73e7d685a88.1457308728@ubuntu-vm-main>
Download mbox | patch
Permalink /patch/13631/
State Accepted
Delegated to: Martin von Zweigbergk
Headers show

Comments

Gregory Szorc - March 6, 2016, 11:58 p.m.
# HG changeset patch
# User Gregory Szorc <gregory.szorc@gmail.com>
# Date 1457299597 28800
#      Sun Mar 06 13:26:37 2016 -0800
# Node ID 45c41cbfe73e7d685a8831cb73e0064eddc6d33e
# Parent  7531b8572b611e13fe45a9882a1c7d9aa6e793d6
context: use changelogrevision

Upcoming patches will make the changelogrevision object perform
lazy parsing. Let's switch to it.

Because we're switching from a tuple to an object, everthing that
accesses the internal cached attribute needs to be updated to access
via attributes. A nice side-effect is this makes the code easier to
read!

Surprisingly, this appears to make revsets accessing this data
slightly faster (values are before series, p1, this patch):

author(mpm)
0.896565
0.929984
0.914234

desc(bug)
0.887169
0.935642
0.921073

date(2015)
0.878797
0.908094
0.891980

extra(rebase_source)
0.865446
0.922624
0.912514

author(mpm) or author(greg)
1.801832
1.902112
1.860402

author(mpm) or desc(bug)
1.812438
1.860977
1.844850

date(2015) or branch(default)
0.968276
1.005824
0.994673

author(mpm) or desc(bug) or date(2015) or extra(rebase_source)
3.656193
3.743381
3.721032

Patch

diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -254,17 +254,17 @@  class basectx(object):
                 return self._manifest[path], self._manifest.flags(path)
             except KeyError:
                 raise error.ManifestLookupError(self._node, path,
                                                 _('not found in manifest'))
         if '_manifestdelta' in self.__dict__ or path in self.files():
             if path in self._manifestdelta:
                 return (self._manifestdelta[path],
                         self._manifestdelta.flags(path))
-        node, flag = self._repo.manifest.find(self._changeset[0], path)
+        node, flag = self._repo.manifest.find(self._changeset.manifest, path)
         if not node:
             raise error.ManifestLookupError(self._node, path,
                                             _('not found in manifest'))
 
         return node, flag
 
     def filenode(self, path):
         return self._fileinfo(path)[0]
@@ -519,53 +519,61 @@  class changectx(basectx):
         except AttributeError:
             return id(self)
 
     def __nonzero__(self):
         return self._rev != nullrev
 
     @propertycache
     def _changeset(self):
-        return self._repo.changelog.read(self.rev())
+        return self._repo.changelog.changelogrevision(self.rev())
 
     @propertycache
     def _manifest(self):
-        return self._repo.manifest.read(self._changeset[0])
+        return self._repo.manifest.read(self._changeset.manifest)
 
     @propertycache
     def _manifestdelta(self):
-        return self._repo.manifest.readdelta(self._changeset[0])
+        return self._repo.manifest.readdelta(self._changeset.manifest)
 
     @propertycache
     def _parents(self):
         repo = self._repo
         p1, p2 = repo.changelog.parentrevs(self._rev)
         if p2 == nullrev:
             return [changectx(repo, p1)]
         return [changectx(repo, p1), changectx(repo, p2)]
 
     def changeset(self):
-        return self._changeset
+        c = self._changeset
+        return (
+            c.manifest,
+            c.user,
+            c.date,
+            c.files,
+            c.description,
+            c.extra,
+        )
     def manifestnode(self):
-        return self._changeset[0]
+        return self._changeset.manifest
 
     def user(self):
-        return self._changeset[1]
+        return self._changeset.user
     def date(self):
-        return self._changeset[2]
+        return self._changeset.date
     def files(self):
-        return self._changeset[3]
+        return self._changeset.files
     def description(self):
-        return self._changeset[4]
+        return self._changeset.description
     def branch(self):
-        return encoding.tolocal(self._changeset[5].get("branch"))
+        return encoding.tolocal(self._changeset.extra.get("branch"))
     def closesbranch(self):
-        return 'close' in self._changeset[5]
+        return 'close' in self._changeset.extra
     def extra(self):
-        return self._changeset[5]
+        return self._changeset.extra
     def tags(self):
         return self._repo.nodetags(self._node)
     def bookmarks(self):
         return self._repo.nodebookmarks(self._node)
     def phase(self):
         return self._repo._phasecache.phase(self._repo, self._rev)
     def hidden(self):
         return self._rev in repoview.filterrevs(self._repo, 'visible')