changeset 22859:513c0ba61db8

addset: do lazy sorting The previous implementation was consuming the whole revset when asked for any sort. The addset class is now doing lazy sorting like all other smarset classes. This has no significant impact in the benchmark as-is. But this is important to later change.
author Pierre-Yves David <pierre-yves.david@fb.com>
date Thu, 09 Oct 2014 20:15:41 -0700
parents d7cedb32a8ab
children 1dd178277cf5
files mercurial/revset.py
diffstat 1 files changed, 30 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/revset.py	Thu Oct 09 04:40:04 2014 -0700
+++ b/mercurial/revset.py	Thu Oct 09 20:15:41 2014 -0700
@@ -2521,6 +2521,7 @@
         self._iter = None
         self._ascending = ascending
         self._genlist = None
+        self._asclist = None
 
     def __len__(self):
         return len(self._list)
@@ -2560,12 +2561,31 @@
         return gen
 
     def __iter__(self):
-        if self._genlist:
-            return iter(self._genlist)
-        return iter(self._iterator())
+        if self._ascending is None:
+            if self._genlist:
+                return iter(self._genlist)
+            return iter(self._iterator())
+        self._trysetasclist()
+        if self._ascending:
+            it = self.fastasc
+        else:
+            it = self.fastdesc
+        if it is None:
+            # consume the gen and try again
+            self._list
+            return iter(self)
+        return it()
+
+    def _trysetasclist(self):
+        """populate the _asclist attribut if possible and necessary"""
+        if self._genlist is not None and self._asclist is None:
+            self._asclist = sorted(self._genlist)
 
     @property
     def fastasc(self):
+        self._trysetasclist()
+        if self._asclist is not None:
+            return self._asclist.__iter__
         iter1 = self._r1.fastasc
         iter2 = self._r2.fastasc
         if None in (iter1, iter2):
@@ -2574,6 +2594,9 @@
 
     @property
     def fastdesc(self):
+        self._trysetasclist()
+        if self._asclist is not None:
+            return self._asclist.__reversed__
         iter1 = self._r1.fastdesc
         iter2 = self._r2.fastdesc
         if None in (iter1, iter2):
@@ -2633,12 +2656,7 @@
         For this we use the cached list with all the generated values and if we
         know they are ascending or descending we can sort them in a smart way.
         """
-        if self._ascending is None:
-            self._list.sort(reverse=reverse)
-            self._ascending = not reverse
-        else:
-            if bool(self._ascending) == bool(reverse):
-                self.reverse()
+        self._ascending = not reverse
 
     def isascending(self):
         return self._ascending is not None and self._ascending
@@ -2647,8 +2665,9 @@
         return self._ascending is not None and not self._ascending
 
     def reverse(self):
-        self._list.reverse()
-        if self._ascending is not None:
+        if self._ascending is None:
+            self._list.reverse()
+        else:
             self._ascending = not self._ascending
 
     def first(self):