Confirm a group, and split one, in one transaction

`confirm_all` called `faces::confirm` per face, and `split_off` called
`reject` then `confirm` per face: each opens and commits its own
transaction, so a click on a group of several hundred was several hundred
commits. `faces::confirm_all` is two statements — clear the rejections the
confirmations override, then flip the rows — and `faces::reassign` does a
split's reject-and-confirm for every face under one commit. 16 ms → 2 ms
and 22 ms → 4 ms on the largest group.
This commit is contained in:
2026-09-20 10:56:36 +02:00
parent 97a854833d
commit 9d1aa5735b
2 changed files with 70 additions and 16 deletions
+4 -16
View File
@@ -580,15 +580,7 @@ pub fn rename(
/// right — the common case for a well-photographed person — should cost one
/// click, not forty.
pub fn confirm_all(catalog: &Catalog, person: PersonId) -> Result<usize, dr_catalog::CatalogError> {
let conn = catalog.connection();
let mut n = 0;
for f in faces::for_person(conn, person, true)? {
if !f.confirmed {
faces::confirm(conn, f.id, person)?;
n += 1;
}
}
Ok(n)
faces::confirm_all(catalog.connection(), person).map(|n| n as usize)
}
/// The user says this face is this person.
@@ -733,13 +725,9 @@ pub fn split_off(
) -> Result<PersonId, dr_catalog::CatalogError> {
let conn = catalog.connection();
let new_person = faces::create_person(conn, name.trim())?;
for &face in members {
// Rejecting first is what stops the split being undone: without it the
// next pass sees a face that looks like `from` and suggests it straight
// back, and the user's correction becomes an argument they keep having.
faces::reject(conn, face, from)?;
faces::confirm(conn, face, new_person)?;
}
// Rejected from `from` and confirmed onto the new person, in one
// transaction rather than two per face: `faces::reassign` says why both.
faces::reassign(conn, members, from, new_person)?;
Ok(new_person)
}