comparison mercurial/graphmod.py @ 16132:41fc1e078d68

graphmod: add config cache Before, we'd lookup the branch for every edge segment in the entire graph: extremely expensive. This happened even when no per-branch settings existed. Now we define a revision -> config cache function that's LRU-cached and is a no-op when no configuration exists. Still not terribly fast, but hopefully only one real branch lookup per revision. This might degenerate for wide graphs as the LRU is hard-coded to 20 elements.
author Matt Mackall <mpm@selenic.com>
date Fri, 17 Feb 2012 13:53:41 -0600
parents 6f236c8bdc01
children 6e4de55a41a4
comparison
equal deleted inserted replaced
16131:6f236c8bdc01 16132:41fc1e078d68
16 context of the graph returned. Type is a constant specifying the node type. 16 context of the graph returned. Type is a constant specifying the node type.
17 Data depends on type. 17 Data depends on type.
18 """ 18 """
19 19
20 from mercurial.node import nullrev 20 from mercurial.node import nullrev
21 import util
21 22
22 CHANGESET = 'C' 23 CHANGESET = 'C'
23 24
24 def dagwalker(repo, revs): 25 def dagwalker(repo, revs):
25 """cset DAG generator yielding (id, CHANGESET, ctx, [parentids]) tuples 26 """cset DAG generator yielding (id, CHANGESET, ctx, [parentids]) tuples
92 if setting == "width" and val.isdigit(): 93 if setting == "width" and val.isdigit():
93 config.setdefault(branch, {})[setting] = val 94 config.setdefault(branch, {})[setting] = val
94 elif setting == "color" and val.isalnum(): 95 elif setting == "color" and val.isalnum():
95 config.setdefault(branch, {})[setting] = val 96 config.setdefault(branch, {})[setting] = val
96 97
98 if config:
99 getconf = util.lrucachefunc(lambda rev: config.get(repo[rev].branch()))
100 else:
101 getconf = lambda rev: None
97 102
98 for (cur, type, data, parents) in dag: 103 for (cur, type, data, parents) in dag:
99 104
100 # Compute seen and next 105 # Compute seen and next
101 if cur not in seen: 106 if cur not in seen:
123 edges = [] 128 edges = []
124 for ecol, eid in enumerate(seen): 129 for ecol, eid in enumerate(seen):
125 if eid in next: 130 if eid in next:
126 edges.append(( 131 edges.append((
127 ecol, next.index(eid), colors[eid], 132 ecol, next.index(eid), colors[eid],
128 config.get(repo[eid].branch(), None))) 133 getconf(eid)))
129 elif eid == cur: 134 elif eid == cur:
130 for p in parents: 135 for p in parents:
131 edges.append(( 136 edges.append((
132 ecol, next.index(p), color, 137 ecol, next.index(p), color,
133 config.get(repo[p].branch(), None))) 138 getconf(p)))
134 139
135 # Yield and move on 140 # Yield and move on
136 yield (cur, type, data, (col, color), edges) 141 yield (cur, type, data, (col, color), edges)
137 seen = next 142 seen = next
138 143