From 7d880f94db5485fdda342cf72cedf0e7901a2293 Mon Sep 17 00:00:00 2001 From: zhupengfei Date: Sun, 16 Feb 2020 23:25:30 +0800 Subject: [PATCH] Add simple zstd compression Just a simple default compression is able to shrink savestate file size from ~160MB to ~20MB. --- src/core/core.cpp | 29 +++++++++++++++++++++++------ src/core/core.h | 2 +- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/core/core.cpp b/src/core/core.cpp index 18c2e77e1..0bbb79aea 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -13,6 +13,7 @@ #include "common/archives.h" #include "common/logging/log.h" #include "common/texture.h" +#include "common/zstd_compression.h" #include "core/arm/arm_interface.h" #ifdef ARCHITECTURE_x86_64 #include "core/arm/dynarmic/arm_dynarmic.h" @@ -116,7 +117,7 @@ System::ResultStatus System::RunLoop(bool tight_loop) { case Signal::Load: { LOG_INFO(Core, "Begin load"); auto stream = std::ifstream("save0.citrasave", std::fstream::binary); - System::Load(stream); + System::Load(stream, FileUtil::GetSize("save0.citrasave")); LOG_INFO(Core, "Load completed"); } break; case Signal::Save: { @@ -464,27 +465,43 @@ void System::serialize(Archive& ar, const unsigned int file_version) { } void System::Save(std::ostream& stream) const { + std::ostringstream sstream{std::ios_base::binary}; try { { - oarchive oa{stream}; + oarchive oa{sstream}; oa&* this; } - VideoCore::Save(stream); + VideoCore::Save(sstream); } catch (const std::exception& e) { LOG_ERROR(Core, "Error saving: {}", e.what()); } + const std::string& str{sstream.str()}; + auto buffer = Common::Compression::CompressDataZSTDDefault( + reinterpret_cast(str.data()), str.size()); + stream.write(reinterpret_cast(buffer.data()), buffer.size()); } -void System::Load(std::istream& stream) { +void System::Load(std::istream& stream, std::size_t size) { + std::vector decompressed; + { + std::vector buffer(size); + stream.read(reinterpret_cast(buffer.data()), size); + decompressed = Common::Compression::DecompressDataZSTD(buffer); + } + std::istringstream sstream{ + std::string{reinterpret_cast(decompressed.data()), decompressed.size()}, + std::ios_base::binary}; + decompressed.clear(); + try { { - iarchive ia{stream}; + iarchive ia{sstream}; ia&* this; } - VideoCore::Load(stream); + VideoCore::Load(sstream); } catch (const std::exception& e) { LOG_ERROR(Core, "Error loading: {}", e.what()); diff --git a/src/core/core.h b/src/core/core.h index a3b2f5cdd..80c1505b5 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -278,7 +278,7 @@ public: void Save(std::ostream& stream) const; - void Load(std::istream& stream); + void Load(std::istream& stream, std::size_t size); private: /**