aboutsummaryrefslogtreecommitdiff
path: root/src/zenutil
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2026-04-20 07:27:35 +0200
committerGitHub Enterprise <[email protected]>2026-04-20 07:27:35 +0200
commitc7c59cdc5a70bfd6e5f66f3b032ea3f8f6b4d12a (patch)
tree8ce2472f9fbdd29a899be25adc864baf98ff8184 /src/zenutil
parentMerge pull request #976 from ue-foundation/zs/config-build-storage (diff)
downloadarchived-zen-c7c59cdc5a70bfd6e5f66f3b032ea3f8f6b4d12a.tar.xz
archived-zen-c7c59cdc5a70bfd6e5f66f3b032ea3f8f6b4d12a.zip
builds cmd refactor (#975)
- Bugfix: `builds download` partial-block fetch decisions now account for build storage host latency - Bugfix: Transfer rate displays in `builds` commands now smooth correctly - Split `buildstorageoperations.cpp` (8.5k lines) into per-operation TUs: buildinspect, buildprimecache, buildstorageresolve, buildupdatefolder, builduploadfolder, buildvalidatebuildpart; stats moved to buildstoragestats.h. - FilteredRate extracted to zenutil. - BuildsCommand shared state consolidated into a BuildsConfiguration struct; subcommands inherit from BuildsSubCmdBase holding a `const BuildsConfiguration&` instead of a `BuildsCommand&`. - `ProgressBar` renamed to `ConsoleProgressBar`; mode enum (`ConsoleProgressMode`) lifted to namespace scope; `PushLogOperation`/`PopLogOperation`/`ForceLinebreak` promoted to virtuals on `ProgressBase`. - Free-function wrappers (`UploadFolder`, `DownloadFolder`, `ValidateBuildPart`) added around the existing operation classes so callers stop reimplementing setup + stats logging.
Diffstat (limited to 'src/zenutil')
-rw-r--r--src/zenutil/filteredrate.cpp92
-rw-r--r--src/zenutil/include/zenutil/filteredrate.h37
-rw-r--r--src/zenutil/include/zenutil/progress.h3
-rw-r--r--src/zenutil/progress.cpp3
4 files changed, 135 insertions, 0 deletions
diff --git a/src/zenutil/filteredrate.cpp b/src/zenutil/filteredrate.cpp
new file mode 100644
index 000000000..de01af57b
--- /dev/null
+++ b/src/zenutil/filteredrate.cpp
@@ -0,0 +1,92 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#include <zenutil/filteredrate.h>
+
+namespace zen {
+
+void
+FilteredRate::Start()
+{
+ if (StartTimeUS == (uint64_t)-1)
+ {
+ uint64_t Expected = (uint64_t)-1;
+ if (StartTimeUS.compare_exchange_strong(Expected, Timer.GetElapsedTimeUs()))
+ {
+ LastTimeUS = StartTimeUS.load();
+ }
+ }
+}
+
+void
+FilteredRate::Stop()
+{
+ if (EndTimeUS == (uint64_t)-1)
+ {
+ uint64_t Expected = (uint64_t)-1;
+ EndTimeUS.compare_exchange_strong(Expected, Timer.GetElapsedTimeUs());
+ }
+}
+
+void
+FilteredRate::Update(uint64_t Count)
+{
+ if (LastTimeUS == (uint64_t)-1)
+ {
+ return;
+ }
+ uint64_t TimeUS = Timer.GetElapsedTimeUs();
+ uint64_t TimeDeltaUS = TimeUS - LastTimeUS;
+ if (TimeDeltaUS >= 2000000)
+ {
+ uint64_t Delta = Count - LastCount;
+ uint64_t PerSecond = (Delta * 1000000) / TimeDeltaUS;
+
+ FilteredPerSecond = (PerSecond + (LastPerSecond * 7)) / 8;
+
+ LastPerSecond = PerSecond;
+ LastCount = Count;
+ LastTimeUS = TimeUS;
+ }
+}
+
+uint64_t
+FilteredRate::GetCurrent() const
+{
+ if (LastTimeUS == (uint64_t)-1)
+ {
+ return 0;
+ }
+ return FilteredPerSecond;
+}
+
+uint64_t
+FilteredRate::GetElapsedTimeUS() const
+{
+ if (StartTimeUS == (uint64_t)-1)
+ {
+ return 0;
+ }
+ if (EndTimeUS == (uint64_t)-1)
+ {
+ return 0;
+ }
+ return EndTimeUS - StartTimeUS;
+}
+
+bool
+FilteredRate::IsActive() const
+{
+ return (StartTimeUS != (uint64_t)-1) && (EndTimeUS == (uint64_t)-1);
+}
+
+uint64_t
+GetBytesPerSecond(uint64_t ElapsedWallTimeUS, uint64_t Count)
+{
+ if (ElapsedWallTimeUS == 0)
+ {
+ return 0;
+ }
+ return Count * 1000000 / ElapsedWallTimeUS;
+}
+
+} // namespace zen
diff --git a/src/zenutil/include/zenutil/filteredrate.h b/src/zenutil/include/zenutil/filteredrate.h
new file mode 100644
index 000000000..3349823d0
--- /dev/null
+++ b/src/zenutil/include/zenutil/filteredrate.h
@@ -0,0 +1,37 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#pragma once
+
+#include <zencore/timer.h>
+
+#include <atomic>
+#include <cstdint>
+
+namespace zen {
+
+class FilteredRate
+{
+public:
+ FilteredRate() {}
+
+ void Start();
+ void Stop();
+ void Update(uint64_t Count);
+
+ uint64_t GetCurrent() const;
+ uint64_t GetElapsedTimeUS() const;
+ bool IsActive() const;
+
+private:
+ Stopwatch Timer;
+ std::atomic<uint64_t> StartTimeUS = (uint64_t)-1;
+ std::atomic<uint64_t> EndTimeUS = (uint64_t)-1;
+ std::atomic<uint64_t> LastTimeUS = (uint64_t)-1;
+ uint64_t LastCount = 0;
+ uint64_t LastPerSecond = 0;
+ uint64_t FilteredPerSecond = 0;
+};
+
+uint64_t GetBytesPerSecond(uint64_t ElapsedWallTimeUS, uint64_t Count);
+
+} // namespace zen
diff --git a/src/zenutil/include/zenutil/progress.h b/src/zenutil/include/zenutil/progress.h
index 6a137ae9c..4103723b3 100644
--- a/src/zenutil/include/zenutil/progress.h
+++ b/src/zenutil/include/zenutil/progress.h
@@ -16,6 +16,8 @@ public:
virtual void SetLogOperationName(std::string_view Name) = 0;
virtual void SetLogOperationProgress(uint32_t StepIndex, uint32_t StepCount) = 0;
+ virtual void PushLogOperation(std::string_view Name) = 0;
+ virtual void PopLogOperation() = 0;
virtual uint32_t GetProgressUpdateDelayMS() const = 0;
class ProgressBar
@@ -54,6 +56,7 @@ public:
virtual ~ProgressBar() = default;
virtual void UpdateState(const State& NewState, bool DoLinebreak) = 0;
+ virtual void ForceLinebreak() = 0;
virtual void Finish() = 0;
};
diff --git a/src/zenutil/progress.cpp b/src/zenutil/progress.cpp
index a12076dcc..01f6529f2 100644
--- a/src/zenutil/progress.cpp
+++ b/src/zenutil/progress.cpp
@@ -14,6 +14,7 @@ public:
StandardProgressBar(StandardProgressBase& Owner, std::string_view InSubTask) : m_Owner(Owner), m_SubTask(InSubTask) {}
virtual void UpdateState(const State& NewState, bool DoLinebreak) override;
+ virtual void ForceLinebreak() override {}
virtual void Finish() override;
private:
@@ -38,6 +39,8 @@ public:
const size_t PercentDone = StepCount > 0u ? (100u * StepIndex) / StepCount : 0u;
ZEN_INFO("{}: {}%", m_LogOperationName, PercentDone);
}
+ virtual void PushLogOperation(std::string_view Name) override { ZEN_UNUSED(Name); }
+ virtual void PopLogOperation() override {}
virtual uint32_t GetProgressUpdateDelayMS() const override { return 2000; }
virtual std::unique_ptr<ProgressBar> CreateProgressBar(std::string_view InSubTask) override
{