1
0
Fork 0
mirror of https://we.phorge.it/source/arcanist.git synced 2024-11-29 10:12:41 +01:00

Use PhutilEditDistanceMatrix in ArcanistDiffUtils

Summary: Replace this old hard-coded implementation with the new vector-based, unicode-capable one.

Test Plan: Ran unit tests. Looked at revisions in Differential, using whitespace modes to bypass cache.

Reviewers: btrahan, Afaque_Hussain

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T2379

Differential Revision: https://secure.phabricator.com/D6016
This commit is contained in:
epriestley 2013-05-23 14:36:42 -07:00
parent 4c37e6ff4a
commit 24d54a5fbd
3 changed files with 14 additions and 126 deletions

View file

@ -210,133 +210,20 @@ final class ArcanistDiffUtils {
return str_repeat('d', $olt); return str_repeat('d', $olt);
} }
$min = min($olt, $nlt); if ($o === $n) {
$t_start = microtime(true); return str_repeat('s', $olt);
$pre = 0;
while ($pre < $min && $o[$pre] == $n[$pre]) {
$pre++;
} }
$end = 0; $ov = str_split($o);
while ($end < $min && $o[($olt - 1) - $end] == $n[($nlt - 1) - $end]) { $nv = str_split($n);
$end++;
}
if ($end + $pre >= $min) { return id(new PhutilEditDistanceMatrix())
$end = min($end, $min - $pre); ->setComputeString(true)
$prefix = str_repeat('s', $pre); ->setAlterCost(0.001)
$suffix = str_repeat('s', $end); ->setReplaceCost(2)
$infix = null; ->setMaximumLength(80)
if ($olt > $nlt) { ->setSequences($ov, $nv)
$infix = str_repeat('d', $olt - ($end + $pre)); ->getEditString();
} else if ($nlt > $olt) {
$infix = str_repeat('i', $nlt - ($end + $pre));
}
return $prefix.$infix.$suffix;
}
if ($min - ($end + $pre) > 80) {
$max = max($olt, $nlt);
return str_repeat('x', $min) .
str_repeat($olt < $nlt ? 'i' : 'd', $max - $min);
}
$prefix = str_repeat('s', $pre);
$suffix = str_repeat('s', $end);
$o = substr($o, $pre, $olt - $end - $pre);
$n = substr($n, $pre, $nlt - $end - $pre);
$ol = strlen($o);
$nl = strlen($n);
$m = array_fill(0, $ol + 1, array_fill(0, $nl + 1, array()));
$t_d = 'd';
$t_i = 'i';
$t_s = 's';
$t_x = 'x';
$m[0][0] = array(
0,
null);
for ($ii = 1; $ii <= $ol; $ii++) {
$m[$ii][0] = array(
$ii * 1000,
$t_d);
}
for ($jj = 1; $jj <= $nl; $jj++) {
$m[0][$jj] = array(
$jj * 1000,
$t_i);
}
$ii = 1;
do {
$jj = 1;
do {
if ($o[$ii - 1] == $n[$jj - 1]) {
$sub_t_cost = $m[$ii - 1][$jj - 1][0] + 0;
$sub_t = $t_s;
} else {
$sub_t_cost = $m[$ii - 1][$jj - 1][0] + 2000;
$sub_t = $t_x;
}
if ($m[$ii - 1][$jj - 1][1] != $sub_t) {
$sub_t_cost += 1;
}
$del_t_cost = $m[$ii - 1][$jj][0] + 1000;
if ($m[$ii - 1][$jj][1] != $t_d) {
$del_t_cost += 1;
}
$ins_t_cost = $m[$ii][$jj - 1][0] + 1000;
if ($m[$ii][$jj - 1][1] != $t_i) {
$ins_t_cost += 1;
}
if ($sub_t_cost <= $del_t_cost && $sub_t_cost <= $ins_t_cost) {
$m[$ii][$jj] = array(
$sub_t_cost,
$sub_t);
} else if ($ins_t_cost <= $del_t_cost) {
$m[$ii][$jj] = array(
$ins_t_cost,
$t_i);
} else {
$m[$ii][$jj] = array(
$del_t_cost,
$t_d);
}
} while ($jj++ < $nl);
} while ($ii++ < $ol);
$result = '';
$ii = $ol;
$jj = $nl;
do {
$r = $m[$ii][$jj][1];
$result .= $r;
switch ($r) {
case $t_s:
case $t_x:
$ii--;
$jj--;
break;
case $t_i:
$jj--;
break;
case $t_d:
$ii--;
break;
}
} while ($ii || $jj);
return $prefix.strrev($result).$suffix;
} }
public static function generateUTF8IntralineDiff($o, $n) { public static function generateUTF8IntralineDiff($o, $n) {

View file

@ -94,7 +94,8 @@ final class ArcanistDiffUtilsTestCase extends ArcanistTestCase {
$test[2], $test[2],
ArcanistDiffUtils::buildLevenshteinDifferenceString( ArcanistDiffUtils::buildLevenshteinDifferenceString(
$test[0], $test[0],
$test[1])); $test[1]),
"'{$test[0]}' vs '{$test[1]}'");
} }
} }

View file

@ -68,7 +68,7 @@ abstract class ArcanistPhutilTestCase {
if (strpos($expect, "\n") === false && strpos($result, "\n") === false) { if (strpos($expect, "\n") === false && strpos($result, "\n") === false) {
$output .= "Expected: {$expect}\n"; $output .= "Expected: {$expect}\n";
$output .= "Actual: {$result}"; $output .= " Actual: {$result}";
} else { } else {
$output .= "Expected vs Actual Output Diff\n"; $output .= "Expected vs Actual Output Diff\n";
$output .= ArcanistDiffUtils::renderDifferences( $output .= ArcanistDiffUtils::renderDifferences(