Commit Graph

73 Commits

Author SHA1 Message Date
Pierre-Yves David
a61297246c obsolete: extract encoding of marker for pushkey from the list key function
We now have a function taking a list and marker and returning an encoded
version. This will allow obsolescence marker exchange experimentation to easily
pushkey-encode markers to be pushed after selection.
2014-02-27 20:01:28 -08:00
Pierre-Yves David
d8fd55e6c1 obsstore: add a __len__ method
We can already use "for mark in store:" it make sense to allow
"len(store)" too.
2014-02-25 10:32:54 -08:00
Pierre-Yves David
8ed33f95d4 obsstore: create method return True if a marker is actually added
The obsstore method now have a return value. This informs caller about the
actual creation of a new markers. No new markers are created if it would have
been a duplicate.
2014-02-25 10:21:54 -08:00
Mads Kiilerich
92dc407d90 comments: fix minor spelling issues found with spell checker 2014-02-20 02:39:01 +01:00
Pierre-Yves David
1c8096195c createmarkers: allow to pass metadata for a marker only
The `metadata` argument only allow to specify metadata for all new markers. We
extension the format of the `relations` argument to support optional metadata
argument.

The first user of this should be the evolve extension who want to store parent
information of pruned changeset in extra (until we make a second version of the
format)
2014-02-13 17:34:09 -08:00
Pierre-Yves David
098932cf2d obsstore: update create docstring to point to the coder friendly function
The `obsstore` class have a `create` method that create new obsolescence marker
from node. There is another function in the same module `createmarkers`. This
other function is higher level and automatically missing meta data (ultimately
calling the first one)

We add a new comment in the docstring of `obsstore.create` highlighting that
people writing new code probably want to use the top level one.
2014-02-13 17:33:45 -08:00
Pierre-Yves David
33b568da08 pull: move obsolescence marker exchange in the exchange module
The obsolescence marker exchange code was already extracted during a previous
cycle. We are moving the extracted functio in this module. This function will
read and write data in the `pulloperation` object and I prefer to have all core
function collaborating through this object in the same place.

This changeset is pure code movement only. Code change for direct consumption of
the `pulloperation` object will come later.
2014-01-30 17:38:41 -08:00
Pierre-Yves David
97a8524afb push: move obsolescence marker exchange in the exchange module
The obsolescence marker exchange code was already extracted during a previous
cycle. We are moving the extracted functio in this module. This function will
read and write data in the `pushoperation` object and I prefer to have all core
function collaborating through this object in the same place.

This changeset is pure code movement only. Code change for direct consumption of
the `pushoperation` object will come later.
2014-01-30 17:54:47 -08:00
Sean Farley
ef93a468a7 obsolete: clarify documentation for succcessorssets 2014-01-15 18:14:12 -06:00
Pierre-Yves David
bab0fe5a64 obsolete: order of magnitude speedup in _computebumpedset
Reminder: a changeset is said "bumped" if it tries to obsolete a immutable
          changeset.


The previous algorithm for computing bumped changeset was:

    1) Get all public changesets
    2) Find all they successors
    3) Search for stuff that are eligible for being "bumped"
       (mutable and non obsolete)

The entry size of this algorithm is `O(len(public))` which is mostly the same as
`O(len(repo))`. Even this this approach mean fewer obsolescence marker are
traveled, this is not very scalable.

The new algorithm is:

    1) For each potential bumped changesets (non obsolete mutable)
    2) iterate over precursors
    3) if a precursors is public. changeset is bumped

We travel more obsolescence marker, but the entry size is much smaller since
the amount of potential bumped should remains mostly stable with time `O(1)`.

