Mercurial > public > mercurial-scm > hg-stable
diff tests/test-fastannotate-protocol.t @ 39238:1ddb296e0dee
fastannotate: initial import from Facebook's hg-experimental
I made as few changes as I could to get the tests to pass, but this
was a bit involved due to some churn in the blame code since someone
last gave fastannotate any TLC.
There's still follow-up work here to rip out support for old versions
of hg and to integrate the protocol with modern standards.
Some performance numbers (all on my 2016 MacBook Pro with a 2.6Ghz i7):
Mercurial mercurial/manifest.py
traditional blame
time: real 1.050 secs (user 0.990+0.000 sys 0.060+0.000)
build cache
time: real 5.900 secs (user 5.720+0.000 sys 0.110+0.000)
fastannotate
time: real 0.120 secs (user 0.100+0.000 sys 0.020+0.000)
Mercurial mercurial/localrepo.py
traditional blame
time: real 3.330 secs (user 3.220+0.000 sys 0.070+0.000)
build cache
time: real 30.610 secs (user 30.190+0.000 sys 0.230+0.000)
fastannotate
time: real 0.180 secs (user 0.160+0.000 sys 0.020+0.000)
mozilla-central dom/ipc/ContentParent.cpp
traditional blame
time: real 7.640 secs (user 7.210+0.000 sys 0.380+0.000)
build cache
time: real 98.650 secs (user 97.000+0.000 sys 0.950+0.000)
fastannotate
time: real 1.580 secs (user 1.340+0.000 sys 0.240+0.000)
mozilla-central dom/base/nsDocument.cpp
traditional blame
time: real 17.110 secs (user 16.490+0.000 sys 0.500+0.000)
build cache
time: real 399.750 secs (user 394.520+0.000 sys 2.610+0.000)
fastannotate
time: real 1.780 secs (user 1.530+0.000 sys 0.240+0.000)
So building the cache is expensive (but might be faster with xdiff
enabled), but the blame results are *way* faster.
Differential Revision: https://phab.mercurial-scm.org/D3994
author | Augie Fackler <augie@google.com> |
---|---|
date | Mon, 30 Jul 2018 22:50:00 -0400 |
parents | |
children | c8a40b33ce30 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-fastannotate-protocol.t Mon Jul 30 22:50:00 2018 -0400 @@ -0,0 +1,216 @@ + $ cat >> $HGRCPATH << EOF + > [ui] + > ssh = $PYTHON "$TESTDIR/dummyssh" + > [extensions] + > fastannotate= + > [fastannotate] + > mainbranch=@ + > EOF + + $ HGMERGE=true; export HGMERGE + +setup the server repo + + $ hg init repo-server + $ cd repo-server + $ cat >> .hg/hgrc << EOF + > [fastannotate] + > server=1 + > EOF + $ for i in 1 2 3 4; do + > echo $i >> a + > hg commit -A -m $i a + > done + $ [ -d .hg/fastannotate ] + [1] + $ hg bookmark @ + $ cd .. + +setup the local repo + + $ hg clone 'ssh://user@dummy/repo-server' repo-local -q + $ cd repo-local + $ cat >> .hg/hgrc << EOF + > [fastannotate] + > client=1 + > clientfetchthreshold=0 + > EOF + $ [ -d .hg/fastannotate ] + [1] + $ hg fastannotate a --debug + running * (glob) + sending hello command + sending between command + remote: * (glob) (?) + remote: capabilities: * (glob) + remote: * (glob) (?) + sending protocaps command + fastannotate: requesting 1 files + sending getannotate command + fastannotate: writing 112 bytes to fastannotate/default/a.l (?) + fastannotate: server returned + fastannotate: writing 112 bytes to fastannotate/default/a.l (?) + fastannotate: writing 94 bytes to fastannotate/default/a.m + fastannotate: a: using fast path (resolved fctx: True) + 0: 1 + 1: 2 + 2: 3 + 3: 4 + +the cache could be reused and no download is necessary + + $ hg fastannotate a --debug + fastannotate: a: using fast path (resolved fctx: True) + 0: 1 + 1: 2 + 2: 3 + 3: 4 + +if the client agrees where the head of the master branch is, no re-download +happens even if the client has more commits + + $ echo 5 >> a + $ hg commit -m 5 + $ hg bookmark -r 3 @ -f + $ hg fastannotate a --debug + 0: 1 + 1: 2 + 2: 3 + 3: 4 + 4: 5 + +if the client has a different "@" (head of the master branch) and "@" is ahead +of the server, the server can detect things are unchanged and does not return +full contents (not that there is no "writing ... to fastannotate"), but the +client can also build things up on its own (causing diverge) + + $ hg bookmark -r 4 @ -f + $ hg fastannotate a --debug + running * (glob) + sending hello command + sending between command + remote: * (glob) (?) + remote: capabilities: * (glob) + remote: * (glob) (?) + sending protocaps command + fastannotate: requesting 1 files + sending getannotate command + fastannotate: server returned + fastannotate: a: 1 new changesets in the main branch + 0: 1 + 1: 2 + 2: 3 + 3: 4 + 4: 5 + +if the client has a different "@" which is behind the server. no download is +necessary + + $ hg fastannotate a --debug --config fastannotate.mainbranch=2 + fastannotate: a: using fast path (resolved fctx: True) + 0: 1 + 1: 2 + 2: 3 + 3: 4 + 4: 5 + +define fastannotate on-disk paths + + $ p1=.hg/fastannotate/default + $ p2=../repo-server/.hg/fastannotate/default + +revert bookmark change so the client is behind the server + + $ hg bookmark -r 2 @ -f + +in the "fctx" mode with the "annotate" command, the client also downloads the +cache. but not in the (default) "fastannotate" mode. + + $ rm $p1/a.l $p1/a.m + $ hg annotate a --debug | grep 'fastannotate: writing' + [1] + $ hg annotate a --config fastannotate.modes=fctx --debug | grep 'fastannotate: writing' | sort + fastannotate: writing 112 bytes to fastannotate/default/a.l + fastannotate: writing 94 bytes to fastannotate/default/a.m + +the fastannotate cache (built server-side, downloaded client-side) in two repos +have the same content (because the client downloads from the server) + + $ diff $p1/a.l $p2/a.l + $ diff $p1/a.m $p2/a.m + +in the "fctx" mode, the client could also build the cache locally + + $ hg annotate a --config fastannotate.modes=fctx --debug --config fastannotate.mainbranch=4 | grep fastannotate + fastannotate: requesting 1 files + fastannotate: server returned + fastannotate: a: 1 new changesets in the main branch + +the server would rebuild broken cache automatically + + $ cp $p2/a.m $p2/a.m.bak + $ echo BROKEN1 > $p1/a.m + $ echo BROKEN2 > $p2/a.m + $ hg fastannotate a --debug | grep 'fastannotate: writing' | sort + fastannotate: writing 112 bytes to fastannotate/default/a.l + fastannotate: writing 94 bytes to fastannotate/default/a.m + $ diff $p1/a.m $p2/a.m + $ diff $p2/a.m $p2/a.m.bak + +use the "debugbuildannotatecache" command to build annotate cache + + $ rm -rf $p1 $p2 + $ hg --cwd ../repo-server debugbuildannotatecache a --debug + fastannotate: a: 4 new changesets in the main branch + $ hg --cwd ../repo-local debugbuildannotatecache a --debug + running * (glob) + sending hello command + sending between command + remote: * (glob) (?) + remote: capabilities: * (glob) + remote: * (glob) (?) + sending protocaps command + fastannotate: requesting 1 files + sending getannotate command + fastannotate: server returned + fastannotate: writing * (glob) + fastannotate: writing * (glob) + $ diff $p1/a.l $p2/a.l + $ diff $p1/a.m $p2/a.m + +with the clientfetchthreshold config option, the client can build up the cache +without downloading from the server + + $ rm -rf $p1 + $ hg fastannotate a --debug --config fastannotate.clientfetchthreshold=10 + fastannotate: a: 3 new changesets in the main branch + 0: 1 + 1: 2 + 2: 3 + 3: 4 + 4: 5 + +if the fastannotate directory is not writable, the fctx mode still works + + $ rm -rf $p1 + $ touch $p1 + $ hg annotate a --debug --traceback --config fastannotate.modes=fctx + fastannotate: a: cache broken and deleted + fastannotate: prefetch failed: * (glob) + fastannotate: a: cache broken and deleted + fastannotate: falling back to the vanilla annotate: * (glob) + 0: 1 + 1: 2 + 2: 3 + 3: 4 + 4: 5 + +with serverbuildondemand=False, the server will not build anything + + $ cat >> ../repo-server/.hg/hgrc <<EOF + > [fastannotate] + > serverbuildondemand=False + > EOF + $ rm -rf $p1 $p2 + $ hg fastannotate a --debug | grep 'fastannotate: writing' + [1]