annotate rust/hg-core/src/copy_tracing.rs @ 45963:0d99778af68a

copies-rust: use immutable "OrdMap" to store copies information The large majority of time is currently spent coping and merging directories. the `IM` crate offer "immutable" Map, that use "copy on write" internally. The new object use the same API as the standard HashMap. So switching to it is trivial and it reduce copying cost significantly. More importantly, using immutable structure will unlock new possibility for a massive speed up of the "merging" part. This will came in a later changesets. Performance wise, we get very significant boost in the worst case. Below is some highlight of how we fare compared to the previous changeset. Repo Cases Source-Rev Dest-Rev Old-Time New-Time Difference Factor ------------------------------------------------------------------------------------------------------------------------------------ pypy x0000_revs_x_added_0_copies d1defd0dc478 c9cb1334cc78 : 62.468362 s, 33.527067 s, -28.941295 s, ? 0.5367 mozilla-central x000_revs_x000_added_x000_copies 7c97034feb78 4407bd0c6330 : 3.619850 s, 0.963905 s, -2.655945 s, ? 0.2663 mozilla-central x0000_revs_xx000_added_x000_copies f78c615a656c 96a38b690156 : 11.926587 s, 4.217003 s, -7.709584 s, ? 0.3536 mozilla-try x0000_revs_x_added_0_copies 63519bfd42ee a36a2a865d92 : 10.674920 s, 1.114864 s, -9.560056 s, ? 0.1044 mozilla-try x00000_revs_x00000_added_0_copies dc8a3ca7010e d16fde900c9c : 19.647038 s, 1.442793 s, -18.204245 s, ? 0.0734 And we sometimes catch up with the performance of the python code as highlighted below: Repo Cases Source-Rev Dest-Rev Py-time Rust-time Difference Factor ------------------------------------------------------------------------------------------------------------------------------------ mozilla-try x00000_revs_x00000_added_0_copies dc8a3ca7010e d16fde900c9c : 1.074593 s, 1.442793 s, +0.368200 s, ? 1.3426 However, multiple case remains significantly slower, as highlighted below Repo Cases Source-Rev Dest-Rev Py-time Rust-time Difference Factor ------------------------------------------------------------------------------------------------------------------------------------ mozilla-central x000_revs_x000_added_x000_copies 7c97034feb78 4407bd0c6330 : 0.190133 s, 0.963905 s, +0.773772 s, ? 5.0696 mozilla-central x0000_revs_xx000_added_x000_copies f78c615a656c 96a38b690156 : 0.440694 s, 4.217003 s, +3.776309 s, ? 9.5690 mozilla-try x0000_revs_x_added_0_copies 63519bfd42ee a36a2a865d92 : 0.370675 s, 1.114864 s, +0.744189 s, ? 3.0077 pypy x0000_revs_x_added_0_copies d1defd0dc478 c9cb1334cc78 : 3.581556 s, 33.527067 s, +29.945511 s, ? 9.3610 Below are two different tables for full performance comparison - this changeset against the previous one (spoiler: it is much better) - this changeset against the python code (spoiler: still slower, but it gets more comparable) This changeset compared to the previous one =========================================== Repo Cases Source-Rev Dest-Rev Old-Time New-Time Difference Factor ------------------------------------------------------------------------------------------------------------------------------------ mercurial x_revs_x_added_0_copies ad6b123de1c7 39cfcef4f463 : 0.000046 s, 0.000049 s, +0.000003 s, ? 1.0652 mercurial x_revs_x_added_x_copies 2b1c78674230 0c1d10351869 : 0.000173 s, 0.000179 s, +0.000006 s, ? 1.0347 mercurial x000_revs_x000_added_x_copies 81f8ff2a9bf2 dd3267698d84 : 0.006303 s, 0.006494 s, +0.000191 s, ? 1.0303 pypy x_revs_x_added_0_copies aed021ee8ae8 099ed31b181b : 0.000229 s, 0.000339 s, +0.000110 s, ? 1.4803 pypy x_revs_x000_added_0_copies 4aa4e1f8e19a 359343b9ac0e : 0.000056 s, 0.000057 s, +0.000001 s, ? 1.0179 pypy x_revs_x_added_x_copies ac52eb7bbbb0 72e022663155 : 0.000143 s, 0.000299 s, +0.000156 s, ? 2.0909 pypy x_revs_x00_added_x_copies c3b14617fbd7 ace7255d9a26 : 0.001166 s, 0.001200 s, +0.000034 s, ? 1.0292 pypy x_revs_x000_added_x000_copies df6f7a526b60 a83dc6a2d56f : 0.022931 s, 0.025120 s, +0.002189 s, ? 1.0955 pypy x000_revs_xx00_added_0_copies 89a76aede314 2f22446ff07e : 0.852446 s, 0.506921 s, -0.345525 s, ? 0.5947 pypy x000_revs_x000_added_x_copies 8a3b5bfd266e 2c68e87c3efe : 2.221824 s, 1.272060 s, -0.949764 s, ? 0.5725 pypy x000_revs_x000_added_x000_copies 89a76aede314 7b3dda341c84 : 1.194162 s, 0.690941 s, -0.503221 s, ? 0.5786 pypy x0000_revs_x_added_0_copies d1defd0dc478 c9cb1334cc78 : 62.468362 s, 33.527067 s, -28.941295 s, ? 0.5367 pypy x0000_revs_xx000_added_0_copies bf2c629d0071 4ffed77c095c : 0.022116 s, 0.021970 s, -0.000146 s, ? 0.9934 pypy x0000_revs_xx000_added_x000_copies 08ea3258278e d9fa043f30c0 : 2.972788 s, 1.772094 s, -1.200694 s, ? 0.5961 netbeans x_revs_x_added_0_copies fb0955ffcbcd a01e9239f9e7 : 0.000180 s, 0.000185 s, +0.000005 s, ? 1.0278 netbeans x_revs_x000_added_0_copies 6f360122949f 20eb231cc7d0 : 0.000123 s, 0.000135 s, +0.000012 s, ? 1.0976 netbeans x_revs_x_added_x_copies 1ada3faf6fb6 5a39d12eecf4 : 0.000315 s, 0.000329 s, +0.000014 s, ? 1.0444 netbeans x_revs_x00_added_x_copies 35be93ba1e2c 9eec5e90c05f : 0.001297 s, 0.001343 s, +0.000046 s, ? 1.0355 netbeans x000_revs_xx00_added_0_copies eac3045b4fdd 51d4ae7f1290 : 0.024884 s, 0.029396 s, +0.004512 s, ? 1.1813 netbeans x000_revs_x000_added_x_copies e2063d266acd 6081d72689dc : 0.032653 s, 0.040210 s, +0.007557 s, ? 1.2314 netbeans x000_revs_x000_added_x000_copies ff453e9fee32 411350406ec2 : 4.230118 s, 4.556794 s, +0.326676 s, ? 1.0772 mozilla-central x_revs_x_added_0_copies 3697f962bb7b 7015fcdd43a2 : 0.000197 s, 0.000199 s, +0.000002 s, ? 1.0102 mozilla-central x_revs_x000_added_0_copies dd390860c6c9 40d0c5bed75d : 0.000622 s, 0.000639 s, +0.000017 s, ? 1.0273 mozilla-central x_revs_x_added_x_copies 8d198483ae3b 14207ffc2b2f : 0.000296 s, 0.000542 s, +0.000246 s, ? 1.8311 mozilla-central x_revs_x00_added_x_copies 98cbc58cc6bc 446a150332c3 : 0.001626 s, 0.001685 s, +0.000059 s, ? 1.0363 mozilla-central x_revs_x000_added_x000_copies 3c684b4b8f68 0a5e72d1b479 : 0.006218 s, 0.006954 s, +0.000736 s, ? 1.1184 mozilla-central x_revs_x0000_added_x0000_copies effb563bb7e5 c07a39dc4e80 : 0.132760 s, 0.132938 s, +0.000178 s, ? 1.0013 mozilla-central x000_revs_xx00_added_0_copies 6100d773079a 04a55431795e : 0.029001 s, 0.008683 s, -0.020318 s, ? 0.2994 mozilla-central x000_revs_x000_added_x_copies 9f17a6fc04f9 2d37b966abed : 0.005886 s, 0.005956 s, +0.000070 s, ? 1.0119 mozilla-central x000_revs_x000_added_x000_copies 7c97034feb78 4407bd0c6330 : 3.619850 s, 0.963905 s, -2.655945 s, ? 0.2663 mozilla-central x0000_revs_xx000_added_0_copies 9eec5917337d 67118cc6dcad : 0.058678 s, 0.049239 s, -0.009439 s, ? 0.8391 mozilla-central x0000_revs_xx000_added_x000_copies f78c615a656c 96a38b690156 : 11.926587 s, 4.217003 s, -7.709584 s, ? 0.3536 mozilla-try x_revs_x_added_0_copies aaf6dde0deb8 9790f499805a : 0.001204 s, 0.001197 s, -0.000007 s, ? 0.9942 mozilla-try x_revs_x000_added_0_copies d8d0222927b4 5bb8ce8c7450 : 0.001217 s, 0.001213 s, -0.000004 s, ? 0.9967 mozilla-try x_revs_x_added_x_copies 092fcca11bdb 936255a0384a : 0.000605 s, 0.000762 s, +0.000157 s, ? 1.2595 mozilla-try x_revs_x00_added_x_copies b53d2fadbdb5 017afae788ec : 0.001876 s, 0.001909 s, +0.000033 s, ? 1.0176 mozilla-try x_revs_x000_added_x000_copies 20408ad61ce5 6f0ee96e21ad : 0.078190 s, 0.093021 s, +0.014831 s, ? 1.1897 mozilla-try x_revs_x0000_added_x0000_copies effb563bb7e5 c07a39dc4e80 : 0.135428 s, 0.134536 s, -0.000892 s, ? 0.9934 mozilla-try x000_revs_xx00_added_0_copies 6100d773079a 04a55431795e : 0.029123 s, 0.009071 s, -0.020052 s, ? 0.3115 mozilla-try x000_revs_x000_added_x_copies 9f17a6fc04f9 2d37b966abed : 0.006141 s, 0.006206 s, +0.000065 s, ? 1.0106 mozilla-try x000_revs_x000_added_x000_copies 1346fd0130e4 4c65cbdabc1f : 4.857827 s, 1.150502 s, -3.707325 s, ? 0.2368 mozilla-try x0000_revs_x_added_0_copies 63519bfd42ee a36a2a865d92 : 10.674920 s, 1.114864 s, -9.560056 s, ? 0.1044 mozilla-try x0000_revs_x_added_x_copies 9fe69ff0762d bcabf2a78927 : 9.789462 s, 1.042658 s, -8.746804 s, ? 0.1065 mozilla-try x0000_revs_xx000_added_x_copies 156f6e2674f2 4d0f2c178e66 : 1.087890 s, 0.447402 s, -0.640488 s, ? 0.4113 mozilla-try x0000_revs_xx000_added_0_copies 9eec5917337d 67118cc6dcad : 0.060556 s, 0.051132 s, -0.009424 s, ? 0.8444 mozilla-try x0000_revs_xx000_added_x000_copies 89294cd501d9 7ccb2fc7ccb5 : killed , 83.508590 s mozilla-try x0000_revs_x0000_added_x0000_copies e928c65095ed e951f4ad123a : killed , 55.079813 s mozilla-try x00000_revs_x00000_added_0_copies dc8a3ca7010e d16fde900c9c : 19.647038 s, 1.442793 s, -18.204245 s, ? 0.0734 This changeset compared to the Python Code ========================================== Repo Cases Source-Rev Dest-Rev Py-time Rust-time Difference Factor ------------------------------------------------------------------------------------------------------------------------------------ mercurial x_revs_x_added_0_copies ad6b123de1c7 39cfcef4f463 : 0.000044 s, 0.000049 s, +0.000005 s, ? 1.1136 mercurial x_revs_x_added_x_copies 2b1c78674230 0c1d10351869 : 0.000138 s, 0.000179 s, +0.000041 s, ? 1.2971 mercurial x000_revs_x000_added_x_copies 81f8ff2a9bf2 dd3267698d84 : 0.005052 s, 0.006494 s, +0.001442 s, ? 1.2854 pypy x_revs_x_added_0_copies aed021ee8ae8 099ed31b181b : 0.000219 s, 0.000339 s, +0.000120 s, ? 1.5479 pypy x_revs_x000_added_0_copies 4aa4e1f8e19a 359343b9ac0e : 0.000055 s, 0.000057 s, +0.000002 s, ? 1.0364 pypy x_revs_x_added_x_copies ac52eb7bbbb0 72e022663155 : 0.000128 s, 0.000299 s, +0.000171 s, ? 2.3359 pypy x_revs_x00_added_x_copies c3b14617fbd7 ace7255d9a26 : 0.001089 s, 0.001200 s, +0.000111 s, ? 1.1019 pypy x_revs_x000_added_x000_copies df6f7a526b60 a83dc6a2d56f : 0.017407 s, 0.025120 s, +0.007713 s, ? 1.4431 pypy x000_revs_xx00_added_0_copies 89a76aede314 2f22446ff07e : 0.094175 s, 0.506921 s, +0.412746 s, ? 5.3828 pypy x000_revs_x000_added_x_copies 8a3b5bfd266e 2c68e87c3efe : 0.238009 s, 1.272060 s, +1.034051 s, ? 5.3446 pypy x000_revs_x000_added_x000_copies 89a76aede314 7b3dda341c84 : 0.125876 s, 0.690941 s, +0.565065 s, ? 5.4891 pypy x0000_revs_x_added_0_copies d1defd0dc478 c9cb1334cc78 : 3.581556 s, 33.527067 s, +29.945511 s, ? 9.3610 pypy x0000_revs_xx000_added_0_copies bf2c629d0071 4ffed77c095c : 0.016721 s, 0.021970 s, +0.005249 s, ? 1.3139 pypy x0000_revs_xx000_added_x000_copies 08ea3258278e d9fa043f30c0 : 0.242367 s, 1.772094 s, +1.529727 s, ? 7.3116 netbeans x_revs_x_added_0_copies fb0955ffcbcd a01e9239f9e7 : 0.000165 s, 0.000185 s, +0.000020 s, ? 1.1212 netbeans x_revs_x000_added_0_copies 6f360122949f 20eb231cc7d0 : 0.000114 s, 0.000135 s, +0.000021 s, ? 1.1842 netbeans x_revs_x_added_x_copies 1ada3faf6fb6 5a39d12eecf4 : 0.000296 s, 0.000329 s, +0.000033 s, ? 1.1115 netbeans x_revs_x00_added_x_copies 35be93ba1e2c 9eec5e90c05f : 0.001124 s, 0.001343 s, +0.000219 s, ? 1.1948 netbeans x000_revs_xx00_added_0_copies eac3045b4fdd 51d4ae7f1290 : 0.013060 s, 0.029396 s, +0.016336 s, ? 2.2508 netbeans x000_revs_x000_added_x_copies e2063d266acd 6081d72689dc : 0.017112 s, 0.040210 s, +0.023098 s, ? 2.3498 netbeans x000_revs_x000_added_x000_copies ff453e9fee32 411350406ec2 : 0.660350 s, 4.556794 s, +3.896444 s, ? 6.9006 netbeans x0000_revs_xx000_added_x000_copies 588c2d1ced70 1aad62e59ddd : 10.032499 s, killed mozilla-central x_revs_x_added_0_copies 3697f962bb7b 7015fcdd43a2 : 0.000189 s, 0.000199 s, +0.000010 s, ? 1.0529 mozilla-central x_revs_x000_added_0_copies dd390860c6c9 40d0c5bed75d : 0.000462 s, 0.000639 s, +0.000177 s, ? 1.3831 mozilla-central x_revs_x_added_x_copies 8d198483ae3b 14207ffc2b2f : 0.000270 s, 0.000542 s, +0.000272 s, ? 2.0074 mozilla-central x_revs_x00_added_x_copies 98cbc58cc6bc 446a150332c3 : 0.001474 s, 0.001685 s, +0.000211 s, ? 1.1431 mozilla-central x_revs_x000_added_x000_copies 3c684b4b8f68 0a5e72d1b479 : 0.004806 s, 0.006954 s, +0.002148 s, ? 1.4469 mozilla-central x_revs_x0000_added_x0000_copies effb563bb7e5 c07a39dc4e80 : 0.085150 s, 0.132938 s, +0.047788 s, ? 1.5612 mozilla-central x000_revs_xx00_added_0_copies 6100d773079a 04a55431795e : 0.007064 s, 0.008683 s, +0.001619 s, ? 1.2292 mozilla-central x000_revs_x000_added_x_copies 9f17a6fc04f9 2d37b966abed : 0.004741 s, 0.005956 s, +0.001215 s, ? 1.2563 mozilla-central x000_revs_x000_added_x000_copies 7c97034feb78 4407bd0c6330 : 0.190133 s, 0.963905 s, +0.773772 s, ? 5.0696 mozilla-central x0000_revs_xx000_added_0_copies 9eec5917337d 67118cc6dcad : 0.035651 s, 0.049239 s, +0.013588 s, ? 1.3811 mozilla-central x0000_revs_xx000_added_x000_copies f78c615a656c 96a38b690156 : 0.440694 s, 4.217003 s, +3.776309 s, ? 9.5690 mozilla-central x00000_revs_x0000_added_x0000_copies 6832ae71433c 4c222a1d9a00 : 18.454163 s, killed mozilla-central x00000_revs_x00000_added_x000_copies 76caed42cf7c 1daa622bbe42 : 31.562719 s, killed mozilla-try x_revs_x_added_0_copies aaf6dde0deb8 9790f499805a : 0.001189 s, 0.001197 s, +0.000008 s, ? 1.0067 mozilla-try x_revs_x000_added_0_copies d8d0222927b4 5bb8ce8c7450 : 0.001204 s, 0.001213 s, +0.000009 s, ? 1.0075 mozilla-try x_revs_x_added_x_copies 092fcca11bdb 936255a0384a : 0.000586 s, 0.000762 s, +0.000176 s, ? 1.3003 mozilla-try x_revs_x00_added_x_copies b53d2fadbdb5 017afae788ec : 0.001845 s, 0.001909 s, +0.000064 s, ? 1.0347 mozilla-try x_revs_x000_added_x000_copies 20408ad61ce5 6f0ee96e21ad : 0.063822 s, 0.093021 s, +0.029199 s, ? 1.4575 mozilla-try x_revs_x0000_added_x0000_copies effb563bb7e5 c07a39dc4e80 : 0.088038 s, 0.134536 s, +0.046498 s, ? 1.5282 mozilla-try x000_revs_xx00_added_0_copies 6100d773079a 04a55431795e : 0.007389 s, 0.009071 s, +0.001682 s, ? 1.2276 mozilla-try x000_revs_x000_added_x_copies 9f17a6fc04f9 2d37b966abed : 0.004868 s, 0.006206 s, +0.001338 s, ? 1.2749 mozilla-try x000_revs_x000_added_x000_copies 1346fd0130e4 4c65cbdabc1f : 0.222450 s, 1.150502 s, +0.928052 s, ? 5.1720 mozilla-try x0000_revs_x_added_0_copies 63519bfd42ee a36a2a865d92 : 0.370675 s, 1.114864 s, +0.744189 s, ? 3.0077 mozilla-try x0000_revs_x_added_x_copies 9fe69ff0762d bcabf2a78927 : 0.358020 s, 1.042658 s, +0.684638 s, ? 2.9123 mozilla-try x0000_revs_xx000_added_x_copies 156f6e2674f2 4d0f2c178e66 : 0.145235 s, 0.447402 s, +0.302167 s, ? 3.0805 mozilla-try x0000_revs_xx000_added_0_copies 9eec5917337d 67118cc6dcad : 0.037606 s, 0.051132 s, +0.013526 s, ? 1.3597 mozilla-try x0000_revs_xx000_added_x000_copies 89294cd501d9 7ccb2fc7ccb5 : 7.382439 s, 83.508590 s, +76.126151 s, ? 11.3118 mozilla-try x0000_revs_x0000_added_x0000_copies e928c65095ed e951f4ad123a : 7.273506 s, 55.079813 s, +47.806307 s, ? 7.5727 mozilla-try x00000_revs_x00000_added_0_copies dc8a3ca7010e d16fde900c9c : 1.074593 s, 1.442793 s, +0.368200 s, ? 1.3426 mozilla-try x00000_revs_x0000_added_x0000_copies 8d3fafa80d4b eb884023b810 : 27.746195 s, killed Differential Revision: https://phab.mercurial-scm.org/D9300
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Tue, 21 Apr 2020 11:28:48 +0200
parents 595979dc924e
children 46a16b2c082d
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
1 use crate::utils::hg_path::HgPathBuf;
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
2 use crate::Revision;
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
3
45963
0d99778af68a copies-rust: use immutable "OrdMap" to store copies information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45944
diff changeset
4 use im_rc::ordmap::OrdMap;
0d99778af68a copies-rust: use immutable "OrdMap" to store copies information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45944
diff changeset
5
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
6 use std::collections::HashMap;
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
7 use std::collections::HashSet;
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
8
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
9 pub type PathCopies = HashMap<HgPathBuf, HgPathBuf>;
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
10
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
11 #[derive(Clone, Debug)]
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
12 struct TimeStampedPathCopy {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
13 /// revision at which the copy information was added
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
14 rev: Revision,
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
15 /// the copy source, (Set to None in case of deletion of the associated
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
16 /// key)
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
17 path: Option<HgPathBuf>,
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
18 }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
19
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
20 /// maps CopyDestination to Copy Source (+ a "timestamp" for the operation)
45963
0d99778af68a copies-rust: use immutable "OrdMap" to store copies information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45944
diff changeset
21 type TimeStampedPathCopies = OrdMap<HgPathBuf, TimeStampedPathCopy>;
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
22
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
23 /// hold parent 1, parent 2 and relevant files actions.
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
24 pub type RevInfo = (Revision, Revision, ChangedFiles);
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
25
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
26 /// represent the files affected by a changesets
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
27 ///
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
28 /// This hold a subset of mercurial.metadata.ChangingFiles as we do not need
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
29 /// all the data categories tracked by it.
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
30 pub struct ChangedFiles {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
31 removed: HashSet<HgPathBuf>,
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
32 merged: HashSet<HgPathBuf>,
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
33 salvaged: HashSet<HgPathBuf>,
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
34 copied_from_p1: PathCopies,
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
35 copied_from_p2: PathCopies,
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
36 }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
37
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
38 impl ChangedFiles {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
39 pub fn new(
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
40 removed: HashSet<HgPathBuf>,
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
41 merged: HashSet<HgPathBuf>,
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
42 salvaged: HashSet<HgPathBuf>,
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
43 copied_from_p1: PathCopies,
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
44 copied_from_p2: PathCopies,
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
45 ) -> Self {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
46 ChangedFiles {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
47 removed,
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
48 merged,
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
49 salvaged,
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
50 copied_from_p1,
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
51 copied_from_p2,
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
52 }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
53 }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
54
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
55 pub fn new_empty() -> Self {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
56 ChangedFiles {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
57 removed: HashSet::new(),
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
58 merged: HashSet::new(),
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
59 salvaged: HashSet::new(),
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
60 copied_from_p1: PathCopies::new(),
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
61 copied_from_p2: PathCopies::new(),
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
62 }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
63 }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
64 }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
65
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
66 /// Same as mercurial.copies._combine_changeset_copies, but in Rust.
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
67 ///
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
68 /// Arguments are:
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
69 ///
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
70 /// revs: all revisions to be considered
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
71 /// children: a {parent ? [childrens]} mapping
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
72 /// target_rev: the final revision we are combining copies to
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
73 /// rev_info(rev): callback to get revision information:
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
74 /// * first parent
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
75 /// * second parent
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
76 /// * ChangedFiles
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
77 /// isancestors(low_rev, high_rev): callback to check if a revision is an
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
78 /// ancestor of another
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
79 pub fn combine_changeset_copies(
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
80 revs: Vec<Revision>,
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
81 children: HashMap<Revision, Vec<Revision>>,
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
82 target_rev: Revision,
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
83 rev_info: &impl Fn(Revision) -> RevInfo,
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
84 is_ancestor: &impl Fn(Revision, Revision) -> bool,
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
85 ) -> PathCopies {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
86 let mut all_copies = HashMap::new();
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
87
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
88 for rev in revs {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
89 // Retrieve data computed in a previous iteration
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
90 let copies = all_copies.remove(&rev);
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
91 let copies = match copies {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
92 Some(c) => c,
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
93 None => TimeStampedPathCopies::default(), // root of the walked set
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
94 };
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
95
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
96 let current_children = match children.get(&rev) {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
97 Some(c) => c,
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
98 None => panic!("inconsistent `revs` and `children`"),
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
99 };
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
100
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
101 for child in current_children {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
102 // We will chain the copies information accumulated for `rev` with
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
103 // the individual copies information for each of its children.
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
104 // Creating a new PathCopies for each `rev` ? `children` vertex.
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
105 let (p1, p2, changes) = rev_info(*child);
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
106
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
107 let (parent, child_copies) = if rev == p1 {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
108 (1, &changes.copied_from_p1)
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
109 } else {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
110 assert_eq!(rev, p2);
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
111 (2, &changes.copied_from_p2)
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
112 };
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
113 let mut new_copies = copies.clone();
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
114
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
115 for (dest, source) in child_copies {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
116 let entry;
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
117 if let Some(v) = copies.get(source) {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
118 entry = match &v.path {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
119 Some(path) => Some((*(path)).to_owned()),
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
120 None => Some(source.to_owned()),
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
121 }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
122 } else {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
123 entry = Some(source.to_owned());
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
124 }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
125 // Each new entry is introduced by the children, we record this
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
126 // information as we will need it to take the right decision
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
127 // when merging conflicting copy information. See
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
128 // merge_copies_dict for details.
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
129 let ttpc = TimeStampedPathCopy {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
130 rev: *child,
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
131 path: entry,
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
132 };
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
133 new_copies.insert(dest.to_owned(), ttpc);
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
134 }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
135
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
136 // We must drop copy information for removed file.
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
137 //
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
138 // We need to explicitly record them as dropped to propagate this
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
139 // information when merging two TimeStampedPathCopies object.
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
140 for f in changes.removed.iter() {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
141 if new_copies.contains_key(f.as_ref()) {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
142 let ttpc = TimeStampedPathCopy {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
143 rev: *child,
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
144 path: None,
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
145 };
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
146 new_copies.insert(f.to_owned(), ttpc);
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
147 }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
148 }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
149
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
150 // Merge has two parents needs to combines their copy information.
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
151 //
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
152 // If the vertex from the other parent was already processed, we
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
153 // will have a value for the child ready to be used. We need to
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
154 // grab it and combine it with the one we already
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
155 // computed. If not we can simply store the newly
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
156 // computed data. The processing happening at
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
157 // the time of the second parent will take care of combining the
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
158 // two TimeStampedPathCopies instance.
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
159 match all_copies.remove(child) {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
160 None => {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
161 all_copies.insert(child, new_copies);
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
162 }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
163 Some(other_copies) => {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
164 let (minor, major) = match parent {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
165 1 => (other_copies, new_copies),
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
166 2 => (new_copies, other_copies),
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
167 _ => unreachable!(),
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
168 };
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
169 let merged_copies =
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
170 merge_copies_dict(minor, major, &changes, is_ancestor);
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
171 all_copies.insert(child, merged_copies);
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
172 }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
173 };
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
174 }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
175 }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
176
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
177 // Drop internal information (like the timestamp) and return the final
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
178 // mapping.
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
179 let tt_result = all_copies
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
180 .remove(&target_rev)
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
181 .expect("target revision was not processed");
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
182 let mut result = PathCopies::default();
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
183 for (dest, tt_source) in tt_result {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
184 if let Some(path) = tt_source.path {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
185 result.insert(dest, path);
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
186 }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
187 }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
188 result
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
189 }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
190
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
191 /// merge two copies-mapping together, minor and major
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
192 ///
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
193 /// In case of conflict, value from "major" will be picked, unless in some
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
194 /// cases. See inline documentation for details.
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
195 #[allow(clippy::if_same_then_else)]
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
196 fn merge_copies_dict(
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
197 minor: TimeStampedPathCopies,
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
198 major: TimeStampedPathCopies,
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
199 changes: &ChangedFiles,
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
200 is_ancestor: &impl Fn(Revision, Revision) -> bool,
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
201 ) -> TimeStampedPathCopies {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
202 let mut result = minor.clone();
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
203 for (dest, src_major) in major {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
204 let overwrite;
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
205 if let Some(src_minor) = minor.get(&dest) {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
206 if src_major.path == src_minor.path {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
207 // we have the same value, but from other source;
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
208 if src_major.rev == src_minor.rev {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
209 // If the two entry are identical, no need to do anything
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
210 overwrite = false;
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
211 } else if is_ancestor(src_major.rev, src_minor.rev) {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
212 overwrite = false;
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
213 } else {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
214 overwrite = true;
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
215 }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
216 } else if src_major.rev == src_minor.rev {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
217 // We cannot get copy information for both p1 and p2 in the
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
218 // same rev. So this is the same value.
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
219 overwrite = false;
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
220 } else if src_major.path.is_none()
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
221 && changes.salvaged.contains(&dest)
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
222 {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
223 // If the file is "deleted" in the major side but was salvaged
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
224 // by the merge, we keep the minor side alive
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
225 overwrite = false;
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
226 } else if src_minor.path.is_none()
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
227 && changes.salvaged.contains(&dest)
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
228 {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
229 // If the file is "deleted" in the minor side but was salvaged
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
230 // by the merge, unconditionnaly preserve the major side.
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
231 overwrite = true;
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
232 } else if changes.merged.contains(&dest) {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
233 // If the file was actively merged, copy information from each
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
234 // side might conflict. The major side will win such conflict.
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
235 overwrite = true;
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
236 } else if is_ancestor(src_major.rev, src_minor.rev) {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
237 // If the minor side is strictly newer than the major side, it
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
238 // should be kept.
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
239 overwrite = false;
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
240 } else if src_major.path.is_some() {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
241 // without any special case, the "major" value win other the
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
242 // "minor" one.
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
243 overwrite = true;
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
244 } else if is_ancestor(src_minor.rev, src_major.rev) {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
245 // the "major" rev is a direct ancestors of "minor", any
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
246 // different value should overwrite
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
247 overwrite = true;
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
248 } else {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
249 // major version is None (so the file was deleted on that
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
250 // branch) annd that branch is independant (neither minor nor
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
251 // major is an ancestors of the other one.) We preserve the new
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
252 // information about the new file.
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
253 overwrite = false;
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
254 }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
255 } else {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
256 // minor had no value
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
257 overwrite = true;
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
258 }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
259 if overwrite {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
260 result.insert(dest, src_major);
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
261 }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
262 }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
263 result
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
264 }