⚡ Optimize hash logic
This commit is contained in:
		@@ -212,36 +212,57 @@ func AnalyzeAttachment(file models.Attachment) error {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func HashAttachment(file models.Attachment) (hash string, err error) {
 | 
					func HashAttachment(file models.Attachment) (hash string, err error) {
 | 
				
			||||||
	if file.Destination != models.AttachmentDstTemporary {
 | 
						const chunkSize = 32 * 1024
 | 
				
			||||||
		err = fmt.Errorf("attachment isn't in temporary storage, unable to hash")
 | 
					
 | 
				
			||||||
		return
 | 
						destMap := viper.GetStringMapString("destinations.temporary")
 | 
				
			||||||
 | 
						destPath := filepath.Join(destMap["path"], file.Uuid)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check if the file exists
 | 
				
			||||||
 | 
						fileInfo, err := os.Stat(destPath)
 | 
				
			||||||
 | 
						if os.IsNotExist(err) {
 | 
				
			||||||
 | 
							return "", fmt.Errorf("file does not exist: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	destMap := viper.GetStringMap("destinations.temporary")
 | 
						// Open the file
 | 
				
			||||||
 | 
						inFile, err := os.Open(destPath)
 | 
				
			||||||
	var dest models.LocalDestination
 | 
					 | 
				
			||||||
	rawDest, _ := jsoniter.Marshal(destMap)
 | 
					 | 
				
			||||||
	_ = jsoniter.Unmarshal(rawDest, &dest)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	dst := filepath.Join(dest.Path, file.Uuid)
 | 
					 | 
				
			||||||
	if _, err = os.Stat(dst); os.IsNotExist(err) {
 | 
					 | 
				
			||||||
		err = fmt.Errorf("attachment doesn't exists in temporary storage: %v", err)
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	var in *os.File
 | 
					 | 
				
			||||||
	in, err = os.Open(dst)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		err = fmt.Errorf("unable to open file: %v", err)
 | 
							return "", fmt.Errorf("unable to open file: %v", err)
 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer in.Close()
 | 
						defer inFile.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hasher := sha256.New()
 | 
						hasher := sha256.New()
 | 
				
			||||||
	if _, err = io.Copy(hasher, in); err != nil {
 | 
					 | 
				
			||||||
		err = fmt.Errorf("unable to hash: %v", err)
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Hash the first 32KB
 | 
				
			||||||
 | 
						buf := make([]byte, chunkSize)
 | 
				
			||||||
 | 
						if _, err := inFile.Read(buf); err != nil && err != io.EOF {
 | 
				
			||||||
 | 
							return "", fmt.Errorf("error reading file: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						hasher.Write(buf)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Hash the middle 32KB
 | 
				
			||||||
 | 
						middleOffset := fileInfo.Size() / 2
 | 
				
			||||||
 | 
						if _, err := inFile.Seek(middleOffset, io.SeekStart); err != nil {
 | 
				
			||||||
 | 
							return "", fmt.Errorf("error seeking to middle: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if _, err := inFile.Read(buf); err != nil && err != io.EOF {
 | 
				
			||||||
 | 
							return "", fmt.Errorf("error reading middle: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						hasher.Write(buf)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Hash the last 32KB
 | 
				
			||||||
 | 
						endOffset := fileInfo.Size() - chunkSize
 | 
				
			||||||
 | 
						if _, err := inFile.Seek(endOffset, io.SeekStart); err != nil {
 | 
				
			||||||
 | 
							return "", fmt.Errorf("error seeking to end: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if _, err := inFile.Read(buf); err != nil && err != io.EOF {
 | 
				
			||||||
 | 
							return "", fmt.Errorf("error reading end: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						hasher.Write(buf)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Hash with the file metadata
 | 
				
			||||||
 | 
						hasher.Write([]byte(fmt.Sprintf("%d", file.Size)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Return the combined hash
 | 
				
			||||||
	hash = hex.EncodeToString(hasher.Sum(nil))
 | 
						hash = hex.EncodeToString(hasher.Sum(nil))
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user