mirror of
https://github.com/immich-app/immich
synced 2025-10-17 18:19:27 +00:00
refactor(trash-sync): optimize performance and fix minor issues
This commit is contained in:
parent
5582a08c3a
commit
d47a2b5669
7 changed files with 44 additions and 24 deletions
2
mobile/drift_schemas/main/drift_schema_v13.json
generated
2
mobile/drift_schemas/main/drift_schema_v13.json
generated
File diff suppressed because one or more lines are too long
|
|
@ -5,6 +5,7 @@ import 'package:immich_mobile/infrastructure/utils/asset.mixin.dart';
|
|||
import 'package:immich_mobile/infrastructure/utils/drift_default.mixin.dart';
|
||||
|
||||
@TableIndex.sql('CREATE INDEX IF NOT EXISTS idx_trashed_local_asset_checksum ON trashed_local_asset_entity (checksum)')
|
||||
@TableIndex.sql('CREATE INDEX IF NOT EXISTS idx_trashed_local_asset_album ON trashed_local_asset_entity (album_id)')
|
||||
class TrashedLocalAssetEntity extends Table with DriftDefaultsMixin, AssetEntityMixin {
|
||||
const TrashedLocalAssetEntity();
|
||||
|
||||
|
|
|
|||
|
|
@ -1073,3 +1073,8 @@ class TrashedLocalAssetEntityCompanion
|
|||
.toString();
|
||||
}
|
||||
}
|
||||
|
||||
i0.Index get idxTrashedLocalAssetAlbum => i0.Index(
|
||||
'idx_trashed_local_asset_album',
|
||||
'CREATE INDEX IF NOT EXISTS idx_trashed_local_asset_album ON trashed_local_asset_entity (album_id)',
|
||||
);
|
||||
|
|
|
|||
|
|
@ -115,6 +115,7 @@ abstract class $Drift extends i0.GeneratedDatabase {
|
|||
trashedLocalAssetEntity,
|
||||
i11.idxLatLng,
|
||||
i19.idxTrashedLocalAssetChecksum,
|
||||
i19.idxTrashedLocalAssetAlbum,
|
||||
];
|
||||
@override
|
||||
i0.StreamQueryUpdateRules
|
||||
|
|
|
|||
|
|
@ -5067,6 +5067,7 @@ final class Schema13 extends i0.VersionedSchema {
|
|||
trashedLocalAssetEntity,
|
||||
idxLatLng,
|
||||
idxTrashedLocalAssetChecksum,
|
||||
idxTrashedLocalAssetAlbum,
|
||||
];
|
||||
late final Shape20 userEntity = Shape20(
|
||||
source: i0.VersionedTable(
|
||||
|
|
@ -5443,6 +5444,10 @@ final class Schema13 extends i0.VersionedSchema {
|
|||
'idx_trashed_local_asset_checksum',
|
||||
'CREATE INDEX IF NOT EXISTS idx_trashed_local_asset_checksum ON trashed_local_asset_entity (checksum)',
|
||||
);
|
||||
final i1.Index idxTrashedLocalAssetAlbum = i1.Index(
|
||||
'idx_trashed_local_asset_album',
|
||||
'CREATE INDEX IF NOT EXISTS idx_trashed_local_asset_album ON trashed_local_asset_entity (album_id)',
|
||||
);
|
||||
}
|
||||
|
||||
class Shape23 extends i0.VersionedTable {
|
||||
|
|
|
|||
|
|
@ -14,17 +14,17 @@ class DriftTrashedLocalAssetRepository extends DriftDatabaseRepository {
|
|||
final Drift _db;
|
||||
|
||||
const DriftTrashedLocalAssetRepository(this._db) : super(_db);
|
||||
static const _chunk = 32000;
|
||||
|
||||
Future<void> updateHashes(Map<String, String> hashes) {
|
||||
if (hashes.isEmpty) {
|
||||
return Future.value();
|
||||
}
|
||||
final now = DateTime.now();
|
||||
return _db.batch((batch) async {
|
||||
for (final entry in hashes.entries) {
|
||||
batch.update(
|
||||
_db.trashedLocalAssetEntity,
|
||||
TrashedLocalAssetEntityCompanion(checksum: Value(entry.value), updatedAt: Value(now)),
|
||||
TrashedLocalAssetEntityCompanion(checksum: Value(entry.value)),
|
||||
where: (e) => e.id.equals(entry.key),
|
||||
);
|
||||
}
|
||||
|
|
@ -102,18 +102,16 @@ class DriftTrashedLocalAssetRepository extends DriftDatabaseRepository {
|
|||
}
|
||||
});
|
||||
|
||||
if (assetIds.length <= 32000) {
|
||||
if (assetIds.length <= _chunk) {
|
||||
await (_db.delete(_db.trashedLocalAssetEntity)..where((row) => row.id.isNotIn(assetIds))).go();
|
||||
} else {
|
||||
final existingIds = await (_db.selectOnly(
|
||||
_db.trashedLocalAssetEntity,
|
||||
)..addColumns([_db.trashedLocalAssetEntity.id])).map((r) => r.read(_db.trashedLocalAssetEntity.id)!).get();
|
||||
final idToDelete = existingIds.where((id) => !assetIds.contains(id));
|
||||
await _db.batch((batch) {
|
||||
for (final id in idToDelete) {
|
||||
batch.deleteWhere(_db.trashedLocalAssetEntity, (row) => row.id.equals(id));
|
||||
}
|
||||
});
|
||||
for (final slice in idToDelete.slices(_chunk)) {
|
||||
await (_db.delete(_db.trashedLocalAssetEntity)..where((t) => t.id.isIn(slice))).go();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -181,7 +179,7 @@ class DriftTrashedLocalAssetRepository extends DriftDatabaseRepository {
|
|||
id: Value(asset.id),
|
||||
name: Value(asset.name),
|
||||
albumId: Value(entry.key),
|
||||
checksum: asset.checksum == null ? const Value.absent() : Value(asset.checksum),
|
||||
checksum: Value(asset.checksum),
|
||||
type: Value(asset.type),
|
||||
width: Value(asset.width),
|
||||
height: Value(asset.height),
|
||||
|
|
@ -200,24 +198,29 @@ class DriftTrashedLocalAssetRepository extends DriftDatabaseRepository {
|
|||
await _db.into(_db.trashedLocalAssetEntity).insertOnConflictUpdate(companion);
|
||||
}
|
||||
|
||||
for (final id in idToDelete) {
|
||||
await (_db.delete(_db.localAssetEntity)..where((row) => row.id.equals(id))).go();
|
||||
for (final slice in idToDelete.slices(_chunk)) {
|
||||
await (_db.delete(_db.trashedLocalAssetEntity)..where((t) => t.id.isIn(slice))).go();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> applyRestoredAssets(Iterable<String> ids) async {
|
||||
if (ids.isEmpty) {
|
||||
Future<void> applyRestoredAssets(List<String> idList) async {
|
||||
if (idList.isEmpty) {
|
||||
return;
|
||||
}
|
||||
|
||||
final trashedAssets = await (_db.select(_db.trashedLocalAssetEntity)..where((tbl) => tbl.id.isIn(ids))).get();
|
||||
final trashedAssets = <TrashedLocalAssetEntityData>[];
|
||||
|
||||
for (final slice in idList.slices(_chunk)) {
|
||||
final q = _db.select(_db.trashedLocalAssetEntity)..where((t) => t.id.isIn(slice));
|
||||
trashedAssets.addAll(await q.get());
|
||||
}
|
||||
|
||||
if (trashedAssets.isEmpty) {
|
||||
return;
|
||||
}
|
||||
|
||||
final localAssets = trashedAssets.map((e) {
|
||||
final companions = trashedAssets.map((e) {
|
||||
return LocalAssetEntityCompanion.insert(
|
||||
id: e.id,
|
||||
name: e.name,
|
||||
|
|
@ -231,15 +234,15 @@ class DriftTrashedLocalAssetRepository extends DriftDatabaseRepository {
|
|||
isFavorite: Value(e.isFavorite),
|
||||
orientation: Value(e.orientation),
|
||||
);
|
||||
}).toList();
|
||||
});
|
||||
|
||||
await _db.transaction(() async {
|
||||
await _db.batch((batch) {
|
||||
batch.insertAllOnConflictUpdate(_db.localAssetEntity, localAssets);
|
||||
for (final id in ids) {
|
||||
batch.deleteWhere(_db.trashedLocalAssetEntity, (row) => row.id.equals(id));
|
||||
}
|
||||
});
|
||||
for (final companion in companions) {
|
||||
await _db.into(_db.localAssetEntity).insertOnConflictUpdate(companion);
|
||||
}
|
||||
for (final slice in idList.slices(_chunk)) {
|
||||
await (_db.delete(_db.trashedLocalAssetEntity)..where((t) => t.id.isIn(slice))).go();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -247,7 +250,7 @@ class DriftTrashedLocalAssetRepository extends DriftDatabaseRepository {
|
|||
Future<Map<String, String>> _getCachedChecksums(Set<String> assetIds) async {
|
||||
final localChecksumById = <String, String>{};
|
||||
|
||||
for (final slice in assetIds.slices(32000)) {
|
||||
for (final slice in assetIds.slices(_chunk)) {
|
||||
final rows =
|
||||
await (_db.selectOnly(_db.localAssetEntity)
|
||||
..where(_db.localAssetEntity.id.isIn(slice) & _db.localAssetEntity.checksum.isNotNull())
|
||||
|
|
|
|||
5
mobile/test/drift/main/generated/schema_v13.dart
generated
5
mobile/test/drift/main/generated/schema_v13.dart
generated
|
|
@ -7720,6 +7720,10 @@ class DatabaseAtV13 extends GeneratedDatabase {
|
|||
'idx_trashed_local_asset_checksum',
|
||||
'CREATE INDEX IF NOT EXISTS idx_trashed_local_asset_checksum ON trashed_local_asset_entity (checksum)',
|
||||
);
|
||||
late final Index idxTrashedLocalAssetAlbum = Index(
|
||||
'idx_trashed_local_asset_album',
|
||||
'CREATE INDEX IF NOT EXISTS idx_trashed_local_asset_album ON trashed_local_asset_entity (album_id)',
|
||||
);
|
||||
@override
|
||||
Iterable<TableInfo<Table, Object?>> get allTables =>
|
||||
allSchemaEntities.whereType<TableInfo<Table, Object?>>();
|
||||
|
|
@ -7751,6 +7755,7 @@ class DatabaseAtV13 extends GeneratedDatabase {
|
|||
trashedLocalAssetEntity,
|
||||
idxLatLng,
|
||||
idxTrashedLocalAssetChecksum,
|
||||
idxTrashedLocalAssetAlbum,
|
||||
];
|
||||
@override
|
||||
int get schemaVersion => 13;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue