|
| 1 | +import 'dart:math'; |
| 2 | + |
1 | 3 | import 'package:collection/collection.dart';
|
2 | 4 | import 'package:meta/meta.dart';
|
3 | 5 |
|
@@ -241,15 +243,36 @@ final class InternalSyncDownloadProgress extends ProgressWithOperations {
|
241 | 243 | factory InternalSyncDownloadProgress.forNewCheckpoint(
|
242 | 244 | Map<String, LocalOperationCounters> localProgress, Checkpoint target) {
|
243 | 245 | final buckets = <String, BucketProgress>{};
|
| 246 | + |
244 | 247 | for (final bucket in target.checksums) {
|
245 | 248 | final savedProgress = localProgress[bucket.bucket];
|
| 249 | + final atLast = savedProgress?.atLast ?? 0; |
| 250 | + final sinceLast = savedProgress?.sinceLast ?? 0; |
246 | 251 |
|
247 | 252 | buckets[bucket.bucket] = (
|
248 | 253 | priority: BucketPriority._(bucket.priority),
|
249 |
| - atLast: savedProgress?.atLast ?? 0, |
250 |
| - sinceLast: savedProgress?.sinceLast ?? 0, |
| 254 | + atLast: atLast, |
| 255 | + sinceLast: sinceLast, |
251 | 256 | targetCount: bucket.count ?? 0,
|
252 | 257 | );
|
| 258 | + |
| 259 | + if (bucket.count case final knownCount?) { |
| 260 | + if (knownCount < atLast + sinceLast) { |
| 261 | + // Either due to a defrag / sync rule deploy or a compaction |
| 262 | + // operation, the size of the bucket shrank so much that the local ops |
| 263 | + // exceed the ops in the updated bucket. We can't possibly report |
| 264 | + // progress in this case (it would overshoot 100%). |
| 265 | + return InternalSyncDownloadProgress({ |
| 266 | + for (final bucket in target.checksums) |
| 267 | + bucket.bucket: ( |
| 268 | + priority: BucketPriority(bucket.priority), |
| 269 | + atLast: 0, |
| 270 | + sinceLast: 0, |
| 271 | + targetCount: knownCount, |
| 272 | + ) |
| 273 | + }); |
| 274 | + } |
| 275 | + } |
253 | 276 | }
|
254 | 277 |
|
255 | 278 | return InternalSyncDownloadProgress(buckets);
|
@@ -282,7 +305,8 @@ final class InternalSyncDownloadProgress extends ProgressWithOperations {
|
282 | 305 | newBucketStates[dataForBucket.bucket] = (
|
283 | 306 | priority: previous.priority,
|
284 | 307 | atLast: previous.atLast,
|
285 |
| - sinceLast: previous.sinceLast + dataForBucket.data.length, |
| 308 | + sinceLast: min(previous.sinceLast + dataForBucket.data.length, |
| 309 | + previous.targetCount - previous.atLast), |
286 | 310 | targetCount: previous.targetCount,
|
287 | 311 | );
|
288 | 312 | }
|
|
0 commit comments