web: impl chunkSize method for faster file size calculation

This commit is contained in:
Abdullah Atta
2024-08-13 14:59:17 +05:00
committed by Abdullah Atta
parent cb52b390ab
commit 782c53b622
2 changed files with 43 additions and 0 deletions

View File

@@ -57,6 +57,12 @@ export class IndexedDBFileStore implements IFileStorage {
(k as string).startsWith(chunkPrefix) (k as string).startsWith(chunkPrefix)
) as string[]; ) as string[];
} }
async chunkSize(chunkName: string): Promise<number> {
const chunk = await this.storage.get<Uint8Array>(chunkName);
return chunk?.length || 0;
}
async list(): Promise<string[]> { async list(): Promise<string[]> {
return (await this.storage.keys()) as string[]; return (await this.storage.keys()) as string[];
} }
@@ -131,6 +137,14 @@ export class CacheStorageFileStore implements IFileStorage {
return keys.map((r) => r.url.slice(1)); return keys.map((r) => r.url.slice(1));
} }
async chunkSize(chunkName: string): Promise<number> {
const cache = await this.getCache();
const response = await cache.match(this.toURL(chunkName));
const length = response?.headers.get("Content-Length");
if (length) return parseInt(length);
return response ? (await response.arrayBuffer()).byteLength : 0;
}
private toURL(chunkName: string) { private toURL(chunkName: string) {
return `/${chunkName}`; return `/${chunkName}`;
} }
@@ -185,6 +199,10 @@ export class OriginPrivateFileSystem implements IFileStorage {
await this.create(); await this.create();
return (await this.worker.listChunks(this.name, chunkPrefix)) || []; return (await this.worker.listChunks(this.name, chunkPrefix)) || [];
} }
async chunkSize(chunkName: string): Promise<number> {
await this.create();
return await this.worker.chunkSize(this.name, chunkName);
}
async list(): Promise<string[]> { async list(): Promise<string[]> {
await this.create(); await this.create();
return (await this.worker.list(this.name)) || []; return (await this.worker.list(this.name)) || [];

View File

@@ -93,6 +93,20 @@ class OriginPrivateFileStore implements IFileStorage {
} }
} }
async chunkSize(chunkName: string): Promise<number> {
try {
if (Object.hasOwn(FileSystemSyncAccessHandle.prototype, "mode")) {
return readFileSize(this.directory, chunkName);
}
return await this.safeOp(chunkName, () =>
readFileSize(this.directory, chunkName)
);
} catch (e) {
console.error("Failed to get chunk size", e);
}
return 0;
}
async listChunks(chunkPrefix: string): Promise<string[]> { async listChunks(chunkPrefix: string): Promise<string[]> {
const chunks: string[] = []; const chunks: string[] = [];
for await (const entry of this.directory.keys()) { for await (const entry of this.directory.keys()) {
@@ -161,6 +175,9 @@ const workerModule = {
}, },
async list(directoryName: string) { async list(directoryName: string) {
return (await fileStores.get(directoryName)?.list()) || []; return (await fileStores.get(directoryName)?.list()) || [];
},
async chunkSize(directoryName: string, chunkName: string) {
return (await fileStores.get(directoryName)?.chunkSize(chunkName)) || 0;
} }
}; };
@@ -176,3 +193,11 @@ async function readFile(directory: FileSystemDirectoryHandle, name: string) {
handle.close(); handle.close();
return buffer; return buffer;
} }
async function readFileSize(
directory: FileSystemDirectoryHandle,
name: string
) {
const file = await directory.getFileHandle(name);
const handle = await file.createSyncAccessHandle({ mode: "read-only" });
return handle.getSize();
}