Commit Graph

378 Commits

Author SHA1 Message Date
Jun Wu
a5a396027d dag: expose API to lookup children by parent
Summary: This will be used to optimize "children(single vertex)" query.

Reviewed By: sfilipco

Differential Revision: D23196409

fbshipit-source-id: 050c0859faf83b909e3174bb7c7bd6e7725165c0
2020-08-26 15:32:23 -07:00
Jun Wu
bad2ae41ef dag: maintain non-master parent-child indexes
Summary:
Update the parent index to store non-master group too. To make
"remove_non_master" work, the index contains a "child group" prefix that
allows efficient range invalidation.

This will allow answering "children(single vertex)" query more efficiently.

This diff does not expose an API to query the index yet.

Reviewed By: sfilipco

Differential Revision: D23196406

fbshipit-source-id: 9137da5ffa8306bdafbcabc06b6f0d23f38dcf57
2020-08-26 15:32:23 -07:00
Jun Wu
6c468b7ac0 dag: add benchmark about children(1 id)
Summary:
Practically, the input of `children` is often one vertex instead of a large set.
Add a benchmark for it.

It looks like:

  children (spans)                                  606.076 ms
  children (1 id)                                   124.105 ms

Reviewed By: sfilipco

Differential Revision: D23196407

fbshipit-source-id: 0645b59ac846836fd061386384f6386a57661741
2020-08-26 15:32:23 -07:00
Jun Wu
6f3616a2b8 nameset: make dag and idmap immutable in hints
Summary: They can be figured out at Hints initialization time. So they don't need to be mutable.

Reviewed By: sfilipco

Differential Revision: D23182518

fbshipit-source-id: 133375fdf27a2546a50b63fb130534acdadc5938
2020-08-26 15:32:22 -07:00
Jun Wu
682365f14d nameset: make Id{Static,Lazy}Set require Dag on construction
Summary:
Both IdSet and IdLazy set require both Dag and IdMap to construct.
This is step 1 torwards making Dag and IdMap immutable in hints.

A misspeall of "lhs" vs "hints" in the union set is discovered by the change
and fixed.

Reviewed By: sfilipco

Differential Revision: D23182520

fbshipit-source-id: 3d052de4b8681d3672ebc45d953d1e784f64b2a4
2020-08-26 15:32:22 -07:00
Jun Wu
3ba655abf3 dag: add DummyDag for testing
Summary:
It will be used in places (ex. tests) where a Dag is required but constructing
a real Dag is troublesome.

Reviewed By: sfilipco

Differential Revision: D23182517

fbshipit-source-id: 736911365778e5071c1e0b9615090a4e960392a0
2020-08-26 15:32:22 -07:00
Jun Wu
bd7769b34a dag: rename snapshot_dag to dag_snapshot
Summary: This is more consistent with `id_map_snapshot`.

Reviewed By: sfilipco

Differential Revision: D23182519

fbshipit-source-id: 62b7fc8bfdc9d6b3a4639a6518ea084c7f3807dd
2020-08-26 15:32:22 -07:00
Jun Wu
4d798c39d9 dag: add new range algorithm
Summary:
Similar to descendants, the new range algorithm avoids potentially expensive
checks about whether high-level segments can be used or not. Practically this
is overall an improvement.

`cargo bench --bench dag_ops -- range`:

Before:

  range (2 ids)                                     115.380 ms
  range (spans)                                     243.666 ms

After:

  range (2 ids)                                     123.274 ms
  range (spans)                                      23.101 ms

It is 100x faster with the range x::y benchmark added later on `git.git`.

Reviewed By: sfilipco

Differential Revision: D23106175

fbshipit-source-id: 691e0418ba2b7ad9f52ac15b5cd6088ec28d5f48
2020-08-26 15:32:22 -07:00
Jun Wu
c2e03b9129 dag: add new descendants algorithm
Summary:
The old algorithm tries to make use high-level segments.
However, the code to test whether a high-level segment can be used is
often too expensive for the benefit. Often, high-level segments cannot
be used most of the time and it's similar to O(flat segments).

This diff adds a simpler algorithm that just iterates through the flat
segments. It's faster in most practical cases.

`cargo bench --bench dag_ops -- descendants` shows improvements too:

Before:

  descendants (small subset)                        436.515 ms

After:

  descendants (small subset)                         33.460 ms

Reviewed By: sfilipco

Differential Revision: D23106174

fbshipit-source-id: e6101483d8539b2b1c881be2ccfd0071f122352f
2020-08-26 15:32:22 -07:00
Jun Wu
e22b816a12 dag: add iddag.iter_segments_ascending API
Summary: This will be used by upcoming changes.

Reviewed By: sfilipco

Differential Revision: D23106177

fbshipit-source-id: 9bf183f7464c06b801be64fd938db0babd544756
2020-08-26 15:32:21 -07:00
Jun Wu
0dcf08e509 dag: add SpanSetAsc struct
Summary: This internal struct will be used by upcoming changes.

Reviewed By: sfilipco

Differential Revision: D23106172

fbshipit-source-id: 6d5b9bc1c810984814d0912100acca38a2565a63
2020-08-26 15:32:21 -07:00
Jun Wu
d7cbb641ff dag: fix fuzz tests
Summary:
The fuzz tests need `TestContext::id_dag()`, which was removed by D20471712 (1fb5acf242).
Restore it so fuzz tests can run. This is mainly to check the new `range`
function.

The `range` fuzz test does find an issue caused by `>` written as `>=`
relatively quickly.

Reviewed By: sfilipco

Differential Revision: D23106176

fbshipit-source-id: e9540cc932503a9d54246d24c70bac829fcb13df
2020-08-21 13:00:45 -07:00
Jun Wu
e5527715b7 gitdag: crate to build segmented dag from git history
Summary:
Read git commit graph and migrate them to `dag::Dag`.

This allows using Rust dag abstractions on the git
commit graph.

Reviewed By: DurhamG

Differential Revision: D23095471

fbshipit-source-id: 2163701350ce82ce6e97074e56ad5877f3c9c158
2020-08-21 13:00:45 -07:00
Jun Wu
be2d28fb95 dag: fix non-master high-level segments building
Summary:
If there is no new master segments, it's still possible to have new non-master
segments. Fix the loop condition so we don't skip building non-master segments.

Reviewed By: sfilipco

Differential Revision: D23095465

fbshipit-source-id: 46eb9d5b5f2b04241981558646e0bc090652abce
2020-08-21 13:00:45 -07:00
Jun Wu
e11f36e96b dag: test high-level segments building for non-master
Summary:
I noticed that high-level segments are somehow not built for non-master vertexes.
Add a test to demonstrate the issue.

Reviewed By: DurhamG, sfilipco

Differential Revision: D23095466

fbshipit-source-id: c5a6da14bdfabcf7c432f6c6dfe096c71cc10ee9
2020-08-21 13:00:45 -07:00
Jun Wu
23074edd9b dag: add some tracing spans
Summary: This is useful to investigate internals of dag calculations.

Reviewed By: sfilipco

Differential Revision: D23095473

fbshipit-source-id: 4750c1b4ffad32b1317051d17db9659aaaed59c4
2020-08-21 13:00:45 -07:00
Jun Wu
cd9aa9cb6c dag: improve segment building perf by using precalculated flat segments
Summary:
Follow up of the previous change by actually using the flat segments to build
segments. This significantly improved the perf. `cargo bench --bench dag_ops`
shows:

  building segments (old)                           774.109 ms
  building segments (new)                           143.879 ms

Besides, a `O(N^2)` update to `head_ids` is changed. It improves performance
when the graph has many heads (ex. the mutation graph).

Reviewed By: sfilipco

Differential Revision: D23036080

fbshipit-source-id: 033565700f253c6f20e30a00adb6b579921d6679
2020-08-21 13:00:45 -07:00
Jun Wu
9c9ecbc82b dag: make IdMap::assign_head calculate flat segments
Summary:
While testing the `obsolete()` set, I found an in-memory segmented DAG takes
10x time to build than a HashMap DAG.

Part of the inefficiency is to use a translated "parent_func" that round-trips
through Id and Vertex, used by segment building logic. This diff makes
`IdMap::assign_head` return flat segments, so we don't need a translated
"parent_func" to build flat segments.

This diff only adds checks to make sure the parent_func (Id version) matches
the segments. The next diff switches the segment building to not use the
translated parent_func.

Reviewed By: sfilipco

Differential Revision: D23036060

fbshipit-source-id: 99137f4b5be455cdf43218ba23eb3954b6d9e05a
2020-08-21 13:00:45 -07:00
Jun Wu
0742dc6293 dag: make to_set API bind the dag
Summary:
This affects the `tonodes` API in the Python world. Practically this will bind
the main commit graph to sets like draft, public.

The `ToSet` requirement on `DagAlgorithm` has to be removed to avoid stack
overflow of rustc resolving constraints.

Reviewed By: sfilipco

Differential Revision: D23036077

fbshipit-source-id: 912b924e29611680ab6b2ee4dbcd7ab39824409a
2020-08-21 13:00:45 -07:00
Jun Wu
adf027742e nameset: add flatten API
Summary: This will be useful for the `obsolete()` set.

Reviewed By: sfilipco

Differential Revision: D23036072

fbshipit-source-id: 2f944ef31cf19f902622d90545fa02b7dda89221
2020-08-21 13:00:45 -07:00
Jun Wu
f23b1112f0 nameset: a & b should not use id-based fast path if id map is incompatible
Summary:
If two sets have different IdMap, their Ids cannot be compared directly
for correctness.

Reviewed By: sfilipco

Differential Revision: D23036068

fbshipit-source-id: e800e8273b95c1f8174236e0f30445db7fd44556
2020-08-21 13:00:45 -07:00
Jun Wu
c1e596dbd6 nameset: use real id map snapshot instead of a pointer in hints
Summary: This is similar to the previous change. This allows "binding" IdMaps to sets.

Reviewed By: sfilipco

Differential Revision: D23036058

fbshipit-source-id: ec1b1ec73e949ad4865aecf17bfcc5c1ca723e0d
2020-08-21 13:00:45 -07:00
Jun Wu
0ac5f05097 nameset: use real dag snapshot instead of a pointer in hints
Summary:
This trades a bit performance (calculating the snapshot) for correctness (no
pointer reuse issues) and convenience (set captures dag information with them
and enables use-cases like converting NameSet from another dag to the
current dag without requiring extra `dag` objects).

