Mercurial > public > mercurial-scm > hg
comparison mercurial/revset.py @ 22741:ef2c1ea8fb2c
addset: split simple and ordered iteration
We have two goals here. First, we would like to restore the former iteration
order we had in 2.9. Second, we want this logic to be reusable for `fastasc`
and `fastdesc` methods.
author | Pierre-Yves David <pierre-yves.david@fb.com> |
---|---|
date | Thu, 02 Oct 2014 23:28:18 -0500 |
parents | f40a57e8fda1 |
children | 6bbc26adcc6a |
comparison
equal
deleted
inserted
replaced
22740:f40a57e8fda1 | 22741:ef2c1ea8fb2c |
---|---|
2636 | 2636 |
2637 If the ascending attribute is set, iterate over both collections at the | 2637 If the ascending attribute is set, iterate over both collections at the |
2638 same time, yielding only one value at a time in the given order. | 2638 same time, yielding only one value at a time in the given order. |
2639 """ | 2639 """ |
2640 if not self._iter: | 2640 if not self._iter: |
2641 def gen(): | 2641 if self._ascending is None: |
2642 if self._ascending is None: | 2642 def gen(): |
2643 for r in self._r1: | 2643 for r in self._r1: |
2644 yield r | 2644 yield r |
2645 s = self._r1.set() | 2645 s = self._r1.set() |
2646 for r in self._r2: | 2646 for r in self._r2: |
2647 if r not in s: | 2647 if r not in s: |
2648 yield r | 2648 yield r |
2649 else: | 2649 gen = gen() |
2650 iter1 = iter(self._r1) | 2650 else: |
2651 iter2 = iter(self._r2) | 2651 iter1 = iter(self._r1) |
2652 | 2652 iter2 = iter(self._r2) |
2653 val1 = None | 2653 gen = self._iterordered(self._ascending, iter1, iter2) |
2654 val2 = None | 2654 self._iter = _generatorset(gen) |
2655 | |
2656 choice = max | |
2657 if self._ascending: | |
2658 choice = min | |
2659 try: | |
2660 # Consume both iterators in an ordered way until one is | |
2661 # empty | |
2662 while True: | |
2663 if val1 is None: | |
2664 val1 = iter1.next() | |
2665 if val2 is None: | |
2666 val2 = iter2.next() | |
2667 next = choice(val1, val2) | |
2668 yield next | |
2669 if val1 == next: | |
2670 val1 = None | |
2671 if val2 == next: | |
2672 val2 = None | |
2673 except StopIteration: | |
2674 # Flush any remaining values and consume the other one | |
2675 it = iter2 | |
2676 if val1 is not None: | |
2677 yield val1 | |
2678 it = iter1 | |
2679 elif val2 is not None: | |
2680 # might have been equality and both are empty | |
2681 yield val2 | |
2682 for val in it: | |
2683 yield val | |
2684 | |
2685 self._iter = _generatorset(gen()) | |
2686 | |
2687 return self._iter | 2655 return self._iter |
2688 | 2656 |
2689 def __iter__(self): | 2657 def __iter__(self): |
2690 if self._genlist: | 2658 if self._genlist: |
2691 return iter(self._genlist) | 2659 return iter(self._genlist) |
2692 return iter(self._iterator()) | 2660 return iter(self._iterator()) |
2661 | |
2662 def _iterordered(self, ascending, iter1, iter2): | |
2663 """produce an ordered iteration from two iterators with the same order | |
2664 | |
2665 The ascending is used to indicated the iteration direction. | |
2666 """ | |
2667 choice = max | |
2668 if ascending: | |
2669 choice = min | |
2670 | |
2671 val1 = None | |
2672 val2 = None | |
2673 | |
2674 choice = max | |
2675 if self._ascending: | |
2676 choice = min | |
2677 try: | |
2678 # Consume both iterators in an ordered way until one is | |
2679 # empty | |
2680 while True: | |
2681 if val1 is None: | |
2682 val1 = iter1.next() | |
2683 if val2 is None: | |
2684 val2 = iter2.next() | |
2685 next = choice(val1, val2) | |
2686 yield next | |
2687 if val1 == next: | |
2688 val1 = None | |
2689 if val2 == next: | |
2690 val2 = None | |
2691 except StopIteration: | |
2692 # Flush any remaining values and consume the other one | |
2693 it = iter2 | |
2694 if val1 is not None: | |
2695 yield val1 | |
2696 it = iter1 | |
2697 elif val2 is not None: | |
2698 # might have been equality and both are empty | |
2699 yield val2 | |
2700 for val in it: | |
2701 yield val | |
2693 | 2702 |
2694 def __contains__(self, x): | 2703 def __contains__(self, x): |
2695 return x in self._r1 or x in self._r2 | 2704 return x in self._r1 or x in self._r2 |
2696 | 2705 |
2697 def set(self): | 2706 def set(self): |