Skip to content

Commit dc604f3

Browse files
committed
perf(fmt): streamline cache loading
1 parent 13a2177 commit dc604f3

3 files changed

Lines changed: 20 additions & 66 deletions

File tree

‎packages/rstack/src/fmt/cacheHash.ts‎

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,4 @@ const cacheHashLength = 16;
66
const createCacheHash = (content: string | Uint8Array): string =>
77
hash('sha256', content, 'base64url').slice(0, cacheHashLength);
88

9-
const isCacheHash = (value: unknown): value is string =>
10-
typeof value === 'string' && value.length === cacheHashLength;
11-
12-
export { cacheHashLength, createCacheHash, isCacheHash };
9+
export { cacheHashLength, createCacheHash };

‎packages/rstack/src/fmt/cacheStore.ts‎

Lines changed: 18 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { randomUUID } from 'node:crypto';
22
import { mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';
33
import path from 'node:path';
4-
import { isCacheHash } from './cacheHash.ts';
54

65
const fmtCacheFileName = 'v2.json';
76
const fmtCacheVersion = 2;
@@ -60,14 +59,6 @@ const createEmptyCache = (namespace: string): ParsedFmtCacheFile => ({
6059
optionsUseCounts: [],
6160
});
6261

63-
const isFmtCacheStateId = (value: unknown): value is FmtCacheStateId =>
64-
typeof value === 'number' &&
65-
Number.isInteger(value) &&
66-
value >= 0 &&
67-
value < fmtCacheStates.length;
68-
69-
const isUnknownArray = (value: unknown): value is unknown[] => Array.isArray(value);
70-
7162
const parseCacheFile = (content: string): ParsedFmtCacheFile | undefined => {
7263
let value: unknown;
7364
try {
@@ -76,60 +67,38 @@ const parseCacheFile = (content: string): ParsedFmtCacheFile | undefined => {
7667
return;
7768
}
7869

70+
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
71+
return;
72+
}
73+
74+
const cache = value as FmtCacheFile;
75+
const { version, namespace, options, files } = cache;
7976
if (
80-
typeof value !== 'object' ||
81-
value === null ||
82-
isUnknownArray(value) ||
83-
!('version' in value) ||
84-
value.version !== fmtCacheVersion ||
85-
!('namespace' in value) ||
86-
typeof value.namespace !== 'string' ||
87-
!('options' in value) ||
88-
!isUnknownArray(value.options) ||
89-
!('files' in value) ||
90-
!isUnknownArray(value.files) ||
91-
value.files.length % fileEntryWidth !== 0
77+
version !== fmtCacheVersion ||
78+
typeof namespace !== 'string' ||
79+
!Array.isArray(options) ||
80+
!Array.isArray(files) ||
81+
files.length % fileEntryWidth !== 0
9282
) {
9383
return;
9484
}
9585

9686
const optionsIndexes = new Map<string, number>();
97-
for (let index = 0; index < value.options.length; index++) {
98-
const optionsHash = value.options[index];
99-
if (!isCacheHash(optionsHash) || optionsIndexes.has(optionsHash)) {
100-
return;
101-
}
102-
optionsIndexes.set(optionsHash, index);
87+
for (let index = 0; index < options.length; index++) {
88+
optionsIndexes.set(options[index], index);
10389
}
10490

10591
const fileOffsets = new Map<string, number>();
106-
const optionsUseCounts = new Array<number>(value.options.length).fill(0);
107-
for (let offset = 0; offset < value.files.length; offset += fileEntryWidth) {
108-
const filePath = value.files[offset];
109-
const contentHash = value.files[offset + contentHashOffset];
110-
const optionsIndex = value.files[offset + optionsIndexOffset];
111-
const state = value.files[offset + stateOffset];
112-
if (
113-
typeof filePath !== 'string' ||
114-
fileOffsets.has(filePath) ||
115-
typeof optionsIndex !== 'number' ||
116-
!Number.isInteger(optionsIndex) ||
117-
optionsIndex < 0 ||
118-
optionsIndex >= value.options.length ||
119-
!isFmtCacheStateId(state) ||
120-
(state === fmtCacheStateIds.unsupported
121-
? contentHash !== null && !isCacheHash(contentHash)
122-
: !isCacheHash(contentHash))
123-
) {
124-
return;
125-
}
126-
92+
const optionsUseCounts = new Array<number>(options.length).fill(0);
93+
for (let offset = 0; offset < files.length; offset += fileEntryWidth) {
94+
const filePath = files[offset] as string;
95+
const optionsIndex = files[offset + optionsIndexOffset] as number;
12796
fileOffsets.set(filePath, offset);
12897
optionsUseCounts[optionsIndex]++;
12998
}
13099

131100
return {
132-
cache: value as FmtCacheFile,
101+
cache,
133102
fileOffsets,
134103
optionsIndexes,
135104
optionsUseCounts,

‎packages/rstack/tests/fmt/cacheStore.test.ts‎

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ test('preserves unvisited entries and skips unchanged updates', async () => {
9494
});
9595
});
9696

97-
test('discards invalid data and entries from another namespace', async () => {
97+
test('discards invalid schemas and other namespaces', async () => {
9898
await withTempProject(async (rootPath) => {
9999
const cachePath = path.join(rootPath, fmtCacheFileName);
100100
const validCache = {
@@ -107,20 +107,8 @@ test('discards invalid data and entries from another namespace', async () => {
107107
'{invalid',
108108
JSON.stringify({ ...validCache, version: fmtCacheVersion - 1 }),
109109
JSON.stringify({ version: fmtCacheVersion, namespace, files: [] }),
110-
JSON.stringify({ ...validCache, options: ['too-short'] }),
111-
JSON.stringify({ ...validCache, options: [optionsA, optionsA] }),
112110
JSON.stringify({ ...validCache, files: { 'src/a.ts': firstEntry } }),
113111
JSON.stringify({ ...validCache, files: ['src/a.ts', contentA, 0] }),
114-
JSON.stringify({ ...validCache, files: [42, contentA, 0, 0] }),
115-
JSON.stringify({ ...validCache, files: ['src/a.ts', 42, 0, 2] }),
116-
JSON.stringify({ ...validCache, files: ['src/a.ts', null, 0, 0] }),
117-
JSON.stringify({ ...validCache, files: ['src/a.ts', contentA, 1, 0] }),
118-
JSON.stringify({ ...validCache, files: ['src/a.ts', contentA, 0.5, 0] }),
119-
JSON.stringify({ ...validCache, files: ['src/a.ts', contentA, 0, 3] }),
120-
JSON.stringify({
121-
...validCache,
122-
files: ['src/a.ts', contentA, 0, 0, 'src/a.ts', contentB, 0, 1],
123-
}),
124112
];
125113

126114
for (const content of invalidContents) {

0 commit comments

Comments
 (0)