@@ -1017,50 +1017,103 @@ func (manager *SnapshotManager) CheckSnapshots(snapshotID string, revisionsToChe
1017
1017
manager .ShowStatistics (snapshotMap , chunkSizeMap , chunkUniqueMap , chunkSnapshotMap )
1018
1018
}
1019
1019
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
+ }
1023
1024
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"
1026
1030
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 )
1030
1042
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 )
1035
1049
} 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
+ }
1037
1056
}
1038
1057
}
1058
+ }
1059
+ defer saveVerifiedChunks ()
1060
+ RunAtError = saveVerifiedChunks
1061
+
1062
+ manager .chunkDownloader .snapshotCache = nil
1063
+ LOG_INFO ("SNAPSHOT_VERIFY" , "Verifying %d chunks" , len (* allChunkHashes ))
1039
1064
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 ++
1045
1078
continue
1046
1079
}
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 )
1056
1080
}
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 )
1060
1084
} else {
1061
- LOG_INFO ( "SNAPSHOT_VERIFY" , "All %d chunks have been successfully verified" , totalChunks )
1085
+ manager . chunkDownloader . AddChunk ( chunkHash )
1062
1086
}
1063
1087
}
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
+ }
1064
1117
return true
1065
1118
}
1066
1119
0 commit comments