Skip to main content

FaceRepo

Struct FaceRepo 

Source
pub struct FaceRepo<'a> { /* private fields */ }
Expand description

Face database repository

Implementations§

Source§

impl<'a> FaceRepo<'a>

Source

pub fn refresh_all_galleries(&self) -> SqliteResult<()>

Source

pub fn face_thumbnail_candidates( &self, cluster_ids: &[i64], max_per_cluster: usize, ) -> SqliteResult<HashMap<i64, Vec<i64>>>

Return fallback face thumbnail candidates for the supplied clusters.

The rows are ordered by cluster, then by face confidence descending. Callers can check the corresponding crop files outside the shared DB mutex and then persist any representative replacement in one batch.

Source

pub fn update_representative_faces( &self, updates: &[(i64, i64)], ) -> SqliteResult<()>

Source

pub fn normalize_cluster_stats(&self) -> SqliteResult<()>

Recompute all cluster stats and prune empty clusters.

Source

pub fn populate_face_thumbnails( &self, clusters: &mut [FaceClusterRecord], drive_path: &Path, ) -> SqliteResult<()>

Populate face thumbnail paths on cluster records.

Call this after get_all_clusters() with the drive root path. The path written into each cluster is relative to drive_root (e.g. .photovault/faces/42.jpg) so it round-trips through the same frontend thumbUrl() helper as photos.thumbnail_path.

Source§

impl<'a> FaceRepo<'a>

Source

pub fn count_pending_face_processing(&self) -> SqliteResult<i64>

Count of photos that haven’t yet had face detection run. Drives the “Resume face detection” banner on the People page.

Source

pub fn get_unclustered_faces_with_photo_embeddings( &self, ) -> SqliteResult<Vec<(i64, i64, FaceEmbedding)>>

Get unclustered faces with photo_id and embeddings.

Source

pub fn get_all_clusters(&self) -> SqliteResult<Vec<FaceClusterRecord>>

Get all clusters, ordered by photo count descending

Source

pub fn get_cluster_photo_ids(&self) -> SqliteResult<Vec<(i64, i64)>>

Source

pub fn get_people_for_photo( &self, photo_id: i64, ) -> SqliteResult<Vec<(i64, String)>>

Get person names for a photo (faces detected in this photo with cluster names) Get (cluster_id, display_name) pairs for all people detected in a photo.

Source

pub fn get_photos_for_cluster(&self, cluster_id: i64) -> SqliteResult<Vec<i64>>

Get all photo IDs that contain faces from a given cluster

Source

pub fn get_all_faces_with_paths( &self, ) -> SqliteResult<Vec<(i64, String, i32, f32, f32, f32, f32)>>

Get all face IDs with bounding boxes and their photo file paths. Used for regenerating missing face crops.

Source

pub fn get_contextual_cluster_candidates( &self, photo_id: i64, folder_prefix_like: Option<&str>, target_ts: i64, window_secs: i64, ) -> SqliteResult<Vec<(i64, i64, i64, String)>>

Find contextual candidate identities from nearby photos in the same folder.

Source

pub fn get_unprocessed_photos_with_context( &self, ) -> SqliteResult<Vec<(i64, String, i32, Option<i64>, String)>>

Get unprocessed photos with optional timestamp for contextual identity linking.

Source

pub fn get_photo_brightness(&self, photo_id: i64) -> SqliteResult<Option<f32>>

Read the cached photos.brightness value for a photo. Returns None if the photo doesn’t exist OR brightness was never computed (NULL in the column). Caller is expected to fall back to on-disk recomputation in that case.

Source

pub fn review_queue_size(&self) -> SqliteResult<i64>

Count of unresolved entries in the face review queue.

Source

pub fn get_review_queue_items( &self, limit: usize, ) -> SqliteResult<Vec<ReviewItem>>

Pull the top-N most informative unresolved review items.

Ordered by ambiguity ascending (closer top-2 scores first = higher information gain) then by candidate cluster size descending (resolving ambiguity on big clusters propagates to more photos).

