Skip to content

Commit 84167ad

Browse files
committed
Add ISequence.elementsAreEqual
1 parent c4821bf commit 84167ad

3 files changed

Lines changed: 37 additions & 25 deletions

File tree

src/vs/base/common/diff/diff.ts

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,31 @@
55

66
import { DiffChange } from 'vs/base/common/diff/diffChange';
77

8-
function createStringSequence(a: string): ISequence {
9-
return {
10-
getLength() { return a.length; },
11-
getElementAtIndex(pos: number) { return a.charCodeAt(pos); }
12-
};
8+
export class StringDiffSequence implements ISequence {
9+
10+
constructor(private source: string) { }
11+
12+
public getLength() {
13+
return this.source.length;
14+
}
15+
16+
public getElementAtIndex(i: number) {
17+
return this.source.charCodeAt(i);
18+
}
19+
20+
public elementsAreEqual(seq1: StringDiffSequence, index1: number, seq2: StringDiffSequence, index2: number) {
21+
return (seq1.source.charCodeAt(index1) === seq2.source.charCodeAt(index2));
22+
}
1323
}
1424

1525
export function stringDiff(original: string, modified: string, pretty: boolean): IDiffChange[] {
16-
return new LcsDiff(createStringSequence(original), createStringSequence(modified)).ComputeDiff(pretty);
26+
return new LcsDiff(new StringDiffSequence(original), new StringDiffSequence(modified)).ComputeDiff(pretty);
1727
}
1828

19-
2029
export interface ISequence {
2130
getLength(): number;
2231
getElementAtIndex(index: number): number | string;
32+
elementsAreEqual(seq1: ISequence, index1: number, seq2: ISequence, index2: number): boolean;
2333
}
2434

2535
export interface IDiffChange {
@@ -239,15 +249,15 @@ export class LcsDiff {
239249
}
240250

241251
private ElementsAreEqual(originalIndex: number, newIndex: number): boolean {
242-
return (this.OriginalSequence.getElementAtIndex(originalIndex) === this.ModifiedSequence.getElementAtIndex(newIndex));
252+
return this.OriginalSequence.elementsAreEqual(this.OriginalSequence, originalIndex, this.ModifiedSequence, newIndex);
243253
}
244254

245255
private OriginalElementsAreEqual(index1: number, index2: number): boolean {
246-
return (this.OriginalSequence.getElementAtIndex(index1) === this.OriginalSequence.getElementAtIndex(index2));
256+
return this.OriginalSequence.elementsAreEqual(this.OriginalSequence, index1, this.OriginalSequence, index2);
247257
}
248258

249259
private ModifiedElementsAreEqual(index1: number, index2: number): boolean {
250-
return (this.ModifiedSequence.getElementAtIndex(index1) === this.ModifiedSequence.getElementAtIndex(index2));
260+
return this.ModifiedSequence.elementsAreEqual(this.ModifiedSequence, index1, this.ModifiedSequence, index2);
251261
}
252262

253263
public ComputeDiff(pretty: boolean): IDiffChange[] {

src/vs/base/test/common/diff/diff.test.ts

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,7 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import * as assert from 'assert';
7-
import { LcsDiff, IDiffChange, ISequence } from 'vs/base/common/diff/diff';
8-
9-
class StringDiffSequence implements ISequence {
10-
11-
constructor(private source: string) {
12-
}
13-
14-
getLength() {
15-
return this.source.length;
16-
}
17-
18-
getElementAtIndex(i: number) {
19-
return this.source.charCodeAt(i);
20-
}
21-
}
7+
import { LcsDiff, IDiffChange, StringDiffSequence } from 'vs/base/common/diff/diff';
228

239
function createArray<T>(length: number, value: T): T[] {
2410
const r: T[] = [];

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import { IDiffChange, ISequence, LcsDiff } from 'vs/base/common/diff/diff';
77
import * as strings from 'vs/base/common/strings';
88
import { ICharChange, ILineChange } from 'vs/editor/common/editorCommon';
9+
import { hash } from 'vs/base/common/hash';
910

1011
const MAXIMUM_RUN_TIME = 5000; // 5 seconds
1112
const MINIMUM_MATCHING_CHARACTER_LENGTH = 3;
@@ -19,17 +20,20 @@ class LineSequence implements ISequence {
1920

2021
private readonly _lines: string[];
2122
private readonly _trimmedLines: string[];
23+
private readonly _trimmedLinesHash: number[];
2224
private readonly _startColumns: number[];
2325
private readonly _endColumns: number[];
2426

2527
constructor(lines: string[]) {
2628
let startColumns: number[] = [];
2729
let endColumns: number[] = [];
2830
this._trimmedLines = [];
31+
this._trimmedLinesHash = [];
2932
for (let i = 0, length = lines.length; i < length; i++) {
3033
startColumns[i] = getFirstNonBlankColumn(lines[i], 1);
3134
endColumns[i] = getLastNonBlankColumn(lines[i], 1);
3235
this._trimmedLines[i] = lines[i].substring(startColumns[i] - 1, endColumns[i] - 1);
36+
this._trimmedLinesHash[i] = hash(this._trimmedLines[i]);
3337
}
3438
this._lines = lines;
3539
this._startColumns = startColumns;
@@ -44,6 +48,14 @@ class LineSequence implements ISequence {
4448
return this._trimmedLines[i];
4549
}
4650

51+
public elementsAreEqual(seq1: LineSequence, index1: number, seq2: LineSequence, index2: number): boolean {
52+
if (seq1._trimmedLinesHash[index1] === seq2._trimmedLinesHash[index2]) {
53+
// hashes are equal
54+
return seq1._trimmedLines[index1] === seq2._trimmedLines[index2];
55+
}
56+
return false;
57+
}
58+
4759
public getStartLineNumber(i: number): number {
4860
return i + 1;
4961
}
@@ -92,6 +104,10 @@ class CharSequence implements ISequence {
92104
return this._charCodes[i];
93105
}
94106

107+
public elementsAreEqual(seq1: CharSequence, index1: number, seq2: CharSequence, index2: number): boolean {
108+
return (seq1.getElementAtIndex(index1) === seq2.getElementAtIndex(index2));
109+
}
110+
95111
public getStartLineNumber(i: number): number {
96112
return this._lineNumbers[i];
97113
}

0 commit comments

Comments
 (0)