Skip to content

Commit a9ba0a5

Browse files
committed
use circular buffer instead of unbounded array
1 parent 78974ef commit a9ba0a5

1 file changed

Lines changed: 29 additions & 17 deletions

File tree

src/server/scriptVersionCache.ts

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -267,15 +267,27 @@ namespace ts.server {
267267

268268
export class ScriptVersionCache {
269269
changes: TextChange[] = [];
270-
versions: LineIndexSnapshot[] = [];
270+
versions: LineIndexSnapshot[] = new Array<LineIndexSnapshot>(ScriptVersionCache.maxVersions);
271271
minVersion = 0; // no versions earlier than min version will maintain change history
272-
private currentVersion = 0;
272+
273273
private host: ServerHost;
274+
private currentVersion = 0;
274275

275276
static changeNumberThreshold = 8;
276277
static changeLengthThreshold = 256;
277278
static maxVersions = 8;
278279

280+
private versionToIndex(version: number) {
281+
if (version < this.minVersion || version > this.currentVersion) {
282+
return undefined;
283+
}
284+
return version % ScriptVersionCache.maxVersions;
285+
}
286+
287+
private currentVersionToIndex() {
288+
return this.currentVersion % ScriptVersionCache.maxVersions;
289+
}
290+
279291
// REVIEW: can optimize by coalescing simple edits
280292
edit(pos: number, deleteLen: number, insertedText?: string) {
281293
this.changes[this.changes.length] = new TextChange(pos, deleteLen, insertedText);
@@ -287,7 +299,7 @@ namespace ts.server {
287299
}
288300

289301
latest() {
290-
return this.versions[this.currentVersion];
302+
return this.versions[this.currentVersionToIndex()];
291303
}
292304

293305
latestVersion() {
@@ -312,38 +324,38 @@ namespace ts.server {
312324
this.currentVersion++;
313325
this.changes = []; // history wiped out by reload
314326
const snap = new LineIndexSnapshot(this.currentVersion, this);
315-
this.versions[this.currentVersion] = snap;
327+
328+
// delete all versions
329+
for (let i = 0; i < this.versions.length; i++) {
330+
this.versions[i] = undefined;
331+
}
332+
333+
this.versions[this.currentVersionToIndex()] = snap;
316334
snap.index = new LineIndex();
317335
const lm = LineIndex.linesFromText(script);
318336
snap.index.load(lm.lines);
319-
// REVIEW: could use linked list
320-
for (let i = this.minVersion; i < this.currentVersion; i++) {
321-
this.versions[i] = undefined;
322-
}
323-
this.minVersion = this.currentVersion;
324337

338+
this.minVersion = this.currentVersion;
325339
}
326340

327341
getSnapshot() {
328-
let snap = this.versions[this.currentVersion];
342+
let snap = this.versions[this.currentVersionToIndex()];
329343
if (this.changes.length > 0) {
330-
let snapIndex = this.latest().index;
344+
let snapIndex = snap.index;
331345
for (let i = 0, len = this.changes.length; i < len; i++) {
332346
const change = this.changes[i];
333347
snapIndex = snapIndex.edit(change.pos, change.deleteLen, change.insertedText);
334348
}
335349
snap = new LineIndexSnapshot(this.currentVersion + 1, this);
336350
snap.index = snapIndex;
337351
snap.changesSincePreviousVersion = this.changes;
352+
338353
this.currentVersion = snap.version;
339-
this.versions[snap.version] = snap;
354+
this.versions[this.currentVersionToIndex()] = snap;
340355
this.changes = [];
356+
341357
if ((this.currentVersion - this.minVersion) >= ScriptVersionCache.maxVersions) {
342-
const oldMin = this.minVersion;
343358
this.minVersion = (this.currentVersion - ScriptVersionCache.maxVersions) + 1;
344-
for (let j = oldMin; j < this.minVersion; j++) {
345-
this.versions[j] = undefined;
346-
}
347359
}
348360
}
349361
return snap;
@@ -354,7 +366,7 @@ namespace ts.server {
354366
if (oldVersion >= this.minVersion) {
355367
const textChangeRanges: ts.TextChangeRange[] = [];
356368
for (let i = oldVersion + 1; i <= newVersion; i++) {
357-
const snap = this.versions[i];
369+
const snap = this.versions[this.versionToIndex(i)];
358370
for (let j = 0, len = snap.changesSincePreviousVersion.length; j < len; j++) {
359371
const textChange = snap.changesSincePreviousVersion[j];
360372
textChangeRanges[textChangeRanges.length] = textChange.getTextChangeRange();

0 commit comments

Comments
 (0)