Skip to content

Commit e6b71b7

Browse files
committed
bounded file cache
1 parent 4851d06 commit e6b71b7

File tree

3 files changed

+90
-8
lines changed

3 files changed

+90
-8
lines changed

src/extension.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@ import {
2727
} from "./support/fileWatcher";
2828
import { info } from "./support/logger";
2929
import { clearParserCaches, setParserBinaryPath } from "./support/parser";
30-
import { clearDefaultPhpCommand, initVendorWatchers } from "./support/php";
30+
import {
31+
clearDefaultPhpCommand,
32+
clearPhpFileCache,
33+
initVendorWatchers,
34+
} from "./support/php";
3135
import { hasWorkspace, projectPathExists } from "./support/project";
3236
import { cleanUpTemp } from "./support/util";
3337

@@ -186,6 +190,7 @@ export function deactivate() {
186190

187191
disposeWatchers();
188192
clearParserCaches();
193+
clearPhpFileCache();
189194

190195
if (client) {
191196
client.stop();

src/support/cache.ts

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import * as fs from "fs";
2+
13
export class Cache<K, V> {
24
private maxSize: number;
35
private cache: Map<K, V>;
@@ -44,3 +46,78 @@ export class Cache<K, V> {
4446
return this.cache.size;
4547
}
4648
}
49+
50+
export class BoundedFileCache {
51+
private cache = new Map<string, string>();
52+
private maxSize: number;
53+
54+
constructor(maxSize: number) {
55+
this.maxSize = maxSize;
56+
}
57+
58+
get(key: string): string | undefined {
59+
return this.cache.get(key);
60+
}
61+
62+
set(key: string, filePath: string): void {
63+
if (this.cache.has(key)) {
64+
return;
65+
}
66+
67+
if (this.cache.size >= this.maxSize) {
68+
const oldestKey = this.cache.keys().next().value;
69+
if (oldestKey !== undefined) {
70+
const oldFilePath = this.cache.get(oldestKey);
71+
if (oldFilePath && fs.existsSync(oldFilePath)) {
72+
try {
73+
fs.unlinkSync(oldFilePath);
74+
} catch (e) {
75+
// File might already be deleted, ignore
76+
}
77+
}
78+
this.cache.delete(oldestKey);
79+
}
80+
}
81+
82+
this.cache.set(key, filePath);
83+
}
84+
85+
has(key: string): boolean {
86+
return this.cache.has(key);
87+
}
88+
89+
delete(key: string): void {
90+
const filePath = this.cache.get(key);
91+
92+
if (filePath && fs.existsSync(filePath)) {
93+
try {
94+
fs.unlinkSync(filePath);
95+
} catch (e) {
96+
// File might already be deleted, ignore
97+
}
98+
}
99+
100+
this.cache.delete(key);
101+
}
102+
103+
clear(): void {
104+
for (const [key] of this.cache.entries()) {
105+
this.delete(key);
106+
}
107+
108+
this.cache.clear();
109+
}
110+
111+
size(): number {
112+
return this.cache.size;
113+
}
114+
115+
deleteByFilePath(filePath: string): void {
116+
for (const [key, value] of this.cache.entries()) {
117+
if (value === filePath) {
118+
this.cache.delete(key);
119+
break;
120+
}
121+
}
122+
}
123+
}

src/support/php.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { getTemplate, TemplateName } from "@src/templates";
22
import * as cp from "child_process";
33
import * as fs from "fs";
44
import * as vscode from "vscode";
5+
import { BoundedFileCache } from "./cache";
56
import { config, PhpEnvironment } from "./config";
67
import { registerWatcher } from "./fileWatcher";
78
import { error, info } from "./logger";
@@ -24,7 +25,7 @@ const toTemplateVar = (str: string) => {
2425

2526
let defaultPhpCommand: string | null = null;
2627

27-
const discoverFiles = new Map<string, string>();
28+
const discoverFiles = new BoundedFileCache(50);
2829

2930
let hasVendor = projectPathExists("vendor/autoload.php");
3031
const hasBootstrap = projectPathExists("bootstrap/app.php");
@@ -46,12 +47,7 @@ export const initVendorWatchers = () => {
4647
);
4748

4849
watcher.onDidDelete((file) => {
49-
for (const [key, value] of discoverFiles) {
50-
if (value === file.fsPath) {
51-
discoverFiles.delete(key);
52-
break;
53-
}
54-
}
50+
discoverFiles.deleteByFilePath(file.fsPath);
5551
});
5652

5753
[internalVendorPath(), projectPath("vendor")].forEach((path) => {
@@ -173,6 +169,10 @@ export const clearDefaultPhpCommand = () => {
173169
defaultPhpCommand = null;
174170
};
175171

172+
export const clearPhpFileCache = () => {
173+
discoverFiles.clear();
174+
};
175+
176176
const getDefaultPhpCommand = (): string => {
177177
defaultPhpCommand ??= getPhpCommand();
178178

0 commit comments

Comments
 (0)