Commit Graph

59 Commits

Author SHA1 Message Date
Laurent Charignon
71a4d24c5d repoview: add missing newline character in debug prints 2016-01-20 13:40:59 -08:00
Pierre-Yves David
7d5370f77a repoview: bypass changelog method to computed cache key
Getting the data necessary for the cache key using the changelog/revlog method
adds a significant overhead. Given how simple the underlying implementation is
and often this code is ran, it makes sense to violate layering and directly
compute the data.

Testing `hg log` on Mozilla-central, this reduce the time spent on changelog
cache validation by an extra half:

before: 12.2s of 69s
after:   6.1s of 62s

Total speed up from this patch and it's parent is 3x

(With stupid python profiler overhead)

The global speedup without profiler overhead is still there,

Before: 51s
After:  39s (-23%)
2015-12-04 14:22:15 -08:00
Pierre-Yves David
509e099539 repoview: stop recomputing cached key in all case
As explained in the comment, we were computing the key of the cache value every
time because of some obscure MQ test failure. I've dropped that code and ran the
test again that failure is gone. I assume some transaction cleanup got rid of
it.

So we are dropping that code. This provide a significant speedup.

Testing `hg log` on Mozilla-central this reduce the time spent on changelog
cache validation by a third:

before: 19.5s of 80s
after:  12.2s of 69s

(With stupid python profiler overhead)
2015-12-04 14:04:24 -08:00
Gregory Szorc
2e850c30e2 repoview: use absolute_import 2015-08-08 19:58:05 -07:00
Augie Fackler
a5b17bd9d1 cleanup: use __builtins__.any instead of util.any
any() is available in all Python versions we support now.
2015-05-16 14:30:07 -04:00
Matt Mackall
f24fd8ebbe repoview: use try/except/finally 2015-05-15 09:57:44 -05:00
Pierre-Yves David
b838547883 repoview: avoid processing the same rev twice in _getstatichidden
If a rev had multiple children, it would be added to the heap multiple times. We
now ensure it is added only once.
2015-04-03 14:41:18 -07:00
Pierre-Yves David
eca03d6be8 repoview: skip public parent earlier in _getstatichidden
Public changeset have nothing to offer regarding hidden changeset. Lets not add
them to the heap at all.
2015-04-03 14:37:52 -07:00
Pierre-Yves David
93633df1d0 repoview: directly skip public head in _getstatichidden
Public heads have nothing to offer regarding hidden stuff, let's skip them.
2015-04-03 14:36:05 -07:00
Pierre-Yves David
201089f587 repoview: simplify process in _getstatichidden
Since all children are processed before their parents, we can apply the following algorithm:

For each rev (descending order):

* If I'm still hidden, no children will block me,
* If I'm not hidden, I must remove my parent from the hidden set,

This allows us to dynamically change the set of 'hidden' revisions, dropping the
need for the 'actuallyhidden' dictionary and the 'blocked' boolean in the queue.

As before, we start iterating from all heads and stop at the first public
changesets. This ensures the hidden computation is 'O(not public())' instead of
'O(len(min(not public()):))'.
2015-04-03 14:35:53 -07:00
Pierre-Yves David
aa3bc6a909 repoview: use a heap in _getstatichidden
Since we want to process all non-public changesets from top to bottom, a heap
seems more appropriate. This will ensure any revision is processed after all
its children, opening the way to code simplification.
2015-04-03 14:16:50 -07:00
Pierre-Yves David
cdd34568db repoview: update documentation of _getstatichidden
In def1a225fdc4, the function name, role and return was changed. But the
documentation was not. This fixes it.
2015-04-03 13:58:12 -07:00
Durham Goode
e33ea26dd5 repoview: improve compute staticblockers perf
Previously we would compute the repoview's static blockers by finding all the
children of hidden commits that were not hidden.  This was O(number of commits
since first hidden change) since 'children' requires walking every commit from
tip until the first hidden change.

The new algorithm walks all heads down until it sees a public commit. This makes
the computation O(number of draft) commits, which is much faster in large
repositories with a large number of commits and a low number of drafts.