Source

pub fn get_photo_other_clusters( &self, photo_id: i64, exclude_face_id: i64, ) -> SqliteResult<Vec<i64>>

Cluster IDs of the already-assigned faces in the given photo (other than the face we’re resolving). Used as the “context” in co-occurrence.

Source

pub fn cooccurrence_count( &self, cluster_a: i64, cluster_b: i64, ) -> SqliteResult<i64>

How many photos contain both cluster_a and cluster_b.

Used as the co-occurrence strength between two clusters. High values mean the two people appear together frequently and should bias retrieval toward whichever matches the rest of the photo’s cast.

Source

pub fn temporal_neighbor_clusters( &self, photo_id: i64, window_secs: i64, ) -> SqliteResult<Vec<(i64, i64)>>

Clusters assigned to faces within a time window around date_taken, excluding the photo itself. Returns (cluster_id, delta_seconds).

Used for temporal-chain propagation: if nearby-in-time photos contain high-confidence assignments for cluster X, an ambiguous face in our photo should be biased toward X.

Source

pub fn get_faces_by_cluster( &self, cluster_id: i64, status: FaceStatus, cursor: Option<i64>, limit: usize, ) -> SqliteResult<Vec<FaceDetail>>

Get faces for a cluster filtered by status.

Source

pub fn get_unclustered_faces( &self, cursor: Option<i64>, limit: usize, ) -> SqliteResult<Vec<FaceDetail>>

Recently detected faces that are not assigned to a person yet. Used only as a live, in-progress surface while the face pipeline is still clustering. The final People grid remains cluster-based.

Source

pub fn count_unconfirmed_in_cluster(&self, cluster_id: i64) -> SqliteResult<i64>

Count unconfirmed faces in a cluster.

Source

pub fn count_unconfirmed_global(&self) -> SqliteResult<(i64, i64)>

Count unconfirmed faces across all clusters. Returns (total_unconfirmed, clusters_with_unconfirmed).

Source

pub fn next_unconfirmed_face_batch( &self, limit: usize, ) -> SqliteResult<Vec<FaceDetail>>

Return the next batch of unconfirmed faces from the cluster with the most pending review work. This keeps the review UI O(1) instead of probing every person until it finds one with faces.

Source

pub fn next_unconfirmed_face_batch_excluding( &self, limit: usize, excluded_face_ids: &[i64], ) -> SqliteResult<Vec<FaceDetail>>

Return the next review batch while ignoring faces the current UI session has skipped. Skips are intentionally not persisted as a reject/confirm decision, but they still need to be excluded from the server-side cluster selection or the reviewer can be sent straight back to the same skipped-only cluster.

Source

pub fn get_negatives_for_face(&self, face_id: i64) -> SqliteResult<Vec<i64>>

Get negatives for a face (clusters it should NOT be in).

Source

pub fn k_similar_to_cluster( &self, cluster_id: i64, k: usize, ) -> SqliteResult<Vec<(i64, f32)>>

K-similar: find K nearest unassigned faces to a cluster’s confirmed gallery centroid.

Source§

impl<'a> FaceRepo<'a>

Source

pub fn reset_if_no_faces(&self) -> SqliteResult<usize>

Reset faces_processed flags when no faces were actually detected.

This handles the case where a prior run marked all photos as processed but failed to actually detect faces (e.g., model loading error).

Source

pub fn name_cluster(&self, cluster_id: i64, name: &str) -> SqliteResult<()>

Name a cluster (set the person’s name)

Source

pub fn delete_cluster(&self, cluster_id: i64) -> SqliteResult<()>

Delete a face cluster — “this isn’t a real person” gesture.

Faces previously assigned to this cluster have their cluster_id set to NULL so a future re-clustering pass can pick them up again. Inferred-identity links and gallery embeddings rooted at the cluster cascade away (FK ON DELETE CASCADE in the schema).

