From 1b5da99cdabb524570b4fd72fb8fa6022dfe44c3 Mon Sep 17 00:00:00 2001 From: maru Date: Wed, 10 Apr 2024 07:25:39 -0400 Subject: [PATCH] Make save reading/writing more efficient --- api/savedata-helper.go | 35 +++++++++--------------------- api/savedata.go | 49 ++++++++++++++++++------------------------ 2 files changed, 31 insertions(+), 53 deletions(-) diff --git a/api/savedata-helper.go b/api/savedata-helper.go index 00a45a3..e96afbe 100644 --- a/api/savedata-helper.go +++ b/api/savedata-helper.go @@ -1,7 +1,6 @@ package api import ( - "bytes" "encoding/gob" "encoding/hex" "fmt" @@ -15,24 +14,17 @@ import ( func readSystemSaveData(uuid []byte) (defs.SystemSaveData, error) { var system defs.SystemSaveData - save, err := os.ReadFile("userdata/" + hex.EncodeToString(uuid) + "/system.pzs") + file, err := os.Open("userdata/" + hex.EncodeToString(uuid) + "/system.pzs") if err != nil { - return system, fmt.Errorf("failed to read save file: %s", err) + return system, fmt.Errorf("failed to open save file: %s", err) } - zstdReader, err := zstd.NewReader(nil) + zstdDecoder, err := zstd.NewReader(file) if err != nil { - return system, fmt.Errorf("failed to create zstd reader: %s", err) + return system, fmt.Errorf("failed to create zstd decoder: %s", err) } - decompressed, err := zstdReader.DecodeAll(save, nil) - if err != nil { - return system, fmt.Errorf("failed to decompress save file: %s", err) - } - - gobDecoderBuf := bytes.NewBuffer(decompressed) - - err = gob.NewDecoder(gobDecoderBuf).Decode(&system) + err = gob.NewDecoder(zstdDecoder).Decode(&system) if err != nil { return system, fmt.Errorf("failed to deserialize save: %s", err) } @@ -48,24 +40,17 @@ func readSessionSaveData(uuid []byte, slotID int) (defs.SessionSaveData, error) fileName += strconv.Itoa(slotID) } - save, err := os.ReadFile(fmt.Sprintf("userdata/%s/%s.pzs", hex.EncodeToString(uuid), fileName)) + file, err := os.Open(fmt.Sprintf("userdata/%s/%s.pzs", hex.EncodeToString(uuid), fileName)) if err != nil { - return session, fmt.Errorf("failed to read save file: %s", err) + return session, fmt.Errorf("failed to open save file: %s", err) } - zstdReader, err := zstd.NewReader(nil) + zstdDecoder, err := zstd.NewReader(file) if err != nil { - return session, fmt.Errorf("failed to create zstd reader: %s", err) + return session, fmt.Errorf("failed to create zstd decoder: %s", err) } - decompressed, err := zstdReader.DecodeAll(save, nil) - if err != nil { - return session, fmt.Errorf("failed to decompress save file: %s", err) - } - - gobDecoderBuf := bytes.NewBuffer(decompressed) - - err = gob.NewDecoder(gobDecoderBuf).Decode(&session) + err = gob.NewDecoder(zstdDecoder).Decode(&session) if err != nil { return session, fmt.Errorf("failed to deserialize save: %s", err) } diff --git a/api/savedata.go b/api/savedata.go index 31656b1..7f096b7 100644 --- a/api/savedata.go +++ b/api/savedata.go @@ -1,7 +1,6 @@ package api import ( - "bytes" "encoding/gob" "encoding/hex" "fmt" @@ -72,27 +71,24 @@ func handleSavedataUpdate(uuid []byte, slot int, save any) error { return fmt.Errorf("failed to update account stats: %s", err) } - var gobBuffer bytes.Buffer - err = gob.NewEncoder(&gobBuffer).Encode(save) - if err != nil { - return fmt.Errorf("failed to serialize save: %s", err) + err = os.MkdirAll("userdata/"+hexUUID, 0755) + if err != nil && !os.IsExist(err) { + return fmt.Errorf("failed to create userdata folder: %s", err) } - zstdWriter, err := zstd.NewWriter(nil) + file, err := os.OpenFile("userdata/"+hexUUID+"/system.pzs", os.O_WRONLY | os.O_TRUNC, 0644) if err != nil { - return fmt.Errorf("failed to create zstd writer, %s", err) + return fmt.Errorf("failed to open save file for writing: %s", err) } - compressed := zstdWriter.EncodeAll(gobBuffer.Bytes(), nil) - - err = os.MkdirAll("userdata/"+hexUUID, 0755) - if err != nil && !os.IsExist(err) { - return fmt.Errorf("failed to create userdata folder: %s", err) + zstdEncoder, err := zstd.NewWriter(file) + if err != nil { + return fmt.Errorf("failed to create zstd encoder: %s", err) } - err = os.WriteFile("userdata/"+hexUUID+"/system.pzs", compressed, 0644) + err = gob.NewEncoder(zstdEncoder).Encode(save) if err != nil { - return fmt.Errorf("failed to write save file: %s", err) + return fmt.Errorf("failed to serialize save: %s", err) } case defs.SessionSaveData: // Session if slot < 0 || slot >= sessionSlotCount { @@ -104,27 +100,24 @@ func handleSavedataUpdate(uuid []byte, slot int, save any) error { fileName += strconv.Itoa(slot) } - var gobBuffer bytes.Buffer - err = gob.NewEncoder(&gobBuffer).Encode(save) - if err != nil { - return fmt.Errorf("failed to serialize save: %s", err) + err = os.MkdirAll("userdata/"+hexUUID, 0755) + if err != nil && !os.IsExist(err) { + return fmt.Errorf(fmt.Sprintf("failed to create userdata folder: %s", err)) } - zstdWriter, err := zstd.NewWriter(nil) + file, err := os.OpenFile(fmt.Sprintf("userdata/%s/%s.pzs", hexUUID, fileName), os.O_WRONLY | os.O_TRUNC, 0644) if err != nil { - return fmt.Errorf("failed to create zstd writer, %s", err) + return fmt.Errorf("failed to open save file for writing: %s", err) } - - compressed := zstdWriter.EncodeAll(gobBuffer.Bytes(), nil) - - err = os.MkdirAll("userdata/"+hexUUID, 0755) - if err != nil && !os.IsExist(err) { - return fmt.Errorf(fmt.Sprintf("failed to create userdata folder: %s", err)) + + zstdEncoder, err := zstd.NewWriter(file) + if err != nil { + return fmt.Errorf("failed to create zstd encoder: %s", err) } - err = os.WriteFile(fmt.Sprintf("userdata/%s/%s.pzs", hexUUID, fileName), compressed, 0644) + err = gob.NewEncoder(zstdEncoder).Encode(save) if err != nil { - return fmt.Errorf("failed to write save file: %s", err) + return fmt.Errorf("failed to serialize save: %s", err) } db.DeleteClaimedAccountCompensations(uuid)