⚡ Optimize hash logic
This commit is contained in:
parent
c6311c466f
commit
f7ab3bfb18
@ -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
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user