immich/mobile/lib/utils/diff.dart
shenlong 97e52c5156
refactor(mobile): device asset entity to use modified time (#17064)
* refactor: device asset entity to use modified time

* chore: cleanup

* refactor: remove album media dependency from hashservice

* refactor: return updated copy of asset

* add hash service tests

* chore: rename hash batch constants

* chore: log the number of assets processed during migration

* chore: more logs

* refactor: use lookup and more tests

* use sort approach

* refactor hash service to use for loop instead

* refactor: rename to getByIds

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2025-04-03 14:42:35 -05:00

92 lines
2.4 KiB
Dart

import 'dart:async';
import 'package:collection/collection.dart';
/// Efficiently compares two sorted lists in O(n), calling the given callback
/// for each item.
/// Return `true` if there are any differences found, else `false`
Future<bool> diffSortedLists<T>(
List<T> la,
List<T> lb, {
required int Function(T a, T b) compare,
required FutureOr<bool> Function(T a, T b) both,
required FutureOr<void> Function(T a) onlyFirst,
required FutureOr<void> Function(T b) onlySecond,
}) async {
assert(la.isSorted(compare), "first argument must be sorted");
assert(lb.isSorted(compare), "second argument must be sorted");
bool diff = false;
int i = 0, j = 0;
for (; i < la.length && j < lb.length;) {
final int order = compare(la[i], lb[j]);
if (order == 0) {
diff |= await both(la[i++], lb[j++]);
} else if (order < 0) {
await onlyFirst(la[i++]);
diff = true;
} else if (order > 0) {
await onlySecond(lb[j++]);
diff = true;
}
}
diff |= i < la.length || j < lb.length;
for (; i < la.length; i++) {
await onlyFirst(la[i]);
}
for (; j < lb.length; j++) {
await onlySecond(lb[j]);
}
return diff;
}
/// Efficiently compares two sorted lists in O(n), calling the given callback
/// for each item.
/// Return `true` if there are any differences found, else `false`
bool diffSortedListsSync<T>(
List<T> la,
List<T> lb, {
required int Function(T a, T b) compare,
required bool Function(T a, T b) both,
required void Function(T a) onlyFirst,
required void Function(T b) onlySecond,
}) {
assert(la.isSorted(compare), "first argument must be sorted");
assert(lb.isSorted(compare), "second argument must be sorted");
bool diff = false;
int i = 0, j = 0;
for (; i < la.length && j < lb.length;) {
final int order = compare(la[i], lb[j]);
if (order == 0) {
diff |= both(la[i++], lb[j++]);
} else if (order < 0) {
onlyFirst(la[i++]);
diff = true;
} else if (order > 0) {
onlySecond(lb[j++]);
diff = true;
}
}
diff |= i < la.length || j < lb.length;
for (; i < la.length; i++) {
onlyFirst(la[i]);
}
for (; j < lb.length; j++) {
onlySecond(lb[j]);
}
return diff;
}
int compareToNullable<T extends Comparable>(T? a, T? b) {
if (a == null && b == null) {
return 0;
}
if (a == null) {
return 1;
}
if (b == null) {
return -1;
}
return a.compareTo(b);
}