Reviewed By: sfilipco

Differential Revision: D23036067

fbshipit-source-id: 2e691f09ad401ba79dbc635e908d79e54dadca5e
2020-08-21 13:00:45 -07:00
Jun Wu
759ceb6212 nameset: do not swap x & y if they come from different graphs
Summary:
If `x` and `y` come from a same graph, `x & y` is more efficient than
`y & x` if `y` is larger. However, if `x` and `y` are from different
graphs, the `FULL` hint can no longer accurately predict which one
is larger. Therefore the swap should be avoided.

Reviewed By: sfilipco

Differential Revision: D23036081

fbshipit-source-id: fe3970fc38c853b36689bfd0ee1dec20643ace78
2020-08-21 13:00:45 -07:00
Jun Wu
762603455a nameset: new metaset for separate iter+contains lazy/fast paths
Summary:
For sets like `obsolete()`, `merge()`, they could have a fast "contains" path:
Just check the given commit without calculating a full set. It's also possible
to have a relatively efficient code path to return StaticSet (for obsolete()),
or IdStaticSet (for merge(), by checking flat segments). This diff adds a
`MetaSet` that allows defining two fast paths separately.

This will be used for the `obsolete()` set in upcoming changes.

Reviewed By: sfilipco

Differential Revision: D23036059

fbshipit-source-id: 06e6f90e7e9511626a12cfa729c306ff539256d2
2020-08-21 13:00:45 -07:00
Jun Wu
7d8f4ef92f dag: fix re-assigning master flush
Summary:
Before this change, `flush` with empty changes but `master` moves will cause an
error, because the `parents_func` only contains "pending changes", aka. new
vertexes. The `parents_func` does not know `master` and `master` is needed to
re-assign them from the non-master to the master group.

With the snapshot API, things become easier. We just take a snapshot before
reloading, and use the snapshot to answer parent_names.

Reviewed By: sfilipco

Differential Revision: D22970569

fbshipit-source-id: 99a25857ba98792edff69985c16df118a560ffb0
2020-08-21 13:00:45 -07:00
Jun Wu
f666cb1cf0 dag: add DagAlgorithm::snapshot_dag
Summary:
This API allows the underlying Dag to provide a snapshot. The snapshot can then
be used in places that do not want a lifetime (ex. NameSet).

Reviewed By: sfilipco

Differential Revision: D22970579

fbshipit-source-id: ededff82009fd5b4583f871eef084ec907b45d33
2020-08-21 13:00:45 -07:00
Jun Wu
b8e7828edd dag: add NameDag::snapshot_dag
Summary:
Make it possible to snapshot a Dag. This is useful for cases where another
struct wants access to the Dag without lifetimes. Namely, the LazySet can
might want to keep a snapshot of Dag.

Reviewed By: sfilipco

Differential Revision: D22970568

fbshipit-source-id: 508c38d3ffac2ffcd2e682578c3c5e5787ea3bcf
2020-08-21 13:00:45 -07:00
Jun Wu
741d050f10 dag: drop inverse DAG
Summary:
The only intended use of the inverse DAG is to implement the Python dag
interface in `dagutil.py`. D22519589 (2d4d44cf3d) stack changed it so the Python dag
interface becomes optional. Therefore there is no need to keep the inverse DAG
interface, which is a bit tricky on sorting.

Reviewed By: sfilipco

Differential Revision: D22970581

fbshipit-source-id: 58a126b41d992e75beaf76ece25cb578ee84760b
2020-08-21 13:00:45 -07:00
Jun Wu
6b64f9a2bf dag: add import_and_flush API
Summary:
This allows importing from other DAGs. It will be used to import revlog DAG to
the new segmented format.

Reviewed By: sfilipco

Differential Revision: D22970572

fbshipit-source-id: 0a183e7b64831574cc9c60d4639124d02d19cf43
2020-08-21 13:00:45 -07:00
Jun Wu
c448e0f575 renderdag: move to dag
Summary:
This allows dag to use renderdag in tests to verify graph result. Previously
it was hard because dag <-> renderdag would form circular dependency.

It also make it possible to implement more efficient and integrated fast paths
for graph rendering.

Reviewed By: sfilipco

Differential Revision: D22970570

fbshipit-source-id: 526497339bd7aa8898d1af4aa9cf6d2a6797aae0
2020-08-21 13:00:45 -07:00
Jun Wu
6fd7a2e582 dag: use concrete error types
Summary:
This is more complex than previous libraries, mainly because `dag` defines APIs
(traits) used by other code, which might raise error type not interested
by `dag` itself. `BackendError::Other(anyhow::Error)` is currently used to
capture types that do not fit in `dag`'s predefined error types.

Reviewed By: sfilipco

Differential Revision: D22883865

fbshipit-source-id: 3699e14775f335620eec28faa9a05c3cc750e1d1
2020-08-06 12:31:57 -07:00
Jun Wu
ff9c979b07 revlogindex: use concrete error types
Summary:
All dependencies of revlogindex have migrated to concreted error types.
Let's migrate revlogindex itself. This allows compile-time type checks
and makes the error returned by revlogindex APIs more predictable.

Reviewed By: sfilipco

Differential Revision: D22857554

fbshipit-source-id: 7d32599508ad682c6e9c827d4599e6ed0769899c
2020-08-06 12:31:57 -07:00
generatedunixname89002005287564
070b9abf48 Daily arc lint --take RUSTFMT
Reviewed By: zertosh

Differential Revision: D22862880

fbshipit-source-id: cc2a30bb5345ffae1a117bb6220d6c2f4d9f73ba
2020-07-31 04:28:59 -07:00
Jun Wu
5f3f7e49d6 dag: add reachable_roots API
Summary:
I thought it was just `roots & (::heads)`. It is actually more complex than
that.

Reviewed By: sfilipco

Differential Revision: D22657201

fbshipit-source-id: bd0b49fc4cdd2c516384cf70c1c5f79af4da1342
2020-07-30 20:32:37 -07:00
Jun Wu
a2b44103bd dag: add fast path for IdLazySet::contains
Summary:
No need to exhaust the entire IdLazySet if there are hints.
This is important to make `small & lazy` fast.

Reviewed By: sfilipco

Differential Revision: D22638462

fbshipit-source-id: 63a71986e6e254769c42eb6250c042ea6aa5808b
2020-07-30 20:32:32 -07:00
Jun Wu
e3059699ee dag: cross-DAG set operations should use FULL and ANCESTORS hint carefully
Summary:
When multiple DAGs (ex. a local DAG and a commit-cloud DAG) are involved,
certain fast paths become unsound. Namely, the fast paths of the FULL hint
should check DAG compatibility. For example:

  localrepodag.all() & remotedag.all()

should not simply return `localrepodag.all()` or `remotedag.all()`.

Fix it by checking DAG pointers.

A StaticSet might be created without using a DAG, add an optimization
to change `all & static` to `static & all`. So StaticSet without DAG
wouldn't require full DAG scans when intersecting with other sets.

Reviewed By: sfilipco

Differential Revision: D22638454

fbshipit-source-id: 72396417e9c1238d5411829da8f16f2c6d4c2f3a
2020-07-30 20:32:32 -07:00
Jun Wu
34de6956f6 dag: improve fmt::Debug on sets
Summary:
Improve `fmt::Debug` so it fits better in the Rust and Python eco-system:
- Support Rust formatter flags. For example `{:#5.3?}`. `5` defines limit of a
  large set to show, `3` defines hex commit hash length. `#` specifies the
  alternate form.
- Show commit hashes together with integer Ids for IdStaticSet.
- Use HG rev range syntax (`a:b`) to represent ranges for IdStaticSet.
- Limit spans to show for IdStaticSet, similar to StaticSet.
- Show only 8 chars of a long hex commit hash by default.
- Minor renames like `dag` -> `spans`, `difference` -> `diff`.

Python bindings uses `fmt::Debug` as `__repr__` and will be affected.

Reviewed By: sfilipco

Differential Revision: D22638455

fbshipit-source-id: 957784fec9c99c8fc5600b040d964ce5918e1bb4
2020-07-30 20:32:31 -07:00
Jun Wu
7c2dffb955 revlogindex: optimize set intersection with hints
Summary:
This makes intersection set stop early. It's useful to stop iteration on some
lazy sets. For example, the below `ancestors(tip) & span` or
`descendants(1) & span` sets can take seconds to calculate without this
optimization.

```
In [1]: cl.dag.ancestors([cl.tip()]) & cl.tonodes(bindings.dag.spans.unsaferange(len(cl)-10,len(cl)))
Out[1]: <and <lazy-id> <dag [...]>>

In [3]: %time len(cl.dag.ancestors([cl.tip()]) & cl.tonodes(bindings.dag.spans.unsaferange(len(cl)-10,len(cl))))
CPU times: user 364 µs, sys: 0 ns, total: 364 µs
Wall time: 362 µs

In [7]: %time len(cl.dag.descendants([repo[1].node()]) & cl.tonodes(bindings.dag.spans.unsaferange(0,100)))
CPU times: user 0 ns, sys: 574 µs, total: 574 µs
Wall time: 583 µs
```

Reviewed By: sfilipco

Differential Revision: D22638458

fbshipit-source-id: b9064ce2ff1aecc2d7d00025928dfcb3c0d78e0c
2020-07-30 20:32:31 -07:00
Jun Wu
a02c93864f dag: add ANCESTORS hint
Summary:
The hint indicates a set `X` is equivalent to `ancestors(X)`.

This allows us to make `heads` use `heads_ancestors` (which is faster in
segmented changelog) automatically without affecting correctness. It also
makes special queries like `ancestors(all())` super cheap because it'll just
return `all()` as-is.

Reviewed By: sfilipco

Differential Revision: D22638463

fbshipit-source-id: 44d9bbcbb0d7e2975a0c8322181c88daa1ba4e37
2020-07-30 20:32:30 -07:00
Jun Wu
a0c5b1b3a5 revlogindex: is_ancestor(x, x) should return true
Summary: This is discovered by using it in Python world.

