Skip to content

Commit

Permalink
Add cache to indexDB
Browse files Browse the repository at this point in the history
  • Loading branch information
ksyeo1010 authored May 22, 2024
1 parent 4a2a49f commit 0231731
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 6 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@picovoice/web-utils",
"version": "1.4.0",
"version": "1.4.1",
"description": "Picovoice web utility functions",
"author": "Picovoice",
"license": "Apache-2.0",
Expand Down
5 changes: 5 additions & 0 deletions src/pv_file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export type PvFileMeta = {
size: number;
numPages: number;
version?: number;
pageSize?: number;
}

/**
Expand All @@ -41,6 +42,10 @@ export abstract class PvFile {
};
}

get pageSize(): number | undefined {
return undefined;
}

public abstract close(): Promise<void> | void;

public abstract read(size: number, count: number): Promise<Uint8Array> | Uint8Array;
Expand Down
83 changes: 80 additions & 3 deletions src/pv_file_idb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,20 +38,59 @@ export function getDB(): Promise<IDBDatabase> {
});
}

/**
* Cache Settings
*/
class PvCache {
private _pos: number;
private _data: Uint8Array;

constructor() {
this._pos = 0;
this._data = new Uint8Array();
}

public get(bytes: number): Uint8Array | undefined {
if (this._pos >= this._data.length) {
return undefined;
}

const res = this._data.slice(this._pos, this._pos + bytes);
this._pos += bytes;
return res;
}

public set(pos: number, data: Uint8Array) {
this._pos = pos;
this._data = data;
}

public clear() {
this._pos = 0;
this._data = new Uint8Array();
}
}

/**
* PvFile Class
* This class mocks the file system using IndexedDB.
* IndexedDB is REQUIRED.
*/
export class PvFileIDB extends PvFile {
private readonly _pageSize = 65536;
private readonly _pageSize = 512 * 1024; // 512KB

private readonly _db: IDBDatabase;
private readonly _mode: IDBTransactionMode;

private _pagePtr = 0;
private _pageOffset = 0;

private _cache: PvCache;

get pageSize() {
return this._pageSize;
}

/**
* Constructor of PvFile instance.
* @param path The path of a file.
Expand All @@ -65,6 +104,8 @@ export class PvFileIDB extends PvFile {
this._meta = meta;
this._db = db;
this._mode = mode;

this._cache = new PvCache();
}

/**
Expand Down Expand Up @@ -155,9 +196,27 @@ export class PvFileIDB extends PvFile {
const totalElems = maxToCopy - (maxToCopy % size);
const buffer = new Uint8Array(totalElems);

// check if there's data in cache
const res = this._cache.get(totalElems);
if (res) {
copied += res.length;
this._pageOffset += res.length;
if (this._pageOffset === this._pageSize) {
this._pagePtr += 1;
this._pageOffset = 0;
}

if (totalElems === copied) {
resolve(res);
return;
}

buffer.set(res);
}

const keyRange = IDBKeyRange.bound(
`${this._path}-${PvFileIDB.createPage(this._pagePtr)}`,
`${this._path}-${PvFileIDB.createPage(this._meta!.numPages)}`
`${this._path}-${PvFileIDB.createPage(this._pagePtr + Math.floor(totalElems / this._pageSize) + 1)}`
);

const store = this._store;
Expand All @@ -178,12 +237,23 @@ export class PvFileIDB extends PvFile {
}
if (copied < totalElems) {
cursor.continue();
} else {
if (this._pageOffset !== 0) {
this._cache.set(this._pageOffset, cursor.value);
} else {
this._cache.clear();
}

if (store.transaction?.commit) {
store.transaction?.commit();
}
}
};

store.transaction.onerror = () => {
reject(store.transaction.error);
};

store.transaction.oncomplete = () => {
resolve(buffer.slice(0, copied));
};
Expand Down Expand Up @@ -228,7 +298,8 @@ export class PvFileIDB extends PvFile {
const newMeta: PvFileMeta = {
size: newSize,
numPages: Math.ceil(newSize / this._pageSize),
version: version
version: version,
pageSize: this._pageSize,
};
store.put(newMeta, this._path);

Expand All @@ -247,6 +318,10 @@ export class PvFileIDB extends PvFile {
store.delete(keyRange);
}

if (store.transaction?.commit) {
store.transaction?.commit();
}

store.transaction.onerror = () => {
reject(store.transaction.error);
};
Expand Down Expand Up @@ -296,6 +371,8 @@ export class PvFileIDB extends PvFile {

this._pageOffset = newOffset % this._pageSize;
this._pagePtr = Math.floor(newOffset / this._pageSize);

this._cache.clear();
}

/**
Expand Down
6 changes: 4 additions & 2 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,8 @@ export async function fromBase64(
if (
forceWrite ||
pvFile.meta === undefined ||
version > pvFile.meta.version!
version > pvFile.meta.version! ||
(pvFile.meta.pageSize !== pvFile.pageSize)
) {
await pvFile.write(base64ToUint8Array(modelBase64), version);
}
Expand All @@ -222,7 +223,8 @@ export async function fromPublicDirectory(
if (
forceWrite ||
pvFile.meta === undefined ||
version > pvFile.meta.version!
version > pvFile.meta.version! ||
(pvFile.meta.pageSize !== pvFile.pageSize)
) {
if (numFetchReties < 0) {
throw Error('numFetchRetries must be a positive number');
Expand Down

0 comments on commit 0231731

Please sign in to comment.