Files
UnrealEngineUWP/Engine/Source/Developer/DerivedDataCache/Private/DerivedDataBuildJobContext.cpp
devin doucette c29fdcf532 DDC: Compress payloads using Oodle Mermaid VeryFast
#rb Zousar.Shaker
#rnx

#ROBOMERGE-SOURCE: CL 16956293 in //UE5/Main/...
#ROBOMERGE-BOT: STARSHIP (Main -> Release-Engine-Test) (v838-16927207)

[CL 16956298 by devin doucette in ue5-release-engine-test branch]
2021-07-26 10:29:10 -04:00

168 lines
5.5 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "DerivedDataBuildJobContext.h"
#include "DerivedDataBuildJob.h"
#include "DerivedDataBuildOutput.h"
#include "DerivedDataBuildPolicy.h"
#include "DerivedDataBuildPrivate.h"
#include "DerivedDataCache.h"
#include "DerivedDataPayloadPrivate.h"
#include "Hash/Blake3.h"
#include "Misc/StringBuilder.h"
#include "UObject/NameTypes.h"
namespace UE::DerivedData::Private
{
FBuildJobContext::FBuildJobContext(
IBuildJob& InJob,
const FCacheKey& InCacheKey,
const IBuildFunction& InFunction,
FBuildOutputBuilder& InOutputBuilder,
EBuildPolicy InBuildPolicy,
TUniqueFunction<void ()>&& InOnEndAsyncBuild)
: Job(InJob)
, CacheKey(InCacheKey)
, Function(InFunction)
, OutputBuilder(InOutputBuilder)
, OnEndAsyncBuild(MoveTemp(InOnEndAsyncBuild))
, CachePolicy(ECachePolicy::Default)
, BuildPolicy(InBuildPolicy)
{
}
FStringView FBuildJobContext::GetName() const
{
return Job.GetName();
}
void FBuildJobContext::AddConstant(FStringView Key, FCbObject&& Value)
{
Constants.EmplaceByHash(GetTypeHash(Key), Key, MoveTemp(Value));
}
void FBuildJobContext::AddInput(FStringView Key, const FCompressedBuffer& Value)
{
Inputs.EmplaceByHash(GetTypeHash(Key), Key, Value);
}
void FBuildJobContext::ResetInputs()
{
Constants.Empty();
Inputs.Empty();
}
FCbObject FBuildJobContext::FindConstant(FStringView Key) const
{
if (const FCbObject* Object = Constants.FindByHash(GetTypeHash(Key), Key))
{
return *Object;
}
return FCbObject();
}
FSharedBuffer FBuildJobContext::FindInput(FStringView Key) const
{
if (const FCompressedBuffer* Input = Inputs.FindByHash(GetTypeHash(Key), Key))
{
FSharedBuffer Buffer = Input->Decompress();
const FBlake3Hash RawHash = FBlake3::HashBuffer(Buffer);
if (RawHash == Input->GetRawHash() && Buffer.GetSize() == Input->GetRawSize())
{
return Buffer;
}
else
{
TStringBuilder<256> Error;
Error << TEXT("Input '") << Key << TEXT("' was expected to have raw hash ") << Input->GetRawHash()
<< TEXT(" and raw size ") << Input->GetRawSize() << TEXT(" but has raw hash ") << RawHash
<< TEXT(" and raw size ") << Buffer.GetSize() << TEXT(" after decompression for build of '")
<< Job.GetName() << TEXT("' by ") << Job.GetFunction() << TEXT(".");
OutputBuilder.AddError(TEXT("LogDerivedDataBuild"_SV), Error);
UE_LOG(LogDerivedDataBuild, Error, TEXT("%.*s"), Error.Len(), Error.GetData());
}
}
return FSharedBuffer();
}
void FBuildJobContext::AddPayload(const FPayload& Payload)
{
OutputBuilder.AddPayload(Payload);
}
void FBuildJobContext::AddPayload(const FPayloadId& Id, const FCompressedBuffer& Buffer)
{
AddPayload(FPayload(Id, Buffer));
}
void FBuildJobContext::AddPayload(const FPayloadId& Id, const FCompositeBuffer& Buffer)
{
AddPayload(FPayload(Id, FCompressedBuffer::Compress(Buffer, GDefaultCompressor, GDefaultCompressionLevel)));
}
void FBuildJobContext::AddPayload(const FPayloadId& Id, const FSharedBuffer& Buffer)
{
AddPayload(FPayload(Id, FCompressedBuffer::Compress(Buffer, GDefaultCompressor, GDefaultCompressionLevel)));
}
void FBuildJobContext::AddPayload(const FPayloadId& Id, const FCbObject& Object)
{
const FCompositeBuffer& Buffer = Object.GetBuffer();
AddPayload(FPayload(Id, FCompressedBuffer::Compress(Buffer, GDefaultCompressor, GDefaultCompressionLevel)));
}
void FBuildJobContext::BeginAsyncBuild()
{
checkf(!bIsAsyncBuild, TEXT("BeginAsyncBuild may only be called once for build of '%s' by %s."),
*WriteToString<128>(Job.GetName()), *WriteToString<32>(Job.GetFunction()));
bIsAsyncBuild = true;
}
void FBuildJobContext::EndAsyncBuild()
{
checkf(bIsAsyncBuild, TEXT("EndAsyncBuild may only be called after BeginAsyncBuild for build of '%s' by %s."),
*WriteToString<128>(Job.GetName()), *WriteToString<32>(Job.GetFunction()));
checkf(!bIsAsyncBuildComplete, TEXT("EndAsyncBuild may only be called once for build of '%s' by %s."),
*WriteToString<128>(Job.GetName()), *WriteToString<32>(Job.GetFunction()));
bIsAsyncBuildComplete = true;
OnEndAsyncBuild();
}
FCacheBucket FBuildJobContext::CreateCacheBucket(FStringView Name) const
{
return Job.GetCache().CreateBucket(Name);
}
void FBuildJobContext::SetCacheBucket(FCacheBucket Bucket)
{
checkf(!Bucket.IsNull(), TEXT("Null cache bucket not allowed for build of '%s' by %s. ")
TEXT("The cache can be disabled by calling SetCachePolicy(ECachePolicy::Disable)."),
*WriteToString<128>(Job.GetName()), *WriteToString<32>(Job.GetFunction()));
CacheKey.Bucket = Bucket;
}
void FBuildJobContext::SetCachePolicy(ECachePolicy Policy)
{
checkf(!EnumHasAnyFlags(Policy, ECachePolicy::SkipData),
TEXT("SkipData flags not allowed on the cache policy for build of '%s' by %s. ")
TEXT("Flags for skipping data may be set indirectly through EBuildPolicy."),
*WriteToString<128>(Job.GetName()), *WriteToString<32>(Job.GetFunction()));
CachePolicy = Policy;
}
void FBuildJobContext::SetBuildPolicy(EBuildPolicy Policy)
{
checkf(!EnumHasAnyFlags(BuildPolicy ^ Policy, EBuildPolicy::Cache),
TEXT("Cache flags may not be modified on the build policy for build of '%s' by %s. ")
TEXT("Flags for modifying cache operations may be set through ECachePolicy."),
*WriteToString<128>(Job.GetName()), *WriteToString<32>(Job.GetFunction()));
checkf(!EnumHasAnyFlags(BuildPolicy ^ Policy, EBuildPolicy::SkipData),
TEXT("SkipData flag may not be modified on the build policy for build of '%s' by %s. ")
TEXT("Flags for skipping the data may only be set through the build session."),
*WriteToString<128>(Job.GetName()), *WriteToString<32>(Job.GetFunction()));
BuildPolicy = Policy;
}
} // UE::DerivedData::Private