Reviewed By: sfilipco

Differential Revision: D22323186

fbshipit-source-id: 295811e0950b94ad2ad73ad242228b6a3f9765d0
2020-07-06 15:50:59 -07:00
Jun Wu
cf1bc37007 dag: avoid using > 2 parents in generic DAG tests
Summary: Some DAG implementations does not support it.

Reviewed By: sfilipco

Differential Revision: D22249158

fbshipit-source-id: ebcdf164677ee647ef44aa1ee3cfd318bac658b0
2020-07-06 15:50:59 -07:00
Jun Wu
9a17be7ce0 dag: do not test the order of vertexes in generic tests
Summary:
Different implementation might return different orders. They should be
considered correct.

Reviewed By: sfilipco

Differential Revision: D22249159

fbshipit-source-id: 36e4cadf814366f7ee2ed8a778948ff810760550
2020-07-06 15:50:58 -07:00
Jun Wu
f24dc621cb dag: make part of the tests generic
Summary: This makes it possible to run tests for other DAGs, like the revlog.

Reviewed By: sfilipco

Differential Revision: D22249155

fbshipit-source-id: 205579eeaccd42a21297d965973957168bb8726e
2020-07-06 15:50:58 -07:00
Jun Wu
2bc4dd01ca dag: add a trait to convert IdSet to Set
Summary:
The reverse `to_id_set` exists.
It turns out that the Python land wants this in many places.

Reviewed By: sfilipco

Differential Revision: D22240175

fbshipit-source-id: b6a3a3a3869dc0c521a21b1d86394421b816632b
2020-07-06 15:50:58 -07:00
Jun Wu
07b3d60f80 dag: add "only(x, y)" to DagAlgorithm
Summary:
This provides a way for implementations to optimize the operation.

For segmented changelog, the default implementation is good enough.

For revlog, `only` can have a fast path that does not iterate through the
entire changelog.

A related API `only_both` is added. For revlog it has multiple use-cases,
including narrow-heads phase calculation and revlog.findcommonmissing used by
discovery.

Reviewed By: markbt

Differential Revision: D21944132

fbshipit-source-id: d11660dae85ea6158977eb00d1ceaceddf1d8234
2020-07-06 15:50:57 -07:00
Jun Wu
d745424bf9 dag: add a utility to help break cycles
Summary:
This makes it easier to remove cycles in other places.

There are probably fancier and more efficient algorithm for this.
For now I just wrote one that is easy to verify correctness.

Reviewed By: markbt

Differential Revision: D22174975

fbshipit-source-id: 8a2dc755e4bc0b066eda5f42a51208c92409f2f9
2020-07-02 13:22:34 -07:00
Jun Wu
234147239a dag: add ToIdSet trait
Summary: The trait converts NameSet to IdSet. It'll be used by the revlog index.

Reviewed By: sfilipco

Differential Revision: D21795869

fbshipit-source-id: 55f7a238158442db9d8bdfe84e64438be504f618
2020-06-03 13:26:25 -07:00
Jun Wu
45d6b00593 dag: add InverseDag
Summary: Add a way to inverse the DAG (swap parent / children relations).

Reviewed By: sfilipco

Differential Revision: D21795870

fbshipit-source-id: 2d076f4ae491141aa758faa5f5f303c97f7e56dc
2020-06-03 13:26:25 -07:00
Jun Wu
a3b663735e dag: add IdLazySet
Summary:
Similar to LazySet, but the iterator is using Ids. This will be useful for
lazy calculations that are cheaper with Ids.

Reviewed By: sfilipco

Differential Revision: D21626208

fbshipit-source-id: 9a34fbf18f0039caeb4f6e698294c4d335354093
2020-06-03 13:26:24 -07:00
Jun Wu
223faebe5f dag: rename DagSet to IdStaticSet
Summary:
The NameSet is not really about Dag. It is about using Id and is static.
Rename it to clarify. In an upcoming change we'll have IdLazySet.

Reviewed By: sfilipco

Differential Revision: D21626204

fbshipit-source-id: 84f25008f7032f6e26a26fc656ccbcd2a5880ecf
2020-06-03 13:26:24 -07:00
Jun Wu
bf90003c24 dag: implement NameIter automatically
Summary:
This makes it possible to use NameIter without manually specifying out iterator
types, which might be quite long.

Reviewed By: sfilipco

Differential Revision: D21626202

fbshipit-source-id: 67b338765c09629645794cf73a9b496271524f9d
2020-06-03 13:26:24 -07:00
Jun Wu
6292253ef8 dag: add fast paths using hints
Summary: Take advantage of Hints and add fast paths.

Reviewed By: sfilipco

Differential Revision: D21626216

fbshipit-source-id: 6d43666bd6cdec7ff4b93032c1064cafd8de85cf
2020-06-03 13:26:23 -07:00
Jun Wu
d3878732f8 dag: set hints with existing hints
Summary: Update hints if they are easy to obtain or calculate.

Reviewed By: sfilipco

Differential Revision: D21626206

fbshipit-source-id: 453b7db2444406ce51d574c688fe536316fb9b0f
2020-06-03 13:26:23 -07:00
Jun Wu
fb56b1962d dag: move optimization hints to a dedicate structure
Summary:
Previously, the NameSet has properties like "is_all", "is_topo_sorted", etc.
To make lazy sets efficient, it's important to have hints about min / max Ids
and maybe some other information.

Add a dedicated Hints structure for that.

Reviewed By: sfilipco

Differential Revision: D21626219

fbshipit-source-id: 845e88d3333f0f48f60f2739adae3dccc4a2dfc4
2020-06-02 14:00:36 -07:00
Jun Wu
13503a1490 dag: add some default impls for DagAlgorithm
Summary:
Implement a small subset of DagAlgorithm by default. This makes
other implementations of DagAlgorithm slightly easier.

Reviewed By: sfilipco

Differential Revision: D21626199

fbshipit-source-id: ac6dfb5c22bf1da44f521fc9e76d59bfb95063c7
2020-06-02 14:00:36 -07:00
Jun Wu
c920549e09 dag: fix DagSet::contains
Summary:
D21479023 broke it. It should convert to Id, and check Id against the SpanSet,
instead of just checking the IdMap ignoring the SpanSet.

Reviewed By: sfilipco

Differential Revision: D21626193

fbshipit-source-id: 6daf86f292a7acfd3688893a55e2a794cfe068fe
2020-06-02 14:00:36 -07:00
Jun Wu
62719f10eb dag: make to_span_set take reference
Summary: This makes the next change easier to implement.

Reviewed By: sfilipco

Differential Revision: D21626198

fbshipit-source-id: 57ab69cba7f43350767e5d0d52ebfe66764895ca
2020-06-02 14:00:35 -07:00
Jun Wu
14b3c2e0f0 dag: move from_ascii to traits
Summary:
This adds flexibility. Now every type that implements DagAddHeads, including
NameDag, can import ASCII graphs.

Reviewed By: sfilipco

Differential Revision: D21626213

fbshipit-source-id: e258d88f97cbcc9aaf98d353a929803325185df7
2020-05-27 12:16:48 -07:00
Jun Wu
bd6c6fe18b dag: implement IdConvert on Dag structs
Reviewed By: sfilipco

Differential Revision: D21626214

fbshipit-source-id: 90d5a587e42340ac2b0f0b3f35f3bc084e969d40
2020-05-27 12:16:48 -07:00
Jun Wu
be5e3a20b4 dag: IdMapLike -> IdConvert
Summary: The trait was about converting between Id and VertexName. Rename to clarify.

Reviewed By: sfilipco

Differential Revision: D21626195

fbshipit-source-id: 874ca4ca3a1467084a08c6d9aa321201974e1978
2020-05-27 12:16:47 -07:00
Jun Wu
64dc05ab9d dag: move add_heads, flush, add_heads_and_flush to traits
Summary: This allows other kinds of DAG to implement the operations.

Reviewed By: sfilipco

Differential Revision: D21626220

fbshipit-source-id: 896c5ccebb1672324d346dfca6bcac9b4d3b4929
2020-05-27 12:16:47 -07:00
Jun Wu
4934987796 dag: implement PrefixLookup for Dag, MemDag and MemIdMap
Summary: This makes things a bit more flexible.

Reviewed By: sfilipco

Differential Revision: D21626194

fbshipit-source-id: f3ad486bcd5a6478d9e00f674d48f99504cded8c
2020-05-27 12:16:46 -07:00
Jun Wu
26217dcdb5 dag: move hex prefix lookup to a trait
Summary: This makes it possible for other types to implement the hex prefix lookup.

Reviewed By: sfilipco

Differential Revision: D21626218

fbshipit-source-id: 96e8b8c37e5aae2bd60658a238333b61902936d1
2020-05-27 12:16:46 -07:00
Jun Wu
577c9442bb dag: add VertexName::from_hex
Summary: It will be used in the next change.

Reviewed By: sfilipco

Differential Revision: D21626207

fbshipit-source-id: bbef70ef9d4f9aaa2039a6bc15d296e88db7f8dc
2020-05-27 12:16:46 -07:00
Jun Wu
38cc83e1bf dag: add short aliases for main public types
Summary:
Types like IdDag are not really used. The use of the word "name" is sometimes
confusing in other context. Therefore export shorter names like Dag, MemDag,
Vertex, avoid "name" in NameDag, MemNameDag and NameSet. This makes external
code shorter and less ambiguous.

Reviewed By: sfilipco

Differential Revision: D21626212

fbshipit-source-id: 5bcf3cecfd38277149b41bf3ba9e6d4ef2a07b2b
2020-05-27 12:16:45 -07:00
Jun Wu
e0d11803f2 dag: move DagAlgorithm to an independent trait
Summary:
This decouples DagAlgorithm from the IdMap + IdDag backend, making it possible
to support other kinds of backends of DagAlgorithm (ex. a revlog backend).

Reviewed By: sfilipco

Differential Revision: D21626200

fbshipit-source-id: f53cc271a200062e9c02f739b6453e1d7de84e6d
2020-05-27 12:16:45 -07:00
Jun Wu
aeac1551d2 dag: implement beautify
Summary:
This function reorders commits so the graph looks better.
It will be used to optimize graph rendering for cloud smartlog (and perhaps
smartlog in the future).

