Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/hgweb/webcommands.py @ 35416:f84b01257e06
hgweb: render next pages on /graph incrementally
Previously, when user scrolled down to see the next page on /graph, all hgweb
did was re-render everything that would be visible (by simply incrementing
revcount). It was not efficient at all, and this patch makes /graph page behave
similarly to the regular /log: every new page only consists of new changesets,
no duplication, and only jsdata is based on the full set of changesets required
to build accurate graph.
This is achieved by adding "?graphtop=<node>" to the next page URL template,
effectively remembering where the graph started, and using that value to create
the new `tree` that covers the whole visible graph. That variable is then used
to produce jsdata for redrawing graph client-side.
nextentry is used for the same purpose as on /log page (to format the next page
URL), but it's not a part of the graph.
author | Anton Shestakov <av6@dwimlabs.net> |
---|---|
date | Mon, 11 Dec 2017 15:43:56 +0800 |
parents | a48af4993aa0 |
children | 0fe5d99804bb |
comparison
equal
deleted
inserted
replaced
35415:a48af4993aa0 | 35416:f84b01257e06 |
---|---|
1205 lessvars = copy.copy(tmpl.defaults['sessionvars']) | 1205 lessvars = copy.copy(tmpl.defaults['sessionvars']) |
1206 lessvars['revcount'] = max(revcount / 2, 1) | 1206 lessvars['revcount'] = max(revcount / 2, 1) |
1207 morevars = copy.copy(tmpl.defaults['sessionvars']) | 1207 morevars = copy.copy(tmpl.defaults['sessionvars']) |
1208 morevars['revcount'] = revcount * 2 | 1208 morevars['revcount'] = revcount * 2 |
1209 | 1209 |
1210 graphtop = req.form.get('graphtop', [ctx.hex()])[0] | |
1211 graphvars = copy.copy(tmpl.defaults['sessionvars']) | |
1212 graphvars['graphtop'] = graphtop | |
1213 | |
1210 count = len(web.repo) | 1214 count = len(web.repo) |
1211 pos = rev | 1215 pos = rev |
1212 | 1216 |
1213 uprev = min(max(0, count - 1), rev + revcount) | 1217 uprev = min(max(0, count - 1), rev + revcount) |
1214 downrev = max(0, rev - revcount) | 1218 downrev = max(0, rev - revcount) |
1215 changenav = webutil.revnav(web.repo).gen(pos, revcount, count) | 1219 changenav = webutil.revnav(web.repo).gen(pos, revcount, count) |
1216 | 1220 |
1217 tree = [] | 1221 tree = [] |
1222 nextentry = [] | |
1223 lastrev = 0 | |
1218 if pos != -1: | 1224 if pos != -1: |
1219 allrevs = web.repo.changelog.revs(pos, 0) | 1225 allrevs = web.repo.changelog.revs(pos, 0) |
1220 revs = [] | 1226 revs = [] |
1221 for i in allrevs: | 1227 for i in allrevs: |
1222 revs.append(i) | 1228 revs.append(i) |
1223 if len(revs) >= revcount: | 1229 if len(revs) >= revcount + 1: |
1224 break | 1230 break |
1231 | |
1232 if len(revs) > revcount: | |
1233 nextentry = [webutil.commonentry(web.repo, web.repo[revs[-1]])] | |
1234 revs = revs[:-1] | |
1235 | |
1236 lastrev = revs[-1] | |
1225 | 1237 |
1226 # We have to feed a baseset to dagwalker as it is expecting smartset | 1238 # We have to feed a baseset to dagwalker as it is expecting smartset |
1227 # object. This does not have a big impact on hgweb performance itself | 1239 # object. This does not have a big impact on hgweb performance itself |
1228 # since hgweb graphing code is not itself lazy yet. | 1240 # since hgweb graphing code is not itself lazy yet. |
1229 dag = graphmod.dagwalker(web.repo, smartset.baseset(revs)) | 1241 dag = graphmod.dagwalker(web.repo, smartset.baseset(revs)) |
1230 # As we said one line above... not lazy. | 1242 # As we said one line above... not lazy. |
1231 tree = list(item for item in graphmod.colored(dag, web.repo) | 1243 tree = list(item for item in graphmod.colored(dag, web.repo) |
1232 if item[1] == graphmod.CHANGESET) | 1244 if item[1] == graphmod.CHANGESET) |
1233 | 1245 |
1246 def fulltree(): | |
1247 pos = web.repo[graphtop].rev() | |
1248 tree = [] | |
1249 if pos != -1: | |
1250 revs = web.repo.changelog.revs(pos, lastrev) | |
1251 dag = graphmod.dagwalker(web.repo, smartset.baseset(revs)) | |
1252 tree = list(item for item in graphmod.colored(dag, web.repo) | |
1253 if item[1] == graphmod.CHANGESET) | |
1254 return tree | |
1255 | |
1234 def jsdata(): | 1256 def jsdata(): |
1235 return [{'node': pycompat.bytestr(ctx), | 1257 return [{'node': pycompat.bytestr(ctx), |
1236 'vertex': vtx, | 1258 'vertex': vtx, |
1237 'edges': edges} | 1259 'edges': edges} |
1238 for (id, type, ctx, vtx, edges) in tree] | 1260 for (id, type, ctx, vtx, edges) in fulltree()] |
1239 | 1261 |
1240 def nodes(): | 1262 def nodes(): |
1241 for row, (id, type, ctx, vtx, edges) in enumerate(tree): | 1263 for row, (id, type, ctx, vtx, edges) in enumerate(tree): |
1242 entry = webutil.commonentry(web.repo, ctx) | 1264 entry = webutil.commonentry(web.repo, ctx) |
1243 edgedata = [{'col': edge[0], | 1265 edgedata = [{'col': edge[0], |
1258 rows = len(tree) | 1280 rows = len(tree) |
1259 | 1281 |
1260 return tmpl('graph', rev=rev, symrev=symrev, revcount=revcount, | 1282 return tmpl('graph', rev=rev, symrev=symrev, revcount=revcount, |
1261 uprev=uprev, | 1283 uprev=uprev, |
1262 lessvars=lessvars, morevars=morevars, downrev=downrev, | 1284 lessvars=lessvars, morevars=morevars, downrev=downrev, |
1285 graphvars=graphvars, | |
1263 rows=rows, | 1286 rows=rows, |
1264 bg_height=bg_height, | 1287 bg_height=bg_height, |
1265 changesets=count, | 1288 changesets=count, |
1289 nextentry=nextentry, | |
1266 jsdata=lambda **x: jsdata(), | 1290 jsdata=lambda **x: jsdata(), |
1267 nodes=lambda **x: nodes(), | 1291 nodes=lambda **x: nodes(), |
1268 node=ctx.hex(), changenav=changenav) | 1292 node=ctx.hex(), changenav=changenav) |
1269 | 1293 |
1270 def _getdoc(e): | 1294 def _getdoc(e): |