| | $oldSlice = array_slice( $oldLines, $start, $m - $start - $end ); |
| | $newSlice = array_slice( $newLines, $start, $n - $start - $end ); |
| | - $countOld = count( $oldSlice ); |
| | - $countNew = count( $newSlice ); |
| | $limit = 100000; |
| | - $result = []; |
| | + $stream = []; |
| | |
| | - if( ($countOld * $countNew) > $limit ) { |
| | - $result = $this->buildFallbackDiff( $oldSlice, $newSlice, $start ); |
| | + for( $i = 0; $i < $start; $i++ ) { |
| | + $stream[] = [ |
| | + 't' => ' ', |
| | + 'l' => $oldLines[$i], |
| | + 'no' => $i + 1, |
| | + 'nn' => $i + 1 |
| | + ]; |
| | + } |
| | + |
| | + $mid = []; |
| | + |
| | + if( (count( $oldSlice ) * count( $newSlice )) > $limit ) { |
| | + $mid = $this->buildFallbackDiff( $oldSlice, $newSlice, $start ); |
| | } else { |
| | - $ops = $this->computeLCS( $oldSlice, $newSlice ); |
| | - $stream = $this->buildDiffStream( $ops, $start ); |
| | - $result = $this->formatDiffOutput( $stream ); |
| | + $ops = $this->computeLCS( $oldSlice, $newSlice ); |
| | + $mid = $this->buildDiffStream( $ops, $start ); |
| | } |
| | |
| | - return $result; |
| | + foreach( $mid as $line ) { |
| | + $stream[] = $line; |
| | + } |
| | + |
| | + for( $i = 0; $i < $end; $i++ ) { |
| | + $idxO = $m - $end + $i; |
| | + $idxN = $n - $end + $i; |
| | + $stream[] = [ |
| | + 't' => ' ', |
| | + 'l' => $oldLines[$idxO], |
| | + 'no' => $idxO + 1, |
| | + 'nn' => $idxN + 1 |
| | + ]; |
| | + } |
| | + |
| | + return $this->formatDiffOutput( $stream ); |
| | } |
| | |
 |
| | |
| | return $stream; |
| | + } |
| | + |
| | +private function calculateDiff( string $old, string $new ): array { |
| | + $oldLines = explode( "\n", str_replace( "\r\n", "\n", $old ) ); |
| | + $newLines = explode( "\n", str_replace( "\r\n", "\n", $new ) ); |
| | + $m = count( $oldLines ); |
| | + $n = count( $newLines ); |
| | + $start = 0; |
| | + $end = 0; |
| | + |
| | + while( $start < $m && $start < $n && |
| | + $oldLines[$start] === $newLines[$start] ) { |
| | + $start++; |
| | + } |
| | + |
| | + while( $m - $end > $start && $n - $end > $start && |
| | + $oldLines[$m - 1 - $end] === $newLines[$n - 1 - $end] ) { |
| | + $end++; |
| | + } |
| | + |
| | + $oldSlice = array_slice( $oldLines, $start, $m - $start - $end ); |
| | + $newSlice = array_slice( $newLines, $start, $n - $start - $end ); |
| | + $limit = 100000; |
| | + $stream = []; |
| | + |
| | + for( $i = 0; $i < $start; $i++ ) { |
| | + $stream[] = [ |
| | + 't' => ' ', |
| | + 'l' => $oldLines[$i], |
| | + 'no' => $i + 1, |
| | + 'nn' => $i + 1 |
| | + ]; |
| | + } |
| | + |
| | + $mid = []; |
| | + |
| | + if( (count( $oldSlice ) * count( $newSlice )) > $limit ) { |
| | + $mid = $this->buildFallbackDiff( $oldSlice, $newSlice, $start ); |
| | + } else { |
| | + $ops = $this->computeLCS( $oldSlice, $newSlice ); |
| | + $mid = $this->buildDiffStream( $ops, $start ); |
| | + } |
| | + |
| | + foreach( $mid as $line ) { |
| | + $stream[] = $line; |
| | + } |
| | + |
| | + for( $i = 0; $i < $end; $i++ ) { |
| | + $idxO = $m - $end + $i; |
| | + $idxN = $n - $end + $i; |
| | + $stream[] = [ |
| | + 't' => ' ', |
| | + 'l' => $oldLines[$idxO], |
| | + 'no' => $idxO + 1, |
| | + 'nn' => $idxN + 1 |
| | + ]; |
| | + } |
| | + |
| | + return $this->formatDiffOutput( $stream ); |
| | } |
| | |
| | private function formatDiffOutput( array $stream ): array { |
| | $n = count( $stream ); |
| | $keep = array_fill( 0, $n, false ); |
| | - $context = 4; |
| | + $context = 2; |
| | |
| | for( $i = 0; $i < $n; $i++ ) { |
 |
| | |
| | $result = []; |
| | - $isGap = false; |
| | + $buffer = []; |
| | |
| | for( $i = 0; $i < $n; $i++ ) { |
| | if( $keep[$i] ) { |
| | + $cnt = count( $buffer ); |
| | + |
| | + if( $cnt > 0 ) { |
| | + if( $cnt > 5 ) { |
| | + $result[] = [ 't' => 'gap' ]; |
| | + } else { |
| | + foreach( $buffer as $bufLine ) { |
| | + $result[] = $bufLine; |
| | + } |
| | + } |
| | + $buffer = []; |
| | + } |
| | + |
| | $result[] = $stream[$i]; |
| | - $isGap = false; |
| | - } elseif( !$isGap ) { |
| | + } else { |
| | + $buffer[] = $stream[$i]; |
| | + } |
| | + } |
| | + |
| | + $cnt = count( $buffer ); |
| | + |
| | + if( $cnt > 0 ) { |
| | + if( $cnt > 5 ) { |
| | $result[] = [ 't' => 'gap' ]; |
| | - $isGap = true; |
| | + } else { |
| | + foreach( $buffer as $bufLine ) { |
| | + $result[] = $bufLine; |
| | + } |
| | } |
| | } |