aboutsummaryrefslogtreecommitdiff
path: root/src/zencore/filesystem.cpp
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2023-11-13 16:19:39 +0100
committerGitHub <[email protected]>2023-11-13 16:19:39 +0100
commitd52bed8d5a37a39c88b78a19e22f2b7b3f6dd1d6 (patch)
tree2709bce7020faa9c73e784dd2a5997b384395b56 /src/zencore/filesystem.cpp
parentpackage dependency clean-ups (#531) (diff)
downloadzen-d52bed8d5a37a39c88b78a19e22f2b7b3f6dd1d6.tar.xz
zen-d52bed8d5a37a39c88b78a19e22f2b7b3f6dd1d6.zip
gc history log (#519)
- Feature: Writes a `gc.log` with settings and detailed result after each GC execution (version 2 only) - Break out file name rotate to allow access for gclog - CompactBinaryToJson(MemoryView Data, StringBuilderBase& InBuilder)
Diffstat (limited to 'src/zencore/filesystem.cpp')
-rw-r--r--src/zencore/filesystem.cpp64
1 files changed, 64 insertions, 0 deletions
diff --git a/src/zencore/filesystem.cpp b/src/zencore/filesystem.cpp
index b64c9973e..06cda7382 100644
--- a/src/zencore/filesystem.cpp
+++ b/src/zencore/filesystem.cpp
@@ -40,6 +40,7 @@ ZEN_THIRD_PARTY_INCLUDES_END
# include <unistd.h>
#endif
+#include <fmt/format.h>
#include <filesystem>
#include <gsl/gsl-lite.hpp>
@@ -1396,6 +1397,69 @@ GetEnvVariable(std::string_view VariableName)
return "";
}
+std::error_code
+RotateFiles(const std::filesystem::path& Filename, std::size_t MaxFiles)
+{
+ const std::filesystem::path BasePath(Filename.parent_path());
+ const std::string Stem(Filename.stem().string());
+ const std::string Extension(Filename.extension().string());
+
+ std::error_code Result;
+
+ auto GetFileName = [&](size_t Index) -> std::filesystem::path {
+ if (Index == 0)
+ {
+ return BasePath / (Stem + Extension);
+ }
+ return BasePath / fmt::format("{}.{}{}", Stem, Index, Extension);
+ };
+
+ auto IsEmpty = [](const std::filesystem::path& Path, std::error_code& Ec) -> bool {
+ bool Exists = std::filesystem::exists(Path, Ec);
+ if (Ec)
+ {
+ return false;
+ }
+ if (!Exists)
+ {
+ return true;
+ }
+ uintmax_t Size = std::filesystem::file_size(Path, Ec);
+ if (Ec)
+ {
+ return false;
+ }
+ return Size == 0;
+ };
+
+ bool BaseIsEmpty = IsEmpty(GetFileName(0), Result);
+ if (Result)
+ {
+ return Result;
+ }
+ if (!BaseIsEmpty)
+ {
+ // We try our best to rotate the logs, if we fail we fail and will try to open the base log file anyway
+ for (auto i = MaxFiles; i > 0; i--)
+ {
+ std::filesystem::path src = GetFileName(i - 1);
+ if (!std::filesystem::exists(src))
+ {
+ continue;
+ }
+ std::error_code DummyEc;
+ std::filesystem::path target = GetFileName(i);
+ if (std::filesystem::exists(target, DummyEc))
+ {
+ std::filesystem::remove(target, DummyEc);
+ }
+ std::filesystem::rename(src, target, DummyEc);
+ }
+ }
+
+ return Result;
+}
+
//////////////////////////////////////////////////////////////////////////
//
// Testing related code follows...