minimized change notifications, fixed logs

This commit is contained in:
Thibault Deckers 2020-01-01 20:21:41 +09:00
parent e3e222c589
commit 03246a8df4
4 changed files with 38 additions and 30 deletions

View file

@ -19,7 +19,7 @@ class ImageCollection with ChangeNotifier {
this.groupFactor,
this.sortFactor,
}) : _rawEntries = entries {
updateSections();
if (_rawEntries.isNotEmpty) updateSections();
}
int get imageCount => _rawEntries.where((entry) => !entry.isVideo).length;
@ -64,7 +64,7 @@ class ImageCollection with ChangeNotifier {
]);
break;
}
debugPrint('$runtimeType updateSections');
debugPrint('$runtimeType updateSections notifyListeners');
notifyListeners();
}
@ -114,7 +114,7 @@ class ImageCollection with ChangeNotifier {
}
Future<void> loadCatalogMetadata() async {
final start = DateTime.now();
final stopwatch = Stopwatch()..start();
final saved = await metadataDb.loadMetadataEntries();
_rawEntries.forEach((entry) {
final contentId = entry.contentId;
@ -122,12 +122,12 @@ class ImageCollection with ChangeNotifier {
entry.catalogMetadata = saved.firstWhere((metadata) => metadata.contentId == contentId, orElse: () => null);
}
});
debugPrint('$runtimeType loadCatalogMetadata complete in ${stopwatch.elapsed.inMilliseconds}ms with ${saved.length} saved entries');
onMetadataChanged();
debugPrint('$runtimeType loadCatalogMetadata complete in ${DateTime.now().difference(start).inSeconds}s with ${saved.length} saved entries');
}
Future<void> loadAddresses() async {
final start = DateTime.now();
final stopwatch = Stopwatch()..start();
final saved = await metadataDb.loadAddresses();
_rawEntries.forEach((entry) {
final contentId = entry.contentId;
@ -135,36 +135,44 @@ class ImageCollection with ChangeNotifier {
entry.addressDetails = saved.firstWhere((address) => address.contentId == contentId, orElse: () => null);
}
});
debugPrint('$runtimeType loadAddresses complete in ${DateTime.now().difference(start).inSeconds}s with ${saved.length} saved entries');
debugPrint('$runtimeType loadAddresses complete in ${stopwatch.elapsed.inMilliseconds}ms with ${saved.length} saved entries');
}
Future<void> catalogEntries() async {
final start = DateTime.now();
final stopwatch = Stopwatch()..start();
final uncataloguedEntries = _rawEntries.where((entry) => !entry.isCatalogued).toList();
if (uncataloguedEntries.isEmpty) return;
final newMetadata = <CatalogMetadata>[];
await Future.forEach<ImageEntry>(uncataloguedEntries, (entry) async {
await entry.catalog();
if (entry.isCatalogued) {
newMetadata.add(entry.catalogMetadata);
}
});
if (newMetadata.isEmpty) return;
await metadataDb.saveMetadata(List.unmodifiable(newMetadata));
onMetadataChanged();
debugPrint('$runtimeType catalogEntries complete in ${DateTime.now().difference(start).inSeconds}s with ${newMetadata.length} new entries');
debugPrint('$runtimeType catalogEntries complete in ${stopwatch.elapsed.inSeconds}s with ${newMetadata.length} new entries');
}
Future<void> locateEntries() async {
final start = DateTime.now();
final stopwatch = Stopwatch()..start();
final unlocatedEntries = _rawEntries.where((entry) => entry.hasGps && !entry.isLocated).toList();
final newAddresses = <AddressDetails>[];
await Future.forEach<ImageEntry>(unlocatedEntries, (entry) async {
await entry.locate();
if (entry.isLocated) {
newAddresses.add(entry.addressDetails);
if (newAddresses.length >= 50) {
await metadataDb.saveAddresses(List.unmodifiable(newAddresses));
newAddresses.clear();
}
}
});
await metadataDb.saveAddresses(List.unmodifiable(newAddresses));
debugPrint('$runtimeType locateEntries complete in ${DateTime.now().difference(start).inSeconds}s');
debugPrint('$runtimeType locateEntries complete in ${stopwatch.elapsed.inMilliseconds}ms');
}
ImageCollection filter(bool Function(ImageEntry) filter) {

View file

@ -143,8 +143,10 @@ class ImageEntry {
Future<void> catalog() async {
if (isCatalogued) return;
catalogMetadata = await MetadataService.getCatalogMetadata(this);
if (catalogMetadata != null) {
metadataChangeNotifier.notifyListeners();
}
}
Future<void> locate() async {
if (isLocated) return;
@ -169,7 +171,7 @@ class ImageEntry {
addressChangeNotifier.notifyListeners();
}
} catch (exception) {
debugPrint('$runtimeType addAddressToMetadata failed with exception=$exception');
debugPrint('$runtimeType addAddressToMetadata failed with path=$path coordinates=$coordinates exception=$exception');
}
}

View file

@ -41,17 +41,17 @@ class MetadataDb {
}
Future<List<CatalogMetadata>> loadMetadataEntries() async {
final start = DateTime.now();
// final stopwatch = Stopwatch()..start();
final db = await _database;
final maps = await db.query(metadataTable);
final metadataEntries = maps.map((map) => CatalogMetadata.fromMap(map)).toList();
debugPrint('$runtimeType loadMetadataEntries complete in ${DateTime.now().difference(start).inMilliseconds}ms with ${metadataEntries.length} entries');
// debugPrint('$runtimeType loadMetadataEntries complete in ${stopwatch.elapsed.inMilliseconds}ms with ${metadataEntries.length} entries');
return metadataEntries;
}
Future<void> saveMetadata(Iterable<CatalogMetadata> metadataEntries) async {
if (metadataEntries == null || metadataEntries.isEmpty) return;
final start = DateTime.now();
final stopwatch = Stopwatch()..start();
final db = await _database;
final batch = db.batch();
metadataEntries.where((metadata) => metadata != null).forEach((metadata) => batch.insert(
@ -60,7 +60,7 @@ class MetadataDb {
conflictAlgorithm: ConflictAlgorithm.replace,
));
await batch.commit(noResult: true);
debugPrint('$runtimeType saveMetadata complete in ${DateTime.now().difference(start).inMilliseconds}ms with ${metadataEntries.length} entries');
debugPrint('$runtimeType saveMetadata complete in ${stopwatch.elapsed.inMilliseconds}ms with ${metadataEntries.length} entries');
}
Future<void> clearAddresses() async {
@ -70,17 +70,17 @@ class MetadataDb {
}
Future<List<AddressDetails>> loadAddresses() async {
final start = DateTime.now();
// final stopwatch = Stopwatch()..start();
final db = await _database;
final maps = await db.query(addressTable);
final addresses = maps.map((map) => AddressDetails.fromMap(map)).toList();
debugPrint('$runtimeType loadAddresses complete in ${DateTime.now().difference(start).inMilliseconds}ms with ${addresses.length} entries');
// debugPrint('$runtimeType loadAddresses complete in ${stopwatch.elapsed.inMilliseconds}ms with ${addresses.length} entries');
return addresses;
}
Future<void> saveAddresses(Iterable<AddressDetails> addresses) async {
if (addresses == null || addresses.isEmpty) return;
final start = DateTime.now();
final stopwatch = Stopwatch()..start();
final db = await _database;
final batch = db.batch();
addresses.where((address) => address != null).forEach((address) => batch.insert(
@ -89,6 +89,6 @@ class MetadataDb {
conflictAlgorithm: ConflictAlgorithm.replace,
));
await batch.commit(noResult: true);
debugPrint('$runtimeType saveAddresses complete in ${DateTime.now().difference(start).inMilliseconds}ms with ${addresses.length} entries');
debugPrint('$runtimeType saveAddresses complete in ${stopwatch.elapsed.inMilliseconds}ms with ${addresses.length} entries');
}
}

View file

@ -8,8 +8,6 @@ import 'package:flutter/services.dart';
import 'package:flutter_native_timezone/flutter_native_timezone.dart';
import 'package:provider/provider.dart';
final _stopwatch = Stopwatch()..start();
class MediaStoreCollectionProvider extends StatefulWidget {
final Widget child;
@ -31,7 +29,7 @@ class _MediaStoreCollectionProviderState extends State<MediaStoreCollectionProvi
}
Future<ImageCollection> _create() async {
debugPrint('$runtimeType _create, elapsed=${_stopwatch.elapsed}');
final stopwatch = Stopwatch()..start();
final mediaStoreCollection = ImageCollection(entries: []);
mediaStoreCollection.groupFactor = settings.collectionGroupFactor;
mediaStoreCollection.sortFactor = settings.collectionSortFactor;
@ -49,7 +47,7 @@ class _MediaStoreCollectionProviderState extends State<MediaStoreCollectionProvi
eventChannel.receiveBroadcastStream().cast<Map>().listen(
(entryMap) => mediaStoreCollection.add(ImageEntry.fromMap(entryMap)),
onDone: () async {
debugPrint('$runtimeType mediastore stream done, elapsed=${_stopwatch.elapsed}');
debugPrint('$runtimeType stream complete in ${stopwatch.elapsed.inMilliseconds}ms');
mediaStoreCollection.updateSections(); // <50ms
// TODO reduce setup time until here
mediaStoreCollection.updateAlbums(); // <50ms
@ -57,7 +55,7 @@ class _MediaStoreCollectionProviderState extends State<MediaStoreCollectionProvi
await mediaStoreCollection.catalogEntries(); // <50ms
await mediaStoreCollection.loadAddresses(); // 350ms
await mediaStoreCollection.locateEntries(); // <50ms
debugPrint('$runtimeType setup end, elapsed=${_stopwatch.elapsed}');
debugPrint('$runtimeType setup end, elapsed=${stopwatch.elapsed}');
},
onError: (error) => debugPrint('$runtimeType mediastore stream error=$error'),
);