Skip to content

Commit 02b0785

Browse files
add diffCommonOverlap (#4)
1 parent e73969b commit 02b0785

1 file changed

Lines changed: 46 additions & 0 deletions

File tree

DiffMatchPatch.zig

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)