Reviewed By: markbt

Differential Revision: D21554675

fbshipit-source-id: d3f0f27c7935c49581cfa6e87d7c32eb5a075f75
2020-05-14 12:03:43 -07:00
Jun Wu
cde3140e8f dag: implement BitAnd, BitOr, Sub for NameSet
Summary: This makes it easier to do `a & b`, `a | b`, `a - b`.

Reviewed By: markbt

Differential Revision: D21554677

fbshipit-source-id: e1e2571a3dc83f80a1ec7a056f2c8f71ab292d9e
2020-05-14 12:03:43 -07:00
Jun Wu
60684eb2c5 dag: make ASCII -> MemNameDag a public API
Summary:
It seems handy to construct a Dag just from ASCII. Therefore move it to a
public interface.

Reviewed By: sfilipco

Differential Revision: D21486525

fbshipit-source-id: de7f4b8dfcbcc486798928d4334c655431373276
2020-05-11 09:49:59 -07:00
Jun Wu
a6b7e965f3 dag: remove a TODO comment
Summary: It was done as NameSet.

Reviewed By: sfilipco

Differential Revision: D21479022

fbshipit-source-id: 1c32cabb27d72a6438409ede226104a9ebac6a1d
2020-05-11 09:49:59 -07:00
Jun Wu
4eb9251172 dag: move sort and parent_names to NameDagAlgorithm
Summary:
They are part of the read-only algorithms that are not specific to a certain
type of NameDag.

Reviewed By: sfilipco

Differential Revision: D21479017

fbshipit-source-id: 3fa58071ac43246d3cd45d84384ee93c7385f414
2020-05-11 09:49:59 -07:00
Jun Wu
282e034d30 dag: add MemNameDag
Summary:
Adds an in-memory NameDag so we can construct the DAG and use its algorithms by
just providing parents function and heads.

Reviewed By: sfilipco

Differential Revision: D21479021

fbshipit-source-id: e12d53a97afec77b2307d5efbb280bd506dee0ba
2020-05-11 09:49:58 -07:00
Jun Wu
5cbb99f4eb dag: add MemIdMap
Summary: Adds an in-memory IdMap to be used in an in-memory NameDag.

Reviewed By: sfilipco

Differential Revision: D21479018

fbshipit-source-id: bc702762b059e8659c6ab322f3c39f032e95d5b6
2020-05-11 09:49:58 -07:00
Jun Wu
682e8e96a7 dag: use IdMap traits in NameDag and NameSet
Summary:
This allows them to switch to a different IdMap implementation relatively
easily.

Reviewed By: sfilipco

Differential Revision: D21479023

fbshipit-source-id: 8ecb99cafe2093ec7d14b848ffa08581c5300414
2020-05-11 09:49:57 -07:00
Jun Wu
759f8b35c5 dag: move some IdMap operations to traits
Summary: This will allow different IdMap implementations.

Reviewed By: sfilipco

Differential Revision: D21479016

fbshipit-source-id: 852501896fddcb82624338acd9dceee41150e302
2020-05-11 09:49:57 -07:00
Jun Wu
30163eeb58 dag: update snapshot_map on change
Summary:
`NameDag::add_heads` API changes the internal `dag` state without updating
`snapshot_map`. That will cause queries relying on `snapshot_map` to fail.
Update it so that `snapshot_map` gets updated by `add_heads`.

Reviewed By: sfilipco

Differential Revision: D21479019

fbshipit-source-id: 70528aa4a488cef3dc71bf21dd89e45cfe763794
2020-05-11 09:49:57 -07:00
Jun Wu
f014f86b7a dag: move NameDag algorithms to a trait
Summary:
This makes it easier to add an "in-memory-only" NameDag with all the algorithms
implemented.

Reviewed By: sfilipco

Differential Revision: D21479020

fbshipit-source-id: c1a73e95f3291c273c800650f70db2a7eb0966d7
2020-05-11 09:49:56 -07:00
Stefan Filip
ea89b541e1 segmented_changelog: add Dag struct and location_to_name functionality
Summary:
The IdDag provides graph algorithms using Segments.
The IdMap allows converting from the SegmentedChangelogId domain to the
ChangesetId domain.
The Dag struct wraps IdDag and IdMap in order to provide graph algorithms using
the common application level identifiers for commits (ChangesetId).

The construction of the Dag is currently mocked with something that can only be
used in a test environment (unit tests but also integration tests).

This diff also implements a location_to_name function. This is the most
important new functionality that segmented changelog clients require. It
recovers the hash of a commit for which the client only has a segmented
changelog Id. The current assumption is that clients have identifiers for all
merge commit parents so the path to a known commit always follow a set
of first parents.

The IdMap queries will have to be changed to async in the future, but IdDag
queries we expect to stay sync.

Reviewed By: quark-zju

Differential Revision: D20635577

fbshipit-source-id: 4f9bd8dd4a5bd9b0de55f51086f3434ff507963c
2020-03-27 13:48:52 -07:00
Stefan Filip
7502ce31ca dag: add in process stored IdMap constructor
Summary: The interesting observation is that InProcessStore is not public.

Reviewed By: quark-zju

Differential Revision: D20635578

fbshipit-source-id: a0149929c8059ff77f047fd385bf3b26dc738dfd
2020-03-27 13:48:51 -07:00
Stefan Filip
c400809eba dag: rename child index iteration to iter_master_flat_segments_with_parent
Summary:
`iter_segments_with_parent` has a few more conditions attached to it than the
name would imply. We are renaming it to give a better sense of its true
behavior.

Reviewed By: quark-zju

Differential Revision: D20547631

fbshipit-source-id: 406f46b9de5efc9e8e6a8c4bc22ab18fa5bc54bb
2020-03-24 13:58:07 -07:00
Stefan Filip
59ff2a8571 dag: remove_non_master implementation for
Summary: Also adding better tests for non master entries.

Reviewed By: quark-zju

Differential Revision: D20504483

fbshipit-source-id: 60d4a20aecb00f7750db2fff5d3832aac99d00e2
2020-03-24 13:58:06 -07:00
Stefan Filip
03c1e1cac5 dag: iterator implementations for InProcessStore
Summary:
The main question I had while writing the tests was whether we expect a
specific order for Segments for `iter_segments_with_parent`. `InProcessStore`
will return the segments in the order that they were inserted.

Reviewed By: quark-zju

Differential Revision: D20501401

fbshipit-source-id: 48ceb78f3191c7425c1488a3392cf3167f7e7268
2020-03-24 13:58:06 -07:00
Stefan Filip
5f4e706f81 dag: Add InProcessStore as iddagstore
Summary:
First 6 methods implemented from the IdDagStore trait for the InProcessStore.

Any suggestions welcome.

Reviewed By: quark-zju

Differential Revision: D20499228

fbshipit-source-id: cb536a3a0136077ada78934d82a25d079a5bc809
2020-03-24 13:58:06 -07:00
Stefan Filip
3dcb56535e dag: add descriptions to IdDagStore methods
Summary: Documentation.

Reviewed By: quark-zju

Differential Revision: D20499926

fbshipit-source-id: ebbb7a1249109bd56ff459a659e0c628c2974179
2020-03-24 13:58:05 -07:00
Jun Wu
8cc30ac302 dag: add Segment::new API
Summary:
Now Segment has no lifetime we can create it directly and return the ownership.

Performance of "building segments" does not seem to change:

  # before
  building segments                                 750.129 ms

  # after
  building segments                                 712.177 ms

Reviewed By: sfilipco

Differential Revision: D20505200

fbshipit-source-id: 2448814751ad1a754b90267e43262da072bf4a16
2020-03-18 15:05:58 -07:00
Jun Wu
1bd54a5971 dag: drop lifetime on Segment<'a>
Summary:
This allows structures like BTreeMap to own and store Segment.

It was not possible until D19818714, which adds minibytes::Bytes interface for
indexedlog.

In theory this hurts performance a little bit. But the perf difference does not
seem visible by `cargo bench --bench dag_ops`:

  # before
  building segments                                 714.420 ms
  ancestors                                          54.045 ms
  children                                          490.386 ms
  common_ancestors (spans)                            2.579 s
  descendants (small subset)                        406.374 ms
  gca_one (2 ids)                                   161.260 ms
  gca_one (spans)                                     2.731 s
  gca_all (2 ids)                                   287.857 ms
  gca_all (spans)                                     2.799 s
  heads                                             234.130 ms
  heads_ancestors                                    39.383 ms
  is_ancestor                                       113.847 ms
  parents                                           251.604 ms
  parent_ids                                         11.412 ms
  range (2 ids)                                     117.037 ms
  range (spans)                                     241.156 ms
  roots                                             507.328 ms

  # after
  building segments                                 750.129 ms
  ancestors                                          53.341 ms
  children                                          515.607 ms
  common_ancestors (spans)                            2.664 s
  descendants (small subset)                        411.556 ms
  gca_one (2 ids)                                   164.466 ms
  gca_one (spans)                                     2.701 s
  gca_all (2 ids)                                   290.516 ms
  gca_all (spans)                                     2.801 s
  heads                                             240.548 ms
  heads_ancestors                                    39.625 ms
  is_ancestor                                       115.735 ms
  parents                                           239.353 ms
  parent_ids                                         11.172 ms
  range (2 ids)                                     115.483 ms
  range (spans)                                     235.694 ms
  roots                                             506.861 ms

Reviewed By: sfilipco

Differential Revision: D20505201

fbshipit-source-id: c34d48f0216fc5b20a1d348a75ace89ace7c080b
2020-03-18 15:05:57 -07:00
Stefan Filip
1fb5acf242 dag: use IdDagStore in IdDag with type parameter
Summary: Make IdDag storage generic by depending on IdDagStore.

Reviewed By: quark-zju

Differential Revision: D20471712

fbshipit-source-id: 3a2668f301758a3c880db35c9f0db6887ef1dd38
2020-03-16 14:41:41 -07:00
Stefan Filip
236292c0fd dag: add the GetLock trait
Summary: Used to generalize `get_lock` functionality.

Reviewed By: quark-zju

Differential Revision: D20471710

