@@ -1079,3 +1079,49 @@ pub fn diffCleanupEfficiency(
10791079 try diffCleanupMerge (allocator , diffs );
10801080 }
10811081}
1082+
1083+ //
1084+ // Determine if the suffix of one string is the prefix of another.
1085+ // @param text1 First string.
1086+ // @param text2 Second string.
1087+ // @return The number of characters common to the end of the first
1088+ // string and the start of the second string.
1089+ //
1090+ fn diffCommonOverlap (text1 : []const u8 , text2 : []const u8 ) usize {
1091+ // Cache the text lengths to prevent multiple calls.
1092+ var text1_length = text1 .len ;
1093+ var text2_length = text2 .len ;
1094+ // Eliminate the null case.
1095+ if (text1_length == 0 or text2_length == 0 ) {
1096+ return 0 ;
1097+ }
1098+ // Truncate the longer string.
1099+ if (text1_length > text2_length ) {
1100+ text1 = text1 [text1_length - text2_length .. ];
1101+ } else if (text1_length < text2_length ) {
1102+ text2 = text2 [0.. text1_length ];
1103+ }
1104+ const text_length = @min (text1_length , text2_length );
1105+ // Quick check for the worst case.
1106+ if (text1 == text2 ) {
1107+ return text_length ;
1108+ }
1109+
1110+ // Start by looking for a single character match
1111+ // and increase length until no match is found.
1112+ // Performance analysis: https://neil.fraser.name/news/2010/11/04/
1113+ var best : usize = 0 ;
1114+ var length : usize = 1 ;
1115+ while (true ) {
1116+ const pattern = text1 [text_length - length .. ];
1117+ const found = mem .indexOf (u8 , text2 , pattern ) orelse
1118+ return best ;
1119+
1120+ length += found ;
1121+
1122+ if (found == 0 or mem .eql (u8 , text1 [text_length - length .. ], text2 [0.. length ])) {
1123+ best = length ;
1124+ length += 1 ;
1125+ }
1126+ }
1127+ }
0 commit comments