Commit Graph

67 Commits

Author SHA1 Message Date
Augie Fackler
87aee9cbf5 repoview: specify setattr values as native strings 2017-03-12 00:48:06 -05:00
Pulkit Goyal
970d2f2cc3 repoview: convert attribute names to unicodes on Python 3
In Python 3, the attribute names must be strings i.e. unicodes.
2017-03-08 00:49:15 +05:30
Stanislau Hlebik
2dc1cd49f3 repoview: separate cache hash computation from cache reading
This change will make it easier for extensions to use another cache hash.
2017-02-20 01:54:07 -08:00
Augie Fackler
ad67b99d20 cleanup: replace uses of util.(md5|sha1|sha256|sha512) with hashlib.\1
All versions of Python we support or hope to support make the hash
functions available in the same way under the same name, so we may as
well drop the util forwards.
2016-06-10 00:12:33 -04:00
Matt Mackall
a684f1361f repoview: ignore unwritable hidden cache
The atomictemp.close() file attempts to do a rename, which can fail.
Moving the close inside the exception handler fixes it.

This doesn't fit well with the with: pattern, as it's the finalizer
that's failing.
2016-04-28 16:26:18 -05:00
Pierre-Yves David
4ceff995cf hideablerevs: expand docstring to warn about possible traps
Sean Farley just wasted multiple hours trying to figure out why his code was
crashing. We update the docstring to make the constraint clearer.
2016-04-02 15:56:47 -07:00
FUJIWARA Katsunori
4bd619a29e repoview: discard filtered changelog if index isn't shared with unfiltered
Before this patch, revisions rollbacked at failure of previous
transaction might be visible at subsequent operations unintentionally,
if repoview object is reused even after failure of transaction:
e.g. command server and HTTP server are typical cases.

'repoview' uses the tuple of values below of unfiltered changelog as
"the key" to examine validity of filtered changelog cache.

     - length
     - tip node
     - filtered revisions (as hashed value)
     - '_delayed' field

'repoview' compares between "the key" of unfiltered changelog at
previous caching and now, and reuses filtered changelog cache if no
change is detected.

But this comparison indicates only that there is no change between
unfiltered 'repo.changelog' at last caching and now, but not that
filtered changelog cache is valid for current unfiltered one.

'repoview' uses "shallow copy" of unfiltered changelog to create
filtered changelog cache. In this case, 'index' buffer of unfiltered
changelog is also referred by filtered changelog.

At failure of transaction, unfiltered changelog itself is invalidated
(= un-referred) on the 'repo' side (see b7829fc79508 also). But
'index' of it still contains revisions to be rollbacked at this
failure, and is referred by filtered changelog.

Therefore, even if there is no change between unfiltered
'repo.changelog' at last caching and now, steps below makes rollbacked
revisions visible via filtered changelog unintentionally.

  1. instantiate unfiltered changelog as 'repo.changelog'
     (call it CL1)

  2. make filtered (= shallow copy of) CL1
     (call it FCL1)

  3. cache FCL1 with "the key" of CL1

  4. revisions are appended to 'index', which is shared by CL1 and FCL1

  5. invalidate 'repo.changelog' (= CL1) at failure of transaction

  6. instantiate 'repo.changelog' again at next operation
     (call it CL2)

     CL2 doesn't have revisions added at (4), because it is
     instantiated from '00changelog.i', which isn't changed while
     failed transaction.

  7. compare between "the key" of CL1 and CL2

  8. FCL1 cached at (3) is reused, because comparison at (7) doesn't
     detect change between CL1 at (1) and CL2

  9. revisions rollbacked at (5) are visible via FCL1 unintentionally,
     because FCL1 still refers 'index' changed at (4)

The root cause of this issue is that there is no examination about
validity of filtered changelog cache against current unfiltered one.

This patch discards filtered changelog cache, if its 'index' object
isn't shared with unfiltered one.

BTW, at the time of this patch, redundant truncation of
'00changelog.i' at failure of transaction (see b7829fc79508 for
detail) often prevents "hg serve" from making already rollbacked
revisions visible, because updating timestamps of '00changelog.i' by
truncation makes "hg serve" discard old repoview object with invalid
filtered changelog cache.

This is reason why this issue is overlooked before this patch, even
though test-bundle2-exchange.t has tests in similar situation: failure
of "hg push" via HTTP by pretxnclose hook on server side doesn't
prevent subsequent commands from looking up outgoing revisions
correctly.

But timestamp on the filesystem doesn't have enough resolution for
recent computation power, and it can't be assumed that this avoidance
always works as expected.

Therefore, without this patch, this issue might appear occasionally.
2016-02-24 06:10:46 +09:00
Laurent Charignon
7dcb9bf272 repoview: fix corrupted hiddencache crash Mercurial (issue5042)
Before this patch if the hiddencache existed but was empty, it would crash
mercurial. This patch adds exception handling when reading the hiddencache to
avoid the issue.
When encountering a corrupted cache file we print a devel warning. There would
be no point in issuing a normal warning as the user wouldn't be able to do
anything about the situation.

The warning looks like:

devel-warn: corrupted hidden cache, removing it at: /path/to/repoview.py
2016-01-20 13:43:01 -08:00
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