##// END OF EJS Templates
copies-rust: remove the ancestor Oracle logic...
marmoute -
r47316:34827c95 default
parent child Browse files
Show More
@@ -363,7 +363,7 b' def _combine_changeset_copies('
363 363
364 364 if rustmod is not None:
365 365 final_copies = rustmod.combine_changeset_copies(
366 list(revs), children_count, targetrev, revinfo, isancestor
366 list(revs), children_count, targetrev, revinfo
367 367 )
368 368 else:
369 369 isancestor = cached_is_ancestor(isancestor)
@@ -281,46 +281,6 b" impl<'a> ChangedFiles<'a> {"
281 281 }
282 282 }
283 283
284 /// A struct responsible for answering "is X ancestors of Y" quickly
285 ///
286 /// The structure will delegate ancestors call to a callback, and cache the
287 /// result.
288 #[derive(Debug)]
289 struct AncestorOracle<'a, A: Fn(Revision, Revision) -> bool> {
290 inner: &'a A,
291 pairs: HashMap<(Revision, Revision), bool>,
292 }
293
294 impl<'a, A: Fn(Revision, Revision) -> bool> AncestorOracle<'a, A> {
295 fn new(func: &'a A) -> Self {
296 Self {
297 inner: func,
298 pairs: HashMap::default(),
299 }
300 }
301
302 fn record_overwrite(&mut self, anc: Revision, desc: Revision) {
303 self.pairs.insert((anc, desc), true);
304 }
305
306 /// returns `true` if `anc` is an ancestors of `desc`, `false` otherwise
307 fn is_overwrite(&mut self, anc: Revision, desc: Revision) -> bool {
308 if anc > desc {
309 false
310 } else if anc == desc {
311 true
312 } else {
313 if let Some(b) = self.pairs.get(&(anc, desc)) {
314 *b
315 } else {
316 let b = (self.inner)(anc, desc);
317 self.pairs.insert((anc, desc), b);
318 b
319 }
320 }
321 }
322 }
323
324 284 struct ActionsIterator<'a> {
325 285 changes: &'a ChangedFiles<'a>,
326 286 parent: Parent,
@@ -419,15 +379,13 b' impl TwoWayPathMap {'
419 379 /// * ChangedFiles
420 380 /// isancestors(low_rev, high_rev): callback to check if a revision is an
421 381 /// ancestor of another
422 pub fn combine_changeset_copies<A: Fn(Revision, Revision) -> bool, D>(
382 pub fn combine_changeset_copies<D>(
423 383 revs: Vec<Revision>,
424 384 mut children_count: HashMap<Revision, usize>,
425 385 target_rev: Revision,
426 386 rev_info: RevInfoMaker<D>,
427 is_ancestor: &A,
428 387 ) -> PathCopies {
429 388 let mut all_copies = HashMap::new();
430 let mut oracle = AncestorOracle::new(is_ancestor);
431 389
432 390 let mut path_map = TwoWayPathMap::default();
433 391
@@ -450,7 +408,6 b' pub fn combine_changeset_copies<A: Fn(Re'
450 408 // combine it with data for that revision
451 409 let vertex_copies = add_from_changes(
452 410 &mut path_map,
453 &mut oracle,
454 411 &parent_copies,
455 412 &changes,
456 413 Parent::FirstParent,
@@ -471,7 +428,6 b' pub fn combine_changeset_copies<A: Fn(Re'
471 428 // combine it with data for that revision
472 429 let vertex_copies = add_from_changes(
473 430 &mut path_map,
474 &mut oracle,
475 431 &parent_copies,
476 432 &changes,
477 433 Parent::SecondParent,
@@ -491,7 +447,6 b' pub fn combine_changeset_copies<A: Fn(Re'
491 447 vertex_copies,
492 448 copies,
493 449 &changes,
494 &mut oracle,
495 450 )),
496 451 };
497 452 }
@@ -548,9 +503,8 b' fn get_and_clean_parent_copies('
548 503
549 504 /// Combine ChangedFiles with some existing PathCopies information and return
550 505 /// the result
551 fn add_from_changes<A: Fn(Revision, Revision) -> bool>(
506 fn add_from_changes(
552 507 path_map: &mut TwoWayPathMap,
553 oracle: &mut AncestorOracle<A>,
554 508 base_copies: &InternalPathCopies,
555 509 changes: &ChangedFiles,
556 510 parent: Parent,
@@ -582,7 +536,6 b' fn add_from_changes<A: Fn(Revision, Revi'
582 536 }
583 537 Entry::Occupied(mut slot) => {
584 538 let ttpc = slot.get_mut();
585 oracle.record_overwrite(ttpc.rev, current_rev);
586 539 ttpc.overwrite(current_rev, entry);
587 540 }
588 541 }
@@ -595,7 +548,6 b' fn add_from_changes<A: Fn(Revision, Revi'
595 548 // InternalPathCopies object.
596 549 let deleted = path_map.tokenize(deleted_path);
597 550 copies.entry(deleted).and_modify(|old| {
598 oracle.record_overwrite(old.rev, current_rev);
599 551 old.mark_delete(current_rev);
600 552 });
601 553 }
@@ -608,31 +560,27 b' fn add_from_changes<A: Fn(Revision, Revi'
608 560 ///
609 561 /// In case of conflict, value from "major" will be picked, unless in some
610 562 /// cases. See inline documentation for details.
611 fn merge_copies_dict<A: Fn(Revision, Revision) -> bool>(
563 fn merge_copies_dict(
612 564 path_map: &TwoWayPathMap,
613 565 current_merge: Revision,
614 566 mut minor: InternalPathCopies,
615 567 mut major: InternalPathCopies,
616 568 changes: &ChangedFiles,
617 oracle: &mut AncestorOracle<A>,
618 569 ) -> InternalPathCopies {
619 570 // This closure exist as temporary help while multiple developper are
620 571 // actively working on this code. Feel free to re-inline it once this
621 572 // code is more settled.
622 let cmp_value = |oracle: &mut AncestorOracle<A>,
623 dest: &PathToken,
624 src_minor: &CopySource,
625 src_major: &CopySource| {
626 compare_value(
627 path_map,
628 current_merge,
629 changes,
630 oracle,
631 dest,
632 src_minor,
633 src_major,
634 )
635 };
573 let cmp_value =
574 |dest: &PathToken, src_minor: &CopySource, src_major: &CopySource| {
575 compare_value(
576 path_map,
577 current_merge,
578 changes,
579 dest,
580 src_minor,
581 src_major,
582 )
583 };
636 584 if minor.is_empty() {
637 585 major
638 586 } else if major.is_empty() {
@@ -661,10 +609,8 b' fn merge_copies_dict<A: Fn(Revision, Rev'
661 609 }
662 610 Some(src_major) => {
663 611 let (pick, overwrite) =
664 cmp_value(oracle, &dest, &src_minor, src_major);
612 cmp_value(&dest, &src_minor, src_major);
665 613 if overwrite {
666 oracle.record_overwrite(src_minor.rev, current_merge);
667 oracle.record_overwrite(src_major.rev, current_merge);
668 614 let src = match pick {
669 615 MergePick::Major => CopySource::new_from_merge(
670 616 current_merge,
@@ -704,10 +650,8 b' fn merge_copies_dict<A: Fn(Revision, Rev'
704 650 }
705 651 Some(src_minor) => {
706 652 let (pick, overwrite) =
707 cmp_value(oracle, &dest, src_minor, &src_major);
653 cmp_value(&dest, src_minor, &src_major);
708 654 if overwrite {
709 oracle.record_overwrite(src_minor.rev, current_merge);
710 oracle.record_overwrite(src_major.rev, current_merge);
711 655 let src = match pick {
712 656 MergePick::Major => CopySource::new_from_merge(
713 657 current_merge,
@@ -769,10 +713,8 b' fn merge_copies_dict<A: Fn(Revision, Rev'
769 713 let (dest, src_major) = new;
770 714 let (_, src_minor) = old;
771 715 let (pick, overwrite) =
772 cmp_value(oracle, dest, src_minor, src_major);
716 cmp_value(dest, src_minor, src_major);
773 717 if overwrite {
774 oracle.record_overwrite(src_minor.rev, current_merge);
775 oracle.record_overwrite(src_major.rev, current_merge);
776 718 let src = match pick {
777 719 MergePick::Major => CopySource::new_from_merge(
778 720 current_merge,
@@ -840,11 +782,10 b' enum MergePick {'
840 782
841 783 /// decide which side prevails in case of conflicting values
842 784 #[allow(clippy::if_same_then_else)]
843 fn compare_value<A: Fn(Revision, Revision) -> bool>(
785 fn compare_value(
844 786 path_map: &TwoWayPathMap,
845 787 current_merge: Revision,
846 788 changes: &ChangedFiles,
847 oracle: &mut AncestorOracle<A>,
848 789 dest: &PathToken,
849 790 src_minor: &CopySource,
850 791 src_major: &CopySource,
@@ -1,5 +1,4 b''
1 1 use cpython::ObjectProtocol;
2 use cpython::PyBool;
3 2 use cpython::PyBytes;
4 3 use cpython::PyDict;
5 4 use cpython::PyList;
@@ -26,32 +25,10 b' pub fn combine_changeset_copies_wrapper('
26 25 children_count: PyDict,
27 26 target_rev: Revision,
28 27 rev_info: PyObject,
29 is_ancestor: PyObject,
30 28 ) -> PyResult<PyDict> {
31 29 let revs: PyResult<_> =
32 30 revs.iter(py).map(|r| Ok(r.extract(py)?)).collect();
33 31
34 // Wrap the `is_ancestor` python callback as a Rust closure
35 //
36 // No errors are expected from the Python side, and they will should only
37 // happens in case of programing error or severe data corruption. Such
38 // errors will raise panic and the rust-cpython harness will turn them into
39 // Python exception.
40 let is_ancestor_wrap = |anc: Revision, desc: Revision| -> bool {
41 is_ancestor
42 .call(py, (anc, desc), None)
43 .expect(
44 "rust-copy-tracing: python call to `is_ancestor` \
45 failed",
46 )
47 .cast_into::<PyBool>(py)
48 .expect(
49 "rust-copy-tracing: python call to `is_ancestor` \
50 returned unexpected non-Bool value",
51 )
52 .is_true()
53 };
54
55 32 // Wrap the `rev_info_maker` python callback as a Rust closure
56 33 //
57 34 // No errors are expected from the Python side, and they will should only
@@ -104,7 +81,6 b' pub fn combine_changeset_copies_wrapper('
104 81 children_count?,
105 82 target_rev,
106 83 rev_info_maker,
107 &is_ancestor_wrap,
108 84 );
109 85 let out = PyDict::new(py);
110 86 for (dest, source) in res.into_iter() {
@@ -134,8 +110,7 b' pub fn init_module(py: Python, package: '
134 110 revs: PyList,
135 111 children: PyDict,
136 112 target_rev: Revision,
137 rev_info: PyObject,
138 is_ancestor: PyObject
113 rev_info: PyObject
139 114 )
140 115 ),
141 116 )?;
General Comments 0
You need to be logged in to leave comments. Login now