##// 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 if rustmod is not None:
364 if rustmod is not None:
365 final_copies = rustmod.combine_changeset_copies(
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 else:
368 else:
369 isancestor = cached_is_ancestor(isancestor)
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 struct ActionsIterator<'a> {
284 struct ActionsIterator<'a> {
325 changes: &'a ChangedFiles<'a>,
285 changes: &'a ChangedFiles<'a>,
326 parent: Parent,
286 parent: Parent,
@@ -419,15 +379,13 b' impl TwoWayPathMap {'
419 /// * ChangedFiles
379 /// * ChangedFiles
420 /// isancestors(low_rev, high_rev): callback to check if a revision is an
380 /// isancestors(low_rev, high_rev): callback to check if a revision is an
421 /// ancestor of another
381 /// ancestor of another
422 pub fn combine_changeset_copies<A: Fn(Revision, Revision) -> bool, D>(
382 pub fn combine_changeset_copies<D>(
423 revs: Vec<Revision>,
383 revs: Vec<Revision>,
424 mut children_count: HashMap<Revision, usize>,
384 mut children_count: HashMap<Revision, usize>,
425 target_rev: Revision,
385 target_rev: Revision,
426 rev_info: RevInfoMaker<D>,
386 rev_info: RevInfoMaker<D>,
427 is_ancestor: &A,
428 ) -> PathCopies {
387 ) -> PathCopies {
429 let mut all_copies = HashMap::new();
388 let mut all_copies = HashMap::new();
430 let mut oracle = AncestorOracle::new(is_ancestor);
431
389
432 let mut path_map = TwoWayPathMap::default();
390 let mut path_map = TwoWayPathMap::default();
433
391
@@ -450,7 +408,6 b' pub fn combine_changeset_copies<A: Fn(Re'
450 // combine it with data for that revision
408 // combine it with data for that revision
451 let vertex_copies = add_from_changes(
409 let vertex_copies = add_from_changes(
452 &mut path_map,
410 &mut path_map,
453 &mut oracle,
454 &parent_copies,
411 &parent_copies,
455 &changes,
412 &changes,
456 Parent::FirstParent,
413 Parent::FirstParent,
@@ -471,7 +428,6 b' pub fn combine_changeset_copies<A: Fn(Re'
471 // combine it with data for that revision
428 // combine it with data for that revision
472 let vertex_copies = add_from_changes(
429 let vertex_copies = add_from_changes(
473 &mut path_map,
430 &mut path_map,
474 &mut oracle,
475 &parent_copies,
431 &parent_copies,
476 &changes,
432 &changes,
477 Parent::SecondParent,
433 Parent::SecondParent,
@@ -491,7 +447,6 b' pub fn combine_changeset_copies<A: Fn(Re'
491 vertex_copies,
447 vertex_copies,
492 copies,
448 copies,
493 &changes,
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 /// Combine ChangedFiles with some existing PathCopies information and return
504 /// Combine ChangedFiles with some existing PathCopies information and return
550 /// the result
505 /// the result
551 fn add_from_changes<A: Fn(Revision, Revision) -> bool>(
506 fn add_from_changes(
552 path_map: &mut TwoWayPathMap,
507 path_map: &mut TwoWayPathMap,
553 oracle: &mut AncestorOracle<A>,
554 base_copies: &InternalPathCopies,
508 base_copies: &InternalPathCopies,
555 changes: &ChangedFiles,
509 changes: &ChangedFiles,
556 parent: Parent,
510 parent: Parent,
@@ -582,7 +536,6 b' fn add_from_changes<A: Fn(Revision, Revi'
582 }
536 }
583 Entry::Occupied(mut slot) => {
537 Entry::Occupied(mut slot) => {
584 let ttpc = slot.get_mut();
538 let ttpc = slot.get_mut();
585 oracle.record_overwrite(ttpc.rev, current_rev);
586 ttpc.overwrite(current_rev, entry);
539 ttpc.overwrite(current_rev, entry);
587 }
540 }
588 }
541 }
@@ -595,7 +548,6 b' fn add_from_changes<A: Fn(Revision, Revi'
595 // InternalPathCopies object.
548 // InternalPathCopies object.
596 let deleted = path_map.tokenize(deleted_path);
549 let deleted = path_map.tokenize(deleted_path);
597 copies.entry(deleted).and_modify(|old| {
550 copies.entry(deleted).and_modify(|old| {
598 oracle.record_overwrite(old.rev, current_rev);
599 old.mark_delete(current_rev);
551 old.mark_delete(current_rev);
600 });
552 });
601 }
553 }
@@ -608,26 +560,22 b' fn add_from_changes<A: Fn(Revision, Revi'
608 ///
560 ///
609 /// In case of conflict, value from "major" will be picked, unless in some
561 /// In case of conflict, value from "major" will be picked, unless in some
610 /// cases. See inline documentation for details.
562 /// cases. See inline documentation for details.
611 fn merge_copies_dict<A: Fn(Revision, Revision) -> bool>(
563 fn merge_copies_dict(
612 path_map: &TwoWayPathMap,
564 path_map: &TwoWayPathMap,
613 current_merge: Revision,
565 current_merge: Revision,
614 mut minor: InternalPathCopies,
566 mut minor: InternalPathCopies,
615 mut major: InternalPathCopies,
567 mut major: InternalPathCopies,
616 changes: &ChangedFiles,
568 changes: &ChangedFiles,
617 oracle: &mut AncestorOracle<A>,
618 ) -> InternalPathCopies {
569 ) -> InternalPathCopies {
619 // This closure exist as temporary help while multiple developper are
570 // This closure exist as temporary help while multiple developper are
620 // actively working on this code. Feel free to re-inline it once this
571 // actively working on this code. Feel free to re-inline it once this
621 // code is more settled.
572 // code is more settled.
622 let cmp_value = |oracle: &mut AncestorOracle<A>,
573 let cmp_value =
623 dest: &PathToken,
574 |dest: &PathToken, src_minor: &CopySource, src_major: &CopySource| {
624 src_minor: &CopySource,
625 src_major: &CopySource| {
626 compare_value(
575 compare_value(
627 path_map,
576 path_map,
628 current_merge,
577 current_merge,
629 changes,
578 changes,
630 oracle,
631 dest,
579 dest,
632 src_minor,
580 src_minor,
633 src_major,
581 src_major,
@@ -661,10 +609,8 b' fn merge_copies_dict<A: Fn(Revision, Rev'
661 }
609 }
662 Some(src_major) => {
610 Some(src_major) => {
663 let (pick, overwrite) =
611 let (pick, overwrite) =
664 cmp_value(oracle, &dest, &src_minor, src_major);
612 cmp_value(&dest, &src_minor, src_major);
665 if overwrite {
613 if overwrite {
666 oracle.record_overwrite(src_minor.rev, current_merge);
667 oracle.record_overwrite(src_major.rev, current_merge);
668 let src = match pick {
614 let src = match pick {
669 MergePick::Major => CopySource::new_from_merge(
615 MergePick::Major => CopySource::new_from_merge(
670 current_merge,
616 current_merge,
@@ -704,10 +650,8 b' fn merge_copies_dict<A: Fn(Revision, Rev'
704 }
650 }
705 Some(src_minor) => {
651 Some(src_minor) => {
706 let (pick, overwrite) =
652 let (pick, overwrite) =
707 cmp_value(oracle, &dest, src_minor, &src_major);
653 cmp_value(&dest, src_minor, &src_major);
708 if overwrite {
654 if overwrite {
709 oracle.record_overwrite(src_minor.rev, current_merge);
710 oracle.record_overwrite(src_major.rev, current_merge);
711 let src = match pick {
655 let src = match pick {
712 MergePick::Major => CopySource::new_from_merge(
656 MergePick::Major => CopySource::new_from_merge(
713 current_merge,
657 current_merge,
@@ -769,10 +713,8 b' fn merge_copies_dict<A: Fn(Revision, Rev'
769 let (dest, src_major) = new;
713 let (dest, src_major) = new;
770 let (_, src_minor) = old;
714 let (_, src_minor) = old;
771 let (pick, overwrite) =
715 let (pick, overwrite) =
772 cmp_value(oracle, dest, src_minor, src_major);
716 cmp_value(dest, src_minor, src_major);
773 if overwrite {
717 if overwrite {
774 oracle.record_overwrite(src_minor.rev, current_merge);
775 oracle.record_overwrite(src_major.rev, current_merge);
776 let src = match pick {
718 let src = match pick {
777 MergePick::Major => CopySource::new_from_merge(
719 MergePick::Major => CopySource::new_from_merge(
778 current_merge,
720 current_merge,
@@ -840,11 +782,10 b' enum MergePick {'
840
782
841 /// decide which side prevails in case of conflicting values
783 /// decide which side prevails in case of conflicting values
842 #[allow(clippy::if_same_then_else)]
784 #[allow(clippy::if_same_then_else)]
843 fn compare_value<A: Fn(Revision, Revision) -> bool>(
785 fn compare_value(
844 path_map: &TwoWayPathMap,
786 path_map: &TwoWayPathMap,
845 current_merge: Revision,
787 current_merge: Revision,
846 changes: &ChangedFiles,
788 changes: &ChangedFiles,
847 oracle: &mut AncestorOracle<A>,
848 dest: &PathToken,
789 dest: &PathToken,
849 src_minor: &CopySource,
790 src_minor: &CopySource,
850 src_major: &CopySource,
791 src_major: &CopySource,
@@ -1,5 +1,4 b''
1 use cpython::ObjectProtocol;
1 use cpython::ObjectProtocol;
2 use cpython::PyBool;
3 use cpython::PyBytes;
2 use cpython::PyBytes;
4 use cpython::PyDict;
3 use cpython::PyDict;
5 use cpython::PyList;
4 use cpython::PyList;
@@ -26,32 +25,10 b' pub fn combine_changeset_copies_wrapper('
26 children_count: PyDict,
25 children_count: PyDict,
27 target_rev: Revision,
26 target_rev: Revision,
28 rev_info: PyObject,
27 rev_info: PyObject,
29 is_ancestor: PyObject,
30 ) -> PyResult<PyDict> {
28 ) -> PyResult<PyDict> {
31 let revs: PyResult<_> =
29 let revs: PyResult<_> =
32 revs.iter(py).map(|r| Ok(r.extract(py)?)).collect();
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 // Wrap the `rev_info_maker` python callback as a Rust closure
32 // Wrap the `rev_info_maker` python callback as a Rust closure
56 //
33 //
57 // No errors are expected from the Python side, and they will should only
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 children_count?,
81 children_count?,
105 target_rev,
82 target_rev,
106 rev_info_maker,
83 rev_info_maker,
107 &is_ancestor_wrap,
108 );
84 );
109 let out = PyDict::new(py);
85 let out = PyDict::new(py);
110 for (dest, source) in res.into_iter() {
86 for (dest, source) in res.into_iter() {
@@ -134,8 +110,7 b' pub fn init_module(py: Python, package: '
134 revs: PyList,
110 revs: PyList,
135 children: PyDict,
111 children: PyDict,
136 target_rev: Revision,
112 target_rev: Revision,
137 rev_info: PyObject,
113 rev_info: PyObject
138 is_ancestor: PyObject
139 )
114 )
140 ),
115 ),
141 )?;
116 )?;
General Comments 0
You need to be logged in to leave comments. Login now