Mercurial > public > mercurial-scm > hg
comparison mercurial/context.py @ 29937:2c302c654451
merge with stable
author | Pierre-Yves David <pierre-yves.david@ens-lyon.org> |
---|---|
date | Wed, 14 Sep 2016 17:12:39 +0200 |
parents | be16091ac14d 2f6d5c60f6fc |
children | a059b17352ef |
comparison
equal
deleted
inserted
replaced
29936:3e7ded768556 | 29937:2c302c654451 |
---|---|
988 | 988 |
989 # This algorithm would prefer to be recursive, but Python is a | 989 # This algorithm would prefer to be recursive, but Python is a |
990 # bit recursion-hostile. Instead we do an iterative | 990 # bit recursion-hostile. Instead we do an iterative |
991 # depth-first search. | 991 # depth-first search. |
992 | 992 |
993 # 1st DFS pre-calculates pcache and needed | |
993 visit = [base] | 994 visit = [base] |
994 hist = {} | |
995 pcache = {} | 995 pcache = {} |
996 needed = {base: 1} | 996 needed = {base: 1} |
997 while visit: | 997 while visit: |
998 f = visit.pop() | |
999 if f in pcache: | |
1000 continue | |
1001 pl = parents(f) | |
1002 pcache[f] = pl | |
1003 for p in pl: | |
1004 needed[p] = needed.get(p, 0) + 1 | |
1005 if p not in pcache: | |
1006 visit.append(p) | |
1007 | |
1008 # 2nd DFS does the actual annotate | |
1009 visit[:] = [base] | |
1010 hist = {} | |
1011 while visit: | |
998 f = visit[-1] | 1012 f = visit[-1] |
999 pcached = f in pcache | 1013 if f in hist: |
1000 if not pcached: | 1014 visit.pop() |
1001 pcache[f] = parents(f) | 1015 continue |
1002 | 1016 |
1003 ready = True | 1017 ready = True |
1004 pl = pcache[f] | 1018 pl = pcache[f] |
1005 for p in pl: | 1019 for p in pl: |
1006 if p not in hist: | 1020 if p not in hist: |
1007 ready = False | 1021 ready = False |
1008 visit.append(p) | 1022 visit.append(p) |
1009 if not pcached: | |
1010 needed[p] = needed.get(p, 0) + 1 | |
1011 if ready: | 1023 if ready: |
1012 visit.pop() | 1024 visit.pop() |
1013 reusable = f in hist | 1025 curr = decorate(f.data(), f) |
1014 if reusable: | |
1015 curr = hist[f] | |
1016 else: | |
1017 curr = decorate(f.data(), f) | |
1018 for p in pl: | 1026 for p in pl: |
1019 if not reusable: | 1027 curr = pair(hist[p], curr) |
1020 curr = pair(hist[p], curr) | |
1021 if needed[p] == 1: | 1028 if needed[p] == 1: |
1022 del hist[p] | 1029 del hist[p] |
1023 del needed[p] | 1030 del needed[p] |
1024 else: | 1031 else: |
1025 needed[p] -= 1 | 1032 needed[p] -= 1 |
1026 | 1033 |
1027 hist[f] = curr | 1034 hist[f] = curr |
1028 pcache[f] = [] | 1035 del pcache[f] |
1029 | 1036 |
1030 return zip(hist[base][0], hist[base][1].splitlines(True)) | 1037 return zip(hist[base][0], hist[base][1].splitlines(True)) |
1031 | 1038 |
1032 def ancestors(self, followfirst=False): | 1039 def ancestors(self, followfirst=False): |
1033 visit = {} | 1040 visit = {} |