@@ -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