|
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