You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
- ICacheStore::Put() has updated documentation to reflect the requirements of partial records. - ICacheStore::Get() now takes a FCacheRecordPolicy, which is implicitly constructible from ECachePolicy, and allows setting the policy by payload. - ICacheStore::GetPayload() is replaced by ICacheStore::GetChunks(), which allows loading parts of payloads. - ICacheStore::CancelAll() is moved to ICache::CancelAll() because the cache can track requests at the top level and cancel them without exposing cancellation on individual cache stores. - ECachePolicy::SkipLocalCopy has been removed because it is difficult to reason about. - ECachePolicy::SkipData flags now have a documented meaning for put requests, to hint that record existence implies payload existence. - The filesystem and memory cache stores have been updated to support partial records, filtering of payloads, and loading parts of payloads. - Requesting part of a payload will decompress the entire payload for now, until compressed buffers expose a way to decompress only part. - Fixed a bug in FTexturePlatformData::AreDerivedMipsAvailable() that caused it to return false for structured cache keys. #rb Zousar.Shaker #rnx #preflight 615e03241ed62f0001b95454 #ROBOMERGE-OWNER: Devin.Doucette #ROBOMERGE-AUTHOR: devin.doucette #ROBOMERGE-SOURCE: CL 17748550 in //UE5/Release-5.0/... via CL 17748555 #ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v879-17706426) #ROBOMERGE-CONFLICT from-shelf #ROBOMERGE[STARSHIP]: UE5-Main [CL 17748602 by Devin Doucette in ue5-release-engine-test branch]
386 lines
15 KiB
C++
386 lines
15 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "CoreTypes.h"
|
|
#include "Containers/StringFwd.h"
|
|
#include "DerivedDataCacheKey.h"
|
|
#include "DerivedDataPayloadId.h"
|
|
#include "DerivedDataRequestTypes.h"
|
|
#include "Math/NumericLimits.h"
|
|
#include "Misc/EnumClassFlags.h"
|
|
#include "Templates/Function.h"
|
|
#include "Templates/RefCounting.h"
|
|
|
|
#define UE_API DERIVEDDATACACHE_API
|
|
|
|
namespace UE::DerivedData { class FCacheRecord; }
|
|
namespace UE::DerivedData { class FCacheRecordPolicy; }
|
|
namespace UE::DerivedData { class IRequestOwner; }
|
|
namespace UE::DerivedData { struct FCacheChunkRequest; }
|
|
namespace UE::DerivedData { struct FCacheGetChunkCompleteParams; }
|
|
namespace UE::DerivedData { struct FCacheGetCompleteParams; }
|
|
namespace UE::DerivedData { struct FCachePutCompleteParams; }
|
|
namespace UE::DerivedData::Private { class ICacheRecordPolicyShared; }
|
|
|
|
namespace UE::DerivedData
|
|
{
|
|
|
|
using FOnCachePutComplete = TUniqueFunction<void (FCachePutCompleteParams&& Params)>;
|
|
using FOnCacheGetComplete = TUniqueFunction<void (FCacheGetCompleteParams&& Params)>;
|
|
using FOnCacheGetChunkComplete = TUniqueFunction<void (FCacheGetChunkCompleteParams&& Params)>;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/**
|
|
* Flags to control the behavior of cache requests.
|
|
*
|
|
* The cache policy flags can be combined to support a variety of usage patterns. Examples:
|
|
*
|
|
* Get(Default): read from any cache; put to writable caches if missing.
|
|
* Get(Remote): read any remote cache; put to writable remote caches if missing.
|
|
* Get(Local): read any local cache; put to writable local caches if missing.
|
|
* Get(Query | StoreRemote): read from any cache; put to writable remote caches if missing.
|
|
* Get(Query | StoreLocal): read from any cache; put to writable local caches if missing.
|
|
* Get(Query | SkipData): check for existence in any cache; do not modify any cache.
|
|
* Get(Default | SkipData): check for existence in any cache; put to writable caches if missing.
|
|
* Get(Default | SkipLocalCopy): read from any cache; put to writable remote caches if missing,
|
|
* and to writable local caches if not present in any local cache.
|
|
*
|
|
* Put(Default): write to every writable cache.
|
|
* Put(Remote): write to every writable remote cache, skipping local caches.
|
|
* Put(Local): write to every writable local cache, skipping remote caches.
|
|
*/
|
|
enum class ECachePolicy : uint32
|
|
{
|
|
/** A value without any flags set. */
|
|
None = 0,
|
|
|
|
/** Allow a cache request to query local caches. */
|
|
QueryLocal = 1 << 0,
|
|
/** Allow a cache request to query remote caches. */
|
|
QueryRemote = 1 << 1,
|
|
/** Allow a cache request to query local and remote caches. */
|
|
Query = QueryLocal | QueryRemote,
|
|
|
|
/** Allow cache records and values to be stored in local caches. */
|
|
StoreLocal = 1 << 2,
|
|
/** Allow cache records and values to be stored in remote caches. */
|
|
StoreRemote = 1 << 3,
|
|
/** Allow cache records and values to be stored in local and remote caches. */
|
|
Store = StoreLocal | StoreRemote,
|
|
|
|
/** Skip fetching the metadata for record requests. */
|
|
SkipMeta = 1 << 4,
|
|
/** Skip fetching the value for record, chunk, or value requests. */
|
|
SkipValue = 1 << 5,
|
|
/** Skip fetching the attachments for record requests. */
|
|
SkipAttachments = 1 << 6,
|
|
/**
|
|
* Skip fetching the data for any requests.
|
|
*
|
|
* Put requests with skip flags may assume that record existence implies payload existence.
|
|
*/
|
|
SkipData = SkipMeta | SkipValue | SkipAttachments,
|
|
|
|
/**
|
|
* Keep records in the cache for at least the duration of the session.
|
|
*
|
|
* This is a hint that the record may be accessed again in this session. This is mainly meant
|
|
* to be used when subsequent accesses will not tolerate a cache miss.
|
|
*/
|
|
KeepAlive = 1 << 7,
|
|
|
|
/** Allow cache requests to query and store records in local caches. */
|
|
Local = QueryLocal | StoreLocal,
|
|
/** Allow cache requests to query and store records in remote caches. */
|
|
Remote = QueryRemote | StoreRemote,
|
|
|
|
/** Allow cache requests to query and store records in local and remote caches. */
|
|
Default = Query | Store,
|
|
|
|
/** Do not allow cache requests to query or store records in local or remote caches. */
|
|
Disable = None,
|
|
};
|
|
|
|
ENUM_CLASS_FLAGS(ECachePolicy);
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/** A payload ID and the policy to use for that payload. */
|
|
struct FCachePayloadPolicy
|
|
{
|
|
FPayloadId Id;
|
|
ECachePolicy Policy = ECachePolicy::Default;
|
|
};
|
|
|
|
/** Interface for the private implementation of the cache record policy. */
|
|
class Private::ICacheRecordPolicyShared
|
|
{
|
|
public:
|
|
virtual ~ICacheRecordPolicyShared() = default;
|
|
virtual void AddRef() const = 0;
|
|
virtual void Release() const = 0;
|
|
virtual TConstArrayView<FCachePayloadPolicy> GetPayloadPolicies() const = 0;
|
|
virtual void AddPayloadPolicy(const FCachePayloadPolicy& Policy) = 0;
|
|
virtual void Build() = 0;
|
|
};
|
|
|
|
/** A policy for cache record requests, with optional overrides by payload. */
|
|
class FCacheRecordPolicy
|
|
{
|
|
public:
|
|
/** Construct a cache record policy that uses the default policy for records and payloads. */
|
|
FCacheRecordPolicy() = default;
|
|
|
|
/** Construct a cache record policy from a single policy for both records and payloads. */
|
|
inline FCacheRecordPolicy(ECachePolicy Policy)
|
|
: BasePolicy(Policy)
|
|
, RecordPolicy(Policy)
|
|
{
|
|
}
|
|
|
|
/** Returns true if the record and every payload use the same policy. */
|
|
inline bool IsUniform() const { return !Shared && BasePolicy == RecordPolicy; }
|
|
|
|
/** Returns the cache policy to use for the record. */
|
|
inline ECachePolicy GetRecordPolicy() const { return RecordPolicy; }
|
|
|
|
/** Returns the cache policy to use for the payload. */
|
|
UE_API ECachePolicy GetPayloadPolicy(const FPayloadId& Id) const;
|
|
|
|
/** Returns the cache policy to use for payloads with no override. */
|
|
inline ECachePolicy GetDefaultPayloadPolicy() const { return BasePolicy; }
|
|
|
|
/** Returns the array of cache policy overrides for payloads, sorted by ID. */
|
|
inline TConstArrayView<FCachePayloadPolicy> GetPayloadPolicies() const
|
|
{
|
|
return Shared ? Shared->GetPayloadPolicies() : TConstArrayView<FCachePayloadPolicy>();
|
|
}
|
|
|
|
private:
|
|
friend class FCacheRecordPolicyBuilder;
|
|
|
|
ECachePolicy BasePolicy = ECachePolicy::Default;
|
|
ECachePolicy RecordPolicy = ECachePolicy::Default;
|
|
TRefCountPtr<const Private::ICacheRecordPolicyShared> Shared;
|
|
};
|
|
|
|
/** A cache record policy builder is used to construct a cache record policy. */
|
|
class FCacheRecordPolicyBuilder
|
|
{
|
|
public:
|
|
/** Construct a cache record policy builder that uses the default policy as its base policy. */
|
|
FCacheRecordPolicyBuilder() = default;
|
|
|
|
/** Construct a cache record policy builder from the base policy for the record and its payloads. */
|
|
inline explicit FCacheRecordPolicyBuilder(ECachePolicy Policy)
|
|
: BasePolicy(Policy)
|
|
{
|
|
}
|
|
|
|
/** Adds a cache policy override for a payload. */
|
|
UE_API void AddPayloadPolicy(const FCachePayloadPolicy& Policy);
|
|
inline void AddPayloadPolicy(const FPayloadId& Id, ECachePolicy Policy) { AddPayloadPolicy({Id, Policy}); }
|
|
|
|
/** Build a cache record policy, which makes this builder subsequently unusable. */
|
|
UE_API FCacheRecordPolicy Build();
|
|
|
|
private:
|
|
ECachePolicy BasePolicy = ECachePolicy::Default;
|
|
TRefCountPtr<Private::ICacheRecordPolicyShared> Shared;
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/**
|
|
* Interface to a store of cache records.
|
|
*
|
|
* Functions on this interface may be called from any thread. When a callback is provided, it may
|
|
* be invoked from a different thread than the request was made on, and may be invoked before the
|
|
* request function returns, both of which must be supported by the caller and the callback.
|
|
*/
|
|
class ICacheStore
|
|
{
|
|
public:
|
|
virtual ~ICacheStore() = default;
|
|
|
|
/**
|
|
* Asynchronous request to put cache records according to the policy.
|
|
*
|
|
* The callback will always be called for every key, and may be called from an arbitrary thread.
|
|
* Records may finish storing in any order, and from multiple threads concurrently.
|
|
*
|
|
* A cache store is free to interpret a record containing only a key as a request to delete that
|
|
* record from the store. Records may contain payloads that do not have data, and these payloads
|
|
* must reference an existing copy of the payload in the store, if available, and must otherwise
|
|
* be stored as a partial record that can attempt recovery of missing payloads when fetched.
|
|
*
|
|
* @param Records The cache records to store. Must have a key.
|
|
* @param Context A description of the request. An object path is typically sufficient.
|
|
* @param Policy Flags to control the behavior of the request. See ECachePolicy.
|
|
* @param Owner The owner to execute the request within.
|
|
* @param OnComplete A callback invoked for every record as it completes or is canceled.
|
|
*/
|
|
virtual void Put(
|
|
TConstArrayView<FCacheRecord> Records,
|
|
FStringView Context,
|
|
ECachePolicy Policy,
|
|
IRequestOwner& Owner,
|
|
FOnCachePutComplete&& OnComplete = FOnCachePutComplete()) = 0;
|
|
|
|
/**
|
|
* Asynchronous request to get cache records according to the policy.
|
|
*
|
|
* The callback will always be called for every key, and may be called from an arbitrary thread.
|
|
* Records may become available in any order, and from multiple threads concurrently.
|
|
*
|
|
* Records may propagate into other cache stores, in accordance with the policy. A propagated
|
|
* record may be a partial record, with some payloads missing data, depending on the policy.
|
|
*
|
|
* When payloads are required by the policy, but not available, the status must be Error, but
|
|
* the cache store may provide a partial record with the available payloads, to be completed,
|
|
* when possible, by another cache store.
|
|
*
|
|
* @param Keys The keys identifying the cache records to query.
|
|
* @param Context A description of the request. An object path is typically sufficient.
|
|
* @param Policy Flags to control the behavior of the request. See FCacheRecordPolicy.
|
|
* @param Owner The owner to execute the request within.
|
|
* @param OnComplete A callback invoked for every key as it completes or is canceled.
|
|
*/
|
|
virtual void Get(
|
|
TConstArrayView<FCacheKey> Keys,
|
|
FStringView Context,
|
|
FCacheRecordPolicy Policy,
|
|
IRequestOwner& Owner,
|
|
FOnCacheGetComplete&& OnComplete) = 0;
|
|
|
|
/**
|
|
* Asynchronous request to get chunks, which are subsets of payloads, from cache records.
|
|
*
|
|
* The callback will always be called for every chunk, and may be called from an arbitrary thread.
|
|
* Chunks may become available in any order, and from multiple threads concurrently.
|
|
*
|
|
* There is no requirement that the cache store validate the existence of other payloads from
|
|
* the requested records. Requests for whole payloads may propagate those payloads into other
|
|
* cache stores, in accordance with the policy, through a put of a partial record.
|
|
*
|
|
* @param Chunks The keys, IDs, offsets, and sizes of the chunks to query.
|
|
* @param Context A description of the request. An object path is typically sufficient.
|
|
* @param Owner The owner to execute the request within.
|
|
* @param OnComplete A callback invoked for every chunk as it completes or is canceled.
|
|
*/
|
|
virtual void GetChunks(
|
|
TConstArrayView<FCacheChunkRequest> Chunks,
|
|
FStringView Context,
|
|
IRequestOwner& Owner,
|
|
FOnCacheGetChunkComplete&& OnComplete) = 0;
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/**
|
|
* Interface to the cache.
|
|
*
|
|
* @see ICacheStore for cache record storage.
|
|
*/
|
|
class ICache : public ICacheStore
|
|
{
|
|
public:
|
|
virtual ~ICache() = default;
|
|
|
|
/**
|
|
* Cancel all queued and active cache requests and invoke their callbacks.
|
|
*
|
|
* This is meant to be called before destroying the cache. Any new requests that are made during
|
|
* execution of this function will also be canceled, because callbacks might queue requests when
|
|
* they are invoked. This does not block any future cache requests, which must be handled by the
|
|
* owner of the cache if future requests are meant to be avoided.
|
|
*/
|
|
virtual void CancelAll() = 0;
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/** Parameters for the completion callback for cache put requests. */
|
|
struct FCachePutCompleteParams
|
|
{
|
|
/** Key for the part of the put request that completed or was canceled. */
|
|
FCacheKey Key;
|
|
|
|
/** Status of the cache request. */
|
|
EStatus Status = EStatus::Error;
|
|
};
|
|
|
|
/** Parameters for the completion callback for cache get requests. */
|
|
struct FCacheGetCompleteParams
|
|
{
|
|
/**
|
|
* Record for the part of the get request that completed or was canceled.
|
|
*
|
|
* The key is always populated. The remainder of the record is populated when Status is Ok.
|
|
*
|
|
* The value, attachments, and metadata may be skipped based on cache policy flags. When a value
|
|
* or attachment has been skipped, it will have a payload but its data will be null.
|
|
*/
|
|
FCacheRecord&& Record;
|
|
|
|
/** Status of the cache request. */
|
|
EStatus Status = EStatus::Error;
|
|
};
|
|
|
|
/** Parameters to request a chunk, which is a subset of a payload, from a cache record. */
|
|
struct FCacheChunkRequest
|
|
{
|
|
/** The key identifying the cache record to fetch the payload from. */
|
|
FCacheKey Key;
|
|
|
|
/** The ID of the payload to fetch from the cache record. */
|
|
FPayloadId Id;
|
|
|
|
/** The offset into the raw bytes of the payload at which to start fetching. */
|
|
uint64 RawOffset = 0;
|
|
|
|
/** The maximum number of raw bytes of the payload to fetch, starting from the offset. */
|
|
uint64 RawSize = MAX_uint64;
|
|
|
|
/** Flags to control the behavior of the request. See ECachePolicy. */
|
|
ECachePolicy Policy = ECachePolicy::Default;
|
|
};
|
|
|
|
/** Parameters for the completion callback for cache chunk requests. */
|
|
struct FCacheGetChunkCompleteParams
|
|
{
|
|
/** Key from the chunk request that completed or was canceled. */
|
|
FCacheKey Key;
|
|
|
|
/** ID from the chunk request that completed or was canceled. */
|
|
FPayloadId Id;
|
|
|
|
/** Offset from the chunk request that completed or was canceled. */
|
|
uint64 RawOffset = 0;
|
|
|
|
/** Size, in bytes, of the subset of the payload that was fetched, if any. */
|
|
uint64 RawSize = 0;
|
|
|
|
/** Hash of the entire payload, even if only a subset was fetched. */
|
|
const FIoHash& RawHash;
|
|
|
|
/** Data for the subset of the payload that was fetched when Status is Ok, otherwise null. */
|
|
FSharedBuffer&& RawData;
|
|
|
|
/** Status of the cache request. */
|
|
EStatus Status = EStatus::Error;
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/** Returns a reference to the cache. Asserts if not available. */
|
|
UE_API ICache& GetCache();
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
} // UE::DerivedData
|
|
|
|
#undef UE_API
|