fbshipit-source-id: e44d5b22ecacdb653170ef83914354f521f82dfc
2020-03-16 14:41:40 -07:00
Stefan Filip
66436b4a3c dag: add the IdDagStore trait
Summary: Abstract the storage functionality required by IdDag.

Reviewed By: quark-zju

Differential Revision: D20449122

fbshipit-source-id: fc3c7d7b88d74f7a93670d310be2e680f35e8ce7
2020-03-16 14:41:40 -07:00
Stefan Filip
1239628ef8 dag: move IdDag storage details to the iddagstore module
Summary:
Right now the module has one implementation IndexedLogStore. The name could
be more specific in the context of the crate.

The goal will be to add a trait for storage requirements of IdDag and
make IndexedLogStorage one implementation of that trait.

Reviewed By: quark-zju

Differential Revision: D20446042

fbshipit-source-id: 7576e1cc4ad757c1a2c00322936cc884838ff710
2020-03-16 14:41:40 -07:00
Jun Wu
1f64b4ec50 nameset: fix LazySet iteration
Summary:
The `next` method forgot to increase the iteration index, causing infinite
iteration.

Reviewed By: ikostia

Differential Revision: D20473206

fbshipit-source-id: 82a95de1b1c12ac4e9e4d328a0adba7145d7b24c
2020-03-16 13:00:35 -07:00
Jun Wu
194b38385a nameset: add a way to convert between NameSet and SpanSet
Summary:
This will be used in the Python world for legacy reasons. It shouldn't be used
in new Rust node.

To use it, the name `LegacyCodeNeedIdAccess` has to be used so we can do a code
search to find all users of it.

Reviewed By: sfilipco

Differential Revision: D20367834

fbshipit-source-id: 9b93a29f1461ce24bba6f31a2bbb1f327e216c6d
2020-03-11 20:37:30 -07:00
Jun Wu
eef56d9c5b namedag: add a sort API
Summary: This will be useful to actually sort commits.

Reviewed By: sfilipco

Differential Revision: D20367835

fbshipit-source-id: 43bc7835277af3a14ef323ce34247e0c03878dc8
2020-03-11 20:37:29 -07:00
Jun Wu
2ecc0bb757 namedag: move "all" concept to DagSet
Summary:
The old "AllSet" implementation is not very practical - it does not support
iteration. Practically, the "all()" set comes from the DAG. Change the "all"
concept to a hint similar to "is_topo_sorted", and update the fast path
(intersection) accordingly.

Reviewed By: sfilipco

Differential Revision: D20367837

fbshipit-source-id: fdbf370897c93058bfcab0571c1f6fa4b99b0f6b
2020-03-11 20:37:29 -07:00
Jun Wu
ef1696b4db namedag: rename arc_map to snapshot_map
Summary: The word "snapshot" more accurately describes its purpose.

Reviewed By: sfilipco

Differential Revision: D20367836

fbshipit-source-id: c91a0bd402fa1718b5d805beedc0e062824c53d3
2020-03-11 20:37:29 -07:00
Jun Wu
4960709aa3 dag: do not depend on types
Summary:
The dag crate is designed to work with any kind of binary commit hashes (ex. bonsai,
git or hg). The only use of `types` is to convert from binary to hex. Since dag
already has its own `to_hex` logic in `VertexName`. Let's use that instead.

Reviewed By: sfilipco

Differential Revision: D20378447

fbshipit-source-id: 00ecb551ea927fdb60dd91e5e645064f23139bcd
2020-03-11 10:49:31 -07:00
Stefan Filip
d8b4ddcecf dag: split lock file acquisition to own function
Summary:
Spliting lock file acquisition from `IdDag::prepare_filesystem_sync` to its own
function.
Useful when looking ahead to split IdDag from IndexedLog.

Reviewed By: quark-zju

Differential Revision: D20316443

fbshipit-source-id: a0fd43439730376920706bb4349ce497f6624335
2020-03-09 10:18:07 -07:00
Stefan Filip
620cdd96f2 dag: add IdDag::iter_segments_with_parent
Summary:
This removes an inline use of the indexedlog indexes.
This is going to be useful when we try to separate IndexedLog specifics from
IdDag functionality.

Reviewed By: quark-zju

Differential Revision: D20316058

fbshipit-source-id: 942a0a71660bb327376c81fd3ac435d002ecca6e
2020-03-09 10:18:07 -07:00
Jun Wu
64ba669a51 nameset: add some tests for DagSet
Summary:
With the new crate-public interfaces and Debug implementations it's possible to
write tests for DagSet. So let's do it.

Reviewed By: sfilipco

Differential Revision: D20242561

fbshipit-source-id: 180e04d9535f79471c79c4307f6ab6e8e8815067
2020-03-05 11:46:18 -08:00
Jun Wu
bb1562604a dag: make some test APIs public in crate
Summary: Those will be reused by nameset::DagSet.

Reviewed By: sfilipco

Differential Revision: D20242563

fbshipit-source-id: 944e9a04aeb15439256ecea64355b67e326e5c89
2020-03-04 17:33:25 -08:00
Jun Wu
b8e1477401 nameset: impl Debug for other sets
Summary:
This is useful for `assert_eq!(format!("{:?}", set), "...")` tests.

It will be eventually exposed to Python as `__repr__`, similar to Python's
smartsets.

Reviewed By: sfilipco

Differential Revision: D20242562

fbshipit-source-id: 5373bb180db7cafebf273ace7cf2cb80fbfb8038
2020-03-04 17:33:25 -08:00
Jun Wu
fa069204e3 nameset: impl Debug for StaticSet
Summary:
In the Python world all smartsets have some kind of "debug" information. Let's
do something similar in Rust.

Related code is updated so the test is more readable.

Reviewed By: sfilipco

Differential Revision: D20242564

fbshipit-source-id: 7439c93d82d5d037c7167818f4e1125c5a1e513e
2020-03-04 17:33:24 -08:00
Jun Wu
10bb5a144e revset: replace some repo.revs with repo.nodes
Summary:
Migrate away from some uses of revision numbers.
Some dead code in discovery.py is removed.

I also fixed some test issues when I run tests locally.

Reviewed By: sfilipco

Differential Revision: D20155399

fbshipit-source-id: bfdcb57f06374f9f27be51b0980652ef50a2c8e0
2020-02-28 17:45:26 -08:00
Jun Wu
0220b4a0c3 nameset: make NameIter Send
Summary: This makes it possible to use NameIter in py_class.

Reviewed By: sfilipco

Differential Revision: D20020529

fbshipit-source-id: b9147b7dccb38d18d8361b420507fcbe97e01351
2020-02-28 16:35:25 -08:00
Jun Wu
782f2017aa dag: add hex prefix lookup
Summary: This will be used by commit hash prefix lookup.

Reviewed By: sfilipco

Differential Revision: D20020523

fbshipit-source-id: f2905ddf63098704b08dad8eb48272c3ffba7e25
2020-02-28 16:35:24 -08:00
Jun Wu
12441f48bf dag: re-export common types at top-level
Summary: Export common types at the top-level of the crate so it's easier to use.

Reviewed By: sfilipco

Differential Revision: D20020526

fbshipit-source-id: e9a0a8bc3cc91f81d0bc74e7530cd4613fc1dd61
2020-02-28 16:35:23 -08:00
Jun Wu
bc9f72ccf3 dag: implement DAG algorithms on NameDag
Summary: Those just delegate to IdDag for the actual calculation.

Reviewed By: sfilipco

Differential Revision: D20020522

fbshipit-source-id: 272828c520097c993ab50dac6ecc94dc370c8e8b
2020-02-28 16:35:23 -08:00
Jun Wu
b88da34fb0 dag: expose NameDag in tests
Summary: This allows tests to check NameDag APIs.

Reviewed By: sfilipco

Differential Revision: D20020525

fbshipit-source-id: 4ee8e4bcbd0731512ba17068e827b8045fc5d522
2020-02-28 16:35:23 -08:00
Jun Wu
194cd25f4f dag: add Arc<IdMap> to NameDag
Summary: This will be used to produce NameSet.

Reviewed By: sfilipco

Differential Revision: D20020519

fbshipit-source-id: abf6d73f2b985b74560d6b5db2800ff25450f02e
2020-02-28 16:35:22 -08:00
Jun Wu
7a343271b9 dag: rename NameDag::parents to NameDag::parent_names
Summary: This matches IdDag::parents (taking a set) and IdDag::parent_ids.

Reviewed By: sfilipco

Differential Revision: D20020524

fbshipit-source-id: 6e90727c355a7400f9a23e0b25e3392bdc032f49
2020-02-28 16:35:22 -08:00
Jun Wu
e3b28a683c nameset: add fast paths for DagSet
Summary: DagSet's SpanSet has fast paths for set operations. Use them.

Reviewed By: sfilipco

Differential Revision: D19912104

fbshipit-source-id: 24b55aa14d03be2f1be59c923e0b8e79d6bcbe6d
2020-02-28 16:35:22 -08:00
Jun Wu
587b06efee nameset: AllSet
Summary: This is similar to hg's fullreposet. It'll be useful as a dummy "subset".

Reviewed By: sfilipco

Differential Revision: D19912108

fbshipit-source-id: 33a95bcb3cf5931a431a1201d1a1f3c627cec7a1
2020-02-28 16:35:21 -08:00
Jun Wu
d41c55a13b nameset: SortedSet
Summary: SortedSet is a wrapper to other sets that marks it as topologically sorted.

Reviewed By: sfilipco

Differential Revision: D19912111

fbshipit-source-id: 2637e8fd29b97f6db0c5bae3f0decd7ac382eeb1
2020-02-28 16:35:21 -08:00
Jun Wu
51bea7aff7 nameset: LazySet
Summary: Similar to Mercurial's smartset.generatorset.

Reviewed By: sfilipco

Differential Revision: D19912110

fbshipit-source-id: 7d940b8578ec7090282e2addb1fde871cddb2b25
2020-02-28 16:35:20 -08:00
Jun Wu
5e451d07b1 nameset: DagSet
Summary:
Wraps SpanSet + IdMap so it only exposes commit names without ids.
There is no equivalent smartset in Mercurial.

Reviewed By: sfilipco

