[mob] use ml version when to decide need for re-index

This commit is contained in:
Neeraj Gupta
2024-03-19 16:16:08 +05:30
parent e83e8cdb6e
commit a79b14db78
4 changed files with 25 additions and 15 deletions

View File

@@ -78,12 +78,16 @@ class FaceMLDataDB {
}
}
Future<Set<int>> getIndexedFileIds() async {
Future<Map<int, int>> getIndexedFileIds() async {
final db = await instance.database;
final List<Map<String, dynamic>> maps = await db.rawQuery(
'SELECT DISTINCT $fileIDColumn FROM $facesTable',
'SELECT $fileIDColumn, $mlVersionColumn FROM $facesTable',
);
return maps.map((e) => e[fileIDColumn] as int).toSet();
final Map<int, int> result = {};
for (final map in maps) {
result[map[fileIDColumn] as int] = map[mlVersionColumn] as int;
}
return result;
}
Future<Map<int, int>> clusterIdToFaceCount() async {

View File

@@ -5,6 +5,7 @@ import "package:photos/face/model/detection.dart";
import "package:photos/face/model/face.dart";
import "package:photos/face/model/person.dart";
import "package:photos/generated/protos/ente/common/vector.pb.dart";
import "package:photos/models/ml/ml_versions.dart";
int boolToSQLInt(bool? value, {bool defaultValue = false}) {
final bool v = value ?? defaultValue;
@@ -58,7 +59,7 @@ Map<String, dynamic> mapRemoteToFaceDB(Face face) {
).writeToBuffer(),
faceScore: face.score,
faceBlur: face.blur,
mlVersionColumn: 1,
mlVersionColumn: faceMlVersion,
};
}

View File

@@ -415,7 +415,7 @@ class FaceMlService {
_logger.info('starting image indexing');
final List<EnteFile> enteFiles =
await SearchService.instance.getAllFiles();
final Set<int> alreadyIndexedFiles =
final Map<int, int> alreadyIndexedFiles =
await FaceMLDataDB.instance.getIndexedFileIds();
// Make sure the image conversion isolate is spawned
@@ -456,7 +456,7 @@ class FaceMlService {
final res =
await RemoteFileMLService.instance.getFilessEmbedding(fileIds);
final List<Face> faces = [];
final indexedFileIds = <int>{};
final remoteFileIdToVersion = <int, int>{};
for (FileMl fileMl in res.mlData.values) {
if (fileMl.faceEmbedding.version != faceMlVersion) continue;
if (fileMl.faceEmbedding.faces.isEmpty) {
@@ -473,11 +473,13 @@ class FaceMlService {
} else {
faces.addAll(fileMl.faceEmbedding.faces);
}
indexedFileIds.add(fileMl.fileID);
remoteFileIdToVersion[fileMl.fileID] = fileMl.faceEmbedding.version;
}
await FaceMLDataDB.instance.bulkInsertFaces(faces);
alreadyIndexedFiles.addAll(indexedFileIds);
_logger.info('already indexed files ${indexedFileIds.length}');
for (final entry in remoteFileIdToVersion.entries) {
alreadyIndexedFiles[entry.key] = entry.value;
}
_logger.info('already indexed files ${remoteFileIdToVersion.length}');
} catch (e, s) {
_logger.severe("err while getting files embeddings", e, s);
rethrow;
@@ -1147,7 +1149,7 @@ class FaceMlService {
/// Checks if the ente file to be analyzed actually can be analyzed: it must be uploaded and in the correct format.
void _checkEnteFileForID(EnteFile enteFile) {
if (_skipAnalysisEnteFile(enteFile, <int>{})) {
if (_skipAnalysisEnteFile(enteFile, <int, int>{})) {
_logger.severe(
"Skipped analysis of image with enteFile ${enteFile.toString()} because it is the wrong format or has no uploadedFileID",
);
@@ -1155,7 +1157,7 @@ class FaceMlService {
}
}
bool _skipAnalysisEnteFile(EnteFile enteFile, Set<int> indexedFileIds) {
bool _skipAnalysisEnteFile(EnteFile enteFile, Map<int, int> indexedFileIds) {
// Skip if the file is not uploaded or not owned by the user
if (!enteFile.isUploaded || enteFile.isOwner == false) {
return true;
@@ -1171,7 +1173,9 @@ class FaceMlService {
}
// Skip if the file is already analyzed with the latest ml version
final id = enteFile.uploadedFileID!;
return indexedFileIds.contains(id);
return indexedFileIds.containsKey(id) &&
indexedFileIds[id]! >= faceMlVersion;
}
Future<FaceMlResult?> _checkForExistingUpToDateResult(

View File

@@ -8,6 +8,7 @@ import "package:photos/events/people_changed_event.dart";
import "package:photos/extensions/stop_watch.dart";
import "package:photos/face/db.dart";
import "package:photos/face/model/person.dart";
import "package:photos/models/ml/ml_versions.dart";
import "package:photos/services/face_ml/face_ml_service.dart";
import "package:photos/services/face_ml/feedback/cluster_feedback.dart";
import 'package:photos/theme/ente_theme.dart';
@@ -58,7 +59,7 @@ class _FaceDebugSectionWidgetState extends State<FaceDebugSectionWidget> {
return Column(
children: [
MenuItemWidget(
captionedTextWidget: FutureBuilder<Set<int>>(
captionedTextWidget: FutureBuilder<Map<int, int>>(
future: FaceMLDataDB.instance.getIndexedFileIds(),
builder: (context, snapshot) {
if (snapshot.hasData) {
@@ -182,7 +183,7 @@ class _FaceDebugSectionWidgetState extends State<FaceDebugSectionWidget> {
if (kDebugMode) sectionOptionSpacing,
if (kDebugMode)
MenuItemWidget(
captionedTextWidget: FutureBuilder<Set<int>>(
captionedTextWidget: FutureBuilder<Map<int, int>>(
future: FaceMLDataDB.instance.getIndexedFileIds(),
builder: (context, snapshot) {
if (snapshot.hasData) {
@@ -204,7 +205,7 @@ class _FaceDebugSectionWidgetState extends State<FaceDebugSectionWidget> {
watch.logAndReset('read embeddings ${result.length} ');
showShortToast(
context,
"Done in ${watch.elapsed.inSeconds} secs",
"Read ${result.length} face embeddings in ${watch.elapsed.inSeconds} secs",
);
},
),