|
46 | 46 |
|
47 | 47 | use SebastianBergmann\Diff\LCS\LongestCommonSubsequence;
|
48 | 48 | use SebastianBergmann\Diff\LCS\TimeEfficientImplementation;
|
| 49 | +use SebastianBergmann\Diff\LCS\MemoryEfficientImplementation; |
49 | 50 |
|
50 | 51 | /**
|
51 | 52 | * Diff implementation.
|
@@ -156,10 +157,6 @@ public function diff($from, $to, LongestCommonSubsequence $lcs = null)
|
156 | 157 | */
|
157 | 158 | public function diffToArray($from, $to, LongestCommonSubsequence $lcs = null)
|
158 | 159 | {
|
159 |
| - if ($lcs === null) { |
160 |
| - $lcs = $this->selectLcsImplementation($from, $to); |
161 |
| - } |
162 |
| - |
163 | 160 | preg_match_all('(\r\n|\r|\n)', $from, $fromMatches);
|
164 | 161 | preg_match_all('(\r\n|\r|\n)', $to, $toMatches);
|
165 | 162 |
|
@@ -197,6 +194,10 @@ public function diffToArray($from, $to, LongestCommonSubsequence $lcs = null)
|
197 | 194 | }
|
198 | 195 | }
|
199 | 196 |
|
| 197 | + if ($lcs === null) { |
| 198 | + $lcs = $this->selectLcsImplementation($from, $to); |
| 199 | + } |
| 200 | + |
200 | 201 | $common = $lcs->calculate(array_values($from), array_values($to));
|
201 | 202 | $diff = array();
|
202 | 203 |
|
@@ -252,7 +253,26 @@ public function diffToArray($from, $to, LongestCommonSubsequence $lcs = null)
|
252 | 253 | */
|
253 | 254 | private function selectLcsImplementation($from, $to)
|
254 | 255 | {
|
255 |
| - // @todo Automagically choose best strategy based on input size |
| 256 | + // We don't want to use the time efficient implementation if it's memory |
| 257 | + // footprint will probably exceed this value. Note that the footprint |
| 258 | + // calculation is only an estimation for the matrix and the LCS method |
| 259 | + // will typically allocate a bit more memory than this. |
| 260 | + $memoryLimit = 100 * 1024*1024; |
| 261 | + if ($this->calculateEstimatedFootprint($from, $to) > $memoryLimit) { |
| 262 | + return new MemoryEfficientImplementation; |
| 263 | + } |
256 | 264 | return new TimeEfficientImplementation;
|
257 | 265 | }
|
| 266 | + |
| 267 | + /** |
| 268 | + * Calculates the estimated memory footprint for the DP-based method. |
| 269 | + * |
| 270 | + * @param type $from |
| 271 | + * @param type $to |
| 272 | + */ |
| 273 | + private function calculateEstimatedFootprint($from, $to) |
| 274 | + { |
| 275 | + $itemSize = PHP_INT_SIZE == 4 ? 76 : 144; |
| 276 | + return $itemSize * pow(min(count($from), count($to)), 2); |
| 277 | + } |
258 | 278 | }
|
0 commit comments