From c7c59cdc5a70bfd6e5f66f3b032ea3f8f6b4d12a Mon Sep 17 00:00:00 2001 From: Dan Engelbrecht Date: Mon, 20 Apr 2026 07:27:35 +0200 Subject: 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. --- src/zenutil/filteredrate.cpp | 92 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 src/zenutil/filteredrate.cpp (limited to 'src/zenutil/filteredrate.cpp') 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 + +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 -- cgit v1.2.3