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):