Differential Revision: D19912112

fbshipit-source-id: 0d257de11527dfa8836065ac94f652730a97a468
2020-02-28 16:35:20 -08:00
Jun Wu
e7e7a5b356 nameset: StaticSet
Summary: Similar to Mercurial's smartset.baseset. All names are statically known.

Reviewed By: sfilipco

Differential Revision: D19912105

fbshipit-source-id: e4fcf2d59291adb3ca01b3b90f1ac32c65ad7eaa
2020-02-28 16:35:20 -08:00
Jun Wu
349d1bc33e nameset: IntersectionSet
Summary: Similar to Mercurial's smartset.filterset.

Reviewed By: sfilipco

Differential Revision: D19912113

fbshipit-source-id: 7cf2101b2eb7ba34b542199293cdbfd3973ef72f
2020-02-28 16:35:19 -08:00
Jun Wu
c0a1a3ab22 nameset: DifferenceSet
Summary: Similar to Mercurial's smartset.filterset.

Reviewed By: sfilipco

Differential Revision: D19912107

fbshipit-source-id: a3187c94f8e0c64f6d92e924ba46e83ce74c3e19
2020-02-28 16:35:19 -08:00
Jun Wu
b6cea95ea5 dag: use Bytes to avoid some VertexName copies
Summary:
This is an example about how to use the new Bytes type. The performance change
is not obviously visible in benchmarks since the bottleneck is not at the bytes
copying.

Reviewed By: DurhamG

Differential Revision: D19818720

fbshipit-source-id: a431ae206cfa4fa08b2e162a48b3d7cbcd900f7f
2020-02-28 09:23:59 -08:00
Jun Wu
76ab726056 dag: switch from bytes to minibytes
Summary: The APIs are compatible so the switch is straightforward.

Reviewed By: DurhamG

Differential Revision: D19818713

fbshipit-source-id: 504e9149567c90eb661804e0dad20580a401aa76
2020-02-28 09:23:59 -08:00
Jun Wu
9e3920ca1c dag: fix benchmarks
Summary: D19559127 forgot those files.

Reviewed By: DurhamG

Differential Revision: D19818715

fbshipit-source-id: 92321492eae89ed9f748800b3bfcc306a54aab20
2020-02-28 09:23:59 -08:00
Jun Wu
bce29c9562 nameset: UnionSet
Summary: Similar to Mercurial's smartset.addset.

Reviewed By: sfilipco

Differential Revision: D19912106

fbshipit-source-id: 0d0c8d0b71d2757259d26295eb4a564fea807dea
2020-02-27 07:34:57 -08:00
Jun Wu
c906a21ce1 nameset: initial NameSet abstraction
Summary:
The NameSet is something similar to SpanSet and Mercurial's smartset but speaks
VertexNames instead of Ids. The idea is, NameSet will be part of NameDag APIs,
and potentially replace Mercurial's smartset layer (just smartset the container
types, not the revset language), in a way that revision numbers are completely
hidden behind the scenes.

This diff adds some basic abstraction around iteration-related operations.
Other operations will be added later.

Reviewed By: sfilipco

Differential Revision: D19912109

fbshipit-source-id: 504a26c074282ec51f260535ca63e943124f688e
2020-02-27 07:34:57 -08:00
Stefan Filip
d78982a6e8 dag: move iddag to own file
Summary:
Separate Segment and IdDag in two individual files. This is preparation for
refactoring IdDag to be more flexible in terms of storage. That will probably
involve moving stuff out of IdDag into a new file that deals with the storage
abstractions.

Reviewed By: quark-zju

Differential Revision: D19559127

fbshipit-source-id: b3b9b18e2653157e69148b1f29292a57b30016ec
2020-01-24 15:49:54 -08:00
Jun Wu
29c749ef7d dag: add fuzz tests on the octopus DAG
Summary: This gives us some confidence about octopus merge handling.

Reviewed By: DurhamG

Differential Revision: D19540726

fbshipit-source-id: e84de74aecae54429483edd185d39fd1bd858f87
2020-01-23 17:58:51 -08:00
Jun Wu
8ac97da54e bindag: make TestContext more flexible
Summary:
TestContext uses ParentRevs. That limits parents to at most 2.

Use a type parameter so we can opt-in Vec<usize> for octopus merge support,
at the cost of worse cache efficiency.

Reviewed By: DurhamG

Differential Revision: D19540727

fbshipit-source-id: f9e8de151b7b296fd6f0fd89be9de2b8996634c7
2020-01-23 17:58:51 -08:00
Jun Wu
df23791d08 bindag: add some octopus examples
Summary:
Our new algorithms support octopus merges. However there were no tests using
octopus merges. This diff adds a simple one.

Reviewed By: DurhamG

Differential Revision: D19540728

fbshipit-source-id: 8411024f0b7e27c2ebfabbe1935496124c25df7b
2020-01-23 17:58:51 -08:00
Jun Wu
494bdae7cc dag: add a fuzz test about range algorithm
Summary:
The test runs the old and new algorithm and compares their result.  This is more
interesting than using random numbers, since the fuzzing framework will try to
explore new code paths.

Reviewed By: sfilipco

Differential Revision: D19511576

fbshipit-source-id: e9a2066769b54a60bb92643e5715f91a6fccbcb5
2020-01-23 17:58:50 -08:00
Jun Wu
78ea96cb9d bindag: port range algorithm from hg
Summary:
The ported algorithm will work as a comparison to verify dag's range
implementation.

Reviewed By: sfilipco

Differential Revision: D19511574

fbshipit-source-id: 589353d6e6c91b8d6707c977eeb8558ac733b525
2020-01-23 17:58:50 -08:00
Jun Wu
fff2cb833f dag: add a fuzz test about gca algorithm
Summary:
The test runs the old and new algorithm and compares their result.  This is more
interesting than using random numbers, since the fuzzing framework will try to
explore new code paths.

This cannot run on stable Rust yet. I added a README for how to run it.

Reviewed By: sfilipco

Differential Revision: D19504096

fbshipit-source-id: 621da02c50a771dee9932f9d7a407cb1f412a543
2020-01-22 19:30:50 -08:00
Jun Wu
af85f4ff3b bindag: add a way to get a subdag of a parsed bindag
Summary: Sometimes the graph is too large. Provide a way to slice it.

Reviewed By: sfilipco

Differential Revision: D19511575

fbshipit-source-id: 504317d6894764043b23ea49dcf09c8cdea96961
2020-01-22 19:30:49 -08:00
Jun Wu
b5482f8976 bindag: add utilities for easier testing
Summary:
As we plan to test the dag crate with some other DAG implementation,
add a convenient structure that setups both DAG implementations.

Reviewed By: sfilipco

Differential Revision: D19503371

fbshipit-source-id: 3e9933ad37301bfac36eb1af6d82b4298af778b6
2020-01-22 19:30:49 -08:00
Jun Wu
7d11508dfa bindag: port GCA algorithm from hg
Summary:
The ported algorithm will work as a comparison to verify dag's gca
implementation.

Reviewed By: sfilipco

Differential Revision: D19503373

fbshipit-source-id: f5253db89fbcdc2fd02f3fdaa0796e24338b1fba
2020-01-22 19:30:49 -08:00
Jun Wu
a98d288938 bindag: apply smallvec optimization
Summary:
This is similar to D17581248. It will make the old linear-scan algorithm (which
will be added later) about 5x faster.

Reviewed By: sfilipco

Differential Revision: D19503372

fbshipit-source-id: c65d7217e7b144603dadd57f54a5e70f513c8e51
2020-01-22 19:30:48 -08:00
Jun Wu
64271f24ba dag: move bindag from benches to a separate crate
Summary: This allows bindag to be used outside benches.

Reviewed By: sfilipco

Differential Revision: D19503374

fbshipit-source-id: 131061f7d1d28125875a86afc330dbb9634249cf
2020-01-22 19:30:48 -08:00
Jun Wu
124e275377 dag: make NameDag use MultiLog for data consistency
Summary: This ensures IdMap and IdDag are guaranteed consistent in the storage layer.

Reviewed By: DurhamG

Differential Revision: D19432658

fbshipit-source-id: 00f1a9b4c747baa1f14d78c31d925682317463b4
2020-01-17 21:49:57 -08:00
Jun Wu
94c383327a dag: make NameDag support buffered changes
Summary:
Previously, NameDag only supports writing directly to disk. That is not easy
for hg to use, since hg knows commits before bookmark names during pull, while
the API requires both commits and bookmarks (to decide which commits belong to
the "master" group) at the same time.

The old API also does not match other storage layers like indexedlog and
metalog, where writes are buffered until explicitly flushed.

This diff adds the "write-in-memory" (named "add_heads"), and "flush" APIs to
make NameDag easier to use. Under the hood, it just copies the "added" portion
of the DAG, and re-use the old API ("build", renamed to "add_heads_and_flush")
to do the job.

Note: The buffered changes pattern cannot be used in IdDag, since Ids might
have to be re-assigned on flush. But NameDag does not expose the raw Ids in its
"normal" interface, so it's fine to reassign Ids on flush.

Reviewed By: markbt

Differential Revision: D19405474

fbshipit-source-id: 75e5e5815c78c3577a0138f48185f6c4b5a80891
2020-01-15 14:02:07 -08:00
Jun Wu
3a74b82a39 dag: rename NamedDag to NameDag
Summary:
This is more consistent with the name "IdDag", because both "Name" and "Id" are
noun.

Reviewed By: singhsrb

Differential Revision: D19405473

fbshipit-source-id: a3b7546dd0ddcae5d9ed562838bd6be10a47063c
2020-01-15 14:02:06 -08:00
Jun Wu
3c5766d59e dag: rename Dag to IdDag
Summary: This is more consistent with the name "NamedDag".

Reviewed By: singhsrb

Differential Revision: D19405472

fbshipit-source-id: f7023307acaf96bf77c9fa9704dcaf6fc59b56f2
2020-01-15 14:02:06 -08:00
Jun Wu
85a89c6f96 dag: add git commit graph as test fixture
Summary:
The git repo has a lot of merges. So it's interesting as a testing graph.
The file was generated by:

    git clone https://github.com/git/git --bare
    hg --config extensions.hggit= clone git.git git-hg
    hg --cwd git-hg debugbindag -r 'all()' -o git.bindag

