stack: move data computation on the object
authorPierre-Yves David <pierre-yves.david@octobus.net>
Mon, 04 Sep 2017 12:41:30 +0200
changeset 2916 17749d9d3968
parent 2915 b3abdb3d819e
child 2917 044686b25cf7
stack: move data computation on the object We gather multiple data about the stack on the object. Let us move this on the object and keep it cached there.
hgext3rd/topic/stack.py
--- a/hgext3rd/topic/stack.py	Mon Sep 04 12:23:03 2017 +0200
+++ b/hgext3rd/topic/stack.py	Mon Sep 04 12:41:30 2017 +0200
@@ -49,6 +49,10 @@
         return self.revs.index(item)
 
     @util.propertycache
+    def _dependencies(self):
+        return builddependencies(self._repo, self.revs[1:])
+
+    @util.propertycache
     def revs(self):
         revs = _orderrevs(self._repo, self._revs)
         if revs:
@@ -58,6 +62,41 @@
             revs.insert(0, pt1.rev())
         return revs
 
+    @util.propertycache
+    def changesetcount(self):
+        return len(self._revs)
+
+    @util.propertycache
+    def troubledcount(self):
+        return len([r for r in self._revs if self._repo[r].isunstable()])
+
+    @util.propertycache
+    def heads(self):
+        revs = self.revs[1:]
+        deps, rdeps = self._dependencies
+        return [r for r in revs if not rdeps[r]]
+
+    @util.propertycache
+    def behindcount(self):
+        revs = self.revs[1:]
+        deps, rdeps = self._dependencies
+        if revs:
+            minroot = [min(r for r in revs if not deps[r])]
+            try:
+                dest = destutil.destmerge(self._repo, action='rebase',
+                                          sourceset=minroot,
+                                          onheadcheck=False)
+                return len(self._repo.revs("only(%d, %ld)", dest, minroot))
+            except error.NoMergeDestAbort:
+                return 0
+            except error.ManyMergeDestAbort:
+                return -1
+        return 0
+
+    @util.propertycache
+    def branches(self):
+        return sorted(set(self._repo[r].branch() for r in self._revs))
+
 def labelsgen(prefix, labelssuffix):
     """ Takes a label prefix and a list of suffixes. Returns a string of the prefix
     formatted with each suffix separated with a space.
@@ -197,24 +236,10 @@
     :behindcount: number of changeset on rebase destination
     """
     data = {}
-    revs = stack(repo, branch, topic)[1:]
-    data['changesetcount'] = len(revs)
-    data['troubledcount'] = len([r for r in revs if repo[r].isunstable()])
-    deps, rdeps = builddependencies(repo, revs)
-    data['headcount'] = len([r for r in revs if not rdeps[r]])
-    data['behindcount'] = 0
-    if revs:
-        minroot = [min(r for r in revs if not deps[r])]
-        try:
-            dest = destutil.destmerge(repo, action='rebase',
-                                      sourceset=minroot,
-                                      onheadcheck=False)
-            data['behindcount'] = len(repo.revs("only(%d, %ld)", dest,
-                                                minroot))
-        except error.NoMergeDestAbort:
-            data['behindcount'] = 0
-        except error.ManyMergeDestAbort:
-            data['behindcount'] = -1
-    data['branches'] = sorted(set(repo[r].branch() for r in revs))
-
+    current = stack(repo, branch, topic)
+    data['changesetcount'] = current.changesetcount
+    data['troubledcount'] = current.troubledcount
+    data['headcount'] = len(current.heads)
+    data['behindcount'] = current.behindcount
+    data['branches'] = current.branches
     return data