Skip to content

Commit d7c1903

Browse files
committed
Skip chunks already verified in previous runs for check -chunks.
This is done by storing the list of verified chunks in a file `.duplicacy/cache/<storage>/verified_chunks`.
1 parent 7da58c6 commit d7c1903

File tree

1 file changed

+84
-31
lines changed

1 file changed

+84
-31
lines changed

src/duplicacy_snapshotmanager.go

Lines changed: 84 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,50 +1017,103 @@ func (manager *SnapshotManager) CheckSnapshots(snapshotID string, revisionsToChe
10171017
manager.ShowStatistics(snapshotMap, chunkSizeMap, chunkUniqueMap, chunkSnapshotMap)
10181018
}
10191019

1020-
if checkChunks && !checkFiles {
1021-
manager.chunkDownloader.snapshotCache = nil
1022-
LOG_INFO("SNAPSHOT_VERIFY", "Verifying %d chunks", len(*allChunkHashes))
1020+
// Don't verify chunks with -files
1021+
if !checkChunks || checkFiles {
1022+
return true
1023+
}
10231024

1024-
startTime := time.Now()
1025-
var chunkHashes []string
1025+
// This contains chunks that have been verifed in previous checks and is loaded from
1026+
// .duplicacy/cache/storage/verified_chunks. Note that it contains the chunk ids not chunk
1027+
// hashes.
1028+
verifiedChunks := make(map[string]int64)
1029+
verifiedChunksFile := "verified_chunks"
10261030

1027-
// The index of the first chunk to add to the downloader, which may have already downloaded
1028-
// some metadata chunks so the index doesn't start with 0.
1029-
chunkIndex := -1
1031+
manager.fileChunk.Reset(false)
1032+
err = manager.snapshotCache.DownloadFile(0, verifiedChunksFile, manager.fileChunk)
1033+
if err != nil && !os.IsNotExist(err) {
1034+
LOG_WARN("SNAPSHOT_VERIFY", "Failed to load the file containing verified chunks: %v", err)
1035+
} else {
1036+
err = json.Unmarshal(manager.fileChunk.GetBytes(), &verifiedChunks)
1037+
if err != nil {
1038+
LOG_WARN("SNAPSHOT_VERIFY", "Failed to parse the file containing verified chunks: %v", err)
1039+
}
1040+
}
1041+
numberOfVerifiedChunks := len(verifiedChunks)
10301042

1031-
for chunkHash := range *allChunkHashes {
1032-
chunkHashes = append(chunkHashes, chunkHash)
1033-
if chunkIndex == -1 {
1034-
chunkIndex = manager.chunkDownloader.AddChunk(chunkHash)
1043+
saveVerifiedChunks := func() {
1044+
if len(verifiedChunks) > numberOfVerifiedChunks {
1045+
var description []byte
1046+
description, err = json.Marshal(verifiedChunks)
1047+
if err != nil {
1048+
LOG_WARN("SNAPSHOT_VERIFY", "Failed to create a json file for the set of verified chunks: %v", err)
10351049
} else {
1036-
manager.chunkDownloader.AddChunk(chunkHash)
1050+
err = manager.snapshotCache.UploadFile(0, verifiedChunksFile, description)
1051+
if err != nil {
1052+
LOG_WARN("SNAPSHOT_VERIFY", "Failed to save the verified chunks file: %v", err)
1053+
} else {
1054+
LOG_INFO("SNAPSHOT_VERIFY", "Added %d chunks to the list of verified chunks", len(verifiedChunks) - numberOfVerifiedChunks)
1055+
}
10371056
}
10381057
}
1058+
}
1059+
defer saveVerifiedChunks()
1060+
RunAtError = saveVerifiedChunks
1061+
1062+
manager.chunkDownloader.snapshotCache = nil
1063+
LOG_INFO("SNAPSHOT_VERIFY", "Verifying %d chunks", len(*allChunkHashes))
10391064

1040-
var downloadedChunkSize int64
1041-
totalChunks := len(*allChunkHashes)
1042-
for i := 0; i < totalChunks; i++ {
1043-
chunk := manager.chunkDownloader.WaitForChunk(i + chunkIndex)
1044-
if chunk.isBroken {
1065+
startTime := time.Now()
1066+
var chunkHashes []string
1067+
1068+
// The index of the first chunk to add to the downloader, which may have already downloaded
1069+
// some metadata chunks so the index doesn't start with 0.
1070+
chunkIndex := -1
1071+
1072+
skippedChunks := 0
1073+
for chunkHash := range *allChunkHashes {
1074+
if len(verifiedChunks) > 0 {
1075+
chunkID := manager.config.GetChunkIDFromHash(chunkHash)
1076+
if _, found := verifiedChunks[chunkID]; found {
1077+
skippedChunks++
10451078
continue
10461079
}
1047-
downloadedChunkSize += int64(chunk.GetLength())
1048-
1049-
elapsedTime := time.Now().Sub(startTime).Seconds()
1050-
speed := int64(float64(downloadedChunkSize) / elapsedTime)
1051-
remainingTime := int64(float64(totalChunks - i - 1) / float64(i + 1) * elapsedTime)
1052-
percentage := float64(i + 1) / float64(totalChunks) * 100.0
1053-
LOG_INFO("VERIFY_PROGRESS", "Verified chunk %s (%d/%d), %sB/s %s %.1f%%",
1054-
manager.config.GetChunkIDFromHash(chunkHashes[i]), i + 1, totalChunks,
1055-
PrettySize(speed), PrettyTime(remainingTime), percentage)
10561080
}
1057-
1058-
if manager.chunkDownloader.NumberOfFailedChunks > 0 {
1059-
LOG_ERROR("SNAPSHOT_VERIFY", "%d out of %d chunks are corrupted", manager.chunkDownloader.NumberOfFailedChunks, totalChunks)
1081+
chunkHashes = append(chunkHashes, chunkHash)
1082+
if chunkIndex == -1 {
1083+
chunkIndex = manager.chunkDownloader.AddChunk(chunkHash)
10601084
} else {
1061-
LOG_INFO("SNAPSHOT_VERIFY", "All %d chunks have been successfully verified", totalChunks)
1085+
manager.chunkDownloader.AddChunk(chunkHash)
10621086
}
10631087
}
1088+
1089+
if skippedChunks > 0 {
1090+
LOG_INFO("SNAPSHOT_VERIFY", "Skipped %d chunks that have already been verified before", skippedChunks)
1091+
}
1092+
1093+
var downloadedChunkSize int64
1094+
totalChunks := len(chunkHashes)
1095+
for i := 0; i < totalChunks; i++ {
1096+
chunk := manager.chunkDownloader.WaitForChunk(i + chunkIndex)
1097+
chunkID := manager.config.GetChunkIDFromHash(chunkHashes[i])
1098+
if chunk.isBroken {
1099+
continue
1100+
}
1101+
verifiedChunks[chunkID] = startTime.Unix()
1102+
downloadedChunkSize += int64(chunk.GetLength())
1103+
1104+
elapsedTime := time.Now().Sub(startTime).Seconds()
1105+
speed := int64(float64(downloadedChunkSize) / elapsedTime)
1106+
remainingTime := int64(float64(totalChunks - i - 1) / float64(i + 1) * elapsedTime)
1107+
percentage := float64(i + 1) / float64(totalChunks) * 100.0
1108+
LOG_INFO("VERIFY_PROGRESS", "Verified chunk %s (%d/%d), %sB/s %s %.1f%%",
1109+
chunkID, i + 1, totalChunks, PrettySize(speed), PrettyTime(remainingTime), percentage)
1110+
}
1111+
1112+
if manager.chunkDownloader.NumberOfFailedChunks > 0 {
1113+
LOG_ERROR("SNAPSHOT_VERIFY", "%d out of %d chunks are corrupted", manager.chunkDownloader.NumberOfFailedChunks, len(*allChunkHashes))
1114+
} else {
1115+
LOG_INFO("SNAPSHOT_VERIFY", "All %d chunks have been successfully verified", len(*allChunkHashes))
1116+
}
10641117
return true
10651118
}
10661119

0 commit comments

Comments
 (0)