Source

pub fn assign_face_to_cluster( &self, face_id: i64, cluster_id: i64, ) -> SqliteResult<()>

Assign an existing face to an existing cluster and update cluster metadata.

Source

pub fn create_cluster(&self, face_ids: &[i64]) -> SqliteResult<i64>

Create a new face cluster from a set of face IDs

Source

pub fn merge_clusters(&self, source_id: i64, target_id: i64) -> SqliteResult<()>

Merge source cluster into target cluster

Moves all faces from source to target, updates counts, deletes source. Refuses if a cannot-merge constraint exists between the two clusters.

Source

pub fn get_cannot_merge_map(&self) -> SqliteResult<HashMap<i64, HashSet<i64>>>

Load all cannot-merge pairs (returns them in both directions for easy lookup).

Source

pub fn enqueue_review( &self, face_id: i64, candidate_cluster_id: i64, score: f32, ambiguity: Option<f32>, ) -> SqliteResult<()>

Add a face to the review queue with its top candidate cluster.

Idempotent via UNIQUE(face_id, candidate_cluster_id). Updates score and ambiguity on conflict.

Source

pub fn resolve_review_same(&self, queue_id: i64) -> SqliteResult<()>

User confirmed this face is the same person as the candidate cluster.

Atomic: assigns the face, marks user_confirmed=1, adds the face to the cluster’s gallery with source=‘user_confirmed’ (sticky), resolves the queue entry, refreshes cluster stats.

Source

pub fn resolve_review_different(&self, queue_id: i64) -> SqliteResult<()>

User rejected this candidate: the face is NOT the candidate cluster.

  • Marks the face with user_confirmed = -1 (rejected for this candidate).
  • If the face was previously assigned to a different cluster, records a cluster_cannot_merge pair.
  • Resolves the queue entry.
Source

pub fn resolve_review_skip(&self, queue_id: i64) -> SqliteResult<()>

User skipped this item: mark resolved_as = ‘skipped’ so it doesn’t resurface in the next review session (but can be re-queued on a future scan if the situation changes).

Source

pub fn confirm_face(&self, face_id: i64) -> SqliteResult<()>

Confirm a face: set user_confirmed=1. Add to gallery if not already.

Source

pub fn reject_face_to_unknown( &self, face_id: i64, prev_cluster_id: i64, ) -> SqliteResult<()>

Reject face to unknown: set cluster_id=NULL, user_confirmed=0. Write negative.

Source

pub fn hide_face(&self, face_id: i64) -> SqliteResult<()>

Hide face: set cluster_id=NULL, user_confirmed=-1. Excluded from future clustering.

Source

pub fn reassign_face( &self, face_id: i64, new_cluster_id: i64, old_cluster_id: i64, ) -> SqliteResult<()>

Reassign a face to a different cluster. Marks user_confirmed=1, writes negative against the old cluster_id so it won’t come back.

Source

pub fn confirm_face_to_cluster( &self, face_id: i64, cluster_id: i64, ) -> SqliteResult<()>

Confirm a currently-unassigned face into a cluster (used by K-similar flow).

Source

pub fn unresolve_review(&self, queue_id: i64) -> SqliteResult<()>

Reverse a prior review resolution (for undo).

Source§

impl<'a> FaceRepo<'a>

Source

pub fn new(conn: &'a Connection) -> Self

Auto Trait Implementations§

§

impl<'a> Freeze for FaceRepo<'a>

§

impl<'a> !RefUnwindSafe for FaceRepo<'a>

§

impl<'a> !Send for FaceRepo<'a>

§

impl<'a> !Sync for FaceRepo<'a>

§

impl<'a> Unpin for FaceRepo<'a>

§

impl<'a> UnsafeUnpin for FaceRepo<'a>

§

impl<'a> !UnwindSafe for FaceRepo<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

impl<T> PolicyExt for T
where T: ?Sized,

§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] only if self and other return Action::Follow. Read more
§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more