Files
UnrealEngine/Engine/Source/Runtime/Online/BuildPatchServices/Private/Installer/Statistics/InstallChunkSourceStatistics.cpp
2025-05-18 13:04:45 +08:00

111 lines
3.8 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "Installer/Statistics/InstallChunkSourceStatistics.h"
#include "HAL/ThreadSafeBool.h"
#include "Core/AsyncHelpers.h"
#include "Common/SpeedRecorder.h"
#include "Common/StatsCollector.h"
#include "Installer/InstallerAnalytics.h"
#include "Installer/Statistics/FileOperationTracker.h"
namespace BuildPatchServices
{
class FInstallChunkSourceStatistics
: public IInstallChunkSourceStatistics
{
public:
FInstallChunkSourceStatistics(ISpeedRecorder* SpeedRecorder, IInstallerAnalytics* InstallerAnalytics, IFileOperationTracker* FileOperationTracker);
~FInstallChunkSourceStatistics();
// IInstallChunkSourceStat interface begin.
virtual void OnLoadStarted(const FGuid& ChunkId) override;
virtual void OnLoadComplete(const FGuid& ChunkId, const ELoadResult& Result, const ISpeedRecorder::FRecord& Record) override;
// IInstallChunkSourceStat interface end.
// IInstallChunkSourceStatistics interface begin.
virtual uint64 GetBytesRead() const;
virtual int32 GetNumSuccessfulChunkRecycles() const override;
virtual int32 GetNumFailedChunkRecycles() const override;
virtual bool IsCurrentlyReading() const override;
// IInstallChunkSourceStatistics interface end.
private:
ISpeedRecorder* SpeedRecorder;
IInstallerAnalytics* InstallerAnalytics;
IFileOperationTracker* FileOperationTracker;
FThreadSafeInt32 NumSuccessfulLoads;
FThreadSafeInt32 NumFailedLoads;
FThreadSafeInt64 TotalBytesRead;
FThreadSafeBool bIsReading;
FThreadSafeInt64 LastReadCycles;
};
FInstallChunkSourceStatistics::FInstallChunkSourceStatistics(ISpeedRecorder* InSpeedRecorder, IInstallerAnalytics* InInstallerAnalytics, IFileOperationTracker* InFileOperationTracker)
: SpeedRecorder(InSpeedRecorder)
, InstallerAnalytics(InInstallerAnalytics)
, FileOperationTracker(InFileOperationTracker)
, NumSuccessfulLoads(0)
, NumFailedLoads(0)
, TotalBytesRead(0)
, bIsReading(false)
, LastReadCycles(0)
{
}
FInstallChunkSourceStatistics::~FInstallChunkSourceStatistics()
{
}
void FInstallChunkSourceStatistics::OnLoadStarted(const FGuid& ChunkId)
{
bIsReading = true;
FileOperationTracker->OnDataStateUpdate(ChunkId, EFileOperationState::RetrievingLocalInstallData);
}
void FInstallChunkSourceStatistics::OnLoadComplete(const FGuid& ChunkId, const ELoadResult& Result, const ISpeedRecorder::FRecord& Record)
{
if (Result == ELoadResult::Success)
{
NumSuccessfulLoads.Increment();
}
else
{
FileOperationTracker->OnDataStateUpdate(ChunkId, EFileOperationState::PendingRemoteCloudData);
InstallerAnalytics->RecordChunkCacheError(ChunkId, TEXT(""), FPlatformMisc::GetLastError(), TEXT("InstallChunkSourceLoad"), ToString(Result));
NumFailedLoads.Increment();
}
SpeedRecorder->AddRecord(Record);
TotalBytesRead.Add(Record.Size);
bIsReading = false;
LastReadCycles = Record.CyclesEnd;
}
uint64 FInstallChunkSourceStatistics::GetBytesRead() const
{
return TotalBytesRead.GetValue();
}
int32 FInstallChunkSourceStatistics::GetNumSuccessfulChunkRecycles() const
{
return NumSuccessfulLoads.GetValue();
}
int32 FInstallChunkSourceStatistics::GetNumFailedChunkRecycles() const
{
return NumFailedLoads.GetValue();
}
bool FInstallChunkSourceStatistics::IsCurrentlyReading() const
{
const int64 CyclesSinceRead = FStatsCollector::GetCycles() - LastReadCycles.GetValue();
return bIsReading || FStatsCollector::CyclesToSeconds(CyclesSinceRead) < 0.05;
}
IInstallChunkSourceStatistics* FInstallChunkSourceStatisticsFactory::Create(ISpeedRecorder* SpeedRecorder, IInstallerAnalytics* InstallerAnalytics, IFileOperationTracker* FileOperationTracker)
{
check(SpeedRecorder != nullptr);
check(InstallerAnalytics != nullptr);
check(FileOperationTracker != nullptr);
return new FInstallChunkSourceStatistics(SpeedRecorder, InstallerAnalytics, FileOperationTracker);
}
};