rust/hg-core/src/copy_tracing.rs
changeset 46128 c94d013e2299
parent 46127 c58c8f1d63b1
child 46129 818502d2f5e3
equal deleted inserted replaced
46127:c58c8f1d63b1 46128:c94d013e2299
   456 /// merge two copies-mapping together, minor and major
   456 /// merge two copies-mapping together, minor and major
   457 ///
   457 ///
   458 /// In case of conflict, value from "major" will be picked, unless in some
   458 /// In case of conflict, value from "major" will be picked, unless in some
   459 /// cases. See inline documentation for details.
   459 /// cases. See inline documentation for details.
   460 fn merge_copies_dict<A: Fn(Revision, Revision) -> bool>(
   460 fn merge_copies_dict<A: Fn(Revision, Revision) -> bool>(
   461     minor: TimeStampedPathCopies,
   461     mut minor: TimeStampedPathCopies,
   462     major: TimeStampedPathCopies,
   462     mut major: TimeStampedPathCopies,
   463     changes: &ChangedFiles,
   463     changes: &ChangedFiles,
   464     oracle: &mut AncestorOracle<A>,
   464     oracle: &mut AncestorOracle<A>,
   465 ) -> TimeStampedPathCopies {
   465 ) -> TimeStampedPathCopies {
   466     // This closure exist as temporary help while multiple developper are
   466     // This closure exist as temporary help while multiple developper are
   467     // actively working on this code. Feel free to re-inline it once this
   467     // actively working on this code. Feel free to re-inline it once this
   473             compare_value(changes, oracle, dest, src_minor, src_major)
   473             compare_value(changes, oracle, dest, src_minor, src_major)
   474         };
   474         };
   475     if minor.is_empty() {
   475     if minor.is_empty() {
   476         major
   476         major
   477     } else if major.is_empty() {
   477     } else if major.is_empty() {
       
   478         minor
       
   479     } else if minor.len() * 2 < major.len() {
       
   480         // Lets says we are merging two TimeStampedPathCopies instance A and B.
       
   481         //
       
   482         // If A contains N items, the merge result will never contains more
       
   483         // than N values differents than the one in A
       
   484         //
       
   485         // If B contains M items, with M > N, the merge result will always
       
   486         // result in a minimum of M - N value differents than the on in
       
   487         // A
       
   488         //
       
   489         // As a result, if N < (M-N), we know that simply iterating over A will
       
   490         // yield less difference than iterating over the difference
       
   491         // between A and B.
       
   492         //
       
   493         // This help performance a lot in case were a tiny
       
   494         // TimeStampedPathCopies is merged with a much larger one.
       
   495         for (dest, src_minor) in minor {
       
   496             let src_major = major.get(&dest);
       
   497             match src_major {
       
   498                 None => major.insert(dest, src_minor),
       
   499                 Some(src_major) => {
       
   500                     match cmp_value(&dest, &src_minor, src_major) {
       
   501                         MergePick::Any | MergePick::Major => None,
       
   502                         MergePick::Minor => major.insert(dest, src_minor),
       
   503                     }
       
   504                 }
       
   505             };
       
   506         }
       
   507         major
       
   508     } else if major.len() * 2 < minor.len() {
       
   509         // This use the same rational than the previous block.
       
   510         // (Check previous block documentation for details.)
       
   511         for (dest, src_major) in major {
       
   512             let src_minor = minor.get(&dest);
       
   513             match src_minor {
       
   514                 None => minor.insert(dest, src_major),
       
   515                 Some(src_minor) => {
       
   516                     match cmp_value(&dest, src_minor, &src_major) {
       
   517                         MergePick::Any | MergePick::Minor => None,
       
   518                         MergePick::Major => minor.insert(dest, src_major),
       
   519                     }
       
   520                 }
       
   521             };
       
   522         }
   478         minor
   523         minor
   479     } else {
   524     } else {
   480         let mut override_minor = Vec::new();
   525         let mut override_minor = Vec::new();
   481         let mut override_major = Vec::new();
   526         let mut override_major = Vec::new();
   482 
   527