# HG changeset patch # User Pierre-Yves David # Date 1412290937 18000 # Node ID b89f7e3a414d63217576cee4c97d554f5bf54757 # Parent 6877ba8d85ff3ff2f075f4353f21af91f7a64014 spanset: enforce the order lazily to gain `fastasc` and `fastdesc` methods Instead of having the direction of iteration enforced through the ordering of `start` and `end` attributes of spanset, we encode the iteration direction in an explicit attribute and always store start < end. The logic for sort and reverse has to be updated. The __iter__ is now based on the newly introduced `fastasc` and `fastdesc` methods. This will allow other code simplifications in the future. diff -r 6877ba8d85ff -r b89f7e3a414d mercurial/revset.py --- a/mercurial/revset.py Tue Sep 30 22:26:34 2014 -0500 +++ b/mercurial/revset.py Thu Oct 02 18:02:17 2014 -0500 @@ -2855,27 +2855,44 @@ Spanset will be descending if `end` < `start`. """ + if end is None: + end = len(repo) + self._ascending = start <= end + if not self._ascending: + start, end = end + 1, start +1 self._start = start - if end is not None: - self._end = end - else: - self._end = len(repo) + self._end = end self._hiddenrevs = repo.changelog.filteredrevs + def sort(self, reverse=False): + self._ascending = not reverse + + def reverse(self): + self._ascending = not self._ascending + + def _iterfilter(self, iterrange): + s = self._hiddenrevs + for r in iterrange: + if r not in s: + yield r + def __iter__(self): - if self.isascending(): - iterrange = xrange(self._start, self._end) + if self._ascending: + return self.fastasc() else: - iterrange = xrange(self._start, self._end, -1) - + return self.fastdesc() + + def fastasc(self): + iterrange = xrange(self._start, self._end) if self._hiddenrevs: - s = self._hiddenrevs - for r in iterrange: - if r not in s: - yield r - else: - for r in iterrange: - yield r + return self._iterfilter(iterrange) + return iter(iterrange) + + def fastdesc(self): + iterrange = xrange(self._end - 1, self._start - 1, -1) + if self._hiddenrevs: + return self._iterfilter(iterrange) + return iter(iterrange) def __contains__(self, rev): start = self._start @@ -2923,17 +2940,6 @@ l = baseset([r for r in self]) return l[x] - def sort(self, reverse=False): - if bool(reverse) != (self._start > self._end): - self.reverse() - - def reverse(self): - # Just switch the _start and _end parameters - if self.isascending(): - self._start, self._end = self._end - 1, self._start - 1 - else: - self._start, self._end = self._end + 1, self._start + 1 - def set(self): return self