comparison mercurial/revset.py @ 24939:85544a52ee84

revset: use an iterator instead of a dequeue in ancestors() The dequeue was actually just used to be able to pop value one at a time. Building the dequeue means we are reading all the input value at once at the beginning of the evaluation. This defeat the lazyness of revset. We replace the deque with iterator usage for the sake of simplicity and lazyness. This provide massive speedup to get the first result if the input set is big max(::all()) before) wall 0.001917 comb 0.000000 user 0.000000 sys 0.000000 (best of 1115) after) wall 0.000107 comb 0.000000 user 0.000000 sys 0.000000 (best of 22222)
author Pierre-Yves David <pierre-yves.david@fb.com>
date Wed, 26 Mar 2014 16:21:30 -0700
parents 6db8074f9150
children 6b54f749659b
comparison
equal deleted inserted replaced
24938:6db8074f9150 24939:85544a52ee84
24 cut = None 24 cut = None
25 cl = repo.changelog 25 cl = repo.changelog
26 26
27 def iterate(): 27 def iterate():
28 revs.sort(reverse=True) 28 revs.sort(reverse=True)
29 revqueue = util.deque(revs) 29 irevs = iter(revs)
30 if not revqueue: 30 h = []
31 try:
32 inputrev = irevs.next()
33 heapq.heappush(h, -inputrev)
34 except StopIteration:
31 return 35 return
32
33 h = []
34 inputrev = revqueue.popleft()
35 heapq.heappush(h, -inputrev)
36 36
37 seen = set() 37 seen = set()
38 while h: 38 while h:
39 current = -heapq.heappop(h) 39 current = -heapq.heappop(h)
40 if current not in seen: 40 if current not in seen:
41 if current == inputrev: 41 if current == inputrev:
42 if revqueue: 42 try:
43 inputrev = revqueue.popleft() 43 inputrev = irevs.next()
44 heapq.heappush(h, -inputrev) 44 heapq.heappush(h, -inputrev)
45 except StopIteration:
46 pass
45 seen.add(current) 47 seen.add(current)
46 yield current 48 yield current
47 for parent in cl.parentrevs(current)[:cut]: 49 for parent in cl.parentrevs(current)[:cut]:
48 if parent != node.nullrev: 50 if parent != node.nullrev:
49 heapq.heappush(h, -parent) 51 heapq.heappush(h, -parent)