smartlog: migrate some revset calculation to a faster path

Summary:
Detect the "segments" backend and calculate the revset differently.

Practically, with collapse-obsolete disabled, the time of related revset
calculation drops from 0.14s to 0.03s in my fbsource repo.

The `obsolete()` set calculation is expensive (0.4-0.6s) and a bit more
expensive with the new DAG APIs, which will be addressed in upcoming
changes. EDIT: Addressed by D23036063.

Reviewed By: DurhamG

Differential Revision: D23036055

fbshipit-source-id: 71140a88599cc68bfa90d564c786da89b3ebd38b
This commit is contained in:
Jun Wu 2020-08-20 17:33:07 -07:00 committed by Jun Wu
parent 8c9f1f5cee
commit d6bff56df1
2 changed files with 46 additions and 14 deletions

View File

@ -391,6 +391,14 @@ def smartlogrevset(repo, subset, x):
masterset -= smartset.baseset([nodemod.nullrev])
if nodemod.nullrev in heads:
heads.remove(nodemod.nullrev)
cl = repo.changelog
if cl.algorithmbackend == "segments":
heads = cl.tonodes(heads)
master = cl.tonodes(masterset)
nodes = smartlognodes(repo, heads, master)
return subset & smartset.idset(cl.torevs(nodes))
# Explicitly disable revnum deprecation warnings.
with repo.ui.configoverride({("devel", "legacy.revnum:real"): ""}):
# Select ancestors that are draft.
@ -420,6 +428,28 @@ def smartlogrevset(repo, subset, x):
return subset & revs
def smartlognodes(repo, headnodes, masternodes):
"""Calculate nodes based on new DAG abstraction.
This function does not use revs or revsets.
"""
draftnodes = repo.dageval(lambda: ancestors(headnodes) & draft())
nodes = repo.dageval(
lambda: parents(draftnodes) | draftnodes | headnodes | masternodes
)
# Include the ancestor of above commits to make the graph connected.
nodes = repo.dageval(lambda: gcaall(public() & nodes) | nodes)
# Collapse long obsoleted stack - only keep their heads and roots.
# This is incompatible with automation (namely, nuclide-core) yet.
if repo.ui.configbool("smartlog", "collapse-obsolete") and not repo.ui.plain():
obsnodes = repo.dageval(lambda: nodes & obsolete())
hidenodes = repo.dageval(lambda: obsnodes - heads(obsnodes) - roots(obsnodes))
nodes = nodes - hidenodes
return nodes
@revsetpredicate("interestingbookmarks()")
def interestingheads(repo, subset, x):
"""Set of interesting bookmarks (local and remote)"""

View File

@ -3,6 +3,8 @@
$ disable treemanifest
$ enable smartlog
$ readconfig <<EOF
> [format]
> use-segmented-changelog=1
> [experimental]
> graphstyle.grandparent=|
> graphstyle.missing=|
@ -30,7 +32,7 @@ Continue repo setup
$ touch d && hg add d && hg ci -md
$ hg debugmakepublic master
$ hg log -G -T "{node|short} {bookmarks} {desc}"
$ hg log -G -T "{node|short} {bookmarks} {desc}" -r 'sort(:, topo)'
@ db92053d5c83 feature2 d
|
o 38d85b506754 master c2
@ -72,9 +74,9 @@ As a revset
$ hg log -G -T '{node|short} {bookmarks} {desc}' -r 'smartlog()'
@ 05d10250273e feature2 d
|
o 38d85b506754 master c2
|
| o 49cdb4091aca feature1 b
| |
o | 38d85b506754 master c2
|/
o b68836a6e2ca a2
|
@ -82,30 +84,30 @@ As a revset
With --master
$ hg smartlog -T '{node|short} {bookmarks} {desc}' --master 'desc(a2)'
@ 05d10250273e feature2 d
o 49cdb4091aca feature1 b
|
o 38d85b506754 master c2
.
| o 49cdb4091aca feature1 b
| @ 05d10250273e feature2 d
| |
| o 38d85b506754 master c2
|/
o b68836a6e2ca a2
|
Specific revs
$ hg smartlog -T '{node|short} {bookmarks} {desc}' -r 'desc(b)' -r 'desc(c2)'
o 38d85b506754 master c2
.
| o 49cdb4091aca feature1 b
o 49cdb4091aca feature1 b
|
| o 38d85b506754 master c2
|/
o b68836a6e2ca a2
|
$ hg smartlog -T '{node|short} {bookmarks} {desc}' -r 'smartlog()' -r 'desc(a1)'
@ 05d10250273e feature2 d
o 49cdb4091aca feature1 b
|
o 38d85b506754 master c2
.
| o 49cdb4091aca feature1 b
| @ 05d10250273e feature2 d
| |
| o 38d85b506754 master c2
|/
o b68836a6e2ca a2
|