feat(mobile)!: batched full/initial sync (#4840)

* feat(mobile): batched full/initial sync

* use OptionalBetween

* skip/take as integer

---------

Co-authored-by: Fynn Petersen-Frey <zoodyy@users.noreply.github.com>
Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
This commit is contained in:
Fynn Petersen-Frey 2023-11-06 18:40:43 +01:00 committed by GitHub
parent 26fd9d7e5f
commit 21f2d3058a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 189 additions and 63 deletions

View file

@ -197,7 +197,7 @@ class SyncService {
User user,
FutureOr<List<Asset>?> Function(User user) loadAssets,
) async {
final DateTime now = DateTime.now();
final DateTime now = DateTime.now().toUtc();
final List<Asset>? remote = await loadAssets(user);
if (remote == null) {
return false;
@ -210,6 +210,10 @@ class SyncService {
assert(inDb.isSorted(Asset.compareByChecksum), "inDb not sorted!");
remote.sort(Asset.compareByChecksum);
// filter our duplicates that might be introduced by the chunked retrieval
remote.uniqueConsecutive(compare: Asset.compareByChecksum);
final (toAdd, toUpdate, toRemove) = _diffAssets(remote, inDb, remote: true);
if (toAdd.isEmpty && toUpdate.isEmpty && toRemove.isEmpty) {
await _updateUserAssetsETag(user, now);
@ -759,6 +763,12 @@ class SyncService {
final List<Asset> toAdd = [];
final List<Asset> toUpdate = [];
final List<Asset> toRemove = [];
if (assets.isEmpty || inDb.isEmpty) {
// fast path for trivial cases: halfes memory usage during initial sync
return assets.isEmpty
? (toAdd, toUpdate, inDb) // remove all from DB
: (assets, toUpdate, toRemove); // add all assets
}
diffSortedListsSync(
inDb,
assets,