Match server schema

This commit is contained in:
Manav Rathi
2024-09-18 12:03:54 +05:30
parent 1521971a5d
commit b7a45b4327
3 changed files with 17 additions and 24 deletions

View File

@@ -8,12 +8,9 @@ import { faceDirection, type Face, type FaceIndex } from "./face";
import { dotProduct } from "./math";
/**
* A face cluster is an set of faces.
* A face cluster is an set of faces, and a nanoid to uniquely identify it.
*
* Each cluster has an id so that a {@link CGroup} can refer to it.
*
* The cluster is not directly synced to remote. Only clusters that the user
* interacts with get synced to remote, as part of a {@link CGroup}.
* A cluster may be local only, or synced to remote as part of a {@link CGroup}.
*/
export interface FaceCluster {
/**
@@ -26,7 +23,7 @@ export interface FaceCluster {
* For ergonomics of transportation and persistence this is an array, but it
* should conceptually be thought of as a set.
*/
faceIDs: string[];
faces: string[];
}
export interface ClusteringOpts {
@@ -164,11 +161,11 @@ export const clusterFaces = (
// Prune clusters that are smaller than the threshold.
const validClusters = clusters.filter(
(cs) => cs.faceIDs.length > minClusterSize,
(cs) => cs.faces.length > minClusterSize,
);
const sortedClusters = validClusters.sort(
(a, b) => b.faceIDs.length - a.faceIDs.length,
(a, b) => b.faces.length - a.faces.length,
);
// Convert into the data structure we're using to debug/visualize.
@@ -177,9 +174,7 @@ export const clusterFaces = (
? sortedClusters
: sortedClusters.slice(0, 30).concat(sortedClusters.slice(-30));
const clusterPreviews = clusterPreviewClusters.map((cluster) => {
const faces = cluster.faceIDs.map((id) =>
ensure(faceForFaceID.get(id)),
);
const faces = cluster.faces.map((id) => ensure(faceForFaceID.get(id)));
const topFace = faces.reduce((top, face) =>
top.score > face.score ? top : face,
);
@@ -188,7 +183,7 @@ export const clusterFaces = (
return { face, cosineSimilarity: csim, wasMerged: false };
});
return {
clusterSize: cluster.faceIDs.length,
clusterSize: cluster.faces.length,
faces: previewFaces
.sort((a, b) => b.cosineSimilarity - a.cosineSimilarity)
.slice(0, 50),
@@ -201,9 +196,7 @@ export const clusterFaces = (
const cgroups: AnnotatedCGroup[] = [];
for (const cluster of sortedClusters) {
const faces = cluster.faceIDs.map((id) =>
ensure(faceForFaceID.get(id)),
);
const faces = cluster.faces.map((id) => ensure(faceForFaceID.get(id)));
const topFace = faces.reduce((top, face) =>
top.score > face.score ? top : face,
);
@@ -377,12 +370,12 @@ const clusterBatchLinear = (
state.clusterIDForFaceID.set(fi.faceID, nnCluster.id);
state.clusterIndexForFaceID.set(fi.faceID, nnClusterIndex);
nnCluster.faceIDs.push(fi.faceID);
nnCluster.faces.push(fi.faceID);
} else {
// No neighbour within the threshold. Create a new cluster.
const clusterID = newClusterID();
const clusterIndex = state.clusters.length;
const cluster = { id: clusterID, faceIDs: [fi.faceID] };
const cluster = { id: clusterID, faces: [fi.faceID] };
state.clusterIDForFaceID.set(fi.faceID, cluster.id);
state.clusterIndexForFaceID.set(fi.faceID, clusterIndex);

View File

@@ -429,7 +429,7 @@ export const wipClusterDebugPageContents = async (
const faceIDs = cgroup.clusterIDs
.map((id) => ensure(clusterByID.get(id)))
.flatMap((cluster) => cluster.faceIDs);
.flatMap((cluster) => cluster.faces);
const fileIDs = faceIDs
.map((faceID) => fileIDFromFaceID(faceID))
.filter((fileID) => fileID !== undefined);

View File

@@ -132,14 +132,14 @@ export const pullCGroups = (masterKey: Uint8Array) => {
return pullUserEntities("cgroup", masterKey, processBatch);
};
const RemoteFaceCluster = z.object({
id: z.string(),
faces: z.string().array(),
});
const RemoteCGroup = z.object({
name: z.string().nullish().transform(nullToUndefined),
assigned: z.array(
z.object({
id: z.string(),
faces: z.string().array(),
}),
),
assigned: z.array(RemoteFaceCluster),
// The remote cgroup also has a "rejected" property, but that is not
// currently used by any of the clients.
isHidden: z.boolean(),