Reviewed By: DurhamG

Differential Revision: D19411825

fbshipit-source-id: 0fec8a16786dc8e6790986bca5c62a76276aa942
2020-01-15 11:03:52 -08:00
Jun Wu
064068169b dag: rename slice to VertexName
Summary:
Per discussion, we decided to use "VertexName" as the struct name for things
like commit hashes, or the string names in tests (or the Mozilla DAG in tests).
Therefore, introduce a dedicated VertexName type and repalce all callsites to
use it.

`bytes::Bytes` is used so copying the `VertexName` is somewhat considered cheap.

This adds some overhead copying slices (and `Bytes` has some overhead). It
regresses the "building segments" benchmark from 673ms to 773ms, which seems
okay given the cleaner interface.

Reviewed By: markbt

Differential Revision: D19154905

fbshipit-source-id: 4c6d4eca67c11c10ed5f21999ccdc3f1b01695e8
2020-01-08 21:35:28 -08:00
Jun Wu
232d5047cc dag: fix incorrect gca calculation
Summary: `gca(X) = gca(roots(X))`, not `gca(heads(X))`.

Reviewed By: sfilipco

Differential Revision: D19154907

fbshipit-source-id: 8d54992fbf5b03ce7ab2fbcc689c79351bf75947
2020-01-08 18:46:08 -08:00
Jun Wu
c6c4baa07e dag: redefine Id::{MIN, MAX} using Group
Summary:
Redefine Id::{MIN, MAX} using Group so Id::MAX.group() is a valid group.
Previously Id::MAX has an invalid group.

Reviewed By: sfilipco

Differential Revision: D19154908

fbshipit-source-id: 6108f02da786eb228a7d1b772ca5134c1ebb6f6b
2020-01-08 18:46:07 -08:00
Jun Wu
c4cd7df3b2 dag: extract logic calculating universal commits to a method
Summary:
Address review feedback on D18670160.

This also fixes the definition of "universal" a bit - the new code no longer
assumes there are only one head in the master group.

Reviewed By: sfilipco

Differential Revision: D19154906

fbshipit-source-id: 4fbf080354318300ce09dc7fba2dcc5f942b6308
2020-01-08 18:46:07 -08:00
Jun Wu
bcaff9062c dag: rebuild non-master id and segments if needed
Summary:
Add utilities to rebuild non-master ids and segments if necessary.

The `NamedDag` structure ensures indexes have 1:1 mapping.

Reviewed By: sfilipco

Differential Revision: D18838995

fbshipit-source-id: 4a48b183c182bd5e6336a2ca4973c36091fbbfd8
2020-01-08 18:46:07 -08:00
Jun Wu
28380e0272 dag: fix logic about avoiding unnecessary high level segments
Summary:
The check of "is this high level segment necessary or not" should be done
before dropping the last segment. This fixes an issue discovered in D18838992.

Reviewed By: sfilipco

Differential Revision: D19154904

fbshipit-source-id: fb4c83c39d66215bae168ad98e5cf78de91cc5a3
2020-01-08 18:46:06 -08:00
Jun Wu
d4eddd6b11 dag: use NamedDag in tests
Summary:
NamedDag is the high-level interface that is more interesting to test.

High-level segments are changed subtly because NamedDag syncs them to disk
first.

Reviewed By: sfilipco

Differential Revision: D18838992

fbshipit-source-id: c6a557e0a44a1d24320ea4a9e4283262f6f30f67
2020-01-08 18:46:06 -08:00
Jun Wu
5c7acfc1ca dag: add a NamedDag that keeps Dag and IdMap consistent
Summary:
It turns out the interaction between dag and idmap can be complex, especially
when a non-master id gets re-assigned a master id.

A high-level structure is helpful here to handle the corner cases correctly.

This diff adds basic definitions, and one of the most complex function - build.
The build function is ported from pydag.

Reviewed By: sfilipco

Differential Revision: D18838994

fbshipit-source-id: a2f6db3b188d5fd04d8e1d6df40ba985e33281f6
2019-12-22 11:27:32 -08:00
Jun Wu
61e0f06417 dag: add ways to remove non-master ids in Dag and IdMap
Summary: First step to implement segment and idmap rewrites for non-master ids.

Reviewed By: sfilipco

Differential Revision: D18838996

fbshipit-source-id: 0380c0193d9078a2a2d7fde9c5f565e8dbc8e713
2019-12-22 11:27:32 -08:00
Jun Wu
05ba5a56d4 dag: rewrite Debug for Dag
Summary:
The current implementation iterates through all entries, which will include
deleted entries. Rewrite it to use index lookups so it does not print
deleted entries.

Reviewed By: sfilipco

Differential Revision: D18838993

fbshipit-source-id: 58d3f2da27cd3e91bc10cbb04bcdca3b7ff07dbb
2019-12-20 16:14:21 -08:00
Jun Wu
859b79de3b dag: replace Group::MAX with Group::COUNT
Summary:
Address review comment in D18640899. I went a bit further that makes COUNT,
ALL, and BITS consistent.

Reviewed By: sfilipco

Differential Revision: D18820721

fbshipit-source-id: e354a3aecf0d8cbe66c43d56198933cdc6420241
2019-12-20 16:14:21 -08:00
Jun Wu
710e2c9ae8 dag: replace Id(0) and Id::max_value() with Id::{MIN,MAX}
Summary:
Address review comment in D18640898.

Id::min_value and Id::max_value become unused and are removed.

Reviewed By: sfilipco

Differential Revision: D18820722

fbshipit-source-id: d9682bf5918307166571fa35aa15cc9eee1a7140
2019-12-20 16:14:21 -08:00
Jun Wu
a1d710fa58 dag: rename GroupId to Group
Summary:
Address review comment in D18640899. This makes the word `id` universally
refer to a same concept within the crate.

Reviewed By: sfilipco

Differential Revision: D18820723

fbshipit-source-id: 6803192db7e1304a72100568f8f29b90f25c7779
2019-12-20 16:14:21 -08:00
Jun Wu
d3543665eb dag: de-dup IdMap at insertion time
Summary: There is no need to insert duplicated entries to IdMap.

Reviewed By: sfilipco

Differential Revision: D18670158

fbshipit-source-id: 812ea421c9f36cd12b4aa2be5b2560abec627a52
2019-12-20 16:14:20 -08:00
Jun Wu
d60355d1ba dag: add a way to generate sparse IdMap
Summary: This emulates what IdMap the server will send to the client at initial clone.

Reviewed By: sfilipco

Differential Revision: D18670160

fbshipit-source-id: 496142c1e149df9accf816e3d0a1b8316ff64c67
2019-12-20 16:14:20 -08:00
Jun Wu
3125f6bbd5 dag: implement Debug for IdMap
Summary: This makes it easier to check what's stored in IdMap.

Reviewed By: sfilipco

Differential Revision: D18670159

fbshipit-source-id: 91387d01da7d52a0d349e87ffa0aa8983bbe2213
2019-12-20 16:14:20 -08:00
Jun Wu
0d8ae15299 dag: implement more protocols
Summary:
This diff implements the following part in a local-only environment:

  Id -> Slice: Id -> Request --> Response -> Slice
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  Slice -> Id: Slice -> Request --> Response -> Id
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^

Reviewed By: sfilipco

Differential Revision: D18664210

fbshipit-source-id: 740b9cdfe533e7bcc9bbbf2a53c8bcc5bc3648bf
2019-12-20 16:14:20 -08:00
Jun Wu
7a35f20e72 dag: implement some protocols
Summary:
This diff implements the following part in a local-only environment:

  Id -> Slice: Id -> Request --> Response -> Slice
               ^^^^^^^^^^^^^
  Slice -> Id: Slice -> Request --> Response -> Id
               ^^^^^^^^^^^^^^^^

Reviewed By: sfilipco

Differential Revision: D18664205

fbshipit-source-id: 47a35c6f95a58ab29c014ac3c6799f16e6114da3
2019-12-20 16:14:20 -08:00
Jun Wu
2467448518 dag: abstractions around remote protocols
Summary:
In the future the client will have a sparse IdMap, and needs the server (who
has a complete IdMap)'s help to convert between Id and Slice (commit hash)
for commits in the MASTER group.

This diff defines basic abstractions for communications between a sparse IdMap
and a complete IdMap. The basic flows are:

  To convert Id to Slice: Id -> Request --> Response -> Slice
  To convert Slice to Id: Slice -> Request --> Response -> Id

(`->`: client-side; `-->`: server-side)

Reviewed By: sfilipco

Differential Revision: D18664206

fbshipit-source-id: 93a6b671be30ab1247c71d814817a2ea06b6bc66
2019-12-20 16:14:20 -08:00
Jun Wu
3d65779318 dag: add IdMapLike for minimal IdMap interface
Summary:
In the future we might have revlog or more complicated storage for maintaining
the IdMap. Define a trait for it.

Reviewed By: sfilipco

Differential Revision: D18664208

fbshipit-source-id: 242611d78852e8d82a52ab52192db87c13b848e7
2019-12-05 17:01:13 -08:00
Jun Wu
dbfc96ca15 dag: add to_first_ancestor_nth
Summary: This is the reverse of first_ancestor_nth. It will be used later.

Reviewed By: sfilipco

Differential Revision: D18664209

fbshipit-source-id: 8d3706cdc080086ec60da60870fde76c8933f6a8
2019-12-05 17:01:13 -08:00
Jun Wu
74e624297c dag: add first_ancestor_nth
Summary: This will be used in an upcoming change.

Reviewed By: sfilipco

Differential Revision: D18664207

fbshipit-source-id: 3030bb02e172b95c6dbabda74c318e7f16212f59
2019-12-05 17:01:12 -08:00
Jun Wu
f028832a62 dag: add a fast path to ancestors calculation
Summary:
With the ONLY_HEAD flag, ancestors can be sped up sometimes.  Since ancestors
is used widely in other DAG calculations, perf improvements are visible across
the benchmark. The trade-off is to spend a bit more time on building segments
to figure out ONLY_HEAD.

