Store a boolean on whether the cache is trimmed
This commit is contained in:
@@ -16,20 +16,20 @@ class TestBufferLine extends BufferLine {
|
||||
return this._combined;
|
||||
}
|
||||
|
||||
public get cachedCanonicalString(): string | undefined {
|
||||
return this._cachedCanonicalString;
|
||||
public get cachedString(): string | undefined {
|
||||
return this._cachedString;
|
||||
}
|
||||
|
||||
public set cachedCanonicalString(value: string | undefined) {
|
||||
this._cachedCanonicalString = value;
|
||||
public set cachedString(value: string | undefined) {
|
||||
this._cachedString = value;
|
||||
}
|
||||
|
||||
public get cachedCanonicalTrimmedString(): string | undefined {
|
||||
return this._cachedCanonicalTrimmedString;
|
||||
public get isCachedStringTrimmed(): boolean {
|
||||
return this._isCachedStringTrimmed;
|
||||
}
|
||||
|
||||
public set cachedCanonicalTrimmedString(value: string | undefined) {
|
||||
this._cachedCanonicalTrimmedString = value;
|
||||
public set isCachedStringTrimmed(value: boolean) {
|
||||
this._isCachedStringTrimmed = value;
|
||||
}
|
||||
|
||||
public toArray(): CharData[] {
|
||||
@@ -833,26 +833,32 @@ describe('BufferLine', function(): void {
|
||||
// Trimmed-only canonical request should cache the trimmed value.
|
||||
const trimmed = line.translateToString(true, undefined, undefined, undefined);
|
||||
assert.equal(trimmed, 'abc');
|
||||
assert.equal(line.cachedCanonicalTrimmedString, 'abc');
|
||||
assert.equal(line.cachedString, 'abc');
|
||||
assert.equal(line.isCachedStringTrimmed, true);
|
||||
|
||||
// Non-trimmed canonical request should cache the full value and free trimmed cache.
|
||||
// Non-trimmed canonical request should refresh cache with the full value.
|
||||
const translated = line.translateToString(false, undefined, undefined, undefined);
|
||||
assert.equal(translated, 'abc ');
|
||||
assert.equal(line.cachedCanonicalString, 'abc ');
|
||||
assert.equal(line.cachedCanonicalTrimmedString, undefined);
|
||||
assert.equal(line.cachedString, 'abc ');
|
||||
assert.equal(line.isCachedStringTrimmed, false);
|
||||
|
||||
// Once non-trimmed is cached, trimmed should be derived from trimEnd() (not re-cached).
|
||||
// Once non-trimmed is cached, trimmed should be derived via trimEnd().
|
||||
assert.equal(line.translateToString(true, undefined, undefined, undefined), 'abc');
|
||||
assert.equal(line.cachedCanonicalTrimmedString, undefined);
|
||||
assert.equal(line.cachedString, 'abc ');
|
||||
assert.equal(line.isCachedStringTrimmed, false);
|
||||
|
||||
line.cachedCanonicalString = 'cached-non-trimmed ';
|
||||
line.cachedCanonicalTrimmedString = 'cached-trimmed';
|
||||
line.cachedString = 'cached-non-trimmed ';
|
||||
line.isCachedStringTrimmed = false;
|
||||
assert.equal(line.translateToString(false, undefined, undefined, undefined), 'cached-non-trimmed ');
|
||||
assert.equal(line.translateToString(true, undefined, undefined, undefined), 'cached-trimmed');
|
||||
|
||||
line.cachedCanonicalTrimmedString = undefined;
|
||||
assert.equal(line.translateToString(true, undefined, undefined, undefined), 'cached-non-trimmed');
|
||||
|
||||
line.cachedString = 'cached-trimmed';
|
||||
line.isCachedStringTrimmed = true;
|
||||
assert.equal(line.translateToString(true, undefined, undefined, undefined), 'cached-trimmed');
|
||||
assert.equal(line.translateToString(false, undefined, undefined, undefined), 'abc ');
|
||||
assert.equal(line.cachedString, 'abc ');
|
||||
assert.equal(line.isCachedStringTrimmed, false);
|
||||
|
||||
// Any optional translation argument should bypass cache.
|
||||
assert.equal(line.translateToString(false, 0, 2, undefined), 'ab');
|
||||
assert.equal(line.translateToString(true, 0, 2, undefined), 'ab');
|
||||
@@ -863,13 +869,14 @@ describe('BufferLine', function(): void {
|
||||
const line = new TestBufferLine(5);
|
||||
line.fill(createCellData(1, 'a', 1));
|
||||
line.translateToString(true, undefined, undefined, undefined);
|
||||
assert.equal(line.cachedCanonicalTrimmedString, 'aaaaa');
|
||||
assert.equal(line.cachedString, 'aaaaa');
|
||||
assert.equal(line.isCachedStringTrimmed, true);
|
||||
line.translateToString(false, undefined, undefined, undefined);
|
||||
assert.equal(line.cachedCanonicalString, 'aaaaa');
|
||||
assert.equal(line.cachedCanonicalTrimmedString, undefined);
|
||||
assert.equal(line.cachedString, 'aaaaa');
|
||||
assert.equal(line.isCachedStringTrimmed, false);
|
||||
mutate(line);
|
||||
assert.equal(line.cachedCanonicalString, undefined);
|
||||
assert.equal(line.cachedCanonicalTrimmedString, undefined);
|
||||
assert.equal(line.cachedString, undefined);
|
||||
assert.equal(line.isCachedStringTrimmed, false);
|
||||
};
|
||||
|
||||
assertCacheInvalidated(line => line.set(0, [0, 'b', 1, 'b'.charCodeAt(0)]));
|
||||
|
||||
@@ -63,9 +63,8 @@ export class BufferLine implements IBufferLine {
|
||||
protected _data: Uint32Array;
|
||||
protected _combined: {[index: number]: string} = {};
|
||||
protected _extendedAttrs: {[index: number]: IExtendedAttrs | undefined} = {};
|
||||
// Cache for canonical full-line translations.
|
||||
protected _cachedCanonicalString: string | undefined;
|
||||
protected _cachedCanonicalTrimmedString: string | undefined;
|
||||
protected _cachedString: string | undefined;
|
||||
protected _isCachedStringTrimmed: boolean = false;
|
||||
public length: number;
|
||||
|
||||
constructor(cols: number, fillCellData?: ICellData, public isWrapped: boolean = false) {
|
||||
@@ -537,9 +536,13 @@ export class BufferLine implements IBufferLine {
|
||||
*/
|
||||
public translateToString(trimRight?: boolean, startCol?: number, endCol?: number, outColumns?: number[]): string {
|
||||
const isCanonicalRequest = (startCol === undefined || startCol === 0) && endCol === undefined && outColumns === undefined;
|
||||
const cachedResult = trimRight ? this._cachedCanonicalTrimmedString ?? this._cachedCanonicalString?.trimEnd() : this._cachedCanonicalString;
|
||||
if (isCanonicalRequest && cachedResult !== undefined) {
|
||||
return cachedResult;
|
||||
if (isCanonicalRequest && this._cachedString !== undefined) {
|
||||
if (trimRight) {
|
||||
return this._isCachedStringTrimmed ? this._cachedString : this._cachedString.trimEnd();
|
||||
}
|
||||
if (!this._isCachedStringTrimmed) {
|
||||
return this._cachedString;
|
||||
}
|
||||
}
|
||||
startCol = startCol ?? 0;
|
||||
endCol = endCol ?? this.length;
|
||||
@@ -566,19 +569,14 @@ export class BufferLine implements IBufferLine {
|
||||
outColumns.push(startCol);
|
||||
}
|
||||
if (isCanonicalRequest) {
|
||||
if (trimRight) {
|
||||
this._cachedCanonicalTrimmedString = result;
|
||||
} else {
|
||||
this._cachedCanonicalString = result;
|
||||
// Free the trimmed string as trimEnd() will be used to save memory
|
||||
this._cachedCanonicalTrimmedString = undefined;
|
||||
}
|
||||
this._cachedString = result;
|
||||
this._isCachedStringTrimmed = !!trimRight;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private _invalidateStringCache(): void {
|
||||
this._cachedCanonicalString = undefined;
|
||||
this._cachedCanonicalTrimmedString = undefined;
|
||||
this._cachedString = undefined;
|
||||
this._isCachedStringTrimmed = false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user