On a large repo with 1000+ obsolete markers and the earliest draft commit around
tip~200000, this improves computehidden perf by 200x (2s to 0.01s).
2015-04-01 12:50:10 -07:00
Matt Mackall
3f5d6ecec7 repoview: invalidate cached changelog if _delayed changes (issue4549)
Starting with b1e85ff3a7fc, when a clone reached the checkout stage,
the cached changelog in the filtered view was still seeing the
_delayed flag, even though the changelog had already been finalized.
2015-03-01 23:20:02 -06:00
Pierre-Yves David
e0712f847d repoview: backout 542a704cdc0f
Monkey patching repoview does not really work and making it really work will
be really hard. So we better have it broken without complexity than broken with
extra complexity.
2014-12-17 12:21:07 -08:00
Matt Harbison
f2d468fb0a repoview: allow methods on the proxy class to be replaced
It doesn't seem to be a common idiom for repo instances, but the status() method
is replaced in largefiles' purge() override.  Since __setattr__ is implemented
in repoview to setattr() on the unfiltered repo, the replacement method wouldn't
get called unless it was invoked with the unfiltered repo, because the filtered
repo remains unchanged.

Since this doesn't seem to be commonly used, I didn't bother to filter out
methods that perhaps shouldn't be replaced, such as changelog().
2014-12-07 10:52:56 -05:00
Pierre-Yves David
8f926bef9a repoview: extract actual hidden cache writing in its own function
This will allow the generation of this cache within the transaction. Relying on
the transaction will reduce the chance of reader seeing bad cache.
2014-11-13 11:11:17 +00:00
David Soria Parra
fdc87e21e5 repoview: remove hiddencache verification
We have been running hiddencache verification since 3.1.1 and so
far not received a bug report concerning it. Therefore we remove
the verification code and make the hiddencache authoritive. That
way we get the intended speedup.
2014-10-06 07:29:40 -07:00
Augie Fackler
f41d193435 merge with stable 2014-09-04 09:59:23 -04:00
Mike Hommey
edf6a59652 repoview: fix typo in repoview.changelog
Incidentally, this avoids the changelog cache being invalidated each time
it's accessed on a repoview.

On a filtering experiment on a repository the size of mozilla-central,
this makes a significant difference:

Before, running hg log -l 10 --time with about 8k changesets filtered out:
time: real 1.490 secs (user 1.450+0.000 sys 0.040+0.000)

After:
time: real 0.540 secs (user 0.530+0.000 sys 0.010+0.000)
2014-08-31 19:43:03 +09:00
Matt Mackall
9bc396577d repoview: fix 0L with pack/unpack for 2.4 2014-08-26 13:11:53 +02:00
Matt Mackall
17ab77f157 repoview: filter tags to non-existent nodes from blockers (issue4328) 2014-08-12 02:40:42 -05:00
Augie Fackler
cceb152b73 repoview: use util.sha1() instead of hashlib.sha1()
6f2e3119e8a1 accidentally broke Python 2.4 compatibility, this fixes it.
2014-08-20 13:21:41 -04:00
Matt Mackall
7a0d67564b repoview: fix try/except/finally for py2.4 2014-08-14 16:39:02 -05:00
David Soria Parra
698eea6e2b repoview: cache hidden changesets
Use the introduced caching infrastructure to cache hidden
changesets. We crosscheck if the content of the cache unless
experimental.verifyhiddencache is set to False. This will be removed
in the future. Without crosschecking the caches speed ups hg status and
other commands:

without caching:
$ time hg status
hg status  0.72s user 0.20s system 100% cpu 0.917 total

with caching
$ time hg status
hg status  0.49s user 0.15s system 100% cpu 0.645 total
2014-08-12 09:39:14 -07:00
David Soria Parra
75f779a75d repoview: add caching bits
Add a caching infrastructure to cache hidden changesets. The cache tries to read
the cache lazily and falls back to recomputing if no wlock can be obtain.
To validate the cache we store a sha of the obstore content and repo heads in
the beginning of the cache which we check every request.
2014-08-12 16:48:54 -07:00
David Soria Parra
c878b027dc repoview: split _gethiddenblockers
Split up _gethiddenblockers into two categories: (1) "static' blockers
that solely rely on the contents of obstore and are visible children of
hidden changsets. (2) "dynamic" blockers, appearing by having wd parents,
bookmarks or tags pointing to hidden changesets.

