Augie Fackler <augie@google.com> [Sun, 19 Feb 2017 20:12:52 -0500] rev 31026
ui: rename neverpager to disablepager
I agree this is a clearer name for this method.
Yuya Nishihara <yuya@tcha.org> [Sun, 19 Feb 2017 20:00:18 +0900] rev 31025
scmutil: proxy revrange() through repo to break import cycles
This was one of the hardest import cycles as scmutil is widely used and
revset functions are likely to depend on a variety of modules.
New repo.anyrevs() does not expand user aliases by default to copy the
behavior of the existing repo.revs(). I don't want to add new function to
localrepository, but this function is quite similar to repo.revs() so it
won't increase the complexity of the localrepository class so much.
Yuya Nishihara <yuya@tcha.org> [Sun, 19 Feb 2017 18:19:33 +0900] rev 31024
revset: split language services to revsetlang module (API)
New revsetlang module hosts parser, tokenizer, and miscellaneous functions
working on parsed tree. It does not include functions for evaluation such as
getset() and match().
2288 mercurial/revset.py
684 mercurial/revsetlang.py
2972 total
get*() functions are aliased since they are common in revset.py.
Yuya Nishihara <yuya@tcha.org> [Sun, 19 Feb 2017 18:16:09 +0900] rev 31023
revset: import set classes directly from smartset module
Follows up
1be65deb3d54.
Yuya Nishihara <yuya@tcha.org> [Sat, 18 Feb 2017 18:00:01 +0900] rev 31022
help: add pointer how to narrow list of resolved/unresolved files (
issue5469)
liscju <piotr.listkiewicz@gmail.com> [Sun, 19 Feb 2017 10:56:08 +0100] rev 31021
shelve: add -n/--name option to unshelve (
issue5475)
This makes using shelve/unshelve more consistent because
shelving can be done using name option and unshelving as
well. Author of the idea of this improvement and solution is
joshgold.
Jun Wu <quark@fb.com> [Sat, 18 Feb 2017 17:23:43 -0800] rev 31020
smartset: use native set operations as fast paths
For set operations like "&" and "-", where we know both basesets have their
sets ready, and the first set is sorted, use the native Python set
operations as a fast path.
Note: "+" is not optimized as that will break the ordering.
This leads to noticeable improvements on performance:
revset | before | after | delta
----------------------------------------------------------------
draft() & draft() & draft() & draft() | 776 | 477 | -39%
draft() + draft() + draft() + draft() | 2849 | 2864 |
draft() - draft() + draft() - draft() | 943 | 240 | -75%
draft() - draft() - draft() - draft() | 557 | 197 | -64%
(time measured in microseconds)
Jun Wu <quark@fb.com> [Sat, 18 Feb 2017 16:30:07 -0800] rev 31019
smartset: add some doctests
Add doctests explaining the set / list behavior. This will make the
following changes more confident.
Jun Wu <quark@fb.com> [Sat, 18 Feb 2017 00:55:20 -0800] rev 31018
obsolete: avoid using revset language to compute the obsolete revset
This is part of a refactoring that moves some phase query optimization from
revset.py to phases.py. See previous patches for the motivation.
Now we have APIs in phasecache to get the non-public set efficiently, let's
use it directly instead of going through the "not public()" revset language
in "obsolete()" computation.
This patch was meaured using:
for i in 'public()' 'not public()' 'draft()' 'not draft()'; do
hg perfrevset "$i"; hg perfrevset "$i" --hidden;
done
and no noticeable (> 1%) performance difference was observed.
Jun Wu <quark@fb.com> [Sat, 18 Feb 2017 00:39:31 -0800] rev 31017
revset: use phasecache.getrevset
This is part of a refactoring that moves some phase query optimization from
revset.py to phases.py. See the previous patch for motivation.
This patch changes revset code to use phasecache.getrevset so it no longer
accesses the private field: _phasecache._phasesets directly.
For performance impact, this patch was tested using the following query, on
my hg-committed repo:
for i in 'public()' 'not public()' 'draft()' 'not draft()'; do
echo $i;
hg perfrevset "$i";
hg perfrevset "$i" --hidden;
done
For the CPython implementation, most operations are unchanged (within
+/- 1%), while "not public()" and "draft()" is noticeably faster on an
unfiltered repo. It may be because the new code avoids a set copy if
filteredrevs is empty.
revset | public() | not public() | draft() | not draft()
hidden | yes | no | yes | no | yes | no | yes | no
------------------------------------------------------------------
before | 19006 | 17352 | 239 | 286 | 180 | 228 | 7690 | 5745
after | 19137 | 17231 | 240 | 207 | 182 | 150 | 7687 | 5658
delta | | -38% | | -52% |
(timed in microseconds)
For the pure Python implementation, some operations are faster while "not
draft()" is noticeably slower:
revset | public() | not public() | draft() | not draft()
hidden | yes | no | yes | no | yes | no | yes | no
------------------------------------------------------------------------
before | 18852 | 17183 | 17758 | 15921 | 17505 | 15973 | 41521 | 39822
after | 18924 | 17380 | 17558 | 14545 | 16727 | 13593 | 48356 | 43992
delta | | -9% | -5% | -15% | +16% | +10%
That may be the different performance characters of generatorset vs.
filteredset. The "not draft()" query could be optimized in this case where
both "public" and "secret" are passed to "getrevsets" so it won't iterate
the whole repo twice.
Jun Wu <quark@fb.com> [Fri, 17 Feb 2017 22:49:05 -0800] rev 31016
phases: add a getrevset method to phasecache
This is part of a refactoring that moves some phase query optimization from
revset.py to phases.py.
The motivation behind this was chg repo preloading - to make the obsstore
depend on less things (like the revset language). The refactoring also looks
good by itself - phasecache does not expose its private field "_phasesets"
via public methods and revset.py is accessing it in a hacky way.
This patch adds a "getrevset" method, which takes multiple phases and
returns a revset in an best-effort efficient way - for "public" phase, it
returns a lazy generatorset; for "draft" and "secret", it returns efficient
"baseset".
Jun Wu <quark@fb.com> [Fri, 17 Feb 2017 20:59:29 -0800] rev 31015
smartset: convert set to list lazily
If the caller only wants to construct a baseset via a set, and then do
"__contains__" tests. It's unnecessary to initialize the list.
Testing on my unfiltered hg-committed repo where len(draft()) is 2600, this
patch shows about 6% improvement on set intensive queries:
Before:
$ for i in `seq 5`; hg perfrevset 'draft() & draft() & draft() & draft()'
! wall 0.001196 comb 0.000000 user 0.000000 sys 0.000000 (best of 2011)
! wall 0.001191 comb 0.000000 user 0.000000 sys 0.000000 (best of 2099)
! wall 0.001186 comb 0.010000 user 0.010000 sys 0.000000 (best of 1953)
! wall 0.001182 comb 0.000000 user 0.000000 sys 0.000000 (best of 2135)
! wall 0.001193 comb 0.000000 user 0.000000 sys 0.000000 (best of 2177)
After:
$ for i in `seq 5`; hg perfrevset 'draft() & draft() & draft() & draft()'
! wall 0.001128 comb 0.000000 user 0.000000 sys 0.000000 (best of 2247)
! wall 0.001119 comb 0.000000 user 0.000000 sys 0.000000 (best of 2317)
! wall 0.001115 comb 0.000000 user 0.000000 sys 0.000000 (best of 2244)
! wall 0.001131 comb 0.000000 user 0.000000 sys 0.000000 (best of 2093)
! wall 0.001124 comb 0.000000 user 0.000000 sys 0.000000 (best of 2134)
It could have bigger impact on larger sets in theory.
Augie Fackler <augie@google.com> [Thu, 16 Feb 2017 11:34:50 -0500] rev 31014
ui: construct _keepalnum list in a python3-friendly way
It'll be more expensive, but it preserves the behavior.
Rodrigo Damazio Bovendorp <rdamazio@google.com> [Mon, 13 Feb 2017 17:03:14 -0800] rev 31013
match: making visitdir() deal with non-recursive entries
Primarily as an optimization to avoid recursing into directories that will
never have a match inside, this classifies each matcher pattern's root as
recursive or non-recursive (erring on the side of keeping it recursive,
which may lead to wasteful directory or manifest walks that yield no matches).
I measured the performance of "rootfilesin" in two repos:
- The Firefox repo with tree manifests, with
"hg files -r . -I rootfilesin:browser".
The browser directory contains about 3K files across 249 subdirectories.
- A specific Google-internal directory which contains 75K files across 19K
subdirectories, with "hg files -r . -I rootfilesin:REDACTED".
I tested with both cold and warm disk caches. Cold cache was produced by
running "sync; echo 3 > /proc/sys/vm/drop_caches". Warm cache was produced
by re-running the same command a few times.
These were the results:
Cold cache Warm cache
Before After Before After
firefox 0m5.1s 0m2.18s 0m0.22s 0m0.14s
google3 dir 2m3.9s 0m1.57s 0m8.12s 0m0.16s
Certain extensions, notably narrowhg, can depend on this for correctness
(not trying to recurse into directories for which it has no information).
Rodrigo Damazio Bovendorp <rdamazio@google.com> [Mon, 13 Feb 2017 15:39:29 -0800] rev 31012
match: adding support for matching files inside a directory
This adds a new "rootfilesin" matcher type which matches files inside a
directory, but not any subdirectories (so it matches non-recursively).
This has the "root" prefix per foozy's plan for other matchers (rootglob,
rootpath, cwdre, etc.).
Jun Wu <quark@fb.com> [Fri, 17 Feb 2017 01:21:15 -0800] rev 31011
runtests: add an IPv6 command line flag
Now we have all IPv6 related issues fixed, add a command line flag so people
could actually run tests with IPv6.