Fix Already Safe = 0: hybrid ManifestIndex preserves localIdentifiers + NAS filenames
The root cause: buildManifestIndex was discarding manifest localIdentifiers and switching to pure filename-only matching whenever dirCount > manifest.totalCount (which is always true when the NAS has files from other tools). If filenames didn't match exactly, Already Safe dropped to 0 on every stale-cache reconcile. Fix: introduce ManifestIndex(manifest:nasFilenames:totalCount:) — a hybrid that keeps Kisani's localIdentifiers as primary keys AND adds all NAS directory filenames for filename-fallback. Used in: - buildManifestIndex (full reconcile) - fast path (when dirCount > cached.entries.count, previously gated at <= 1) - BackupEngine step 3b (so "Back up again" only uploads genuinely missing files) Also simplify countSafe / pendingIDs / step-4 filter to always try filename fallback (removes the isFilenameOnly gate that blocked matches when the index had IDs). Co-Authored-By: Kutesir <kutesir@provoc.ug> Co-Authored-By: Sentry <sentry@provoc.ug>
This commit is contained in:
@@ -61,14 +61,7 @@ actor LocalPhotoIndex {
|
||||
var safe = 0
|
||||
for record in records.values {
|
||||
guard passes(record, filter: filter) else { continue }
|
||||
if index.matches(localIdentifier: record.localIdentifier) {
|
||||
safe += 1
|
||||
} else if index.isFilenameOnly && index.matches(filename: record.filename) {
|
||||
// Pure bootstrap mode: every entry is filename-only, match by name.
|
||||
safe += 1
|
||||
} else if index.matchesUnclaimed(filename: record.filename) {
|
||||
// Mixed mode: this specific entry was uploaded without a localIdentifier
|
||||
// (interrupted session / pre-ID backup). Filename match prevents re-upload.
|
||||
if index.matches(localIdentifier: record.localIdentifier) || index.matches(filename: record.filename) {
|
||||
safe += 1
|
||||
}
|
||||
}
|
||||
@@ -79,10 +72,7 @@ actor LocalPhotoIndex {
|
||||
func pendingIDs(against index: ManifestIndex, filter: BackupFilter) -> [String] {
|
||||
records.values.compactMap { record in
|
||||
guard passes(record, filter: filter) else { return nil }
|
||||
let alreadyBacked =
|
||||
index.matches(localIdentifier: record.localIdentifier) ||
|
||||
(index.isFilenameOnly && index.matches(filename: record.filename)) ||
|
||||
index.matchesUnclaimed(filename: record.filename)
|
||||
let alreadyBacked = index.matches(localIdentifier: record.localIdentifier) || index.matches(filename: record.filename)
|
||||
return alreadyBacked ? nil : record.localIdentifier
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user