2021-09-03 02:57:01 -04:00
|
|
|
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
|
|
|
|
|
|
#include "VirtualizationDDCBackend.h"
|
|
|
|
|
|
|
|
|
|
#include "Misc/Parse.h"
|
|
|
|
|
#include "DerivedDataCache.h"
|
|
|
|
|
#include "DerivedDataCacheRecord.h"
|
|
|
|
|
#include "DerivedDataRequestOwner.h"
|
2022-01-06 11:05:57 -05:00
|
|
|
#include "DerivedDataValue.h"
|
2021-09-03 02:57:01 -04:00
|
|
|
|
|
|
|
|
namespace UE::Virtualization
|
|
|
|
|
{
|
|
|
|
|
|
2022-02-02 02:21:24 -05:00
|
|
|
/** Utility function to help convert from UE::Virtualization::FIoHash to UE::DerivedData::FValueId */
|
|
|
|
|
static UE::DerivedData::FValueId ToDerivedDataValueId(const FIoHash& Id)
|
2021-09-03 02:57:01 -04:00
|
|
|
{
|
2022-02-02 02:21:24 -05:00
|
|
|
return UE::DerivedData::FValueId::FromHash(Id);
|
2021-09-03 02:57:01 -04:00
|
|
|
}
|
|
|
|
|
|
2022-03-08 11:22:45 -05:00
|
|
|
FDDCBackend::FDDCBackend(FStringView ProjectName, FStringView ConfigName, FStringView InDebugName)
|
2022-04-21 03:15:13 -04:00
|
|
|
: IVirtualizationBackend(ConfigName, InDebugName, EOperations::Push | EOperations::Pull)
|
2021-09-03 02:57:01 -04:00
|
|
|
, BucketName(TEXT("BulkData"))
|
|
|
|
|
, TransferPolicy(UE::DerivedData::ECachePolicy::None)
|
|
|
|
|
, QueryPolicy(UE::DerivedData::ECachePolicy::None)
|
|
|
|
|
{
|
2021-11-18 14:37:34 -05:00
|
|
|
|
2021-09-03 02:57:01 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool FDDCBackend::Initialize(const FString& ConfigEntry)
|
|
|
|
|
{
|
|
|
|
|
TRACE_CPUPROFILER_EVENT_SCOPE(Initialize::Initialize);
|
|
|
|
|
|
|
|
|
|
if (!FParse::Value(*ConfigEntry, TEXT("Bucket="), BucketName))
|
|
|
|
|
{
|
2021-11-18 14:37:34 -05:00
|
|
|
UE_LOG(LogVirtualization, Fatal, TEXT("[%s] 'Bucket=' not found in the config file"), *GetDebugName());
|
2021-09-03 02:57:01 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool bAllowLocal = true;
|
|
|
|
|
if (FParse::Bool(*ConfigEntry, TEXT("LocalStorage="), bAllowLocal))
|
|
|
|
|
{
|
2022-02-17 02:53:27 -05:00
|
|
|
UE_LOG(LogVirtualization, Display, TEXT("[%s] Use of local storage set to '%s"), *GetDebugName(), bAllowLocal ? TEXT("true") : TEXT("false"));
|
2021-09-03 02:57:01 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool bAllowRemote = true;
|
|
|
|
|
if (FParse::Bool(*ConfigEntry, TEXT("RemoteStorage="), bAllowRemote))
|
|
|
|
|
{
|
2022-02-17 02:53:27 -05:00
|
|
|
UE_LOG(LogVirtualization, Display, TEXT("[%s] Use of remote storage set to '%s"), *GetDebugName(), bAllowRemote ? TEXT("true") : TEXT("false"));
|
2021-09-03 02:57:01 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!bAllowLocal && !bAllowRemote)
|
|
|
|
|
{
|
2021-11-18 14:37:34 -05:00
|
|
|
UE_LOG(LogVirtualization, Fatal, TEXT("[%s] LocalStorage and RemoteStorage cannot both be disabled"), *GetDebugName());
|
2021-09-03 02:57:01 -04:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (bAllowLocal)
|
|
|
|
|
{
|
|
|
|
|
TransferPolicy |= UE::DerivedData::ECachePolicy::Local;
|
|
|
|
|
QueryPolicy |= UE::DerivedData::ECachePolicy::QueryLocal;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (bAllowRemote)
|
|
|
|
|
{
|
|
|
|
|
TransferPolicy |= UE::DerivedData::ECachePolicy::Remote;
|
|
|
|
|
QueryPolicy |= UE::DerivedData::ECachePolicy::QueryRemote;
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-13 07:00:55 -04:00
|
|
|
Bucket = UE::DerivedData::FCacheBucket(BucketName);
|
|
|
|
|
|
2021-09-03 02:57:01 -04:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-02 02:21:24 -05:00
|
|
|
EPushResult FDDCBackend::PushData(const FIoHash& Id, const FCompressedBuffer& Payload, const FString& PackageContext)
|
2021-09-03 02:57:01 -04:00
|
|
|
{
|
|
|
|
|
TRACE_CPUPROFILER_EVENT_SCOPE(FDDCBackend::PushData);
|
|
|
|
|
|
2021-12-01 11:13:31 -05:00
|
|
|
if (DoesPayloadExist(Id))
|
2021-09-03 02:57:01 -04:00
|
|
|
{
|
2022-01-27 04:20:46 -05:00
|
|
|
UE_LOG(LogVirtualization, Verbose, TEXT("[%s] Already has a copy of the payload '%s'."), *GetDebugName(), *LexToString(Id));
|
2021-09-03 02:57:01 -04:00
|
|
|
return EPushResult::PayloadAlreadyExisted;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UE::DerivedData::ICache& Cache = UE::DerivedData::GetCache();
|
|
|
|
|
|
|
|
|
|
UE::DerivedData::FCacheKey Key;
|
2021-09-13 07:00:55 -04:00
|
|
|
Key.Bucket = Bucket;
|
2022-02-02 02:21:24 -05:00
|
|
|
Key.Hash = Id;
|
2021-09-03 02:57:01 -04:00
|
|
|
|
2022-01-07 23:22:29 -05:00
|
|
|
UE::DerivedData::FValue DerivedDataValue(Payload);
|
2022-02-02 02:21:24 -05:00
|
|
|
check(DerivedDataValue.GetRawHash() == Id);
|
2021-09-03 02:57:01 -04:00
|
|
|
|
|
|
|
|
UE::DerivedData::FCacheRecordBuilder RecordBuilder(Key);
|
2022-01-07 23:22:29 -05:00
|
|
|
RecordBuilder.AddValue(ToDerivedDataValueId(Id), DerivedDataValue);
|
2021-09-03 02:57:01 -04:00
|
|
|
|
|
|
|
|
UE::DerivedData::FRequestOwner Owner(UE::DerivedData::EPriority::Blocking);
|
|
|
|
|
|
2022-01-11 17:09:20 -05:00
|
|
|
UE::DerivedData::FCachePutResponse Result;
|
|
|
|
|
auto Callback = [&Result](UE::DerivedData::FCachePutResponse&& Response)
|
2021-09-03 02:57:01 -04:00
|
|
|
{
|
2022-01-11 17:09:20 -05:00
|
|
|
Result = Response;
|
2021-09-03 02:57:01 -04:00
|
|
|
};
|
|
|
|
|
|
2022-01-04 14:38:48 -05:00
|
|
|
// TODO: Improve the name when we start passing more context to this function
|
|
|
|
|
Cache.Put({{{TEXT("Mirage")}, RecordBuilder.Build(), TransferPolicy}}, Owner, MoveTemp(Callback));
|
2021-09-03 02:57:01 -04:00
|
|
|
|
|
|
|
|
Owner.Wait();
|
|
|
|
|
|
|
|
|
|
if (Result.Status == UE::DerivedData::EStatus::Ok)
|
|
|
|
|
{
|
|
|
|
|
return EPushResult::Success;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return EPushResult::Failed;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-02 02:21:24 -05:00
|
|
|
FCompressedBuffer FDDCBackend::PullData(const FIoHash& Id)
|
2021-09-03 02:57:01 -04:00
|
|
|
{
|
|
|
|
|
TRACE_CPUPROFILER_EVENT_SCOPE(FDDCBackend::PullData);
|
|
|
|
|
|
|
|
|
|
UE::DerivedData::ICache& Cache = UE::DerivedData::GetCache();
|
|
|
|
|
|
|
|
|
|
UE::DerivedData::FCacheKey Key;
|
2021-09-13 07:00:55 -04:00
|
|
|
Key.Bucket = Bucket;
|
2022-02-02 02:21:24 -05:00
|
|
|
Key.Hash = Id;
|
2021-09-03 02:57:01 -04:00
|
|
|
|
|
|
|
|
UE::DerivedData::FRequestOwner Owner(UE::DerivedData::EPriority::Blocking);
|
|
|
|
|
|
|
|
|
|
FCompressedBuffer ResultData;
|
|
|
|
|
UE::DerivedData::EStatus ResultStatus;
|
|
|
|
|
|
2022-01-11 17:09:20 -05:00
|
|
|
auto Callback = [&Id, &ResultData, &ResultStatus](UE::DerivedData::FCacheGetResponse&& Response)
|
2021-09-03 02:57:01 -04:00
|
|
|
{
|
2022-01-11 17:09:20 -05:00
|
|
|
ResultStatus = Response.Status;
|
2021-09-03 02:57:01 -04:00
|
|
|
if (ResultStatus == UE::DerivedData::EStatus::Ok)
|
|
|
|
|
{
|
2022-01-11 17:09:20 -05:00
|
|
|
ResultData = Response.Record.GetValue(ToDerivedDataValueId(Id)).GetData();
|
2021-09-03 02:57:01 -04:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2022-01-04 14:38:48 -05:00
|
|
|
// TODO: Improve the name when we start passing more context to this function
|
|
|
|
|
Cache.Get({{{TEXT("Mirage")}, Key, TransferPolicy}}, Owner, MoveTemp(Callback));
|
2021-09-03 02:57:01 -04:00
|
|
|
|
|
|
|
|
Owner.Wait();
|
|
|
|
|
|
|
|
|
|
return ResultData;
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-02 02:21:24 -05:00
|
|
|
bool FDDCBackend::DoesPayloadExist(const FIoHash& Id)
|
2021-09-03 02:57:01 -04:00
|
|
|
{
|
2021-12-01 11:13:31 -05:00
|
|
|
TRACE_CPUPROFILER_EVENT_SCOPE(FDDCBackend::DoesPayloadExist);
|
2021-09-03 02:57:01 -04:00
|
|
|
|
|
|
|
|
UE::DerivedData::ICache& Cache = UE::DerivedData::GetCache();
|
|
|
|
|
|
|
|
|
|
UE::DerivedData::FCacheKey Key;
|
2021-09-13 07:00:55 -04:00
|
|
|
Key.Bucket = Bucket;
|
2022-02-02 02:21:24 -05:00
|
|
|
Key.Hash = Id;
|
2021-09-03 02:57:01 -04:00
|
|
|
|
|
|
|
|
UE::DerivedData::FRequestOwner Owner(UE::DerivedData::EPriority::Blocking);
|
|
|
|
|
|
|
|
|
|
UE::DerivedData::EStatus ResultStatus;
|
2022-01-11 17:09:20 -05:00
|
|
|
auto Callback = [&ResultStatus](UE::DerivedData::FCacheGetResponse&& Response)
|
2021-09-03 02:57:01 -04:00
|
|
|
{
|
2022-01-11 17:09:20 -05:00
|
|
|
ResultStatus = Response.Status;
|
2021-09-03 02:57:01 -04:00
|
|
|
};
|
|
|
|
|
|
2022-01-04 14:38:48 -05:00
|
|
|
// TODO: Improve the name when we start passing more context to this function
|
|
|
|
|
Cache.Get({{{TEXT("Mirage")}, Key, QueryPolicy | UE::DerivedData::ECachePolicy::SkipData}}, Owner, MoveTemp(Callback));
|
2021-09-03 02:57:01 -04:00
|
|
|
|
|
|
|
|
Owner.Wait();
|
|
|
|
|
|
|
|
|
|
return ResultStatus == UE::DerivedData::EStatus::Ok;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UE_REGISTER_VIRTUALIZATION_BACKEND_FACTORY(FDDCBackend, DDCBackend);
|
|
|
|
|
} // namespace UE::Virtualization
|