Optimize merge files

This commit is contained in:
LittleSheep 2024-09-22 15:39:36 +08:00
parent db57e4764c
commit c6311c466f

View File

@ -2,22 +2,23 @@ package services
import ( import (
"fmt" "fmt"
"git.solsynth.dev/hydrogen/paperclip/pkg/internal/database"
"git.solsynth.dev/hydrogen/paperclip/pkg/internal/models"
jsoniter "github.com/json-iterator/go"
"github.com/spf13/viper"
"io" "io"
"os" "os"
"path/filepath" "path/filepath"
"git.solsynth.dev/hydrogen/paperclip/pkg/internal/database"
"git.solsynth.dev/hydrogen/paperclip/pkg/internal/models"
"github.com/spf13/viper"
) )
func MergeFileChunks(meta models.Attachment, arrange []string) (models.Attachment, error) { func MergeFileChunks(meta models.Attachment, arrange []string) (models.Attachment, error) {
destMap := viper.GetStringMap("destinations.temporary") // Fetch destination from config
destMap := viper.GetStringMapString("destinations.temporary")
var dest models.LocalDestination var dest models.LocalDestination
rawDest, _ := jsoniter.Marshal(destMap) dest.Path = destMap["path"]
_ = jsoniter.Unmarshal(rawDest, &dest)
// Create the destination file
destPath := filepath.Join(dest.Path, meta.Uuid) destPath := filepath.Join(dest.Path, meta.Uuid)
destFile, err := os.Create(destPath) destFile, err := os.Create(destPath)
if err != nil { if err != nil {
@ -25,7 +26,10 @@ func MergeFileChunks(meta models.Attachment, arrange []string) (models.Attachmen
} }
defer destFile.Close() defer destFile.Close()
// Merge files // 32KB buffer
buf := make([]byte, 32*1024)
// Merge the chunks into the destination file
for _, chunk := range arrange { for _, chunk := range arrange {
chunkPath := filepath.Join(dest.Path, fmt.Sprintf("%s.part%s", meta.Uuid, chunk)) chunkPath := filepath.Join(dest.Path, fmt.Sprintf("%s.part%s", meta.Uuid, chunk))
chunkFile, err := os.Open(chunkPath) chunkFile, err := os.Open(chunkPath)
@ -33,27 +37,39 @@ func MergeFileChunks(meta models.Attachment, arrange []string) (models.Attachmen
return meta, err return meta, err
} }
_, err = io.Copy(destFile, chunkFile) defer chunkFile.Close() // Ensure the file is closed after reading
if err != nil {
_ = chunkFile.Close() for {
n, err := chunkFile.Read(buf)
if err != nil && err != io.EOF {
return meta, err return meta, err
} }
if n == 0 {
_ = chunkFile.Close() break
} }
// Do post-upload tasks if _, err := destFile.Write(buf[:n]); err != nil {
return meta, err
}
}
}
// Post-upload tasks
meta.IsUploaded = true meta.IsUploaded = true
meta.FileChunks = nil meta.FileChunks = nil
database.C.Save(&meta) if err := database.C.Save(&meta).Error; err != nil {
return meta, err
}
CacheAttachment(meta) CacheAttachment(meta)
PublishAnalyzeTask(meta) PublishAnalyzeTask(meta)
// Clean up // Clean up: remove chunk files
for _, chunk := range arrange { for _, chunk := range arrange {
chunkPath := filepath.Join(dest.Path, fmt.Sprintf("%s.part%s", meta.Uuid, chunk)) chunkPath := filepath.Join(dest.Path, fmt.Sprintf("%s.part%s", meta.Uuid, chunk))
_ = os.Remove(chunkPath) if err := os.Remove(chunkPath); err != nil {
return meta, err
}
} }
return meta, nil return meta, nil