Files

634 lines
20 KiB
C++
Raw Permalink Normal View History

DDC: Switched to the async cache hierarchy and fully implemented the verify wrapper The async cache hierarchy: - Is required to add compression to the legacy cache by forwarding LegacyPut/LegacyGet to PutValue/GetValue. - Is always present in the graph, unlike the previous cache hierarchy, which will allow significant simplification of leaf cache stores. - Allows for the leaf cache store nodes to operate asynchronously without blocking a worker thread like the previous cache hierarchy. - Shifts from controlling cache behavior by speed class to controlling cache behavior by local/remote classification, which is a critical distinction for a cache like Zen that can identify as both local and remote. - Respects the local/remote and query/store flags in the cache policy. - Does not fully implement the partial record cache policy at this time. - Does not propagate records or values in GetChunks, which will be added in a future release. The verify wrapper was previously missing an implementation for the new cache interface. This version is more efficient than the previous because requests through the new cache interface can compare data without loading it from storage, and load it only when a mismatch has been detected, to dump it to disk. #jira UE-134381 #lockdown Mark.Lintott #preflight 61fc32ac0a50c2606f266388 #rb Zousar.Shaker #rnx #ROBOMERGE-AUTHOR: devin.doucette #ROBOMERGE-SOURCE: CL 18851861 in //UE5/Release-5.0/... via CL 18851943 via CL 18852169 #ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v910-18824042) [CL 18852184 by devin doucette in ue5-main branch]
2022-02-03 16:49:32 -05:00
// Copyright Epic Games, Inc. All Rights Reserved.
#include "Algo/Compare.h"
#include "Containers/Set.h"
#include "DerivedDataCacheKey.h"
#include "DerivedDataCacheKeyFilter.h"
DDC: Switched to the async cache hierarchy and fully implemented the verify wrapper The async cache hierarchy: - Is required to add compression to the legacy cache by forwarding LegacyPut/LegacyGet to PutValue/GetValue. - Is always present in the graph, unlike the previous cache hierarchy, which will allow significant simplification of leaf cache stores. - Allows for the leaf cache store nodes to operate asynchronously without blocking a worker thread like the previous cache hierarchy. - Shifts from controlling cache behavior by speed class to controlling cache behavior by local/remote classification, which is a critical distinction for a cache like Zen that can identify as both local and remote. - Respects the local/remote and query/store flags in the cache policy. - Does not fully implement the partial record cache policy at this time. - Does not propagate records or values in GetChunks, which will be added in a future release. The verify wrapper was previously missing an implementation for the new cache interface. This version is more efficient than the previous because requests through the new cache interface can compare data without loading it from storage, and load it only when a mismatch has been detected, to dump it to disk. #jira UE-134381 #lockdown Mark.Lintott #preflight 61fc32ac0a50c2606f266388 #rb Zousar.Shaker #rnx #ROBOMERGE-AUTHOR: devin.doucette #ROBOMERGE-SOURCE: CL 18851861 in //UE5/Release-5.0/... via CL 18851943 via CL 18852169 #ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v910-18824042) [CL 18852184 by devin doucette in ue5-main branch]
2022-02-03 16:49:32 -05:00
#include "DerivedDataLegacyCacheStore.h"
#include "HAL/CriticalSection.h"
#include "Misc/CommandLine.h"
#include "Misc/Parse.h"
DDC: Switched to the async cache hierarchy and fully implemented the verify wrapper The async cache hierarchy: - Is required to add compression to the legacy cache by forwarding LegacyPut/LegacyGet to PutValue/GetValue. - Is always present in the graph, unlike the previous cache hierarchy, which will allow significant simplification of leaf cache stores. - Allows for the leaf cache store nodes to operate asynchronously without blocking a worker thread like the previous cache hierarchy. - Shifts from controlling cache behavior by speed class to controlling cache behavior by local/remote classification, which is a critical distinction for a cache like Zen that can identify as both local and remote. - Respects the local/remote and query/store flags in the cache policy. - Does not fully implement the partial record cache policy at this time. - Does not propagate records or values in GetChunks, which will be added in a future release. The verify wrapper was previously missing an implementation for the new cache interface. This version is more efficient than the previous because requests through the new cache interface can compare data without loading it from storage, and load it only when a mismatch has been detected, to dump it to disk. #jira UE-134381 #lockdown Mark.Lintott #preflight 61fc32ac0a50c2606f266388 #rb Zousar.Shaker #rnx #ROBOMERGE-AUTHOR: devin.doucette #ROBOMERGE-SOURCE: CL 18851861 in //UE5/Release-5.0/... via CL 18851943 via CL 18852169 #ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v910-18824042) [CL 18852184 by devin doucette in ue5-main branch]
2022-02-03 16:49:32 -05:00
#include "Misc/Paths.h"
#include "Misc/PathViews.h"
#include "Misc/ScopeLock.h"
#include "Misc/ScopeRWLock.h"
#include "Misc/FileHelper.h"
#include "String/Find.h"
DDC: Switched to the async cache hierarchy and fully implemented the verify wrapper The async cache hierarchy: - Is required to add compression to the legacy cache by forwarding LegacyPut/LegacyGet to PutValue/GetValue. - Is always present in the graph, unlike the previous cache hierarchy, which will allow significant simplification of leaf cache stores. - Allows for the leaf cache store nodes to operate asynchronously without blocking a worker thread like the previous cache hierarchy. - Shifts from controlling cache behavior by speed class to controlling cache behavior by local/remote classification, which is a critical distinction for a cache like Zen that can identify as both local and remote. - Respects the local/remote and query/store flags in the cache policy. - Does not fully implement the partial record cache policy at this time. - Does not propagate records or values in GetChunks, which will be added in a future release. The verify wrapper was previously missing an implementation for the new cache interface. This version is more efficient than the previous because requests through the new cache interface can compare data without loading it from storage, and load it only when a mismatch has been detected, to dump it to disk. #jira UE-134381 #lockdown Mark.Lintott #preflight 61fc32ac0a50c2606f266388 #rb Zousar.Shaker #rnx #ROBOMERGE-AUTHOR: devin.doucette #ROBOMERGE-SOURCE: CL 18851861 in //UE5/Release-5.0/... via CL 18851943 via CL 18852169 #ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v910-18824042) [CL 18852184 by devin doucette in ue5-main branch]
2022-02-03 16:49:32 -05:00
#include "Templates/Tuple.h"
#include "Templates/UniquePtr.h"
namespace UE::DerivedData
{
/**
* A cache store that verifies that derived data is generated deterministically.
*
* This wraps a cache store and fails every get until a matching put occurs, then compares the derived data.
*/
class FCacheStoreVerify final : public ILegacyCacheStore
DDC: Switched to the async cache hierarchy and fully implemented the verify wrapper The async cache hierarchy: - Is required to add compression to the legacy cache by forwarding LegacyPut/LegacyGet to PutValue/GetValue. - Is always present in the graph, unlike the previous cache hierarchy, which will allow significant simplification of leaf cache stores. - Allows for the leaf cache store nodes to operate asynchronously without blocking a worker thread like the previous cache hierarchy. - Shifts from controlling cache behavior by speed class to controlling cache behavior by local/remote classification, which is a critical distinction for a cache like Zen that can identify as both local and remote. - Respects the local/remote and query/store flags in the cache policy. - Does not fully implement the partial record cache policy at this time. - Does not propagate records or values in GetChunks, which will be added in a future release. The verify wrapper was previously missing an implementation for the new cache interface. This version is more efficient than the previous because requests through the new cache interface can compare data without loading it from storage, and load it only when a mismatch has been detected, to dump it to disk. #jira UE-134381 #lockdown Mark.Lintott #preflight 61fc32ac0a50c2606f266388 #rb Zousar.Shaker #rnx #ROBOMERGE-AUTHOR: devin.doucette #ROBOMERGE-SOURCE: CL 18851861 in //UE5/Release-5.0/... via CL 18851943 via CL 18852169 #ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v910-18824042) [CL 18852184 by devin doucette in ue5-main branch]
2022-02-03 16:49:32 -05:00
{
public:
FCacheStoreVerify(ILegacyCacheStore* InInnerCache, bool bInPutOnError)
: InnerCache(InInnerCache)
, bPutOnError(bInPutOnError)
{
check(InnerCache);
const TCHAR* const CommandLine = FCommandLine::Get();
const bool bDefaultMatch = FParse::Param(CommandLine, TEXT("DDC-Verify")) ||
String::FindFirst(CommandLine, TEXT("-DDC-Verify="), ESearchCase::IgnoreCase) == INDEX_NONE;
float DefaultRate = bDefaultMatch ? 100.0f : 0.0f;
FParse::Value(CommandLine, TEXT("-DDC-VerifyRate="), DefaultRate);
Filter = FCacheKeyFilter::Parse(CommandLine, TEXT("-DDC-Verify="), DefaultRate);
uint32 Salt;
if (FParse::Value(CommandLine, TEXT("-DDC-VerifySalt="), Salt))
{
if (Salt == 0)
{
UE_LOG(LogDerivedDataCache, Warning,
TEXT("Verify: Ignoring salt of 0. The salt must be a positive integer."));
}
else
{
Filter.SetSalt(Salt);
}
}
if (Filter)
{
UE_LOG(LogDerivedDataCache, Display,
TEXT("Verify: Using salt -DDC-VerifySalt=%u to filter cache keys to verify."), Filter.GetSalt());
}
bPutOnError = bPutOnError || FParse::Param(CommandLine, TEXT("DDC-VerifyFix"));
UE_CLOG(bPutOnError, LogDerivedDataCache, Display,
TEXT("Verify: Any record or value that differs will be overwritten."));
DDC: Switched to the async cache hierarchy and fully implemented the verify wrapper The async cache hierarchy: - Is required to add compression to the legacy cache by forwarding LegacyPut/LegacyGet to PutValue/GetValue. - Is always present in the graph, unlike the previous cache hierarchy, which will allow significant simplification of leaf cache stores. - Allows for the leaf cache store nodes to operate asynchronously without blocking a worker thread like the previous cache hierarchy. - Shifts from controlling cache behavior by speed class to controlling cache behavior by local/remote classification, which is a critical distinction for a cache like Zen that can identify as both local and remote. - Respects the local/remote and query/store flags in the cache policy. - Does not fully implement the partial record cache policy at this time. - Does not propagate records or values in GetChunks, which will be added in a future release. The verify wrapper was previously missing an implementation for the new cache interface. This version is more efficient than the previous because requests through the new cache interface can compare data without loading it from storage, and load it only when a mismatch has been detected, to dump it to disk. #jira UE-134381 #lockdown Mark.Lintott #preflight 61fc32ac0a50c2606f266388 #rb Zousar.Shaker #rnx #ROBOMERGE-AUTHOR: devin.doucette #ROBOMERGE-SOURCE: CL 18851861 in //UE5/Release-5.0/... via CL 18851943 via CL 18852169 #ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v910-18824042) [CL 18852184 by devin doucette in ue5-main branch]
2022-02-03 16:49:32 -05:00
}
~FCacheStoreVerify()
{
delete InnerCache;
}
DDC: Switched to the async cache hierarchy and fully implemented the verify wrapper The async cache hierarchy: - Is required to add compression to the legacy cache by forwarding LegacyPut/LegacyGet to PutValue/GetValue. - Is always present in the graph, unlike the previous cache hierarchy, which will allow significant simplification of leaf cache stores. - Allows for the leaf cache store nodes to operate asynchronously without blocking a worker thread like the previous cache hierarchy. - Shifts from controlling cache behavior by speed class to controlling cache behavior by local/remote classification, which is a critical distinction for a cache like Zen that can identify as both local and remote. - Respects the local/remote and query/store flags in the cache policy. - Does not fully implement the partial record cache policy at this time. - Does not propagate records or values in GetChunks, which will be added in a future release. The verify wrapper was previously missing an implementation for the new cache interface. This version is more efficient than the previous because requests through the new cache interface can compare data without loading it from storage, and load it only when a mismatch has been detected, to dump it to disk. #jira UE-134381 #lockdown Mark.Lintott #preflight 61fc32ac0a50c2606f266388 #rb Zousar.Shaker #rnx #ROBOMERGE-AUTHOR: devin.doucette #ROBOMERGE-SOURCE: CL 18851861 in //UE5/Release-5.0/... via CL 18851943 via CL 18852169 #ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v910-18824042) [CL 18852184 by devin doucette in ue5-main branch]
2022-02-03 16:49:32 -05:00
void Put(
TConstArrayView<FCachePutRequest> Requests,
IRequestOwner& Owner,
FOnCachePutComplete&& OnComplete) final;
void Get(
TConstArrayView<FCacheGetRequest> Requests,
IRequestOwner& Owner,
FOnCacheGetComplete&& OnComplete) final;
void PutValue(
TConstArrayView<FCachePutValueRequest> Requests,
IRequestOwner& Owner,
FOnCachePutValueComplete&& OnComplete) final;
void GetValue(
TConstArrayView<FCacheGetValueRequest> Requests,
IRequestOwner& Owner,
FOnCacheGetValueComplete&& OnComplete) final;
void GetChunks(
TConstArrayView<FCacheGetChunkRequest> Requests,
IRequestOwner& Owner,
FOnCacheGetChunkComplete&& OnComplete) final;
void LegacyStats(FDerivedDataCacheStatsNode& OutNode) final
{
InnerCache->LegacyStats(OutNode);
}
bool LegacyDebugOptions(FBackendDebugOptions& Options) final
{
return InnerCache->LegacyDebugOptions(Options);
}
private:
struct FVerifyPutState
{
TArray<FCachePutRequest> ForwardRequests;
TArray<FCachePutRequest> VerifyRequests;
FOnCachePutComplete OnComplete;
int32 ActiveRequests = 0;
FRWLock Lock;
};
struct FVerifyPutValueState
{
TArray<FCachePutValueRequest> ForwardRequests;
TArray<FCachePutValueRequest> VerifyRequests;
FOnCachePutValueComplete OnComplete;
int32 ActiveRequests = 0;
FRWLock Lock;
};
void GetMetaComplete(IRequestOwner& Owner, FVerifyPutState* State, FCacheGetResponse&& Response);
void GetDataComplete(IRequestOwner& Owner, FVerifyPutState* State, FCacheGetResponse&& Response);
void GetComplete(IRequestOwner& Owner, FVerifyPutState* State);
void GetMetaComplete(IRequestOwner& Owner, FVerifyPutValueState* State, FCacheGetValueResponse&& Response);
void GetDataComplete(IRequestOwner& Owner, FVerifyPutValueState* State, FCacheGetValueResponse&& Response);
void GetComplete(IRequestOwner& Owner, FVerifyPutValueState* State);
static bool CompareRecords(const FCacheRecord& PutRecord, const FCacheRecord& GetRecord, const FSharedString& Name);
static void LogChangedValue(
const FSharedString& Name,
const FCacheKey& Key,
const FValueId& Id,
const FIoHash& NewRawHash,
const FIoHash& OldRawHash,
const FCompositeBuffer& NewRawData,
const FCompositeBuffer& OldRawData);
DDC: Switched to the async cache hierarchy and fully implemented the verify wrapper The async cache hierarchy: - Is required to add compression to the legacy cache by forwarding LegacyPut/LegacyGet to PutValue/GetValue. - Is always present in the graph, unlike the previous cache hierarchy, which will allow significant simplification of leaf cache stores. - Allows for the leaf cache store nodes to operate asynchronously without blocking a worker thread like the previous cache hierarchy. - Shifts from controlling cache behavior by speed class to controlling cache behavior by local/remote classification, which is a critical distinction for a cache like Zen that can identify as both local and remote. - Respects the local/remote and query/store flags in the cache policy. - Does not fully implement the partial record cache policy at this time. - Does not propagate records or values in GetChunks, which will be added in a future release. The verify wrapper was previously missing an implementation for the new cache interface. This version is more efficient than the previous because requests through the new cache interface can compare data without loading it from storage, and load it only when a mismatch has been detected, to dump it to disk. #jira UE-134381 #lockdown Mark.Lintott #preflight 61fc32ac0a50c2606f266388 #rb Zousar.Shaker #rnx #ROBOMERGE-AUTHOR: devin.doucette #ROBOMERGE-SOURCE: CL 18851861 in //UE5/Release-5.0/... via CL 18851943 via CL 18852169 #ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v910-18824042) [CL 18852184 by devin doucette in ue5-main branch]
2022-02-03 16:49:32 -05:00
private:
ILegacyCacheStore* InnerCache;
FCriticalSection AlreadyTestedLock;
DDC: Switched to the async cache hierarchy and fully implemented the verify wrapper The async cache hierarchy: - Is required to add compression to the legacy cache by forwarding LegacyPut/LegacyGet to PutValue/GetValue. - Is always present in the graph, unlike the previous cache hierarchy, which will allow significant simplification of leaf cache stores. - Allows for the leaf cache store nodes to operate asynchronously without blocking a worker thread like the previous cache hierarchy. - Shifts from controlling cache behavior by speed class to controlling cache behavior by local/remote classification, which is a critical distinction for a cache like Zen that can identify as both local and remote. - Respects the local/remote and query/store flags in the cache policy. - Does not fully implement the partial record cache policy at this time. - Does not propagate records or values in GetChunks, which will be added in a future release. The verify wrapper was previously missing an implementation for the new cache interface. This version is more efficient than the previous because requests through the new cache interface can compare data without loading it from storage, and load it only when a mismatch has been detected, to dump it to disk. #jira UE-134381 #lockdown Mark.Lintott #preflight 61fc32ac0a50c2606f266388 #rb Zousar.Shaker #rnx #ROBOMERGE-AUTHOR: devin.doucette #ROBOMERGE-SOURCE: CL 18851861 in //UE5/Release-5.0/... via CL 18851943 via CL 18852169 #ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v910-18824042) [CL 18852184 by devin doucette in ue5-main branch]
2022-02-03 16:49:32 -05:00
TSet<FCacheKey> AlreadyTested;
FCacheKeyFilter Filter;
DDC: Switched to the async cache hierarchy and fully implemented the verify wrapper The async cache hierarchy: - Is required to add compression to the legacy cache by forwarding LegacyPut/LegacyGet to PutValue/GetValue. - Is always present in the graph, unlike the previous cache hierarchy, which will allow significant simplification of leaf cache stores. - Allows for the leaf cache store nodes to operate asynchronously without blocking a worker thread like the previous cache hierarchy. - Shifts from controlling cache behavior by speed class to controlling cache behavior by local/remote classification, which is a critical distinction for a cache like Zen that can identify as both local and remote. - Respects the local/remote and query/store flags in the cache policy. - Does not fully implement the partial record cache policy at this time. - Does not propagate records or values in GetChunks, which will be added in a future release. The verify wrapper was previously missing an implementation for the new cache interface. This version is more efficient than the previous because requests through the new cache interface can compare data without loading it from storage, and load it only when a mismatch has been detected, to dump it to disk. #jira UE-134381 #lockdown Mark.Lintott #preflight 61fc32ac0a50c2606f266388 #rb Zousar.Shaker #rnx #ROBOMERGE-AUTHOR: devin.doucette #ROBOMERGE-SOURCE: CL 18851861 in //UE5/Release-5.0/... via CL 18851943 via CL 18852169 #ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v910-18824042) [CL 18852184 by devin doucette in ue5-main branch]
2022-02-03 16:49:32 -05:00
bool bPutOnError;
};
void FCacheStoreVerify::Put(
const TConstArrayView<FCachePutRequest> Requests,
IRequestOwner& Owner,
FOnCachePutComplete&& OnComplete)
{
TUniquePtr<FVerifyPutState> State = MakeUnique<FVerifyPutState>();
State->VerifyRequests.Reserve(Requests.Num());
{
FScopeLock Lock(&AlreadyTestedLock);
DDC: Switched to the async cache hierarchy and fully implemented the verify wrapper The async cache hierarchy: - Is required to add compression to the legacy cache by forwarding LegacyPut/LegacyGet to PutValue/GetValue. - Is always present in the graph, unlike the previous cache hierarchy, which will allow significant simplification of leaf cache stores. - Allows for the leaf cache store nodes to operate asynchronously without blocking a worker thread like the previous cache hierarchy. - Shifts from controlling cache behavior by speed class to controlling cache behavior by local/remote classification, which is a critical distinction for a cache like Zen that can identify as both local and remote. - Respects the local/remote and query/store flags in the cache policy. - Does not fully implement the partial record cache policy at this time. - Does not propagate records or values in GetChunks, which will be added in a future release. The verify wrapper was previously missing an implementation for the new cache interface. This version is more efficient than the previous because requests through the new cache interface can compare data without loading it from storage, and load it only when a mismatch has been detected, to dump it to disk. #jira UE-134381 #lockdown Mark.Lintott #preflight 61fc32ac0a50c2606f266388 #rb Zousar.Shaker #rnx #ROBOMERGE-AUTHOR: devin.doucette #ROBOMERGE-SOURCE: CL 18851861 in //UE5/Release-5.0/... via CL 18851943 via CL 18852169 #ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v910-18824042) [CL 18852184 by devin doucette in ue5-main branch]
2022-02-03 16:49:32 -05:00
for (const FCachePutRequest& Request : Requests)
{
const FCacheKey& Key = Request.Record.GetKey();
bool bForward = !Filter.IsMatch(Key);
if (!bForward)
{
AlreadyTested.Add(Key, &bForward);
}
(bForward ? State->ForwardRequests : State->VerifyRequests).Add(Request);
DDC: Switched to the async cache hierarchy and fully implemented the verify wrapper The async cache hierarchy: - Is required to add compression to the legacy cache by forwarding LegacyPut/LegacyGet to PutValue/GetValue. - Is always present in the graph, unlike the previous cache hierarchy, which will allow significant simplification of leaf cache stores. - Allows for the leaf cache store nodes to operate asynchronously without blocking a worker thread like the previous cache hierarchy. - Shifts from controlling cache behavior by speed class to controlling cache behavior by local/remote classification, which is a critical distinction for a cache like Zen that can identify as both local and remote. - Respects the local/remote and query/store flags in the cache policy. - Does not fully implement the partial record cache policy at this time. - Does not propagate records or values in GetChunks, which will be added in a future release. The verify wrapper was previously missing an implementation for the new cache interface. This version is more efficient than the previous because requests through the new cache interface can compare data without loading it from storage, and load it only when a mismatch has been detected, to dump it to disk. #jira UE-134381 #lockdown Mark.Lintott #preflight 61fc32ac0a50c2606f266388 #rb Zousar.Shaker #rnx #ROBOMERGE-AUTHOR: devin.doucette #ROBOMERGE-SOURCE: CL 18851861 in //UE5/Release-5.0/... via CL 18851943 via CL 18852169 #ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v910-18824042) [CL 18852184 by devin doucette in ue5-main branch]
2022-02-03 16:49:32 -05:00
}
}
if (State->VerifyRequests.IsEmpty())
{
return InnerCache->Put(State->ForwardRequests, Owner, MoveTemp(OnComplete));
}
TArray<FCacheGetRequest> GetMetaRequests;
GetMetaRequests.Reserve(State->VerifyRequests.Num());
{
uint64 PutIndex = 0;
const ECachePolicy GetPolicy = ECachePolicy::Query | ECachePolicy::PartialRecord | ECachePolicy::SkipData;
for (const FCachePutRequest& PutRequest : State->VerifyRequests)
{
GetMetaRequests.Add({PutRequest.Name, PutRequest.Record.GetKey(), GetPolicy, PutIndex++});
}
}
State->OnComplete = MoveTemp(OnComplete);
State->ActiveRequests = GetMetaRequests.Num();
InnerCache->Get(GetMetaRequests, Owner, [this, &Owner, State = State.Release()](FCacheGetResponse&& MetaResponse)
{
GetMetaComplete(Owner, State, MoveTemp(MetaResponse));
});
}
void FCacheStoreVerify::GetMetaComplete(IRequestOwner& Owner, FVerifyPutState* State, FCacheGetResponse&& Response)
{
FCachePutRequest& Request = State->VerifyRequests[int32(Response.UserData)];
if ((Response.Status == EStatus::Ok) ||
(Response.Status == EStatus::Error && !Response.Record.GetValues().IsEmpty()))
{
const auto MakeValueTuple = [](const FValueWithId& Value) -> TTuple<FValueId, FIoHash>
{
return MakeTuple(Value.GetId(), Value.GetRawHash());
};
if (Algo::CompareBy(Request.Record.GetValues(), Response.Record.GetValues(), MakeValueTuple))
{
UE_LOG(LogDerivedDataCache, Verbose,
DDC: Switched to the async cache hierarchy and fully implemented the verify wrapper The async cache hierarchy: - Is required to add compression to the legacy cache by forwarding LegacyPut/LegacyGet to PutValue/GetValue. - Is always present in the graph, unlike the previous cache hierarchy, which will allow significant simplification of leaf cache stores. - Allows for the leaf cache store nodes to operate asynchronously without blocking a worker thread like the previous cache hierarchy. - Shifts from controlling cache behavior by speed class to controlling cache behavior by local/remote classification, which is a critical distinction for a cache like Zen that can identify as both local and remote. - Respects the local/remote and query/store flags in the cache policy. - Does not fully implement the partial record cache policy at this time. - Does not propagate records or values in GetChunks, which will be added in a future release. The verify wrapper was previously missing an implementation for the new cache interface. This version is more efficient than the previous because requests through the new cache interface can compare data without loading it from storage, and load it only when a mismatch has been detected, to dump it to disk. #jira UE-134381 #lockdown Mark.Lintott #preflight 61fc32ac0a50c2606f266388 #rb Zousar.Shaker #rnx #ROBOMERGE-AUTHOR: devin.doucette #ROBOMERGE-SOURCE: CL 18851861 in //UE5/Release-5.0/... via CL 18851943 via CL 18852169 #ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v910-18824042) [CL 18852184 by devin doucette in ue5-main branch]
2022-02-03 16:49:32 -05:00
TEXT("Verify: Data in the cache matches newly generated data for %s from '%s'."),
*WriteToString<96>(Request.Record.GetKey()), *Request.Name);
State->OnComplete(Request.MakeResponse(EStatus::Ok));
}
else
{
const ECachePolicy Policy = ECachePolicy::Default | ECachePolicy::PartialRecord;
const FCacheGetRequest GetDataRequests[]{{Response.Name, Response.Record.GetKey(), Policy, Response.UserData}};
return InnerCache->Get(GetDataRequests, Owner, [this, &Owner, State](FCacheGetResponse&& DataResponse)
{
GetDataComplete(Owner, State, MoveTemp(DataResponse));
});
}
}
else
{
UE_LOG(LogDerivedDataCache, Warning,
TEXT("Verify: Cache did not contain a record for %s from '%s'."),
*WriteToString<96>(Request.Record.GetKey()), *Request.Name);
FWriteScopeLock Lock(State->Lock);
State->ForwardRequests.Add(MoveTemp(Request));
}
GetComplete(Owner, State);
}
void FCacheStoreVerify::GetDataComplete(IRequestOwner& Owner, FVerifyPutState* State, FCacheGetResponse&& Response)
{
FCachePutRequest& Request = State->VerifyRequests[int32(Response.UserData)];
if ((Response.Status == EStatus::Ok) ||
(Response.Status == EStatus::Error && !Response.Record.GetValues().IsEmpty()))
{
if (CompareRecords(Request.Record, Response.Record, Request.Name))
{
UE_LOG(LogDerivedDataCache, Verbose,
DDC: Switched to the async cache hierarchy and fully implemented the verify wrapper The async cache hierarchy: - Is required to add compression to the legacy cache by forwarding LegacyPut/LegacyGet to PutValue/GetValue. - Is always present in the graph, unlike the previous cache hierarchy, which will allow significant simplification of leaf cache stores. - Allows for the leaf cache store nodes to operate asynchronously without blocking a worker thread like the previous cache hierarchy. - Shifts from controlling cache behavior by speed class to controlling cache behavior by local/remote classification, which is a critical distinction for a cache like Zen that can identify as both local and remote. - Respects the local/remote and query/store flags in the cache policy. - Does not fully implement the partial record cache policy at this time. - Does not propagate records or values in GetChunks, which will be added in a future release. The verify wrapper was previously missing an implementation for the new cache interface. This version is more efficient than the previous because requests through the new cache interface can compare data without loading it from storage, and load it only when a mismatch has been detected, to dump it to disk. #jira UE-134381 #lockdown Mark.Lintott #preflight 61fc32ac0a50c2606f266388 #rb Zousar.Shaker #rnx #ROBOMERGE-AUTHOR: devin.doucette #ROBOMERGE-SOURCE: CL 18851861 in //UE5/Release-5.0/... via CL 18851943 via CL 18852169 #ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v910-18824042) [CL 18852184 by devin doucette in ue5-main branch]
2022-02-03 16:49:32 -05:00
TEXT("Verify: Data in the cache matches newly generated data for %s from '%s'."),
*WriteToString<96>(Request.Record.GetKey()), *Request.Name);
State->OnComplete(Request.MakeResponse(EStatus::Ok));
}
else if (bPutOnError)
{
// Ask to overwrite existing records to potentially eliminate the mismatch.
UE_LOG(LogDerivedDataCache, Display,
TEXT("Verify: Writing newly generated data to the cache for %s from '%s'."),
*WriteToString<96>(Request.Record.GetKey()), *Request.Name);
Request.Policy = Request.Policy.Transform([](ECachePolicy P) { return P & ~ECachePolicy::Query; });
FWriteScopeLock Lock(State->Lock);
State->ForwardRequests.Add(MoveTemp(Request));
}
else
{
State->OnComplete(Request.MakeResponse(EStatus::Ok));
}
}
else
{
UE_LOG(LogDerivedDataCache, Warning,
TEXT("Verify: Cache did not contain a record for %s from '%s'."),
*WriteToString<96>(Request.Record.GetKey()), *Request.Name);
FWriteScopeLock Lock(State->Lock);
State->ForwardRequests.Add(MoveTemp(Request));
}
GetComplete(Owner, State);
}
void FCacheStoreVerify::GetComplete(IRequestOwner& Owner, FVerifyPutState* State)
{
if (FWriteScopeLock Lock(State->Lock); --State->ActiveRequests > 0)
{
return;
}
if (!State->ForwardRequests.IsEmpty())
{
InnerCache->Put(State->ForwardRequests, Owner, MoveTemp(State->OnComplete));
}
delete State;
}
void FCacheStoreVerify::Get(
const TConstArrayView<FCacheGetRequest> Requests,
IRequestOwner& Owner,
FOnCacheGetComplete&& OnComplete)
{
TArray<FCacheGetRequest, TInlineAllocator<8>> ForwardRequests;
TArray<FCacheGetRequest, TInlineAllocator<8>> VerifyRequests;
ForwardRequests.Reserve(Requests.Num());
VerifyRequests.Reserve(Requests.Num());
{
FScopeLock Lock(&AlreadyTestedLock);
DDC: Switched to the async cache hierarchy and fully implemented the verify wrapper The async cache hierarchy: - Is required to add compression to the legacy cache by forwarding LegacyPut/LegacyGet to PutValue/GetValue. - Is always present in the graph, unlike the previous cache hierarchy, which will allow significant simplification of leaf cache stores. - Allows for the leaf cache store nodes to operate asynchronously without blocking a worker thread like the previous cache hierarchy. - Shifts from controlling cache behavior by speed class to controlling cache behavior by local/remote classification, which is a critical distinction for a cache like Zen that can identify as both local and remote. - Respects the local/remote and query/store flags in the cache policy. - Does not fully implement the partial record cache policy at this time. - Does not propagate records or values in GetChunks, which will be added in a future release. The verify wrapper was previously missing an implementation for the new cache interface. This version is more efficient than the previous because requests through the new cache interface can compare data without loading it from storage, and load it only when a mismatch has been detected, to dump it to disk. #jira UE-134381 #lockdown Mark.Lintott #preflight 61fc32ac0a50c2606f266388 #rb Zousar.Shaker #rnx #ROBOMERGE-AUTHOR: devin.doucette #ROBOMERGE-SOURCE: CL 18851861 in //UE5/Release-5.0/... via CL 18851943 via CL 18852169 #ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v910-18824042) [CL 18852184 by devin doucette in ue5-main branch]
2022-02-03 16:49:32 -05:00
for (const FCacheGetRequest& Request : Requests)
{
const bool bForward = !Filter.IsMatch(Request.Key) || AlreadyTested.Contains(Request.Key);
(bForward ? ForwardRequests : VerifyRequests).Add(Request);
DDC: Switched to the async cache hierarchy and fully implemented the verify wrapper The async cache hierarchy: - Is required to add compression to the legacy cache by forwarding LegacyPut/LegacyGet to PutValue/GetValue. - Is always present in the graph, unlike the previous cache hierarchy, which will allow significant simplification of leaf cache stores. - Allows for the leaf cache store nodes to operate asynchronously without blocking a worker thread like the previous cache hierarchy. - Shifts from controlling cache behavior by speed class to controlling cache behavior by local/remote classification, which is a critical distinction for a cache like Zen that can identify as both local and remote. - Respects the local/remote and query/store flags in the cache policy. - Does not fully implement the partial record cache policy at this time. - Does not propagate records or values in GetChunks, which will be added in a future release. The verify wrapper was previously missing an implementation for the new cache interface. This version is more efficient than the previous because requests through the new cache interface can compare data without loading it from storage, and load it only when a mismatch has been detected, to dump it to disk. #jira UE-134381 #lockdown Mark.Lintott #preflight 61fc32ac0a50c2606f266388 #rb Zousar.Shaker #rnx #ROBOMERGE-AUTHOR: devin.doucette #ROBOMERGE-SOURCE: CL 18851861 in //UE5/Release-5.0/... via CL 18851943 via CL 18852169 #ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v910-18824042) [CL 18852184 by devin doucette in ue5-main branch]
2022-02-03 16:49:32 -05:00
}
}
CompleteWithStatus(VerifyRequests, OnComplete, EStatus::Error);
if (!ForwardRequests.IsEmpty())
{
InnerCache->Get(ForwardRequests, Owner, MoveTemp(OnComplete));
}
}
void FCacheStoreVerify::PutValue(
const TConstArrayView<FCachePutValueRequest> Requests,
IRequestOwner& Owner,
FOnCachePutValueComplete&& OnComplete)
{
TUniquePtr<FVerifyPutValueState> State = MakeUnique<FVerifyPutValueState>();
State->VerifyRequests.Reserve(Requests.Num());
{
FScopeLock Lock(&AlreadyTestedLock);
DDC: Switched to the async cache hierarchy and fully implemented the verify wrapper The async cache hierarchy: - Is required to add compression to the legacy cache by forwarding LegacyPut/LegacyGet to PutValue/GetValue. - Is always present in the graph, unlike the previous cache hierarchy, which will allow significant simplification of leaf cache stores. - Allows for the leaf cache store nodes to operate asynchronously without blocking a worker thread like the previous cache hierarchy. - Shifts from controlling cache behavior by speed class to controlling cache behavior by local/remote classification, which is a critical distinction for a cache like Zen that can identify as both local and remote. - Respects the local/remote and query/store flags in the cache policy. - Does not fully implement the partial record cache policy at this time. - Does not propagate records or values in GetChunks, which will be added in a future release. The verify wrapper was previously missing an implementation for the new cache interface. This version is more efficient than the previous because requests through the new cache interface can compare data without loading it from storage, and load it only when a mismatch has been detected, to dump it to disk. #jira UE-134381 #lockdown Mark.Lintott #preflight 61fc32ac0a50c2606f266388 #rb Zousar.Shaker #rnx #ROBOMERGE-AUTHOR: devin.doucette #ROBOMERGE-SOURCE: CL 18851861 in //UE5/Release-5.0/... via CL 18851943 via CL 18852169 #ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v910-18824042) [CL 18852184 by devin doucette in ue5-main branch]
2022-02-03 16:49:32 -05:00
for (const FCachePutValueRequest& Request : Requests)
{
bool bForward = !Filter.IsMatch(Request.Key);
if (!bForward)
{
AlreadyTested.Add(Request.Key, &bForward);
}
(bForward ? State->ForwardRequests : State->VerifyRequests).Add(Request);
DDC: Switched to the async cache hierarchy and fully implemented the verify wrapper The async cache hierarchy: - Is required to add compression to the legacy cache by forwarding LegacyPut/LegacyGet to PutValue/GetValue. - Is always present in the graph, unlike the previous cache hierarchy, which will allow significant simplification of leaf cache stores. - Allows for the leaf cache store nodes to operate asynchronously without blocking a worker thread like the previous cache hierarchy. - Shifts from controlling cache behavior by speed class to controlling cache behavior by local/remote classification, which is a critical distinction for a cache like Zen that can identify as both local and remote. - Respects the local/remote and query/store flags in the cache policy. - Does not fully implement the partial record cache policy at this time. - Does not propagate records or values in GetChunks, which will be added in a future release. The verify wrapper was previously missing an implementation for the new cache interface. This version is more efficient than the previous because requests through the new cache interface can compare data without loading it from storage, and load it only when a mismatch has been detected, to dump it to disk. #jira UE-134381 #lockdown Mark.Lintott #preflight 61fc32ac0a50c2606f266388 #rb Zousar.Shaker #rnx #ROBOMERGE-AUTHOR: devin.doucette #ROBOMERGE-SOURCE: CL 18851861 in //UE5/Release-5.0/... via CL 18851943 via CL 18852169 #ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v910-18824042) [CL 18852184 by devin doucette in ue5-main branch]
2022-02-03 16:49:32 -05:00
}
}
if (State->VerifyRequests.IsEmpty())
{
return InnerCache->PutValue(State->ForwardRequests, Owner, MoveTemp(OnComplete));
}
TArray<FCacheGetValueRequest> GetMetaRequests;
GetMetaRequests.Reserve(State->VerifyRequests.Num());
{
uint64 PutIndex = 0;
const ECachePolicy GetPolicy = ECachePolicy::Query | ECachePolicy::SkipData;
for (const FCachePutValueRequest& PutRequest : State->VerifyRequests)
{
GetMetaRequests.Add({PutRequest.Name, PutRequest.Key, GetPolicy, PutIndex++});
}
}
State->OnComplete = MoveTemp(OnComplete);
State->ActiveRequests = GetMetaRequests.Num();
InnerCache->GetValue(GetMetaRequests, Owner, [this, &Owner, State = State.Release()](FCacheGetValueResponse&& MetaResponse)
{
GetMetaComplete(Owner, State, MoveTemp(MetaResponse));
});
}
void FCacheStoreVerify::GetMetaComplete(IRequestOwner& Owner, FVerifyPutValueState* State, FCacheGetValueResponse&& Response)
{
FCachePutValueRequest& Request = State->VerifyRequests[int32(Response.UserData)];
if (Response.Status == EStatus::Ok)
{
if (Request.Value.GetRawHash() == Response.Value.GetRawHash())
{
UE_LOG(LogDerivedDataCache, Verbose,
DDC: Switched to the async cache hierarchy and fully implemented the verify wrapper The async cache hierarchy: - Is required to add compression to the legacy cache by forwarding LegacyPut/LegacyGet to PutValue/GetValue. - Is always present in the graph, unlike the previous cache hierarchy, which will allow significant simplification of leaf cache stores. - Allows for the leaf cache store nodes to operate asynchronously without blocking a worker thread like the previous cache hierarchy. - Shifts from controlling cache behavior by speed class to controlling cache behavior by local/remote classification, which is a critical distinction for a cache like Zen that can identify as both local and remote. - Respects the local/remote and query/store flags in the cache policy. - Does not fully implement the partial record cache policy at this time. - Does not propagate records or values in GetChunks, which will be added in a future release. The verify wrapper was previously missing an implementation for the new cache interface. This version is more efficient than the previous because requests through the new cache interface can compare data without loading it from storage, and load it only when a mismatch has been detected, to dump it to disk. #jira UE-134381 #lockdown Mark.Lintott #preflight 61fc32ac0a50c2606f266388 #rb Zousar.Shaker #rnx #ROBOMERGE-AUTHOR: devin.doucette #ROBOMERGE-SOURCE: CL 18851861 in //UE5/Release-5.0/... via CL 18851943 via CL 18852169 #ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v910-18824042) [CL 18852184 by devin doucette in ue5-main branch]
2022-02-03 16:49:32 -05:00
TEXT("Verify: Data in the cache matches newly generated data for %s from '%s'."),
*WriteToString<96>(Request.Key), *Request.Name);
State->OnComplete(Request.MakeResponse(EStatus::Ok));
}
else
{
const FCacheGetValueRequest GetDataRequests[]{{Response.Name, Response.Key, ECachePolicy::Default, Response.UserData}};
return InnerCache->GetValue(GetDataRequests, Owner, [this, &Owner, State](FCacheGetValueResponse&& DataResponse)
{
GetDataComplete(Owner, State, MoveTemp(DataResponse));
});
}
}
else
{
UE_LOG(LogDerivedDataCache, Display,
DDC: Switched to the async cache hierarchy and fully implemented the verify wrapper The async cache hierarchy: - Is required to add compression to the legacy cache by forwarding LegacyPut/LegacyGet to PutValue/GetValue. - Is always present in the graph, unlike the previous cache hierarchy, which will allow significant simplification of leaf cache stores. - Allows for the leaf cache store nodes to operate asynchronously without blocking a worker thread like the previous cache hierarchy. - Shifts from controlling cache behavior by speed class to controlling cache behavior by local/remote classification, which is a critical distinction for a cache like Zen that can identify as both local and remote. - Respects the local/remote and query/store flags in the cache policy. - Does not fully implement the partial record cache policy at this time. - Does not propagate records or values in GetChunks, which will be added in a future release. The verify wrapper was previously missing an implementation for the new cache interface. This version is more efficient than the previous because requests through the new cache interface can compare data without loading it from storage, and load it only when a mismatch has been detected, to dump it to disk. #jira UE-134381 #lockdown Mark.Lintott #preflight 61fc32ac0a50c2606f266388 #rb Zousar.Shaker #rnx #ROBOMERGE-AUTHOR: devin.doucette #ROBOMERGE-SOURCE: CL 18851861 in //UE5/Release-5.0/... via CL 18851943 via CL 18852169 #ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v910-18824042) [CL 18852184 by devin doucette in ue5-main branch]
2022-02-03 16:49:32 -05:00
TEXT("Verify: Cache did not contain a value for %s from '%s'."),
*WriteToString<96>(Request.Key), *Request.Name);
FWriteScopeLock Lock(State->Lock);
State->ForwardRequests.Add(MoveTemp(Request));
}
GetComplete(Owner, State);
}
void FCacheStoreVerify::GetDataComplete(IRequestOwner& Owner, FVerifyPutValueState* State, FCacheGetValueResponse&& Response)
{
FCachePutValueRequest& Request = State->VerifyRequests[int32(Response.UserData)];
if (Response.Status == EStatus::Ok)
{
if (Request.Value.GetRawHash() == Response.Value.GetRawHash())
{
UE_LOG(LogDerivedDataCache, Verbose,
DDC: Switched to the async cache hierarchy and fully implemented the verify wrapper The async cache hierarchy: - Is required to add compression to the legacy cache by forwarding LegacyPut/LegacyGet to PutValue/GetValue. - Is always present in the graph, unlike the previous cache hierarchy, which will allow significant simplification of leaf cache stores. - Allows for the leaf cache store nodes to operate asynchronously without blocking a worker thread like the previous cache hierarchy. - Shifts from controlling cache behavior by speed class to controlling cache behavior by local/remote classification, which is a critical distinction for a cache like Zen that can identify as both local and remote. - Respects the local/remote and query/store flags in the cache policy. - Does not fully implement the partial record cache policy at this time. - Does not propagate records or values in GetChunks, which will be added in a future release. The verify wrapper was previously missing an implementation for the new cache interface. This version is more efficient than the previous because requests through the new cache interface can compare data without loading it from storage, and load it only when a mismatch has been detected, to dump it to disk. #jira UE-134381 #lockdown Mark.Lintott #preflight 61fc32ac0a50c2606f266388 #rb Zousar.Shaker #rnx #ROBOMERGE-AUTHOR: devin.doucette #ROBOMERGE-SOURCE: CL 18851861 in //UE5/Release-5.0/... via CL 18851943 via CL 18852169 #ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v910-18824042) [CL 18852184 by devin doucette in ue5-main branch]
2022-02-03 16:49:32 -05:00
TEXT("Verify: Data in the cache matches newly generated data for %s from '%s'."),
*WriteToString<96>(Request.Key), *Request.Name);
State->OnComplete(Request.MakeResponse(EStatus::Ok));
}
else
{
LogChangedValue(Request.Name, Request.Key, FValueId::Null,
Request.Value.GetRawHash(), Response.Value.GetRawHash(),
Request.Value.GetData().DecompressToComposite(), Response.Value.GetData().DecompressToComposite());
DDC: Switched to the async cache hierarchy and fully implemented the verify wrapper The async cache hierarchy: - Is required to add compression to the legacy cache by forwarding LegacyPut/LegacyGet to PutValue/GetValue. - Is always present in the graph, unlike the previous cache hierarchy, which will allow significant simplification of leaf cache stores. - Allows for the leaf cache store nodes to operate asynchronously without blocking a worker thread like the previous cache hierarchy. - Shifts from controlling cache behavior by speed class to controlling cache behavior by local/remote classification, which is a critical distinction for a cache like Zen that can identify as both local and remote. - Respects the local/remote and query/store flags in the cache policy. - Does not fully implement the partial record cache policy at this time. - Does not propagate records or values in GetChunks, which will be added in a future release. The verify wrapper was previously missing an implementation for the new cache interface. This version is more efficient than the previous because requests through the new cache interface can compare data without loading it from storage, and load it only when a mismatch has been detected, to dump it to disk. #jira UE-134381 #lockdown Mark.Lintott #preflight 61fc32ac0a50c2606f266388 #rb Zousar.Shaker #rnx #ROBOMERGE-AUTHOR: devin.doucette #ROBOMERGE-SOURCE: CL 18851861 in //UE5/Release-5.0/... via CL 18851943 via CL 18852169 #ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v910-18824042) [CL 18852184 by devin doucette in ue5-main branch]
2022-02-03 16:49:32 -05:00
if (bPutOnError)
{
// Ask to overwrite existing values to potentially eliminate the mismatch.
UE_LOG(LogDerivedDataCache, Display,
TEXT("Verify: Writing newly generated data to the cache for %s from '%s'."),
*WriteToString<96>(Request.Key), *Request.Name);
Request.Policy &= ~ECachePolicy::Query;
FWriteScopeLock Lock(State->Lock);
State->ForwardRequests.Add(MoveTemp(Request));
}
else
{
State->OnComplete(Request.MakeResponse(EStatus::Ok));
}
}
}
else
{
UE_LOG(LogDerivedDataCache, Display,
DDC: Switched to the async cache hierarchy and fully implemented the verify wrapper The async cache hierarchy: - Is required to add compression to the legacy cache by forwarding LegacyPut/LegacyGet to PutValue/GetValue. - Is always present in the graph, unlike the previous cache hierarchy, which will allow significant simplification of leaf cache stores. - Allows for the leaf cache store nodes to operate asynchronously without blocking a worker thread like the previous cache hierarchy. - Shifts from controlling cache behavior by speed class to controlling cache behavior by local/remote classification, which is a critical distinction for a cache like Zen that can identify as both local and remote. - Respects the local/remote and query/store flags in the cache policy. - Does not fully implement the partial record cache policy at this time. - Does not propagate records or values in GetChunks, which will be added in a future release. The verify wrapper was previously missing an implementation for the new cache interface. This version is more efficient than the previous because requests through the new cache interface can compare data without loading it from storage, and load it only when a mismatch has been detected, to dump it to disk. #jira UE-134381 #lockdown Mark.Lintott #preflight 61fc32ac0a50c2606f266388 #rb Zousar.Shaker #rnx #ROBOMERGE-AUTHOR: devin.doucette #ROBOMERGE-SOURCE: CL 18851861 in //UE5/Release-5.0/... via CL 18851943 via CL 18852169 #ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v910-18824042) [CL 18852184 by devin doucette in ue5-main branch]
2022-02-03 16:49:32 -05:00
TEXT("Verify: Cache did not contain a value for %s from '%s'."),
*WriteToString<96>(Request.Key), *Request.Name);
FWriteScopeLock Lock(State->Lock);
State->ForwardRequests.Add(MoveTemp(Request));
}
GetComplete(Owner, State);
}
void FCacheStoreVerify::GetComplete(IRequestOwner& Owner, FVerifyPutValueState* State)
{
if (FWriteScopeLock Lock(State->Lock); --State->ActiveRequests > 0)
{
return;
}
if (!State->ForwardRequests.IsEmpty())
{
InnerCache->PutValue(State->ForwardRequests, Owner, MoveTemp(State->OnComplete));
}
delete State;
}
void FCacheStoreVerify::GetValue(
const TConstArrayView<FCacheGetValueRequest> Requests,
IRequestOwner& Owner,
FOnCacheGetValueComplete&& OnComplete)
{
TArray<FCacheGetValueRequest, TInlineAllocator<8>> ForwardRequests;
TArray<FCacheGetValueRequest, TInlineAllocator<8>> VerifyRequests;
ForwardRequests.Reserve(Requests.Num());
VerifyRequests.Reserve(Requests.Num());
{
FScopeLock Lock(&AlreadyTestedLock);
DDC: Switched to the async cache hierarchy and fully implemented the verify wrapper The async cache hierarchy: - Is required to add compression to the legacy cache by forwarding LegacyPut/LegacyGet to PutValue/GetValue. - Is always present in the graph, unlike the previous cache hierarchy, which will allow significant simplification of leaf cache stores. - Allows for the leaf cache store nodes to operate asynchronously without blocking a worker thread like the previous cache hierarchy. - Shifts from controlling cache behavior by speed class to controlling cache behavior by local/remote classification, which is a critical distinction for a cache like Zen that can identify as both local and remote. - Respects the local/remote and query/store flags in the cache policy. - Does not fully implement the partial record cache policy at this time. - Does not propagate records or values in GetChunks, which will be added in a future release. The verify wrapper was previously missing an implementation for the new cache interface. This version is more efficient than the previous because requests through the new cache interface can compare data without loading it from storage, and load it only when a mismatch has been detected, to dump it to disk. #jira UE-134381 #lockdown Mark.Lintott #preflight 61fc32ac0a50c2606f266388 #rb Zousar.Shaker #rnx #ROBOMERGE-AUTHOR: devin.doucette #ROBOMERGE-SOURCE: CL 18851861 in //UE5/Release-5.0/... via CL 18851943 via CL 18852169 #ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v910-18824042) [CL 18852184 by devin doucette in ue5-main branch]
2022-02-03 16:49:32 -05:00
for (const FCacheGetValueRequest& Request : Requests)
{
const bool bForward = !Filter.IsMatch(Request.Key) || AlreadyTested.Contains(Request.Key);
(bForward ? ForwardRequests : VerifyRequests).Add(Request);
DDC: Switched to the async cache hierarchy and fully implemented the verify wrapper The async cache hierarchy: - Is required to add compression to the legacy cache by forwarding LegacyPut/LegacyGet to PutValue/GetValue. - Is always present in the graph, unlike the previous cache hierarchy, which will allow significant simplification of leaf cache stores. - Allows for the leaf cache store nodes to operate asynchronously without blocking a worker thread like the previous cache hierarchy. - Shifts from controlling cache behavior by speed class to controlling cache behavior by local/remote classification, which is a critical distinction for a cache like Zen that can identify as both local and remote. - Respects the local/remote and query/store flags in the cache policy. - Does not fully implement the partial record cache policy at this time. - Does not propagate records or values in GetChunks, which will be added in a future release. The verify wrapper was previously missing an implementation for the new cache interface. This version is more efficient than the previous because requests through the new cache interface can compare data without loading it from storage, and load it only when a mismatch has been detected, to dump it to disk. #jira UE-134381 #lockdown Mark.Lintott #preflight 61fc32ac0a50c2606f266388 #rb Zousar.Shaker #rnx #ROBOMERGE-AUTHOR: devin.doucette #ROBOMERGE-SOURCE: CL 18851861 in //UE5/Release-5.0/... via CL 18851943 via CL 18852169 #ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v910-18824042) [CL 18852184 by devin doucette in ue5-main branch]
2022-02-03 16:49:32 -05:00
}
}
CompleteWithStatus(VerifyRequests, OnComplete, EStatus::Error);
if (!ForwardRequests.IsEmpty())
{
InnerCache->GetValue(ForwardRequests, Owner, MoveTemp(OnComplete));
}
}
void FCacheStoreVerify::GetChunks(
const TConstArrayView<FCacheGetChunkRequest> Requests,
IRequestOwner& Owner,
FOnCacheGetChunkComplete&& OnComplete)
{
TArray<FCacheGetChunkRequest, TInlineAllocator<8>> ForwardRequests;
TArray<FCacheGetChunkRequest, TInlineAllocator<8>> VerifyRequests;
ForwardRequests.Reserve(Requests.Num());
VerifyRequests.Reserve(Requests.Num());
{
FScopeLock Lock(&AlreadyTestedLock);
DDC: Switched to the async cache hierarchy and fully implemented the verify wrapper The async cache hierarchy: - Is required to add compression to the legacy cache by forwarding LegacyPut/LegacyGet to PutValue/GetValue. - Is always present in the graph, unlike the previous cache hierarchy, which will allow significant simplification of leaf cache stores. - Allows for the leaf cache store nodes to operate asynchronously without blocking a worker thread like the previous cache hierarchy. - Shifts from controlling cache behavior by speed class to controlling cache behavior by local/remote classification, which is a critical distinction for a cache like Zen that can identify as both local and remote. - Respects the local/remote and query/store flags in the cache policy. - Does not fully implement the partial record cache policy at this time. - Does not propagate records or values in GetChunks, which will be added in a future release. The verify wrapper was previously missing an implementation for the new cache interface. This version is more efficient than the previous because requests through the new cache interface can compare data without loading it from storage, and load it only when a mismatch has been detected, to dump it to disk. #jira UE-134381 #lockdown Mark.Lintott #preflight 61fc32ac0a50c2606f266388 #rb Zousar.Shaker #rnx #ROBOMERGE-AUTHOR: devin.doucette #ROBOMERGE-SOURCE: CL 18851861 in //UE5/Release-5.0/... via CL 18851943 via CL 18852169 #ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v910-18824042) [CL 18852184 by devin doucette in ue5-main branch]
2022-02-03 16:49:32 -05:00
for (const FCacheGetChunkRequest& Request : Requests)
{
const bool bForward = !Filter.IsMatch(Request.Key) || AlreadyTested.Contains(Request.Key);
(bForward ? ForwardRequests : VerifyRequests).Add(Request);
DDC: Switched to the async cache hierarchy and fully implemented the verify wrapper The async cache hierarchy: - Is required to add compression to the legacy cache by forwarding LegacyPut/LegacyGet to PutValue/GetValue. - Is always present in the graph, unlike the previous cache hierarchy, which will allow significant simplification of leaf cache stores. - Allows for the leaf cache store nodes to operate asynchronously without blocking a worker thread like the previous cache hierarchy. - Shifts from controlling cache behavior by speed class to controlling cache behavior by local/remote classification, which is a critical distinction for a cache like Zen that can identify as both local and remote. - Respects the local/remote and query/store flags in the cache policy. - Does not fully implement the partial record cache policy at this time. - Does not propagate records or values in GetChunks, which will be added in a future release. The verify wrapper was previously missing an implementation for the new cache interface. This version is more efficient than the previous because requests through the new cache interface can compare data without loading it from storage, and load it only when a mismatch has been detected, to dump it to disk. #jira UE-134381 #lockdown Mark.Lintott #preflight 61fc32ac0a50c2606f266388 #rb Zousar.Shaker #rnx #ROBOMERGE-AUTHOR: devin.doucette #ROBOMERGE-SOURCE: CL 18851861 in //UE5/Release-5.0/... via CL 18851943 via CL 18852169 #ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v910-18824042) [CL 18852184 by devin doucette in ue5-main branch]
2022-02-03 16:49:32 -05:00
}
}
CompleteWithStatus(VerifyRequests, OnComplete, EStatus::Error);
if (!ForwardRequests.IsEmpty())
{
InnerCache->GetChunks(ForwardRequests, Owner, MoveTemp(OnComplete));
}
}
bool FCacheStoreVerify::CompareRecords(const FCacheRecord& PutRecord, const FCacheRecord& GetRecord, const FSharedString& Name)
{
bool bEqual = true;
const FCacheKey& Key = PutRecord.GetKey();
const TConstArrayView<FValueWithId> PutValues = PutRecord.GetValues();
const TConstArrayView<FValueWithId> GetValues = GetRecord.GetValues();
const FValueWithId* PutIt = PutValues.GetData();
const FValueWithId* GetIt = GetValues.GetData();
const FValueWithId* const PutEnd = PutIt + PutValues.Num();
const FValueWithId* const GetEnd = GetIt + GetValues.Num();
const auto LogNewValue = [&Name, &Key](const FValueWithId& Value)
{
UE_LOG(LogDerivedDataCache, Error,
TEXT("Verify: Value %s with hash %s is in the new record but does not exist in the cache for %s from '%s'."),
*WriteToString<32>(Value.GetId()), *WriteToString<48>(Value.GetRawHash()), *WriteToString<96>(Key), *Name);
};
const auto LogOldValue = [&Name, &Key](const FValueWithId& Value)
{
UE_LOG(LogDerivedDataCache, Error,
TEXT("Verify: Value %s with hash %s is in the cache but does not exist in the new record for %s from '%s'."),
*WriteToString<32>(Value.GetId()), *WriteToString<48>(Value.GetRawHash()), *WriteToString<96>(Key), *Name);
};
while (PutIt != PutEnd && GetIt != GetEnd)
{
if (PutIt->GetId() == GetIt->GetId())
{
if (PutIt->GetRawHash() != GetIt->GetRawHash())
{
LogChangedValue(Name, Key, PutIt->GetId(),
PutIt->GetRawHash(), GetIt->GetRawHash(),
PutIt->GetData().DecompressToComposite(), GetIt->GetData().DecompressToComposite());
DDC: Switched to the async cache hierarchy and fully implemented the verify wrapper The async cache hierarchy: - Is required to add compression to the legacy cache by forwarding LegacyPut/LegacyGet to PutValue/GetValue. - Is always present in the graph, unlike the previous cache hierarchy, which will allow significant simplification of leaf cache stores. - Allows for the leaf cache store nodes to operate asynchronously without blocking a worker thread like the previous cache hierarchy. - Shifts from controlling cache behavior by speed class to controlling cache behavior by local/remote classification, which is a critical distinction for a cache like Zen that can identify as both local and remote. - Respects the local/remote and query/store flags in the cache policy. - Does not fully implement the partial record cache policy at this time. - Does not propagate records or values in GetChunks, which will be added in a future release. The verify wrapper was previously missing an implementation for the new cache interface. This version is more efficient than the previous because requests through the new cache interface can compare data without loading it from storage, and load it only when a mismatch has been detected, to dump it to disk. #jira UE-134381 #lockdown Mark.Lintott #preflight 61fc32ac0a50c2606f266388 #rb Zousar.Shaker #rnx #ROBOMERGE-AUTHOR: devin.doucette #ROBOMERGE-SOURCE: CL 18851861 in //UE5/Release-5.0/... via CL 18851943 via CL 18852169 #ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v910-18824042) [CL 18852184 by devin doucette in ue5-main branch]
2022-02-03 16:49:32 -05:00
bEqual = false;
}
++PutIt;
++GetIt;
}
else if (PutIt->GetId() < GetIt->GetId())
{
LogNewValue(*PutIt++);
bEqual = false;
}
else
{
LogOldValue(*GetIt++);
bEqual = false;
}
}
while (PutIt != PutEnd)
{
LogNewValue(*PutIt++);
bEqual = false;
}
while (GetIt != GetEnd)
{
LogOldValue(*GetIt++);
bEqual = false;
}
return bEqual;
}
void FCacheStoreVerify::LogChangedValue(
const FSharedString& Name,
const FCacheKey& Key,
const FValueId& Id,
const FIoHash& NewRawHash,
const FIoHash& OldRawHash,
const FCompositeBuffer& NewRawData,
const FCompositeBuffer& OldRawData)
DDC: Switched to the async cache hierarchy and fully implemented the verify wrapper The async cache hierarchy: - Is required to add compression to the legacy cache by forwarding LegacyPut/LegacyGet to PutValue/GetValue. - Is always present in the graph, unlike the previous cache hierarchy, which will allow significant simplification of leaf cache stores. - Allows for the leaf cache store nodes to operate asynchronously without blocking a worker thread like the previous cache hierarchy. - Shifts from controlling cache behavior by speed class to controlling cache behavior by local/remote classification, which is a critical distinction for a cache like Zen that can identify as both local and remote. - Respects the local/remote and query/store flags in the cache policy. - Does not fully implement the partial record cache policy at this time. - Does not propagate records or values in GetChunks, which will be added in a future release. The verify wrapper was previously missing an implementation for the new cache interface. This version is more efficient than the previous because requests through the new cache interface can compare data without loading it from storage, and load it only when a mismatch has been detected, to dump it to disk. #jira UE-134381 #lockdown Mark.Lintott #preflight 61fc32ac0a50c2606f266388 #rb Zousar.Shaker #rnx #ROBOMERGE-AUTHOR: devin.doucette #ROBOMERGE-SOURCE: CL 18851861 in //UE5/Release-5.0/... via CL 18851943 via CL 18852169 #ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v910-18824042) [CL 18852184 by devin doucette in ue5-main branch]
2022-02-03 16:49:32 -05:00
{
TStringBuilder<32> IdString;
if (Id.IsValid())
{
IdString << TEXT(' ') << Id;
}
const auto LogDataToFile = [&Name, &Key, &Id, &IdString](const FIoHash& RawHash, const FCompositeBuffer& RawData, FStringView Extension)
DDC: Switched to the async cache hierarchy and fully implemented the verify wrapper The async cache hierarchy: - Is required to add compression to the legacy cache by forwarding LegacyPut/LegacyGet to PutValue/GetValue. - Is always present in the graph, unlike the previous cache hierarchy, which will allow significant simplification of leaf cache stores. - Allows for the leaf cache store nodes to operate asynchronously without blocking a worker thread like the previous cache hierarchy. - Shifts from controlling cache behavior by speed class to controlling cache behavior by local/remote classification, which is a critical distinction for a cache like Zen that can identify as both local and remote. - Respects the local/remote and query/store flags in the cache policy. - Does not fully implement the partial record cache policy at this time. - Does not propagate records or values in GetChunks, which will be added in a future release. The verify wrapper was previously missing an implementation for the new cache interface. This version is more efficient than the previous because requests through the new cache interface can compare data without loading it from storage, and load it only when a mismatch has been detected, to dump it to disk. #jira UE-134381 #lockdown Mark.Lintott #preflight 61fc32ac0a50c2606f266388 #rb Zousar.Shaker #rnx #ROBOMERGE-AUTHOR: devin.doucette #ROBOMERGE-SOURCE: CL 18851861 in //UE5/Release-5.0/... via CL 18851943 via CL 18852169 #ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v910-18824042) [CL 18852184 by devin doucette in ue5-main branch]
2022-02-03 16:49:32 -05:00
{
if (!RawData.IsNull())
DDC: Switched to the async cache hierarchy and fully implemented the verify wrapper The async cache hierarchy: - Is required to add compression to the legacy cache by forwarding LegacyPut/LegacyGet to PutValue/GetValue. - Is always present in the graph, unlike the previous cache hierarchy, which will allow significant simplification of leaf cache stores. - Allows for the leaf cache store nodes to operate asynchronously without blocking a worker thread like the previous cache hierarchy. - Shifts from controlling cache behavior by speed class to controlling cache behavior by local/remote classification, which is a critical distinction for a cache like Zen that can identify as both local and remote. - Respects the local/remote and query/store flags in the cache policy. - Does not fully implement the partial record cache policy at this time. - Does not propagate records or values in GetChunks, which will be added in a future release. The verify wrapper was previously missing an implementation for the new cache interface. This version is more efficient than the previous because requests through the new cache interface can compare data without loading it from storage, and load it only when a mismatch has been detected, to dump it to disk. #jira UE-134381 #lockdown Mark.Lintott #preflight 61fc32ac0a50c2606f266388 #rb Zousar.Shaker #rnx #ROBOMERGE-AUTHOR: devin.doucette #ROBOMERGE-SOURCE: CL 18851861 in //UE5/Release-5.0/... via CL 18851943 via CL 18852169 #ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v910-18824042) [CL 18852184 by devin doucette in ue5-main branch]
2022-02-03 16:49:32 -05:00
{
TStringBuilder<256> Path;
FPathViews::Append(Path, FPaths::ProjectSavedDir(), TEXT("VerifyDDC"), TEXT(""));
Path << Key.Bucket << TEXT('_') << Key.Hash;
if (Id.IsValid())
{
Path << TEXT('_') << Id;
}
Path << Extension;
if (TUniquePtr<FArchive> Ar{IFileManager::Get().CreateFileWriter(*Path, FILEWRITE_Silent)})
{
for (const FSharedBuffer& Segment : RawData.GetSegments())
{
Ar->Serialize(const_cast<void*>(Segment.GetData()), int64(Segment.GetSize()));
}
DDC: Switched to the async cache hierarchy and fully implemented the verify wrapper The async cache hierarchy: - Is required to add compression to the legacy cache by forwarding LegacyPut/LegacyGet to PutValue/GetValue. - Is always present in the graph, unlike the previous cache hierarchy, which will allow significant simplification of leaf cache stores. - Allows for the leaf cache store nodes to operate asynchronously without blocking a worker thread like the previous cache hierarchy. - Shifts from controlling cache behavior by speed class to controlling cache behavior by local/remote classification, which is a critical distinction for a cache like Zen that can identify as both local and remote. - Respects the local/remote and query/store flags in the cache policy. - Does not fully implement the partial record cache policy at this time. - Does not propagate records or values in GetChunks, which will be added in a future release. The verify wrapper was previously missing an implementation for the new cache interface. This version is more efficient than the previous because requests through the new cache interface can compare data without loading it from storage, and load it only when a mismatch has been detected, to dump it to disk. #jira UE-134381 #lockdown Mark.Lintott #preflight 61fc32ac0a50c2606f266388 #rb Zousar.Shaker #rnx #ROBOMERGE-AUTHOR: devin.doucette #ROBOMERGE-SOURCE: CL 18851861 in //UE5/Release-5.0/... via CL 18851943 via CL 18852169 #ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v910-18824042) [CL 18852184 by devin doucette in ue5-main branch]
2022-02-03 16:49:32 -05:00
}
}
else
{
UE_LOG(LogDerivedDataCache, Log,
TEXT("Verify: Value%s does not have data with hash %s to save to disk for %s from '%s'."),
*IdString, *WriteToString<48>(RawHash), *WriteToString<96>(Key), *Name);
DDC: Switched to the async cache hierarchy and fully implemented the verify wrapper The async cache hierarchy: - Is required to add compression to the legacy cache by forwarding LegacyPut/LegacyGet to PutValue/GetValue. - Is always present in the graph, unlike the previous cache hierarchy, which will allow significant simplification of leaf cache stores. - Allows for the leaf cache store nodes to operate asynchronously without blocking a worker thread like the previous cache hierarchy. - Shifts from controlling cache behavior by speed class to controlling cache behavior by local/remote classification, which is a critical distinction for a cache like Zen that can identify as both local and remote. - Respects the local/remote and query/store flags in the cache policy. - Does not fully implement the partial record cache policy at this time. - Does not propagate records or values in GetChunks, which will be added in a future release. The verify wrapper was previously missing an implementation for the new cache interface. This version is more efficient than the previous because requests through the new cache interface can compare data without loading it from storage, and load it only when a mismatch has been detected, to dump it to disk. #jira UE-134381 #lockdown Mark.Lintott #preflight 61fc32ac0a50c2606f266388 #rb Zousar.Shaker #rnx #ROBOMERGE-AUTHOR: devin.doucette #ROBOMERGE-SOURCE: CL 18851861 in //UE5/Release-5.0/... via CL 18851943 via CL 18852169 #ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v910-18824042) [CL 18852184 by devin doucette in ue5-main branch]
2022-02-03 16:49:32 -05:00
}
};
UE_LOG(LogDerivedDataCache, Error,
TEXT("Verify: Value%s has hash %s in the newly generated data and hash %s in the cache for %s from '%s'."),
*IdString, *WriteToString<48>(NewRawHash), *WriteToString<48>(OldRawHash), *WriteToString<96>(Key), *Name);
LogDataToFile(NewRawHash, NewRawData, TEXTVIEW(".verify"));
LogDataToFile(OldRawHash, OldRawData, TEXTVIEW(".fromcache"));
DDC: Switched to the async cache hierarchy and fully implemented the verify wrapper The async cache hierarchy: - Is required to add compression to the legacy cache by forwarding LegacyPut/LegacyGet to PutValue/GetValue. - Is always present in the graph, unlike the previous cache hierarchy, which will allow significant simplification of leaf cache stores. - Allows for the leaf cache store nodes to operate asynchronously without blocking a worker thread like the previous cache hierarchy. - Shifts from controlling cache behavior by speed class to controlling cache behavior by local/remote classification, which is a critical distinction for a cache like Zen that can identify as both local and remote. - Respects the local/remote and query/store flags in the cache policy. - Does not fully implement the partial record cache policy at this time. - Does not propagate records or values in GetChunks, which will be added in a future release. The verify wrapper was previously missing an implementation for the new cache interface. This version is more efficient than the previous because requests through the new cache interface can compare data without loading it from storage, and load it only when a mismatch has been detected, to dump it to disk. #jira UE-134381 #lockdown Mark.Lintott #preflight 61fc32ac0a50c2606f266388 #rb Zousar.Shaker #rnx #ROBOMERGE-AUTHOR: devin.doucette #ROBOMERGE-SOURCE: CL 18851861 in //UE5/Release-5.0/... via CL 18851943 via CL 18852169 #ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v910-18824042) [CL 18852184 by devin doucette in ue5-main branch]
2022-02-03 16:49:32 -05:00
}
ILegacyCacheStore* CreateCacheStoreVerify(ILegacyCacheStore* InnerCache, bool bPutOnError)
{
return new FCacheStoreVerify(InnerCache, bPutOnError);
}
} // UE::DerivedData