⚡️ Save cache state, reuse if possible
This commit is contained in:
parent
b8b9586b1e
commit
80a536d848
1 changed files with 106 additions and 20 deletions
|
@ -18,7 +18,11 @@ export class CacheWorker {
|
||||||
/**
|
/**
|
||||||
* List of cache items
|
* List of cache items
|
||||||
*/
|
*/
|
||||||
private cache: CacheItem[] = [];
|
private cache: CacheData = {
|
||||||
|
timestamp: 0,
|
||||||
|
items: [],
|
||||||
|
files: {},
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new cache
|
* Creates a new cache
|
||||||
|
@ -30,6 +34,7 @@ export class CacheWorker {
|
||||||
context: vscode.ExtensionContext
|
context: vscode.ExtensionContext
|
||||||
): Promise<CacheWorker> {
|
): Promise<CacheWorker> {
|
||||||
const cache = new CacheWorker(context);
|
const cache = new CacheWorker(context);
|
||||||
|
await cache.loadCacheFromFile();
|
||||||
await cache.scanWorkspace();
|
await cache.scanWorkspace();
|
||||||
return cache;
|
return cache;
|
||||||
}
|
}
|
||||||
|
@ -51,6 +56,7 @@ export class CacheWorker {
|
||||||
* TODO: Find a more elegant way to do this
|
* TODO: Find a more elegant way to do this
|
||||||
*/
|
*/
|
||||||
private save() {
|
private save() {
|
||||||
|
this.cache.timestamp = Date.now();
|
||||||
const jsonString = JSON.stringify(this.cache);
|
const jsonString = JSON.stringify(this.cache);
|
||||||
// Save it in the cache.json file in the .cache folder in the workspace
|
// Save it in the cache.json file in the .cache folder in the workspace
|
||||||
const workspaceFolder = vscode.workspace.workspaceFolders?.[0].uri.fsPath;
|
const workspaceFolder = vscode.workspace.workspaceFolders?.[0].uri.fsPath;
|
||||||
|
@ -62,6 +68,22 @@ export class CacheWorker {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the cache from the .cache/cache.json file
|
||||||
|
*/
|
||||||
|
private async loadCacheFromFile() {
|
||||||
|
try {
|
||||||
|
const workspaceFolder = vscode.workspace.workspaceFolders?.[0].uri.fsPath;
|
||||||
|
const cacheUri = vscode.Uri.file(`${workspaceFolder}/.cache/cache.json`);
|
||||||
|
const cache = await vscode.workspace.fs.readFile(cacheUri);
|
||||||
|
const cacheString = new TextDecoder().decode(cache);
|
||||||
|
this.cache = JSON.parse(cacheString);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to load cache from file:", error);
|
||||||
|
this.cache = { timestamp: 0, items: [], files: {} };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a file system watcher
|
* Create a file system watcher
|
||||||
*/
|
*/
|
||||||
|
@ -90,10 +112,36 @@ export class CacheWorker {
|
||||||
* Scans the workspace for all themes and layers
|
* Scans the workspace for all themes and layers
|
||||||
*/
|
*/
|
||||||
private async scanWorkspace() {
|
private async scanWorkspace() {
|
||||||
const files = await vscode.workspace.findFiles("**/assets/**/*.json");
|
let changedFiles = 0;
|
||||||
|
let unchangedFiles = 0;
|
||||||
|
const files = await vscode.workspace.findFiles("assets/*/*/*.json");
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
this.saveFileToCache(file);
|
if (
|
||||||
|
file.fsPath.endsWith("license_info.json") ||
|
||||||
|
file.fsPath.endsWith(".proto.json") ||
|
||||||
|
file.fsPath.endsWith("layers/favourite/favourite.json")
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const stats = await vscode.workspace.fs.stat(file);
|
||||||
|
if (stats.mtime > (this.cache.files[file.fsPath] || 0)) {
|
||||||
|
console.log(
|
||||||
|
"File has changed",
|
||||||
|
file.fsPath,
|
||||||
|
"last modified",
|
||||||
|
stats.mtime,
|
||||||
|
"cache",
|
||||||
|
this.cache.files[file.fsPath]
|
||||||
|
);
|
||||||
|
this.saveFileToCache(file);
|
||||||
|
changedFiles++;
|
||||||
|
} else {
|
||||||
|
unchangedFiles++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
console.log(
|
||||||
|
`Scanned workspace: ${changedFiles} changed files, ${unchangedFiles} unchanged files`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -141,7 +189,7 @@ export class CacheWorker {
|
||||||
* @param uri File URI
|
* @param uri File URI
|
||||||
*/
|
*/
|
||||||
private deleteFileFromCache(uri: vscode.Uri) {
|
private deleteFileFromCache(uri: vscode.Uri) {
|
||||||
this.cache = this.cache.filter(
|
this.cache.items = this.cache.items.filter(
|
||||||
(item) => item.filePath.fsPath !== uri.fsPath
|
(item) => item.filePath.fsPath !== uri.fsPath
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -184,7 +232,7 @@ export class CacheWorker {
|
||||||
`**/assets/layers/${layer}/${layer}.json`
|
`**/assets/layers/${layer}/${layer}.json`
|
||||||
);
|
);
|
||||||
|
|
||||||
this.cache.push({
|
this.cache.items.push({
|
||||||
id: layer,
|
id: layer,
|
||||||
filePath: uri,
|
filePath: uri,
|
||||||
jsonPath: ["layers"],
|
jsonPath: ["layers"],
|
||||||
|
@ -221,7 +269,7 @@ export class CacheWorker {
|
||||||
`**/assets/layers/${layer.builtin}/${layer.builtin}.json`
|
`**/assets/layers/${layer.builtin}/${layer.builtin}.json`
|
||||||
);
|
);
|
||||||
|
|
||||||
this.cache.push({
|
this.cache.items.push({
|
||||||
id: layer.builtin,
|
id: layer.builtin,
|
||||||
filePath: uri,
|
filePath: uri,
|
||||||
jsonPath: ["layers"],
|
jsonPath: ["layers"],
|
||||||
|
@ -258,7 +306,7 @@ export class CacheWorker {
|
||||||
`**/assets/layers/${builtinLayer}/${builtinLayer}.json`
|
`**/assets/layers/${builtinLayer}/${builtinLayer}.json`
|
||||||
);
|
);
|
||||||
|
|
||||||
this.cache.push({
|
this.cache.items.push({
|
||||||
id: builtinLayer,
|
id: builtinLayer,
|
||||||
filePath: uri,
|
filePath: uri,
|
||||||
jsonPath: ["layers"],
|
jsonPath: ["layers"],
|
||||||
|
@ -288,6 +336,12 @@ export class CacheWorker {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We also need to update the timestamp for this file
|
||||||
|
// First, we need to get the last modified date of the file
|
||||||
|
const stats = await vscode.workspace.fs.stat(uri);
|
||||||
|
this.cache.files[uri.fsPath] = stats.mtime;
|
||||||
|
|
||||||
|
// Save the cache
|
||||||
this.save();
|
this.save();
|
||||||
this.printCache();
|
this.printCache();
|
||||||
}
|
}
|
||||||
|
@ -311,6 +365,15 @@ export class CacheWorker {
|
||||||
const from = `layers.${uriFileName.split(".")[0]}`;
|
const from = `layers.${uriFileName.split(".")[0]}`;
|
||||||
|
|
||||||
await this.saveLayerTextToCache(text, uri, from);
|
await this.saveLayerTextToCache(text, uri, from);
|
||||||
|
|
||||||
|
// We also need to update the timestamp for this file
|
||||||
|
// First, we need to get the last modified date of the file
|
||||||
|
const stats = await vscode.workspace.fs.stat(uri);
|
||||||
|
this.cache.files[uri.fsPath] = stats.mtime;
|
||||||
|
|
||||||
|
// Save the cache
|
||||||
|
this.save();
|
||||||
|
this.printCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -375,9 +438,6 @@ export class CacheWorker {
|
||||||
} else {
|
} else {
|
||||||
console.log("No filters found in", filePath);
|
console.log("No filters found in", filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.save();
|
|
||||||
this.printCache();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -444,7 +504,7 @@ export class CacheWorker {
|
||||||
);
|
);
|
||||||
const toRange = getStartEnd(toText, ["tagRenderings", trIndex]);
|
const toRange = getStartEnd(toText, ["tagRenderings", trIndex]);
|
||||||
|
|
||||||
this.cache.push({
|
this.cache.items.push({
|
||||||
id: tagRendering,
|
id: tagRendering,
|
||||||
filePath: fromUri,
|
filePath: fromUri,
|
||||||
jsonPath: ["tagRenderings"],
|
jsonPath: ["tagRenderings"],
|
||||||
|
@ -507,7 +567,7 @@ export class CacheWorker {
|
||||||
);
|
);
|
||||||
const toRange = getStartEnd(toText, ["tagRenderings", trIndex]);
|
const toRange = getStartEnd(toText, ["tagRenderings", trIndex]);
|
||||||
|
|
||||||
this.cache.push({
|
this.cache.items.push({
|
||||||
id: tagRendering.builtin,
|
id: tagRendering.builtin,
|
||||||
filePath: fromUri,
|
filePath: fromUri,
|
||||||
jsonPath: ["tagRenderings"],
|
jsonPath: ["tagRenderings"],
|
||||||
|
@ -565,7 +625,7 @@ export class CacheWorker {
|
||||||
);
|
);
|
||||||
const toRange = getStartEnd(toText, ["tagRenderings", trIndex]);
|
const toRange = getStartEnd(toText, ["tagRenderings", trIndex]);
|
||||||
|
|
||||||
this.cache.push({
|
this.cache.items.push({
|
||||||
id: builtinTagRendering,
|
id: builtinTagRendering,
|
||||||
filePath: fromUri,
|
filePath: fromUri,
|
||||||
jsonPath: ["tagRenderings"],
|
jsonPath: ["tagRenderings"],
|
||||||
|
@ -589,7 +649,7 @@ export class CacheWorker {
|
||||||
} else if (!referencesOnly) {
|
} else if (!referencesOnly) {
|
||||||
// We've now had all possible references, so now we must have an acutal tagRendering
|
// We've now had all possible references, so now we must have an acutal tagRendering
|
||||||
console.log(`TagRendering found in ${from}`);
|
console.log(`TagRendering found in ${from}`);
|
||||||
this.cache.push({
|
this.cache.items.push({
|
||||||
id: `${json.id}.${tagRendering.id}`,
|
id: `${json.id}.${tagRendering.id}`,
|
||||||
filePath: fromUri,
|
filePath: fromUri,
|
||||||
jsonPath: ["tagRenderings"],
|
jsonPath: ["tagRenderings"],
|
||||||
|
@ -663,7 +723,7 @@ export class CacheWorker {
|
||||||
}
|
}
|
||||||
const toRange = getStartEnd(toText, ["filter", toFilterIndex]);
|
const toRange = getStartEnd(toText, ["filter", toFilterIndex]);
|
||||||
|
|
||||||
this.cache.push({
|
this.cache.items.push({
|
||||||
id: filter,
|
id: filter,
|
||||||
filePath: fromUri,
|
filePath: fromUri,
|
||||||
jsonPath: ["filters"],
|
jsonPath: ["filters"],
|
||||||
|
@ -685,7 +745,7 @@ export class CacheWorker {
|
||||||
} else if (typeof filter === "object" && !referencesOnly) {
|
} else if (typeof filter === "object" && !referencesOnly) {
|
||||||
// This is a filter, which can be reused
|
// This is a filter, which can be reused
|
||||||
console.log(`Filter found in ${from}`);
|
console.log(`Filter found in ${from}`);
|
||||||
this.cache.push({
|
this.cache.items.push({
|
||||||
id: `${json.id}.${filter.id}`,
|
id: `${json.id}.${filter.id}`,
|
||||||
filePath: fromUri,
|
filePath: fromUri,
|
||||||
jsonPath: ["filters"],
|
jsonPath: ["filters"],
|
||||||
|
@ -708,7 +768,11 @@ export class CacheWorker {
|
||||||
* Cache for interacting with the cache
|
* Cache for interacting with the cache
|
||||||
*/
|
*/
|
||||||
export class Cache {
|
export class Cache {
|
||||||
private cache: CacheItem[] = [];
|
private cache: CacheData = {
|
||||||
|
timestamp: 0,
|
||||||
|
items: [],
|
||||||
|
files: {},
|
||||||
|
};
|
||||||
|
|
||||||
public static async create() {
|
public static async create() {
|
||||||
const cache = new Cache();
|
const cache = new Cache();
|
||||||
|
@ -742,7 +806,7 @@ export class Cache {
|
||||||
public getTagRenderings(): vscode.CompletionItem[] {
|
public getTagRenderings(): vscode.CompletionItem[] {
|
||||||
console.log("Getting tag renderings from cache");
|
console.log("Getting tag renderings from cache");
|
||||||
const tagRenderings: vscode.CompletionItem[] = [];
|
const tagRenderings: vscode.CompletionItem[] = [];
|
||||||
for (const item of this.cache) {
|
for (const item of this.cache.items) {
|
||||||
if (item.type === "tagRendering") {
|
if (item.type === "tagRendering") {
|
||||||
if (item.id.startsWith("questions.")) {
|
if (item.id.startsWith("questions.")) {
|
||||||
const completionItem = new vscode.CompletionItem(
|
const completionItem = new vscode.CompletionItem(
|
||||||
|
@ -768,7 +832,7 @@ export class Cache {
|
||||||
public getFilters(): vscode.CompletionItem[] {
|
public getFilters(): vscode.CompletionItem[] {
|
||||||
console.log("Getting filters from cache");
|
console.log("Getting filters from cache");
|
||||||
const filters: vscode.CompletionItem[] = [];
|
const filters: vscode.CompletionItem[] = [];
|
||||||
for (const item of this.cache) {
|
for (const item of this.cache.items) {
|
||||||
if (item.type === "filter") {
|
if (item.type === "filter") {
|
||||||
if (item.id.startsWith("filters.")) {
|
if (item.id.startsWith("filters.")) {
|
||||||
const completionItem = new vscode.CompletionItem(
|
const completionItem = new vscode.CompletionItem(
|
||||||
|
@ -795,7 +859,7 @@ export class Cache {
|
||||||
* @returns List of references
|
* @returns List of references
|
||||||
*/
|
*/
|
||||||
public getReferences(to: string): CacheItem[] {
|
public getReferences(to: string): CacheItem[] {
|
||||||
return this.cache.filter((item) => {
|
return this.cache.items.filter((item) => {
|
||||||
if (item.type === "reference") {
|
if (item.type === "reference") {
|
||||||
return item.reference?.to.id === to;
|
return item.reference?.to.id === to;
|
||||||
}
|
}
|
||||||
|
@ -804,6 +868,28 @@ export class Cache {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Layout of a cache data file
|
||||||
|
*/
|
||||||
|
interface CacheData {
|
||||||
|
/**
|
||||||
|
* Timestamp when the cache was last updated
|
||||||
|
*/
|
||||||
|
timestamp: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of cache items
|
||||||
|
*/
|
||||||
|
items: CacheItem[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of files, together with their last modified timestamp
|
||||||
|
*
|
||||||
|
* The timestamp is defined as the number of milliseconds since January 1, 1970, 00:00:00 UTC
|
||||||
|
*/
|
||||||
|
files: Record<string, number>;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A cached item
|
* A cached item
|
||||||
* Can be a tagRendering or filter from a(n) (inline) layer
|
* Can be a tagRendering or filter from a(n) (inline) layer
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue