Skip to content

Commit a7a71d7

Browse files
committed
Improve diff computer
1 parent 0124336 commit a7a71d7

1 file changed

Lines changed: 71 additions & 74 deletions

File tree

src/vs/editor/common/diff/diffComputer.ts

Lines changed: 71 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -11,87 +11,51 @@ import { ICharChange, ILineChange } from 'vs/editor/common/editorCommon';
1111
const MAXIMUM_RUN_TIME = 5000; // 5 seconds
1212
const MINIMUM_MATCHING_CHARACTER_LENGTH = 3;
1313

14-
interface IMarker {
15-
lineNumber: number;
16-
column: number;
17-
offset: number;
18-
}
19-
2014
function computeDiff(originalSequence: ISequence, modifiedSequence: ISequence, continueProcessingPredicate: () => boolean, pretty: boolean): IDiffChange[] {
2115
const diffAlgo = new LcsDiff(originalSequence, modifiedSequence, continueProcessingPredicate);
2216
return diffAlgo.ComputeDiff(pretty);
2317
}
2418

25-
class MarkerSequence implements ISequence {
19+
class LineMarkerSequence implements ISequence {
2620

27-
public buffer: string;
28-
public startMarkers: IMarker[];
29-
public endMarkers: IMarker[];
21+
private readonly _lines: string[];
22+
private readonly _startColumns: number[];
23+
private readonly _endColumns: number[];
3024

31-
constructor(buffer: string, startMarkers: IMarker[], endMarkers: IMarker[]) {
32-
this.buffer = buffer;
33-
this.startMarkers = startMarkers;
34-
this.endMarkers = endMarkers;
25+
constructor(lines: string[]) {
26+
let startColumns: number[] = [];
27+
let endColumns: number[] = [];
28+
for (let i = 0, length = lines.length; i < length; i++) {
29+
startColumns[i] = LineMarkerSequence._getFirstNonBlankColumn(lines[i], 1);
30+
endColumns[i] = LineMarkerSequence._getLastNonBlankColumn(lines[i], 1);
31+
}
32+
this._lines = lines;
33+
this._startColumns = startColumns;
34+
this._endColumns = endColumns;
3535
}
3636

3737
public getLength(): number {
38-
return this.startMarkers.length;
38+
return this._lines.length;
3939
}
4040

4141
public getElementHash(i: number): string {
42-
return this.buffer.substring(this.startMarkers[i].offset, this.endMarkers[i].offset);
42+
return this._lines[i].substring(this._startColumns[i] - 1, this._endColumns[i] - 1);
4343
}
4444

4545
public getStartLineNumber(i: number): number {
46-
if (i === this.startMarkers.length) {
47-
// This is the special case where a change happened after the last marker
48-
return this.startMarkers[i - 1].lineNumber + 1;
49-
}
50-
return this.startMarkers[i].lineNumber;
46+
return i + 1;
5147
}
5248

5349
public getStartColumn(i: number): number {
54-
return this.startMarkers[i].column;
50+
return this._startColumns[i];
5551
}
5652

5753
public getEndLineNumber(i: number): number {
58-
return this.endMarkers[i].lineNumber;
54+
return i + 1;
5955
}
6056

6157
public getEndColumn(i: number): number {
62-
return this.endMarkers[i].column;
63-
}
64-
65-
}
66-
67-
class LineMarkerSequence extends MarkerSequence {
68-
69-
constructor(lines: string[]) {
70-
let buffer = '';
71-
let startMarkers: IMarker[] = [];
72-
let endMarkers: IMarker[] = [];
73-
74-
for (let pos = 0, i = 0, length = lines.length; i < length; i++) {
75-
buffer += lines[i];
76-
const startColumn = LineMarkerSequence._getFirstNonBlankColumn(lines[i], 1);
77-
const endColumn = LineMarkerSequence._getLastNonBlankColumn(lines[i], 1);
78-
79-
startMarkers.push({
80-
offset: pos + startColumn - 1,
81-
lineNumber: i + 1,
82-
column: startColumn
83-
});
84-
85-
endMarkers.push({
86-
offset: pos + endColumn - 1,
87-
lineNumber: i + 1,
88-
column: endColumn
89-
});
90-
91-
pos += lines[i].length;
92-
}
93-
94-
super(buffer, startMarkers, endMarkers);
58+
return this._endColumns[i];
9559
}
9660

9761
public static _getFirstNonBlankColumn(txt: string, defaultValue: number): number {
@@ -110,26 +74,59 @@ class LineMarkerSequence extends MarkerSequence {
11074
return r + 2;
11175
}
11276

113-
public getCharSequence(startIndex: number, endIndex: number): MarkerSequence {
114-
let startMarkers: IMarker[] = [];
115-
let endMarkers: IMarker[] = [];
77+
public getCharSequence(startIndex: number, endIndex: number): CharSequence {
78+
let chars: string[] = [];
79+
let lineNumbers: number[] = [];
80+
let columns: number[] = [];
81+
let len = 0;
11682
for (let index = startIndex; index <= endIndex; index++) {
117-
const startMarker = this.startMarkers[index];
118-
const endMarker = this.endMarkers[index];
119-
for (let i = startMarker.offset; i < endMarker.offset; i++) {
120-
startMarkers.push({
121-
offset: i,
122-
lineNumber: startMarker.lineNumber,
123-
column: startMarker.column + (i - startMarker.offset)
124-
});
125-
endMarkers.push({
126-
offset: i + 1,
127-
lineNumber: startMarker.lineNumber,
128-
column: startMarker.column + (i - startMarker.offset) + 1
129-
});
83+
const startColumn = this._startColumns[index];
84+
const endColumn = this._endColumns[index];
85+
for (let col = startColumn; col < endColumn; col++) {
86+
chars[len] = this._lines[index].charAt(col - 1);
87+
lineNumbers[len] = index + 1;
88+
columns[len] = col;
89+
len++;
13090
}
13191
}
132-
return new MarkerSequence(this.buffer, startMarkers, endMarkers);
92+
return new CharSequence(chars, lineNumbers, columns);
93+
}
94+
}
95+
96+
class CharSequence implements ISequence {
97+
98+
private readonly _chars: string[];
99+
private readonly _lineNumbers: number[];
100+
private readonly _columns: number[];
101+
102+
constructor(chars: string[], lineNumbers: number[], columns: number[]) {
103+
this._chars = chars;
104+
this._lineNumbers = lineNumbers;
105+
this._columns = columns;
106+
}
107+
108+
public getLength(): number {
109+
return this._chars.length;
110+
}
111+
112+
public getElementHash(i: number): string {
113+
return this._chars[i];
114+
}
115+
116+
public getStartLineNumber(i: number): number {
117+
return this._lineNumbers[i];
118+
}
119+
120+
public getStartColumn(i: number): number {
121+
return this._columns[i];
122+
}
123+
124+
public getEndLineNumber(i: number): number {
125+
return this._lineNumbers[i];
126+
}
127+
128+
public getEndColumn(i: number): number {
129+
return this._columns[i] + 1;
133130
}
134131
}
135132

@@ -165,7 +162,7 @@ class CharChange implements ICharChange {
165162
this.modifiedEndColumn = modifiedEndColumn;
166163
}
167164

168-
public static createFromDiffChange(diffChange: IDiffChange, originalCharSequence: MarkerSequence, modifiedCharSequence: MarkerSequence): CharChange {
165+
public static createFromDiffChange(diffChange: IDiffChange, originalCharSequence: CharSequence, modifiedCharSequence: CharSequence): CharChange {
169166
let originalStartLineNumber: number;
170167
let originalStartColumn: number;
171168
let originalEndLineNumber: number;

0 commit comments

Comments
 (0)