On some confidential gigantic repo this move bumped computation from 15.19s to
0.46s (×33 speedup…). On "smaller" repo (mercurial, cubicweb's review) no
significant gain were seen. The additional traversal of obsolescence marker is
probably probably counter balance the advantage of it.

Other optimisation could be done in the future (eg: sharing precursors cache
for divergence detection)
2013-12-23 15:29:51 -08:00
Pierre-Yves David
777603b25a obsolete: add an allprecursors method mirroring allsuccessors one.
Detection of bumped changeset should use `allprecursors(<mutable>)` instead or
`allsuccessors(<immutable>)` so we need the all precursors function to exists.
2013-12-23 13:36:13 -08:00
Pierre-Yves David
04de18abd8 obsolete: improve allsuccessors doc string
The fact original nodes are also yield is not obvious. We update the docstring
to highlight it.
2013-12-23 13:33:21 -08:00
Pierre-Yves David
9cb9a199aa obsolete: fix bad comment
We cannot afford such extra "with" they are far too pricy.
2013-12-23 13:32:03 -08:00
Augie Fackler
2f26b47577 obsolete: add __eq__ and __hash__ to marker to make set() deduplication work 2013-11-16 20:12:02 -05:00
Pierre-Yves David
1a1b1b5ce2 obsolete: do not accept duplicated marker during exchange
Before this patch, duplicated obsolescence markers could slip into an
obstore if the bookmark was unknown locally and duplicated in the
incoming obsolescence stream.

Existing duplicate markers will not be automatically removed but
they'll stop propagating. Having a few duplicated markers is harmless
and people have been warned evolution is <blink>experimental</blink>
anyway.
2013-11-16 20:31:58 -05:00
Pierre-Yves David
f1f6dad830 obsolete: stop doing membership test on list
According to the Surgeon General, computer should not use list for membership
testing because of the risk of being slow.
2013-11-16 20:34:58 -05:00
Mads Kiilerich
eabc047878 spelling: random spell checker fixes 2013-10-24 01:49:56 +08:00
Augie Fackler
2ae3ed4f92 Backed out changeset c65cc2c5ce84 2013-08-15 21:36:53 -04:00
Dan Villiom Podlaski Christiansen
3f40ec5e82 obsolete: allow passing a revision to successorssets() 2013-08-04 13:43:39 +02:00
Augie Fackler
10a7abe904 obsolete: clean up a couple of docstrings for correctness 2013-07-26 15:59:16 -04:00
Pierre-Yves David
69d3fb6919 obsolete: extract obsolescence marker pulling into a dedicated function
Having a dedicated function will allow us to experiment with other exchange
strategies in an extension. As we have no solid clues about how to do it right,
being able to experiment is vital.

Some transaction tricks are necessary for pull. But nothing too scary.
2013-04-17 11:47:49 +02:00
Pierre-Yves David
0a4431da48 obsolete: extract obsolescence marker pushing into a dedicated function
Having a dedicated function will allows us to experiment with other exchange
strategies in an extension. As we have no solid clues about how to do it right,
being able to experiment is vital.

I intended a more ambitious extraction of push logic, but we are far too
advanced in the release cycle for it.
2013-04-17 11:18:36 +02:00
Pierre-Yves David
ccfae81adc obsolete: extract foreground computation from bookmark.validdest
This foreground logic will be reused by update logic.
2013-04-16 15:16:33 +02:00
Pierre-Yves David
a256234df3 obsolete: ensure all markers have a date
Obsolescence creates a sparse DAG mostly composed of a lot of small independent
chain of markers. Date is the only simple and "reliable" way to sort them. The
existence of a date is now enforced at creation time as I'm more and more
convinced that date will have a key role in obsolescence markers exchange.
2013-02-11 11:20:12 +01:00
Mads Kiilerich
5787baee50 spelling: fix some minor issues found by spell checker 2013-02-10 18:24:29 +01:00
Mads Kiilerich
f289ae22ed obsolete: process markers in a stable order
Using set iteration order gave unstable debugsuccessorssets output with
PYTHONHASHSEED=random.
2013-01-15 02:59:13 +01:00
Pierre-Yves David
bafe2b5542 performance: speedup computation of extinct revisions
In their current state, revset calls can be very costly, as we test
predicates on the entire repository.

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

Performance test on my Mercurial checkout
- 19857 total changesets,
- 1584 obsolete changesets,
- 13310 obsolescence markers.

Before:
  ! extinct
  ! wall 0.015124

After:
  ! extinct
  ! wall 0.009424

Performance test on a Mozilla central checkout:
- 117293 total changesets,
- 1 obsolete changeset,
- 1 obsolescence marker.

Before:
  ! extinct
  ! wall 0.032844

After:
  ! extinct
  ! wall 0.000066
2013-01-04 03:16:08 +01:00
Pierre-Yves David
6124831a17 performance: speedup computation of suspended revisions
In their current state, revset calls can be very costly, as we test
predicates on the entire repository.

This change drops a revset call in favor of direct testing of the
phase of changesets.

Performance test on my Mercurial checkout
- 19857 total changesets,
- 1584 obsolete changesets,
- 13310 obsolescence markers.

Before:
  ! suspended
  ! wall 0.014319

After:
  ! suspended
  ! wall 0.009559

Performance test on a Mozilla central checkout:
- 117293 total changesets,
- 1 obsolete changeset,
- 1 obsolescence marker.

Before:
  ! suspended
  ! wall 0.033373

After:
  ! suspended
  ! wall 0.000053
2013-01-04 03:15:44 +01:00
Pierre-Yves David
2b70610cfb performance: speedup computation of unstable revisions
In their current state, revset calls can be very costly, as we test
predicates on the entire repository.

This change drops revset call in favor of direct testing of the
phase of changesets.

Performance test on my Mercurial checkout
- 19857 total changesets,
- 1584 obsolete changesets,
- 13310 obsolescence markers.

Before:
  ! unstable
  ! wall 0.017366

After this changes:
  ! unstable
  ! wall 0.008093

Performance test on a Mozilla central checkout:
- 117293 total changesets,
- 1 obsolete changeset,
- 1 obsolescence marker.

Before:
  ! unstable
  ! wall 0.045190

After:
  ! unstable
  ! wall 0.000032
2013-01-04 03:15:21 +01:00
Pierre-Yves David
6f3c5389b0 performance: speedup computation of obsolete revisions
In their current state, revset calls can be very costly as we test
predicates on the entire repository. As obsolete computation is used
by the "hidden" filter, it needs to be very fast.

This changet drops the revset call 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:
  ! obsolete
  ! wall 0.047041

After:
  ! obsolete
  ! wall 0.004590


Performance test on a Mozilla central checkout:

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

Before:
  ! obsolete
  ! wall 0.001539

After:
  ! obsolete
  ! wall 0.000017
2013-01-04 03:14:54 +01:00
Pierre-Yves David
0ea6453a8a clfilter: add a cache on repo for set of revision to filter for a given set.
Recomputing the filtered revisions at every access to changelog is far too
expensive. This changeset introduce a cache for this information. This cache is
hold by the repository (unfiltered repository) and invalidated when necessary.
This cache is not a protected attribute (leading _) because some logic that
invalidate it is not held by the local repo itself.
2012-12-20 17:14:07 +01:00
Pierre-Yves David
5f44f3518f obsolete: detect divergent changesets
Divergent changeset are final successors (non obsolete) of a changeset who
compete with another set of final successors for this same changeset.

For example if you have two obsolescence markers A -> B and A -> C, B and C are
both "divergent" because they compete to be the one true successors of A.

Public revision can't be divergent.

This function is used and tested in the next changeset.
2012-12-12 03:19:30 +01:00
Pierre-Yves David
70d5b32616 obsolete: drop successors sets which are subset of another one
If both "(B,)" and "(B, C)" are successors set of "A", "(B,)" is dropped.
We won't be interrested in detection such divergence scenario.
2012-11-10 01:56:59 +01:00
Pierre-Yves David
da22110fc6 obsolete: compute successors set
Successors set are an important part of obsolescence. It is necessary to detect
and solve divergence situation. This changeset add a core function to compute
them, a debug command to audit them and solid test on the concept.

Check function docstring for details about the concept.
2012-12-13 15:38:43 +01:00
Pierre-Yves David
4abb88cb7f clfilter: unfilter computation of obsolescence related computation
All obsolescence related sets need to be computed on the full unfiltered
version of the repository, in particular because several of them
(obsolete, extinct) are used to compute the hidden revisions.

On a filtered repo, revset predicates related to these sets will be
properly filtered because of revset's own pre-filtering.
2012-10-08 16:55:00 +02:00
Pierre-Yves David
14f39efa9f obsolete: add a flag that allows fixing "bumped" changeset
The first obsolescence flag is introduced to allows for fixing the "bumped"
changeset situation.

    bumpedfix == 1.

Creator of new changesets intended to fix "bumped" situation should not forget
to add this flag to the marker. Otherwise the newly created changeset will be
bumped too. See inlined documentation for details.
2012-10-19 00:41:53 +02:00
Pierre-Yves David
7463f55b32 obsolete: add the detection of bumped changeset.
Bumped changesets are non-public changesets that tries to succeed a public()
changeset.
2012-10-19 00:36:18 +02:00
Pierre-Yves David
19b261d640 obsolete: have allsuccessors takes a list of nodes
Additional logic, used to detect mutable history troubles, will need to quickly
compute successors of a whole set of changeset.
2012-10-16 15:49:58 +02:00
Pierre-Yves David
1d9b00f6af obsolete: rename anysuccessors into allsuccessors
The "any" prefix looks like it returned a boolean. `allsuccessors` is more
accurate.
2012-10-19 00:30:11 +02:00
Pierre-Yves David
bc08c6dbf1 obsolete: rename getobscache into getrevs
The old name was not very good for two reasons:
- caller does not care about "cache",
- set of revision returned may not be obsolete at all.

The new name was suggested by Kevin Bullock.
2012-10-19 00:28:13 +02:00
Pierre-Yves David
2bf3f1f2c0 obsolete: flip obstore.successors and obsolete.precursors
People were confused by the fact `obstore.precursors` contained marker allowing
to find "precursors" and vice-versa.

This changeset changes their meaning to:

- precursors[x] -> set(markers on precursors edges of x)
- successors[x] -> set(markers on successors edges of x)

Some documentation is added to clarify the situation.
2012-10-16 15:39:12 +02:00
Pierre-Yves David
e7bae9b381 obsolete: add example of marker usage in the documentation
Recent discussion with Augie Fackler pointed the lack of such example in the
documentation.
2012-10-14 23:33:10 +02:00
Pierre-Yves David
57d4155cf7 obsolete: cheap detection of nullid as successors
Nullid as successors create multiple issues:

- Nullid revnum is -1, confusing algorithm that use revnum unless you add
  special handling in all of them.
- Nullid confuses "divergent" changeset detection and resolution. As you can't
  add any successors to Nullid without being in even more troubles

Fortunately, there is no good reason to use nullid as a successor. The only
sensible meaning of "succeed by nullid" is "dropped" and this meaning is already
covered by obsolescence marker with empty successors set.

However, letting some nullid successors to slip in may cause terrible damage in
such algorithm difficult to debug. So I prefer to perform and clear detection of
of such pathological changeset. We could be much smarter by cleaning up nullid
successors on the fly but it would be much for expensive. As core Mercurial does
not create any such changeset, I think it is fine to just abort when suspicious
situation is detected.

Earlier experimental version created such changesets, so there are some out
there.  The evolve extension added the necessary logic to clean up its mess.
2012-10-15 00:12:06 +02:00
Bryan O'Sullivan
dc9ede17dc Merge spelling fixes 2012-09-11 08:36:09 -07:00
Pierre-Yves David
de8b13c1de obsolete: add a high level function to create an obsolete marker
This function is designed to be used by all code that creates new
obsolete markers in the local repository.

It is not used by debugobsolete because debugobsolete allows the
use of an unknown hash as argument.
2012-08-24 21:16:23 +02:00
Pierre-Yves David
785d90eba0 obsolete: introduce caches for all meaningful sets
This changeset introduces caches on the `obsstore` that keeps track of sets of
revisions meaningful for obsolescence related logics. For now they are:

- obsolete: changesets used as precursors (and not public),
- extinct:  obsolete changesets with osbolete descendants only,
- unstable: non obsolete changesets with obsolete ancestors.

The cache is accessed using the `getobscache(repo, '<set-name>')` function which
builds the cache on demand. The `clearobscaches(repo)` function takes care of
clearing the caches if any.

Caches are cleared when one of these events happens:

- a new marker is added,
- a new changeset is added,
- some changesets are made public,
- some public changesets are demoted to draft or secret.

Declaration of more sets is made easy because we will have to handle at least
two other "troubles" (latecomer and conflicting).

Caches are now used by revset and changectx. It is usually not much more
expensive to compute the whole set than to check the property of a few elements.
The performance boost is welcome in case we apply obsolescence logic on a lot of
revisions. This makes the feature usable!
2012-08-28 20:52:04 +02:00
timeless@mozdev.org
b770ee27e4 spelling: transaction 2012-08-17 13:58:19 -07:00
timeless@mozdev.org
2632fc55ea spelling: split 2012-08-17 13:58:19 -07:00
Mads Kiilerich
48016eb3fc declare local constants instead of using magic values and comments 2012-08-27 23:16:22 +02:00
Mads Kiilerich
520076e707 delete some dead comments and docstrings 2012-08-21 02:41:20 +02:00