minimized change notifications, fixed logs
This commit is contained in:
parent
e3e222c589
commit
03246a8df4
4 changed files with 38 additions and 30 deletions
|
@ -19,7 +19,7 @@ class ImageCollection with ChangeNotifier {
|
||||||
this.groupFactor,
|
this.groupFactor,
|
||||||
this.sortFactor,
|
this.sortFactor,
|
||||||
}) : _rawEntries = entries {
|
}) : _rawEntries = entries {
|
||||||
updateSections();
|
if (_rawEntries.isNotEmpty) updateSections();
|
||||||
}
|
}
|
||||||
|
|
||||||
int get imageCount => _rawEntries.where((entry) => !entry.isVideo).length;
|
int get imageCount => _rawEntries.where((entry) => !entry.isVideo).length;
|
||||||
|
@ -64,7 +64,7 @@ class ImageCollection with ChangeNotifier {
|
||||||
]);
|
]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
debugPrint('$runtimeType updateSections');
|
debugPrint('$runtimeType updateSections notifyListeners');
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ class ImageCollection with ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> loadCatalogMetadata() async {
|
Future<void> loadCatalogMetadata() async {
|
||||||
final start = DateTime.now();
|
final stopwatch = Stopwatch()..start();
|
||||||
final saved = await metadataDb.loadMetadataEntries();
|
final saved = await metadataDb.loadMetadataEntries();
|
||||||
_rawEntries.forEach((entry) {
|
_rawEntries.forEach((entry) {
|
||||||
final contentId = entry.contentId;
|
final contentId = entry.contentId;
|
||||||
|
@ -122,12 +122,12 @@ class ImageCollection with ChangeNotifier {
|
||||||
entry.catalogMetadata = saved.firstWhere((metadata) => metadata.contentId == contentId, orElse: () => null);
|
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();
|
onMetadataChanged();
|
||||||
debugPrint('$runtimeType loadCatalogMetadata complete in ${DateTime.now().difference(start).inSeconds}s with ${saved.length} saved entries');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> loadAddresses() async {
|
Future<void> loadAddresses() async {
|
||||||
final start = DateTime.now();
|
final stopwatch = Stopwatch()..start();
|
||||||
final saved = await metadataDb.loadAddresses();
|
final saved = await metadataDb.loadAddresses();
|
||||||
_rawEntries.forEach((entry) {
|
_rawEntries.forEach((entry) {
|
||||||
final contentId = entry.contentId;
|
final contentId = entry.contentId;
|
||||||
|
@ -135,36 +135,44 @@ class ImageCollection with ChangeNotifier {
|
||||||
entry.addressDetails = saved.firstWhere((address) => address.contentId == contentId, orElse: () => null);
|
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 {
|
Future<void> catalogEntries() async {
|
||||||
final start = DateTime.now();
|
final stopwatch = Stopwatch()..start();
|
||||||
final uncataloguedEntries = _rawEntries.where((entry) => !entry.isCatalogued).toList();
|
final uncataloguedEntries = _rawEntries.where((entry) => !entry.isCatalogued).toList();
|
||||||
|
if (uncataloguedEntries.isEmpty) return;
|
||||||
|
|
||||||
final newMetadata = <CatalogMetadata>[];
|
final newMetadata = <CatalogMetadata>[];
|
||||||
await Future.forEach<ImageEntry>(uncataloguedEntries, (entry) async {
|
await Future.forEach<ImageEntry>(uncataloguedEntries, (entry) async {
|
||||||
await entry.catalog();
|
await entry.catalog();
|
||||||
|
if (entry.isCatalogued) {
|
||||||
newMetadata.add(entry.catalogMetadata);
|
newMetadata.add(entry.catalogMetadata);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
if (newMetadata.isEmpty) return;
|
||||||
|
|
||||||
await metadataDb.saveMetadata(List.unmodifiable(newMetadata));
|
await metadataDb.saveMetadata(List.unmodifiable(newMetadata));
|
||||||
onMetadataChanged();
|
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 {
|
Future<void> locateEntries() async {
|
||||||
final start = DateTime.now();
|
final stopwatch = Stopwatch()..start();
|
||||||
final unlocatedEntries = _rawEntries.where((entry) => entry.hasGps && !entry.isLocated).toList();
|
final unlocatedEntries = _rawEntries.where((entry) => entry.hasGps && !entry.isLocated).toList();
|
||||||
final newAddresses = <AddressDetails>[];
|
final newAddresses = <AddressDetails>[];
|
||||||
await Future.forEach<ImageEntry>(unlocatedEntries, (entry) async {
|
await Future.forEach<ImageEntry>(unlocatedEntries, (entry) async {
|
||||||
await entry.locate();
|
await entry.locate();
|
||||||
|
if (entry.isLocated) {
|
||||||
newAddresses.add(entry.addressDetails);
|
newAddresses.add(entry.addressDetails);
|
||||||
if (newAddresses.length >= 50) {
|
if (newAddresses.length >= 50) {
|
||||||
await metadataDb.saveAddresses(List.unmodifiable(newAddresses));
|
await metadataDb.saveAddresses(List.unmodifiable(newAddresses));
|
||||||
newAddresses.clear();
|
newAddresses.clear();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
await metadataDb.saveAddresses(List.unmodifiable(newAddresses));
|
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) {
|
ImageCollection filter(bool Function(ImageEntry) filter) {
|
||||||
|
|
|
@ -143,8 +143,10 @@ class ImageEntry {
|
||||||
Future<void> catalog() async {
|
Future<void> catalog() async {
|
||||||
if (isCatalogued) return;
|
if (isCatalogued) return;
|
||||||
catalogMetadata = await MetadataService.getCatalogMetadata(this);
|
catalogMetadata = await MetadataService.getCatalogMetadata(this);
|
||||||
|
if (catalogMetadata != null) {
|
||||||
metadataChangeNotifier.notifyListeners();
|
metadataChangeNotifier.notifyListeners();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> locate() async {
|
Future<void> locate() async {
|
||||||
if (isLocated) return;
|
if (isLocated) return;
|
||||||
|
@ -169,7 +171,7 @@ class ImageEntry {
|
||||||
addressChangeNotifier.notifyListeners();
|
addressChangeNotifier.notifyListeners();
|
||||||
}
|
}
|
||||||
} catch (exception) {
|
} catch (exception) {
|
||||||
debugPrint('$runtimeType addAddressToMetadata failed with exception=$exception');
|
debugPrint('$runtimeType addAddressToMetadata failed with path=$path coordinates=$coordinates exception=$exception');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,17 +41,17 @@ class MetadataDb {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<CatalogMetadata>> loadMetadataEntries() async {
|
Future<List<CatalogMetadata>> loadMetadataEntries() async {
|
||||||
final start = DateTime.now();
|
// final stopwatch = Stopwatch()..start();
|
||||||
final db = await _database;
|
final db = await _database;
|
||||||
final maps = await db.query(metadataTable);
|
final maps = await db.query(metadataTable);
|
||||||
final metadataEntries = maps.map((map) => CatalogMetadata.fromMap(map)).toList();
|
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;
|
return metadataEntries;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> saveMetadata(Iterable<CatalogMetadata> metadataEntries) async {
|
Future<void> saveMetadata(Iterable<CatalogMetadata> metadataEntries) async {
|
||||||
if (metadataEntries == null || metadataEntries.isEmpty) return;
|
if (metadataEntries == null || metadataEntries.isEmpty) return;
|
||||||
final start = DateTime.now();
|
final stopwatch = Stopwatch()..start();
|
||||||
final db = await _database;
|
final db = await _database;
|
||||||
final batch = db.batch();
|
final batch = db.batch();
|
||||||
metadataEntries.where((metadata) => metadata != null).forEach((metadata) => batch.insert(
|
metadataEntries.where((metadata) => metadata != null).forEach((metadata) => batch.insert(
|
||||||
|
@ -60,7 +60,7 @@ class MetadataDb {
|
||||||
conflictAlgorithm: ConflictAlgorithm.replace,
|
conflictAlgorithm: ConflictAlgorithm.replace,
|
||||||
));
|
));
|
||||||
await batch.commit(noResult: true);
|
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 {
|
Future<void> clearAddresses() async {
|
||||||
|
@ -70,17 +70,17 @@ class MetadataDb {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<AddressDetails>> loadAddresses() async {
|
Future<List<AddressDetails>> loadAddresses() async {
|
||||||
final start = DateTime.now();
|
// final stopwatch = Stopwatch()..start();
|
||||||
final db = await _database;
|
final db = await _database;
|
||||||
final maps = await db.query(addressTable);
|
final maps = await db.query(addressTable);
|
||||||
final addresses = maps.map((map) => AddressDetails.fromMap(map)).toList();
|
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;
|
return addresses;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> saveAddresses(Iterable<AddressDetails> addresses) async {
|
Future<void> saveAddresses(Iterable<AddressDetails> addresses) async {
|
||||||
if (addresses == null || addresses.isEmpty) return;
|
if (addresses == null || addresses.isEmpty) return;
|
||||||
final start = DateTime.now();
|
final stopwatch = Stopwatch()..start();
|
||||||
final db = await _database;
|
final db = await _database;
|
||||||
final batch = db.batch();
|
final batch = db.batch();
|
||||||
addresses.where((address) => address != null).forEach((address) => batch.insert(
|
addresses.where((address) => address != null).forEach((address) => batch.insert(
|
||||||
|
@ -89,6 +89,6 @@ class MetadataDb {
|
||||||
conflictAlgorithm: ConflictAlgorithm.replace,
|
conflictAlgorithm: ConflictAlgorithm.replace,
|
||||||
));
|
));
|
||||||
await batch.commit(noResult: true);
|
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');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,6 @@ import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_native_timezone/flutter_native_timezone.dart';
|
import 'package:flutter_native_timezone/flutter_native_timezone.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
final _stopwatch = Stopwatch()..start();
|
|
||||||
|
|
||||||
class MediaStoreCollectionProvider extends StatefulWidget {
|
class MediaStoreCollectionProvider extends StatefulWidget {
|
||||||
final Widget child;
|
final Widget child;
|
||||||
|
|
||||||
|
@ -31,7 +29,7 @@ class _MediaStoreCollectionProviderState extends State<MediaStoreCollectionProvi
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<ImageCollection> _create() async {
|
Future<ImageCollection> _create() async {
|
||||||
debugPrint('$runtimeType _create, elapsed=${_stopwatch.elapsed}');
|
final stopwatch = Stopwatch()..start();
|
||||||
final mediaStoreCollection = ImageCollection(entries: []);
|
final mediaStoreCollection = ImageCollection(entries: []);
|
||||||
mediaStoreCollection.groupFactor = settings.collectionGroupFactor;
|
mediaStoreCollection.groupFactor = settings.collectionGroupFactor;
|
||||||
mediaStoreCollection.sortFactor = settings.collectionSortFactor;
|
mediaStoreCollection.sortFactor = settings.collectionSortFactor;
|
||||||
|
@ -49,7 +47,7 @@ class _MediaStoreCollectionProviderState extends State<MediaStoreCollectionProvi
|
||||||
eventChannel.receiveBroadcastStream().cast<Map>().listen(
|
eventChannel.receiveBroadcastStream().cast<Map>().listen(
|
||||||
(entryMap) => mediaStoreCollection.add(ImageEntry.fromMap(entryMap)),
|
(entryMap) => mediaStoreCollection.add(ImageEntry.fromMap(entryMap)),
|
||||||
onDone: () async {
|
onDone: () async {
|
||||||
debugPrint('$runtimeType mediastore stream done, elapsed=${_stopwatch.elapsed}');
|
debugPrint('$runtimeType stream complete in ${stopwatch.elapsed.inMilliseconds}ms');
|
||||||
mediaStoreCollection.updateSections(); // <50ms
|
mediaStoreCollection.updateSections(); // <50ms
|
||||||
// TODO reduce setup time until here
|
// TODO reduce setup time until here
|
||||||
mediaStoreCollection.updateAlbums(); // <50ms
|
mediaStoreCollection.updateAlbums(); // <50ms
|
||||||
|
@ -57,7 +55,7 @@ class _MediaStoreCollectionProviderState extends State<MediaStoreCollectionProvi
|
||||||
await mediaStoreCollection.catalogEntries(); // <50ms
|
await mediaStoreCollection.catalogEntries(); // <50ms
|
||||||
await mediaStoreCollection.loadAddresses(); // 350ms
|
await mediaStoreCollection.loadAddresses(); // 350ms
|
||||||
await mediaStoreCollection.locateEntries(); // <50ms
|
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'),
|
onError: (error) => debugPrint('$runtimeType mediastore stream error=$error'),
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue