comparison rust/hg-core/src/copy_tracing.rs @ 46611:b6f65d90e8af

copies-rust: add methods to build and update CopySource Having explicit method with clear semantic help to clarify the code and prepare an update to the underlying documentation without too much disruption. Differential Revision: https://phab.mercurial-scm.org/D9643
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Wed, 23 Dec 2020 03:04:43 +0100
parents 3c5a8b13206a
children 0d840b9d200d
comparison
equal deleted inserted replaced
46610:3c5a8b13206a 46611:b6f65d90e8af
13 13
14 pub type PathCopies = HashMap<HgPathBuf, HgPathBuf>; 14 pub type PathCopies = HashMap<HgPathBuf, HgPathBuf>;
15 15
16 type PathToken = usize; 16 type PathToken = usize;
17 17
18 #[derive(Clone, Debug, PartialEq, Copy)] 18 #[derive(Clone, Debug, PartialEq)]
19 struct CopySource { 19 struct CopySource {
20 /// revision at which the copy information was added 20 /// revision at which the copy information was added
21 rev: Revision, 21 rev: Revision,
22 /// the copy source, (Set to None in case of deletion of the associated 22 /// the copy source, (Set to None in case of deletion of the associated
23 /// key) 23 /// key)
24 path: Option<PathToken>, 24 path: Option<PathToken>,
25 }
26
27 impl CopySource {
28 /// create a new CopySource
29 ///
30 /// Use this when no previous copy source existed.
31 fn new(rev: Revision, path: Option<PathToken>) -> Self {
32 Self { rev, path }
33 }
34
35 /// create a new CopySource from merging two others
36 ///
37 /// Use this when merging two InternalPathCopies requires active merging of
38 /// some entries.
39 fn new_from_merge(rev: Revision, winner: &Self, loser: &Self) -> Self {
40 Self {
41 rev,
42 path: winner.path,
43 }
44 }
45
46 /// Update the value of a pre-existing CopySource
47 ///
48 /// Use this when recording copy information from parent → child edges
49 fn overwrite(&mut self, rev: Revision, path: Option<PathToken>) {
50 self.rev = rev;
51 self.path = path;
52 }
53
54 /// Mark pre-existing copy information as "dropped" by a file deletion
55 ///
56 /// Use this when recording copy information from parent → child edges
57 fn mark_delete(&mut self, rev: Revision) {
58 self.rev = rev;
59 self.path = None;
60 }
25 } 61 }
26 62
27 /// maps CopyDestination to Copy Source (+ a "timestamp" for the operation) 63 /// maps CopyDestination to Copy Source (+ a "timestamp" for the operation)
28 type InternalPathCopies = OrdMap<PathToken, CopySource>; 64 type InternalPathCopies = OrdMap<PathToken, CopySource>;
29 65
519 // record this information as we will need it to take 555 // record this information as we will need it to take
520 // the right decision when merging conflicting copy 556 // the right decision when merging conflicting copy
521 // information. See merge_copies_dict for details. 557 // information. See merge_copies_dict for details.
522 match copies.entry(dest) { 558 match copies.entry(dest) {
523 Entry::Vacant(slot) => { 559 Entry::Vacant(slot) => {
524 let ttpc = CopySource { 560 let ttpc = CopySource::new(current_rev, entry);
525 rev: current_rev,
526 path: entry,
527 };
528 slot.insert(ttpc); 561 slot.insert(ttpc);
529 } 562 }
530 Entry::Occupied(mut slot) => { 563 Entry::Occupied(mut slot) => {
531 let mut ttpc = slot.get_mut(); 564 let ttpc = slot.get_mut();
532 oracle.record_overwrite(ttpc.rev, current_rev); 565 oracle.record_overwrite(ttpc.rev, current_rev);
533 ttpc.rev = current_rev; 566 ttpc.overwrite(current_rev, entry);
534 ttpc.path = entry;
535 } 567 }
536 } 568 }
537 } 569 }
538 Action::Removed(deleted_path) => { 570 Action::Removed(deleted_path) => {
539 // We must drop copy information for removed file. 571 // We must drop copy information for removed file.
542 // propagate this information when merging two 574 // propagate this information when merging two
543 // InternalPathCopies object. 575 // InternalPathCopies object.
544 let deleted = path_map.tokenize(deleted_path); 576 let deleted = path_map.tokenize(deleted_path);
545 copies.entry(deleted).and_modify(|old| { 577 copies.entry(deleted).and_modify(|old| {
546 oracle.record_overwrite(old.rev, current_rev); 578 oracle.record_overwrite(old.rev, current_rev);
547 old.rev = current_rev; 579 old.mark_delete(current_rev);
548 old.path = None;
549 }); 580 });
550 } 581 }
551 } 582 }
552 } 583 }
553 copies 584 copies
612 let (pick, overwrite) = 643 let (pick, overwrite) =
613 cmp_value(oracle, &dest, &src_minor, src_major); 644 cmp_value(oracle, &dest, &src_minor, src_major);
614 if overwrite { 645 if overwrite {
615 oracle.record_overwrite(src_minor.rev, current_merge); 646 oracle.record_overwrite(src_minor.rev, current_merge);
616 oracle.record_overwrite(src_major.rev, current_merge); 647 oracle.record_overwrite(src_major.rev, current_merge);
617 let path = match pick { 648 let src = match pick {
618 MergePick::Major => src_major.path, 649 MergePick::Major => CopySource::new_from_merge(
619 MergePick::Minor => src_minor.path, 650 current_merge,
620 MergePick::Any => src_major.path, 651 src_major,
621 }; 652 &src_minor,
622 let src = CopySource { 653 ),
623 rev: current_merge, 654 MergePick::Minor => CopySource::new_from_merge(
624 path, 655 current_merge,
656 &src_minor,
657 src_major,
658 ),
659 MergePick::Any => CopySource::new_from_merge(
660 current_merge,
661 src_major,
662 &src_minor,
663 ),
625 }; 664 };
626 major.insert(dest, src); 665 major.insert(dest, src);
627 } else { 666 } else {
628 match pick { 667 match pick {
629 MergePick::Any | MergePick::Major => None, 668 MergePick::Any | MergePick::Major => None,
647 let (pick, overwrite) = 686 let (pick, overwrite) =
648 cmp_value(oracle, &dest, src_minor, &src_major); 687 cmp_value(oracle, &dest, src_minor, &src_major);
649 if overwrite { 688 if overwrite {
650 oracle.record_overwrite(src_minor.rev, current_merge); 689 oracle.record_overwrite(src_minor.rev, current_merge);
651 oracle.record_overwrite(src_major.rev, current_merge); 690 oracle.record_overwrite(src_major.rev, current_merge);
652 let path = match pick { 691 let src = match pick {
653 MergePick::Major => src_minor.path, 692 MergePick::Major => CopySource::new_from_merge(
654 MergePick::Minor => src_major.path, 693 current_merge,
655 MergePick::Any => src_major.path, 694 &src_major,
656 }; 695 src_minor,
657 let src = CopySource { 696 ),
658 rev: current_merge, 697 MergePick::Minor => CopySource::new_from_merge(
659 path, 698 current_merge,
699 src_minor,
700 &src_major,
701 ),
702 MergePick::Any => CopySource::new_from_merge(
703 current_merge,
704 &src_major,
705 src_minor,
706 ),
660 }; 707 };
661 minor.insert(dest, src); 708 minor.insert(dest, src);
662 } else { 709 } else {
663 match pick { 710 match pick {
664 MergePick::Any | MergePick::Minor => None, 711 MergePick::Any | MergePick::Minor => None,
704 let (pick, overwrite) = 751 let (pick, overwrite) =
705 cmp_value(oracle, dest, src_minor, src_major); 752 cmp_value(oracle, dest, src_minor, src_major);
706 if overwrite { 753 if overwrite {
707 oracle.record_overwrite(src_minor.rev, current_merge); 754 oracle.record_overwrite(src_minor.rev, current_merge);
708 oracle.record_overwrite(src_major.rev, current_merge); 755 oracle.record_overwrite(src_major.rev, current_merge);
709 let path = match pick { 756 let src = match pick {
710 MergePick::Major => src_major.path, 757 MergePick::Major => CopySource::new_from_merge(
711 MergePick::Minor => src_minor.path, 758 current_merge,
712 // If the two entry are identical, no need to do 759 src_major,
713 // anything (but diff should not have yield them) 760 src_minor,
714 MergePick::Any => src_major.path, 761 ),
715 }; 762 MergePick::Minor => CopySource::new_from_merge(
716 let src = CopySource { 763 current_merge,
717 rev: current_merge, 764 src_minor,
718 path, 765 src_major,
766 ),
767 MergePick::Any => CopySource::new_from_merge(
768 current_merge,
769 src_major,
770 src_minor,
771 ),
719 }; 772 };
720 to_minor(dest, &src); 773 to_minor(dest, &src);
721 to_major(dest, &src); 774 to_major(dest, &src);
722 } else { 775 } else {
723 match pick { 776 match pick {