We assume that (1) doesn't change often and can be easily cached with a good
invalidation strategy. (2) change often, but barely produce blockers, so we
can recompute them if necessary.
2014-08-06 13:26:04 -07:00
David Soria Parra
70d1fce0ac repoview: use set for blockers
Blockers should be unique but tags and bookmarks could point to the same rev,
therefore use a set to ensure that we don't have duplicates.
2014-08-12 16:42:24 -07:00
Pierre-Yves David
05993ab1e8 repoview: make the conversion from node to rev explicit while computing hidden
You cannot use `repo[...]` lookup here. 1. It is slow 2. It is very likely to
trigger a hidden computation itself, entering an infinite loop.
2014-04-13 16:36:51 -04:00
Pierre-Yves David
d9ed66d8f6 repoview: drop duplicated lookup
We are already looking for local tags on the line above. We can safely drop
this extra lookup.
2014-04-13 16:39:31 -04:00
Sean Farley
320875017e repoview: use _gethiddenblockers in computehidden
No functionality has changed, since we've only extracted the code into its own
function. Now extensions can wrap _gethiddenblockers to provide their own
blocker without polluting bookmarks or local tags.
2014-03-28 12:51:05 -05:00
Sean Farley
844f2d5df4 repoview: add _gethiddenblockers method
This is a standalone function that will provide the ability for extensions to
wrap.
2014-04-03 20:07:42 -05:00
Sean Farley
13250b1f33 repoview: improve performance for computehidden (issue4206)
For repos with a large number of heads (including hidden heads), a stale tag
cache would cause computehidden to be drastically slower because of a the call
to repo.tags() (which would build the tag cache).

We actually don't need the tag cache for computehidden because we filter out
global tags. This patch replaces the call to repo.tags with readlocaltags so
as to avoid the tag cache.
2014-03-27 20:14:55 -05:00
Sean Farley
9b0f10caf6 repoview: add non-global tags to candidate list for blocking hidden changesets
Previously, only bookmarks would be considered for blocking a changeset from
being hidden. Now, we also consider non-global tags. This is helpful if we have
local tags that might be hard to find once they are hidden, or tag that are
added by extensions (e.g. hggit or remotebranches).
2014-03-18 20:10:33 -05:00
Mads Kiilerich
92dc407d90 comments: fix minor spelling issues found with spell checker 2014-02-20 02:39:01 +01:00
Augie Fackler
859551f9b1 repoview: use repo.revs() instead of a private revset method
Breaks an import cycle.
2014-02-04 17:13:45 -05:00
Pierre-Yves David
de4bc2f6f8 filter: add a comment so that people do not forget to update subsettable
Changeset aad678a92970 moved `subsettable` from `mercurial/repoview.py` to
`mercurial/branchmap.py`. This mean that `filtertable` and `subsettable` are no
longer next to each other. So we add a comment to remind people to update both.
2013-12-24 17:44:23 -05:00
Augie Fackler
2859ed15ec subsettable: move from repoview to branchmap, the only place it's used
This is a step towards breaking an import cycle between revset and
repoview. Import cycles happened to work in Python 2 with implicit
relative imports, but breaks on Python 3 when we start using explicit
relative imports via 2to3 rewrite rules.
2013-11-06 14:38:34 -05:00
Bryan O'Sullivan
6bdbf1a461 repoview: remove unreachable code
Found using Cython.
2013-04-12 17:18:52 -07:00
Mads Kiilerich
5787baee50 spelling: fix some minor issues found by spell checker 2013-02-10 18:24:29 +01:00
Kevin Bullock
921b868783 bookmarks: don't use bookmarks.listbookmarks in local computations
bookmarks.listbookmarks is for wire-protocol use. The normal way to get
all the bookmarks on a local repository is repo._bookmarks.
2013-01-27 14:24:37 -06:00
Pierre-Yves David
988fc3a302 documentation: update to new filter names
Changeset 7f7f8386b285 change filter names but forgot some documentation
updates.
2013-01-21 19:40:15 +01:00
Pierre-Yves David
d6838f12a9 repoview: cache filtered changelog
Creating a new changelog object for each access is costly and prevents efficient
caching changelog side. This introduced a x5 performance regression in log
because chunk read from disk were never reused. We were jumping from about 100
disk read to about 20 000.

