Skip to content

Commit b00d838

Browse files
committed
Merge branch 'pullrequest_7'
2 parents 2b5d300 + efd1062 commit b00d838

4 files changed

Lines changed: 73 additions & 44 deletions

File tree

src/Diff.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ class Diff
4343
const INSERT = 1;
4444
const EQUAL = 0;
4545

46+
/**
47+
* Number of characters at which line mode speedup is employed.
48+
*/
49+
const LINEMODE_THRESOLD = 100;
50+
4651
/**
4752
* @var float Number of seconds to map a diff before giving up (0 for infinity).
4853
*/
@@ -1099,7 +1104,9 @@ protected function compute($text1, $text2, $checklines, $deadline)
10991104
}
11001105
}
11011106

1102-
if ($checklines && mb_strlen($text1) > 100 && mb_strlen($text2) > 100) {
1107+
if ($checklines
1108+
&& mb_strlen($text1) > Diff::LINEMODE_THRESOLD
1109+
&& mb_strlen($text2) > Diff::LINEMODE_THRESOLD) {
11031110
return $this->lineMode($text1, $text2, $deadline);
11041111
}
11051112

src/DiffToolkit.php

Lines changed: 13 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -293,44 +293,23 @@ protected function linesToCharsMunge($text, array &$lineArray, array &$lineHash)
293293
// explode('\n', $text) would temporarily double our memory footprint,
294294
// but mb_strpos() and mb_substr() work slow
295295
$lines = explode($delimiter, $text);
296+
297+
$last_line_has_delimiter = end($lines) === '';
298+
if ($last_line_has_delimiter) {
299+
array_pop($lines);
300+
}
301+
296302
foreach ($lines as $i => $line) {
297-
if (mb_strlen($line)) {
298-
if (isset($lines[$i + 1])) {
299-
$line .= $delimiter;
300-
}
301-
if (isset($lineHash[$line])) {
302-
$chars .= Utils::unicodeChr($lineHash[$line]);
303-
} else {
304-
$lineArray[] = $line;
305-
$lineHash[$line] = count($lineArray) - 1;
306-
$chars .= Utils::unicodeChr(count($lineArray) - 1);
307-
}
303+
if (isset($lines[$i + 1]) || $last_line_has_delimiter) {
304+
$line .= $delimiter;
308305
}
306+
if (!isset($lineHash[$line])) {
307+
$lineArray[] = $line;
308+
$lineHash[$line] = count($lineArray) - 1;
309+
}
310+
$chars .= Utils::unicodeChr($lineHash[$line]);
309311
}
310312

311-
// // Walk the text, pulling out a substring for each line.
312-
// // explode('\n', $text) would temporarily double our memory footprint.
313-
// // Modifying text would create many large strings to garbage collect.
314-
// $lineStart = 0;
315-
// $lineEnd = -1;
316-
// $textLen = mb_strlen($text);
317-
// while ($lineEnd < $textLen - 1) {
318-
// $lineEnd = mb_strpos($text, "\n", $lineStart);
319-
// if ($lineEnd === false) {
320-
// $lineEnd = $textLen - 1;
321-
// }
322-
// $line = mb_substr($text, $lineStart, $lineEnd + 1 - $lineStart);
323-
// $lineStart = $lineEnd + 1;
324-
//
325-
// if (isset($lineHash[$line])) {
326-
// $chars .= Utils::unicodeChr($lineHash[$line]);
327-
// } else {
328-
// $lineArray[] = $line;
329-
// $lineHash[$line] = count($lineArray) - 1;
330-
// $chars .= Utils::unicodeChr(count($lineArray) - 1);
331-
// }
332-
// }
333-
334313
return $chars;
335314
}
336315

tests/DiffMatchPatchTest.php

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -165,13 +165,36 @@ public function testPatchMake()
165165
$this->assertEquals($expected, $this->dmp->patch_toText($patches));
166166
}
167167

168-
public function testPatchApply()
169-
{
170-
$patches = $this->dmp->patch_make("The quick brown fox jumps over the lazy dog.", "That quick brown fox jumped over a lazy dog.");
171-
$this->assertEquals(
172-
array("That quick red rabbit jumped over a tired tiger.", array(true, true,)),
173-
$this->dmp->patch_apply($patches, "The quick red rabbit jumps over the tired tiger.")
174-
);
168+
protected function _testPatchApply($text1, $text2, $target = NULL, $expected = NULL) {
169+
if ($target === NULL) {
170+
$target = $text1;
171+
}
172+
if ($expected === NULL) {
173+
$expected = $text2;
174+
}
175+
176+
$patches = $this->dmp->patch_make($text1, $text2);
177+
$this->assertEquals(
178+
array($expected, array_map(function() { return TRUE; }, $patches)),
179+
$this->dmp->patch_apply($patches, $target)
180+
);
181+
}
182+
183+
public function testPatchApply() {
184+
$this->_testPatchApply(
185+
"The quick brown fox jumps over the lazy dog.",
186+
"That quick brown fox jumped over a lazy dog.",
187+
"The quick red rabbit jumps over the tired tiger.",
188+
"That quick red rabbit jumped over a tired tiger."
189+
);
190+
}
191+
192+
public function testPatchApply_2() {
193+
$linemode_pad = str_pad('pad', Diff::LINEMODE_THRESOLD, 'x');
194+
$this->_testPatchApply(
195+
"line number one\n\nLine number three" . $linemode_pad . 'a',
196+
"LINE number one\nThe second line\n\nThis is Line number three" . $linemode_pad . 'b'
197+
);
175198
}
176199

177200
}

tests/DiffTest.php

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -843,8 +843,28 @@ public function testMain()
843843
// Test the linemode speedup.
844844
// Must be long to pass the 100 char cutoff.
845845
// Simple line-mode.
846-
$a = str_repeat("1234567890\n", 13);
847-
$b = str_repeat("abcdefghij\n", 13);
846+
$a = str_repeat("1234567890\n", ceil(Diff::LINEMODE_THRESOLD / strlen($a)));
847+
$b = str_repeat("abcdefghij\n", ceil(Diff::LINEMODE_THRESOLD / strlen($b)));
848+
$this->assertEquals(
849+
$this->d->main($a, $b, false)->getChanges(),
850+
$this->d->main($a, $b, true)->getChanges()
851+
);
852+
853+
// Simple line-mode with multiple line breaks.
854+
$a = "12345\n\n67890\n";
855+
$a = str_repeat($a, ceil(Diff::LINEMODE_THRESOLD / strlen($a)));
856+
$b = "abcde\n\nfghij\n";
857+
$b = str_repeat($b, ceil(Diff::LINEMODE_THRESOLD / strlen($b)));
858+
$this->assertEquals(
859+
$this->d->main($a, $b, false)->getChanges(),
860+
$this->d->main($a, $b, true)->getChanges()
861+
);
862+
863+
// Simple line-mode with multiple line breaks but without leading line break
864+
$a = "12345\n\n67890\n";
865+
$a = str_repeat($a, ceil(Diff::LINEMODE_THRESOLD / strlen($a))) . '0';
866+
$b = "abcde\n\nfghij\n";
867+
$b = str_repeat($b, ceil(Diff::LINEMODE_THRESOLD / strlen($b))) . 'a ';
848868
$this->assertEquals(
849869
$this->d->main($a, $b, false)->getChanges(),
850870
$this->d->main($a, $b, true)->getChanges()

0 commit comments

Comments
 (0)