Move cache into Buffer owned object, use WeakRefs

This allows O(1) clearing of the cache, a single TTL timer and we
can avoid making BufferLine's Disposable
This commit is contained in:
Daniel Imms
2026-05-02 05:32:43 -07:00
parent 7615cd210a
commit 52d4b2719c
10 changed files with 219 additions and 40 deletions
@@ -8,6 +8,7 @@ import { assert } from 'chai';
import { DomRendererRowFactory } from 'browser/renderer/dom/DomRendererRowFactory';
import { NULL_CELL_CODE, NULL_CELL_WIDTH, NULL_CELL_CHAR, DEFAULT_ATTR, FgFlags, BgFlags, Attributes, UnderlineStyle } from 'common/buffer/Constants';
import { BufferLine, DEFAULT_ATTR_DATA } from 'common/buffer/BufferLine';
import { BufferLineStringCache } from 'common/buffer/BufferLineStringCache';
import { IBufferLine } from 'common/Types';
import { CellData } from 'common/buffer/CellData';
import { MockCoreService, MockDecorationService, MockOptionsService, createCellData, NULL_CELL_DATA } from 'common/TestUtils.test';
@@ -15,6 +16,7 @@ import { MockCharacterJoinerService, MockCoreBrowserService, MockThemeService }
import { TestWidthCache } from 'browser/renderer/dom/WidthCache.test';
const dom = new jsdom.JSDOM('');
const TEST_STRING_CACHE = new BufferLineStringCache();
describe('DomRendererRowFactory', () => {
@@ -517,7 +519,7 @@ describe('DomRendererRowFactory', () => {
}
function createEmptyLineData(cols: number): IBufferLine {
const lineData = new BufferLine(cols);
const lineData = new BufferLine(TEST_STRING_CACHE, cols);
for (let i = 0; i < cols; i++) {
lineData.setCell(i, NULL_CELL_DATA);
}
@@ -7,10 +7,13 @@ import { assert } from 'chai';
import { ICharacterJoinerService } from 'browser/services/Services';
import { CharacterJoinerService } from 'browser/services/CharacterJoinerService';
import { BufferLine } from 'common/buffer/BufferLine';
import { BufferLineStringCache } from 'common/buffer/BufferLineStringCache';
import { IBufferLine } from 'common/Types';
import { CellData } from 'common/buffer/CellData';
import { MockBufferService, createCellData } from 'common/TestUtils.test';
const TEST_STRING_CACHE = new BufferLineStringCache();
describe('CharacterJoinerService', () => {
let service: ICharacterJoinerService;
@@ -22,7 +25,7 @@ describe('CharacterJoinerService', () => {
lines.set(2, lineData([['a -> b -', 0xFFFFFFFF], ['> c -> d', 0]]));
lines.set(3, lineData([['no joined ranges']]));
lines.set(4, new BufferLine(0));
lines.set(4, new BufferLine(TEST_STRING_CACHE, 0));
lines.set(5, lineData([['a', 0x11111111], [' -> b -> c -> '], ['d', 0x22222222]]));
const line6 = lineData([['wi']]);
line6.resize(line6.length + 1, createCellData(0, '¥', 2));
@@ -267,7 +270,7 @@ describe('CharacterJoinerService', () => {
type IPartialLineData = ([string] | [string, number]);
function lineData(data: IPartialLineData[]): IBufferLine {
const tline = new BufferLine(0);
const tline = new BufferLine(TEST_STRING_CACHE, 0);
for (let i = 0; i < data.length; ++i) {
const line = data[i][0];
const attr = (data[i][1] || 0) as number;
@@ -9,12 +9,15 @@ import { SelectionModel } from 'browser/selection/SelectionModel';
import { IBufferLine } from 'common/Types';
import { MockBufferService, MockOptionsService, MockCoreService, createCellData } from 'common/TestUtils.test';
import { BufferLine } from 'common/buffer/BufferLine';
import { BufferLineStringCache } from 'common/buffer/BufferLineStringCache';
import { IBufferService, IOptionsService } from 'common/services/Services';
import { MockCoreBrowserService, MockMouseService, MockRenderService } from 'browser/TestUtils.test';
import { CellData } from 'common/buffer/CellData';
import { IBuffer } from 'common/buffer/Types';
import { IRenderService } from 'browser/services/Services';
const TEST_STRING_CACHE = new BufferLineStringCache();
class TestSelectionService extends SelectionService {
constructor(
bufferService: IBufferService,
@@ -55,7 +58,7 @@ describe('SelectionService', () => {
});
function stringToRow(text: string): IBufferLine {
const result = new BufferLine(text.length);
const result = new BufferLine(TEST_STRING_CACHE, text.length);
for (let i = 0; i < text.length; i++) {
result.setCell(i, createCellData(0, text.charAt(i), 1));
}
@@ -63,7 +66,7 @@ describe('SelectionService', () => {
}
function stringArrayToRow(chars: string[]): IBufferLine {
const line = new BufferLine(chars.length);
const line = new BufferLine(TEST_STRING_CACHE, chars.length);
chars.map((c, idx) => line.setCell(idx, createCellData(0, c, 1)));
return line;
}
@@ -118,7 +121,7 @@ describe('SelectionService', () => {
[0, 'o', 1, 'o'.charCodeAt(0)],
[0, 'o', 1, 'o'.charCodeAt(0)]
];
const line = new BufferLine(data.length);
const line = new BufferLine(TEST_STRING_CACHE, data.length);
for (let i = 0; i < data.length; ++i) line.setCell(i, CellData.fromCharData(data[i]));
buffer.lines.set(0, line);
// Ensure wide characters take up 2 columns