mercurial/smartset.py
changeset 35505 12a46ad67a3c
parent 34087 01c9700fbf9f
child 35878 f484b9d95c23
equal deleted inserted replaced
35504:87918218da70 35505:12a46ad67a3c
   770     >>> xs = generatorset([0, 1, 4], iterasc=True)
   770     >>> xs = generatorset([0, 1, 4], iterasc=True)
   771     >>> assert xs.last() == xs.last()
   771     >>> assert xs.last() == xs.last()
   772     >>> xs.last()  # cached
   772     >>> xs.last()  # cached
   773     4
   773     4
   774     """
   774     """
       
   775     def __new__(cls, gen, iterasc=None):
       
   776         if iterasc is None:
       
   777             typ = cls
       
   778         elif iterasc:
       
   779             typ = _generatorsetasc
       
   780         else:
       
   781             typ = _generatorsetdesc
       
   782 
       
   783         return super(generatorset, cls).__new__(typ)
       
   784 
   775     def __init__(self, gen, iterasc=None):
   785     def __init__(self, gen, iterasc=None):
   776         """
   786         """
   777         gen: a generator producing the values for the generatorset.
   787         gen: a generator producing the values for the generatorset.
   778         """
   788         """
   779         self._gen = gen
   789         self._gen = gen
   780         self._asclist = None
   790         self._asclist = None
   781         self._cache = {}
   791         self._cache = {}
   782         self._genlist = []
   792         self._genlist = []
   783         self._finished = False
   793         self._finished = False
   784         self._ascending = True
   794         self._ascending = True
   785         if iterasc is not None:
       
   786             if iterasc:
       
   787                 self.fastasc = self._iterator
       
   788                 self.__contains__ = self._asccontains
       
   789             else:
       
   790                 self.fastdesc = self._iterator
       
   791                 self.__contains__ = self._desccontains
       
   792 
   795 
   793     def __nonzero__(self):
   796     def __nonzero__(self):
   794         # Do not use 'for r in self' because it will enforce the iteration
   797         # Do not use 'for r in self' because it will enforce the iteration
   795         # order (default ascending), possibly unrolling a whole descending
   798         # order (default ascending), possibly unrolling a whole descending
   796         # iterator.
   799         # iterator.
   808 
   811 
   809         # Use new values only, as existing values would be cached.
   812         # Use new values only, as existing values would be cached.
   810         for l in self._consumegen():
   813         for l in self._consumegen():
   811             if l == x:
   814             if l == x:
   812                 return True
   815                 return True
   813 
       
   814         self._cache[x] = False
       
   815         return False
       
   816 
       
   817     def _asccontains(self, x):
       
   818         """version of contains optimised for ascending generator"""
       
   819         if x in self._cache:
       
   820             return self._cache[x]
       
   821 
       
   822         # Use new values only, as existing values would be cached.
       
   823         for l in self._consumegen():
       
   824             if l == x:
       
   825                 return True
       
   826             if l > x:
       
   827                 break
       
   828 
       
   829         self._cache[x] = False
       
   830         return False
       
   831 
       
   832     def _desccontains(self, x):
       
   833         """version of contains optimised for descending generator"""
       
   834         if x in self._cache:
       
   835             return self._cache[x]
       
   836 
       
   837         # Use new values only, as existing values would be cached.
       
   838         for l in self._consumegen():
       
   839             if l == x:
       
   840                 return True
       
   841             if l < x:
       
   842                 break
       
   843 
   816 
   844         self._cache[x] = False
   817         self._cache[x] = False
   845         return False
   818         return False
   846 
   819 
   847     def __iter__(self):
   820     def __iter__(self):
   945             return self.last()
   918             return self.last()
   946         return next(it(), None)
   919         return next(it(), None)
   947 
   920 
   948     def __repr__(self):
   921     def __repr__(self):
   949         d = {False: '-', True: '+'}[self._ascending]
   922         d = {False: '-', True: '+'}[self._ascending]
   950         return '<%s%s>' % (type(self).__name__, d)
   923         return '<%s%s>' % (type(self).__name__.lstrip('_'), d)
       
   924 
       
   925 class _generatorsetasc(generatorset):
       
   926     """Special case of generatorset optimized for ascending generators."""
       
   927 
       
   928     fastasc = generatorset._iterator
       
   929 
       
   930     def __contains__(self, x):
       
   931         if x in self._cache:
       
   932             return self._cache[x]
       
   933 
       
   934         # Use new values only, as existing values would be cached.
       
   935         for l in self._consumegen():
       
   936             if l == x:
       
   937                 return True
       
   938             if l > x:
       
   939                 break
       
   940 
       
   941         self._cache[x] = False
       
   942         return False
       
   943 
       
   944 class _generatorsetdesc(generatorset):
       
   945     """Special case of generatorset optimized for descending generators."""
       
   946 
       
   947     fastdesc = generatorset._iterator
       
   948 
       
   949     def __contains__(self, x):
       
   950         if x in self._cache:
       
   951             return self._cache[x]
       
   952 
       
   953         # Use new values only, as existing values would be cached.
       
   954         for l in self._consumegen():
       
   955             if l == x:
       
   956                 return True
       
   957             if l < x:
       
   958                 break
       
   959 
       
   960         self._cache[x] = False
       
   961         return False
   951 
   962 
   952 def spanset(repo, start=0, end=None):
   963 def spanset(repo, start=0, end=None):
   953     """Create a spanset that represents a range of repository revisions
   964     """Create a spanset that represents a range of repository revisions
   954 
   965 
   955     start: first revision included the set (default to 0)
   966     start: first revision included the set (default to 0)