After this diff:

  building segments                                 576.625 ms
  ancestors                                          47.119 ms
  children                                          436.967 ms
  common_ancestors (spans)                          257.096 ms
  descendants (small subset)                        367.316 ms
  gca_one (2 ids)                                   146.315 ms
  gca_one (spans)                                   253.059 ms
  gca_all (2 ids)                                   236.075 ms
  gca_all (spans)                                   266.695 ms
  heads                                             220.766 ms
  heads_ancestors                                    36.258 ms
  is_ancestor                                        98.967 ms
  parents                                           219.173 ms
  parent_ids                                          9.282 ms
  range (2 ids)                                      99.859 ms
  range (spans)                                     205.154 ms
  roots                                             429.047 ms

Before this and previous diff:

  building segments                                 542.564 ms
  ancestors                                         316.075 ms
  children                                          428.612 ms
  common_ancestors (spans)                          452.850 ms
  descendants (small subset)                        537.483 ms
  gca_one (2 ids)                                   526.112 ms
  gca_one (spans)                                   446.726 ms
  gca_all (2 ids)                                   780.590 ms
  gca_all (spans)                                   490.906 ms
  heads                                             214.005 ms
  heads_ancestors                                   217.558 ms
  is_ancestor                                       256.769 ms
  parents                                           213.170 ms
  parent_ids                                          9.313 ms
  range (2 ids)                                     259.435 ms
  range (spans)                                     358.934 ms
  roots                                             423.005 ms

Reviewed By: sfilipco

Differential Revision: D18642797

fbshipit-source-id: 27f1ee5797a92142b2c19195eb26baef58769553
2019-12-05 17:01:12 -08:00
Jun Wu
94a09a890d dag: add a flag to indicate a segment is the only head so far
Summary: The pre-calculated flag can be used for some fast paths.

Reviewed By: sfilipco

Differential Revision: D18642796

fbshipit-source-id: bc16b3517cc29e23478f2027e83e2a2282be0d0a
2019-12-05 17:01:12 -08:00
Jun Wu
3e205e29b3 pydag: revise bindings
Summary:
The bindings APIs are out of date.

The latest idea is to write non-master commits to disk, in a different group.
There are no "segments in memory". Therefore:
- Rename `builddisk` to `build`.
- Make sure `build` updates internal states by calling `reload`.
- Drop `buildmem`.
- In case `builddisk` gets called very frequently, reduce its overhead by
  doing nothing if all commits are built already.

The constructor is revised to match the latest interface (no
"max segment level" and "set_new_segment_size" needs to be called).

Reviewed By: sfilipco

Differential Revision: D18640897

fbshipit-source-id: 76a5d0db363713dc5b763503c238c1bfa61ea02e
2019-12-05 17:01:11 -08:00
Jun Wu
744f17df8b dag: add group support for segments
Summary: Make it possible to build non-master segments.

Reviewed By: sfilipco

Differential Revision: D18641507

fbshipit-source-id: 4d0c46cdea240849af37d28219b6023578514323
2019-12-05 17:01:11 -08:00
Jun Wu
cdcbf836eb dag: fix a correctness issue that flat segment building might be incomplete
Summary:
`build_segments_volatile(id)` should build flat segments so it includes `id`.

Right now it can fail that in a corner case. Fix it.

Reviewed By: sfilipco

Differential Revision: D18641509

fbshipit-source-id: ad1de694e4d31c51f29e9bc5800291066bf16dbb
2019-12-05 17:01:11 -08:00
Jun Wu
5bac1b4598 dag: re-assign non-master ids to master ids
Summary:
This is needed to keep Ids topologically sorted.

This is reflected in the test added by D18641507, when assigning
master ids to `I`:

```
0---1---2---3---4---5---6--------H---I
     \               \          /
      N0-N1-N2-N3     N4-N5-N6-o
                \            \
                 -------------N7--N8
Lv0: R0-1[] 2-3[1] 4-6[3] N0-N1[1] N2-N3[N1] N4-N6[5] N7-N8[N3, N6]
Lv1: R0-3[] 4-6[3] N0-N1[1] N2-N3[N1] N4-N8[5, N3]
Lv2: R0-6[] N0-N3[1] N4-N8[5, N3]
```

Note: 0, 1, 2, ... are ids in the master group. N0, N1, ... are ids in the non-master group.

```
0---1---2---3---4---5---6--------11--12
     \               \          /
      N0-N1-N2-N3     7--8--9--10
                \            \
                 -------------N7--N8
Lv0: R0-1[] 2-3[1] 4-6[3] 7-10[5] 11-12[6, 10] N0-N1[1] N2-N3[N1] N4-N6[5] N7-N8[N3, N6]
Lv1: R0-3[] 4-6[3] 7-12[5, 6] N0-N1[1] N2-N3[N1] N4-N8[5, N3]
Lv2: R0-6[] 7-12[5, 6] N0-N3[1] N4-N8[5, N3]
Lv3: R0-12[] N0-N8[1, 5]
```

Notice that 7, 8, 9 replace the old non-master ids N4, N5, N6. Without this change,
N4, N5, N6 will be kept and break the topo-sorted property.

An `ensure!` was added to make sure Ids are topo-sorted.

Reviewed By: sfilipco

Differential Revision: D18641510

fbshipit-source-id: bbe642df3615c65db7f2e7c889624e00e53ef7ba
2019-12-05 17:01:10 -08:00
Jun Wu
fb718fe106 dag: allow re-assigning a non-master Id to a master Id
Summary:
The IdMap has assertions about 1:1 mapping between Id and Slice.

Practically, a non-master commit can be merged into a master commit.
That means a commit hash might map to 2 Ids: [master-id, non-master-id].
Allow that to happen (temporarily).

Note: The non 1:1 mapping causes more headache than benefit and
D18838995 restores 1:1 mapping. But it still requires temporary
non-1:1 mapping to work.

Reviewed By: sfilipco

Differential Revision: D18641508

fbshipit-source-id: bc4bc831d5ab5ebfc2588bafd48114ae49d31e0f
2019-12-05 17:01:10 -08:00
Jun Wu
81b7593249 dag: avoid panic on drop
Summary: panic on drop is a terrible idea. It can cause SIGILL kill without meaningful messages or meaningful backtrace. Remove it.

Reviewed By: xavierd

Differential Revision: D18640894

fbshipit-source-id: 3ab52ded9875e17e891acd8f9b45d82964615f01
2019-12-04 22:43:24 -08:00
Jun Wu
de9a7fecb1 dag: replace some panic! with bail!
Summary: This makes the code harder to crash in abnormal cases.

Reviewed By: sfilipco

Differential Revision: D18640895

fbshipit-source-id: ee81dd7739739d3d15052bdb7bb2ba80ed48cd0a
2019-12-04 22:43:24 -08:00
Jun Wu
75aff36c7f dag: add group support for IdMap
Summary:
This allows us to allocate Ids for non-master commits in a separate range
so they wouldn't cause fragmentation for commits in the master group.

Reviewed By: sfilipco

Differential Revision: D18640896

fbshipit-source-id: c19c53342583ded8795849584cf5f31bc86b2818
2019-12-04 22:43:23 -08:00
Jun Wu
05157a174a dag: replace u64 with the new Id type
Summary: Migrate the codebase to use the new Id type instead of an alias of u64.

Reviewed By: sfilipco

Differential Revision: D18640898

fbshipit-source-id: 415db9afeda1f8960e18c69e70f53a9eeb63cbbe
2019-12-04 22:43:23 -08:00
Jun Wu
c016535cb6 dag: add a dedicated Id type
Summary:
Background:
- Tests and Nuclide haven't removed usage of revision numbers.
- If we build segments for non-master commits on demand, there are performance
  concerns about very long release branches.
- It's very desirable to keep `ancestors(master)` continuous. In other words,
  `ancestors(master)` is a single integer span. This affects performance for
  DAG algorithms a lot.

To solve the problems, I'm going to use separate ranges for master and
non-master commit Ids (so assigning Ids to non-master commits wouldn't affect
what numbers can be used for the master group). To make the code easier to
read, I'm changing `type Id = u64` to `struct Id` where the struct is
group-aware.

This diff introduces related types and basic operations.

Reviewed By: sfilipco

Differential Revision: D18640899

fbshipit-source-id: 8f7ecbee6e0d1703d1225f18e92742981dbf3757
2019-12-04 22:43:22 -08:00
David Tolnay
d1d8fb939a Switch from failure::Fail trait to std::error::Error for errors
Summary:
This diff replaces eden's dependencies on failure::Error with anyhow::Error.

Failure's error type requires all errors to have an implementation of failure's own failure::Fail trait in order for cause chains and backtraces to work. The necessary methods for this functionality have made their way into the standard library error trait, so modern error libraries build directly on std::error::Error rather than something like failure::Fail. Once we are no longer tied to failure 0.1's Fail trait, different parts of the codebase will be free to use any std::error::Error-based libraries they like while still working nicely together.

Reviewed By: xavierd

Differential Revision: D18576093

fbshipit-source-id: e2d862b659450f2969520d9b74877913fabb2e5d
2019-11-22 08:53:31 -08:00
David Tolnay
b1793a4416 rust: Rename Fallible<T> to Result<T>
Summary:
This diff is preparation for migrating off of failure::Fail / failure::Error for errors in favor of errors that implement std::error::Error. The Fallible terminology is unique to failure and in non-failure code we should be using Result<T>. To minimize the size of the eventual diff that removes failure, this codemod replaces all use of Fallible with Result by:

- In modules that do not use Result<T, E>, we import `failure::Fallible as Result`;
- In modules that use a mix of Result<T, E> and Fallible<T> (only 5) we define `type Result<T, E = failure::Error> = std::result::Result<T, E>` to allow both Result<T> and Result<T, E> to work simultaneously.

Reviewed By: Imxset21

Differential Revision: D18499758

fbshipit-source-id: 9f5a54c47f81fdeedbc6003cef42a1194eee55bf
2019-11-14 14:11:01 -08:00
Adam Simpkins
ab3a7cb21f Move fb-mercurial sources into an eden/scm subdirectory.
Summary:
In preparation for merging fb-mercurial sources to the Eden repository,
move everything from the top-level directory into an `eden/scm`
subdirectory.
2019-11-13 16:04:48 -08:00