From cee093c214dc2eaa36c2e7991da8fd2ee01e5cb7 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 29 May 2024 13:22:40 +0530 Subject: [PATCH] query --- web/apps/photos/src/services/face/db.ts | 60 ++++++++++++++----------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/web/apps/photos/src/services/face/db.ts b/web/apps/photos/src/services/face/db.ts index 56ab5d8368..fa4f8dd63f 100644 --- a/web/apps/photos/src/services/face/db.ts +++ b/web/apps/photos/src/services/face/db.ts @@ -30,7 +30,7 @@ interface FaceDBSchema extends DBSchema { "file-status": { key: number; value: FileStatus; - indexes: { isIndexed: number }; + indexes: { isIndexable: number }; }; } @@ -38,15 +38,11 @@ interface FileStatus { /** The ID of the {@link EnteFile} whose indexing status we represent. */ fileID: number; /** - * `1` if we have indexed a file with this {@link fileID}, `0` otherwise. - * - * It is guaranteed that "face-index" will have an entry for the same - * {@link fileID} if and only if {@link isIndexed} is `1`. + * `1` if this file needs to be indexed, `0` otherwise. * * > Somewhat confusingly, we also have a (IndexedDB) "index" on this field. - * That (IDB) index allows us to effectively select {@link fileIDs} that - * still need indexing (where {@link isIndexed} is not `1`), so it is all - * sensible, just that if I say the word "index" one more time... + * That (IDB) index allows us to efficiently select {@link fileIDs} that + * still need indexing (i.e. entries where {@link isIndexed} is `1`). * * [Note: Boolean IndexedDB indexes]. * @@ -56,12 +52,13 @@ interface FileStatus { * As a workaround, we use numeric fields where `0` denotes `false` and `1` * denotes `true`. */ - isIndexed: number; + isIndexable: number; /** * The number of times attempts to index this file failed. * * This is guaranteed to be `0` for files which have already been - * sucessfully indexed (i.e. files for which `isIndexed` is true). + * sucessfully indexed (i.e. files for which `isIndexable` is 0 and which + * have a corresponding entry in the "face-index" object store). */ failureCount: number; } @@ -77,10 +74,10 @@ interface FileStatus { * version of the schema). * * Note that this is module specific state, so the main thread and each worker - * thread that calls the functions in this module will get their own independent - * connection. To ensure that all connections get torn down correctly, we need - * to call {@link closeFaceDBConnectionsIfNeeded} from both the main thread and - * all the worker threads that use this module. + * thread that calls the functions in this module will have their own promises. + * To ensure that all connections get torn down correctly, we need to call + * {@link closeFaceDBConnectionsIfNeeded} from both the main thread and all the + * worker threads that use this module. */ let _faceDB: ReturnType | undefined; @@ -90,11 +87,9 @@ const openFaceDB = async () => { log.info(`Upgrading face DB ${oldVersion} => ${newVersion}`); if (oldVersion < 1) { db.createObjectStore("face-index", { keyPath: "fileID" }); - - const statusStore = db.createObjectStore("file-status", { + db.createObjectStore("file-status", { keyPath: "fileID", - }); - statusStore.createIndex("isIndexed", "isIndexed"); + }).createIndex("isIndexable", "isIndexable"); } }, blocking() { @@ -172,7 +167,7 @@ export const saveFaceIndex = async (faceIndex: FaceIndex) => { indexStore.put(faceIndex), statusStore.put({ fileID: faceIndex.fileID, - isIndexed: 1, + isIndexable: 0, failureCount: 0, }), tx.done, @@ -196,13 +191,27 @@ export const addFileEntry = async (fileID: number) => { if ((await tx.store.getKey(fileID)) === undefined) { await tx.store.put({ fileID, - isIndexed: 0, + isIndexable: 1, failureCount: 0, }); } return tx.done; }; +/** + * Return a list of fileIDs that need to be indexed. + * + * This list is from the universe of the file IDs that the face DB knows about + * (can use {@link addFileEntry} to inform it about new files). From this + * universe, we filter out fileIDs the files corresponding to which have already + * been indexed, or for which we attempted indexing but failed. + */ +export const unindexedFileIDs = async () => { + const db = await faceDB(); + const tx = db.transaction("file-status", "readonly"); + return tx.store.index("isIndexable").getAllKeys(IDBKeyRange.only(1)); +}; + /** * Increment the failure count associated with the given {@link fileID}. * @@ -215,12 +224,11 @@ export const addFileEntry = async (fileID: number) => { export const markIndexingFailed = async (fileID: number) => { const db = await faceDB(); const tx = db.transaction("file-status", "readwrite"); - const status = (await tx.store.get(fileID)) ?? { + const failureCount = ((await tx.store.get(fileID)).failureCount ?? 0) + 1; + await tx.store.put({ fileID, - isIndexed: 0, - failureCount: 0, - }; - status.failureCount = status.failureCount + 1; - await tx.store.put(status); + isIndexable: 0, + failureCount, + }); return tx.done; };