This changeset introduce a simple cache mechanism that help the last changelog
object created by a repoview. The changelog is reused until the changelog or the
filtering changes.

The cache invalidation is much more complicated than it should be. But MQ test
show a strange cache desync. I was unable to track down the source of this
desync in descent time so I'm not sure if the issue is in MQ or core. However
given the proximity to the 2.5 freeze, I'm choosing the inelegant but safe route
that makes the cache mechanism safer.
2013-01-18 23:43:32 +01:00
Pierre-Yves David
f539d0189a repoview: protect base computation from weird phase root
If for some reason the phase roots contains nullid, the set of filtered revs
will contains -1. That confuse Mercurial a lot. In particular this corrupt the
branchcache.

Standard code path does not result in nullid phase root. It can only result from
altered `.hg/store/phaseroots` or buggy extension. However better safe than
sorry.
2013-01-17 17:51:30 +01:00
Kevin Bullock
93f9cb7f25 filtering: rename filters to their antonyms
Now that changelog filtering is in place, it's become evident that
naming the filters according to the set of revs _not_ included in the
filtered changelog is confusing. This is especially evident in the
collaborative branch cache scheme.

This changes the names of the filters to reflect the revs that _are_
included:

  hidden -> visible
  unserved -> served
  mutable -> immutable
  impactable -> base

repoview.filteredrevs is renamed to filterrevs, so that callers read a
bit more sensibly, e.g.:

  filterrevs('visible') # filter revs according to what's visible
2013-01-13 01:39:16 -06:00
Pierre-Yves David
bf6aa861ef repoview: extract hideable revision computation in a dedicated function
This will help extensions to plug into the hidden mechanism.
2013-01-10 10:25:02 +01:00
Pierre-Yves David
1974a3ac5d performance: speedup computation of mutable revisions
In their current state, revset calls can be very costly, as we test
predicates on the entire repository. The "mutable" filter is used
during branch cache loading operation. We need to make it fast.

This change drops revset calls in favor of direct testing of the
phase of a changeset.

Performance test on my Mercurial checkout
- 19857 total changesets,
- 1646 mutable revision

Before:
  ! mutable
  ! wall 0.032405

After:
  ! mutable
  ! wall 0.001469

Performance test on a Mozilla central checkout:
- 117293 total changesets,
- 1 mutable changeset,

Before:
  ! mutable
  ! wall 0.188636

After:
  ! mutable
  ! wall 0.000022
2013-01-07 15:50:25 +01:00
Pierre-Yves David
fcce734523 performance: speedup computation of unserved revisions
In their current state, revset calls can be very costly, as we test
predicates on the entire repository. The "unserved" filter is used
in multiple applications, and in particular in some branch cache
loading operations. We need to make it fast.

This change drops revset calls in favor of direct testing of the
phase of a changeset.

Performance test on my Mercurial checkout

- 19857 total changesets,
- 1584 obsolete changesets,
- 13310 obsolescence markers.

Before:
  ! unserved
  ! wall 0.030477

After:
  ! unserved
  ! wall 0.011844

Performance test on a Mozilla central checkout:

- 117293 total changesets,
- 1 obsolete changeset,
- 1 obsolescence marker.

Before:
  ! unserved
  ! wall 0.111259

After:
  ! unserved
  ! wall 0.000084
2013-01-04 20:19:05 +01:00
Pierre-Yves David
48ff92e0ee performance: speedup computation of hidden revisions
In their current state, revset calls can be very costlys, as we
test predicates on the entire repository. The hidden filter is very
widely used, and needs to be very fast.

This change drops revset calls in favor of direct revision manipulation.

Performance test on my Mercurial checkout

- 19857 total changesets,
- 1584 obsolete changesets,
- 13310 obsolescence markers.

Before:
 ! hidden
 ! wall 0.077553

After this changes:
  ! hidden
  ! wall 0.011230

Performance test on a Mozilla central checkout:

- 117293 total changesets,
- 1 obsolete changeset,
- 1 obsolescence marker.

Before:
  ! hidden
  ! wall 0.389472

After:
  ! hidden
  ! wall 0.000079
2013-01-04 05:44:01 +01:00
Pierre-Yves David
f3980b618d hidden: use both parents of working directory
If we are merging with and extinct revision, this extinct revision should not be
hidden.
2013-01-08 17:31:00 +01:00